summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configs/default1
-rw-r--r--configure.ac7
-rw-r--r--docs/relnotes-7.5.2.html4
-rw-r--r--docs/relnotes-7.6.html6
-rw-r--r--docs/relnotes-7.7.html1
-rw-r--r--include/GL/gl.h15
-rw-r--r--progs/SConscript1
-rw-r--r--progs/demos/cubemap.c21
-rw-r--r--progs/demos/lodbias.c4
-rw-r--r--progs/fp/add-sat.txt6
-rw-r--r--progs/fp/mov-alias.txt6
-rw-r--r--progs/fp/mul-alias.txt6
-rw-r--r--progs/glsl/Makefile17
-rw-r--r--progs/perf/Makefile55
-rw-r--r--progs/perf/SConscript32
-rw-r--r--progs/perf/common.c133
-rw-r--r--progs/perf/common.h44
-rw-r--r--progs/perf/copytex.c214
-rw-r--r--progs/perf/drawoverhead.c137
-rw-r--r--progs/perf/fbobind.c153
-rw-r--r--progs/perf/fill.c248
-rw-r--r--progs/perf/genmipmap.c136
-rw-r--r--progs/perf/glmain.c268
-rw-r--r--progs/perf/glmain.h68
-rw-r--r--progs/perf/readpixels.c169
-rw-r--r--progs/perf/swapbuffers.c161
-rw-r--r--progs/perf/teximage.c331
-rw-r--r--progs/perf/vbo.c246
-rw-r--r--progs/perf/vertexrate.c276
-rw-r--r--progs/tests/zreaddraw.c67
-rw-r--r--progs/vp/vp-tris.c6
-rw-r--r--scons/crossmingw.py2
-rw-r--r--scons/dxsdk.py15
-rw-r--r--scons/gallium.py6
-rw-r--r--scons/llvm.py6
-rw-r--r--scons/winddk.py45
-rw-r--r--src/gallium/auxiliary/draw/draw_pt_post_vs.c2
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c4
-rw-r--r--src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.c1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_scan.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c100
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c249
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h35
-rw-r--r--src/gallium/auxiliary/util/u_debug.h14
-rw-r--r--src/gallium/auxiliary/util/u_format.csv2
-rw-r--r--src/gallium/auxiliary/util/u_math.h12
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c29
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c7
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c10
-rw-r--r--src/gallium/drivers/i965simple/brw_screen.c4
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile2
-rw-r--r--src/gallium/drivers/llvmpipe/README23
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.c145
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.h18
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.c30
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.h32
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_conv.c46
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_conv.h14
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_flow.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_flow.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format_soa.c6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.h2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.c19
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_sample.h4
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.c21
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi.h6
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c450
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.c25
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.h123
-rw-r--r--src/gallium/drivers/llvmpipe/lp_clear.c1
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c9
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c21
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c16
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test.h20
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_blend.c34
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_conv.c76
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_main.c28
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_c.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.c48
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.h37
-rw-r--r--src/gallium/drivers/nv04/nv04_screen.c2
-rw-r--r--src/gallium/drivers/nv10/nv10_screen.c2
-rw-r--r--src/gallium/drivers/nv20/nv20_screen.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c2
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h3
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c1728
-rw-r--r--src/gallium/drivers/nv50/nv50_program.h35
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c4
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c6
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c22
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c4
-rw-r--r--src/gallium/drivers/r300/r300_context.h11
-rw-r--r--src/gallium/drivers/r300/r300_emit.c4
-rw-r--r--src/gallium/drivers/r300/r300_render.c68
-rw-r--r--src/gallium/drivers/r300/r300_screen.c9
-rw-r--r--src/gallium/drivers/r300/r300_surface.c6
-rw-r--r--src/gallium/drivers/r300/r300_texture.c41
-rw-r--r--src/gallium/drivers/r300/r300_texture.h7
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c1
-rw-r--r--src/gallium/drivers/softpipe/Makefile14
-rw-r--r--src/gallium/drivers/softpipe/SConscript10
-rw-r--r--src/gallium/drivers/softpipe/sp_clear.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_clear.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c114
-rw-r--r--src/gallium/drivers/softpipe/sp_context.h66
-rw-r--r--src/gallium/drivers/softpipe/sp_flush.c25
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c85
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_llvm.c205
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_sse.c77
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.c190
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_setup.h85
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.c189
-rw-r--r--src/gallium/drivers/softpipe/sp_prim_vbuf.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad.h6
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_alpha_test.c108
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_blend.c1401
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_bufloop.c74
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_colormask.c116
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_coverage.c94
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_depth_test.c903
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_earlyz.c88
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_fs.c105
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_occlusion.c85
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_output.c103
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.c89
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_pipe.h4
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stencil.c352
-rw-r--r--src/gallium/drivers/softpipe/sp_quad_stipple.c22
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c10
-rw-r--r--src/gallium/drivers/softpipe/sp_setup.c487
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_state_blend.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c103
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c17
-rw-r--r--src/gallium/drivers/softpipe/sp_state_sampler.c127
-rw-r--r--src/gallium/drivers/softpipe/sp_state_surface.c54
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c2506
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.h123
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.c273
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_tile_cache.h155
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c50
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h9
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.c282
-rw-r--r--src/gallium/drivers/softpipe/sp_tile_cache.h88
-rw-r--r--src/gallium/drivers/trace/tr_context.c10
-rw-r--r--src/gallium/include/pipe/p_defines.h2
-rw-r--r--src/gallium/include/pipe/p_inlines.h28
-rw-r--r--src/gallium/include/pipe/p_state.h24
-rw-r--r--src/gallium/include/pipe/p_thread.h10
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_basic_csc.c12
-rw-r--r--src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf_shaders.inc14
-rw-r--r--src/gallium/state_trackers/wgl/SConscript25
-rw-r--r--src/gallium/state_trackers/wgl/opengl32.def1
-rw-r--r--src/gallium/state_trackers/wgl/opengl32.mingw.def1
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_context.c382
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_public.h73
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.c (renamed from src/gallium/state_trackers/wgl/icd/stw_icd.c)478
-rw-r--r--src/gallium/state_trackers/wgl/stw_context.h (renamed from src/gallium/state_trackers/wgl/shared/stw_context.h)8
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.c (renamed from src/gallium/state_trackers/wgl/shared/stw_device.c)85
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h (renamed from src/gallium/state_trackers/wgl/shared/stw_device.h)9
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c (renamed from src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.c (renamed from src/gallium/state_trackers/wgl/shared/stw_extgallium.c)2
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_gallium.h (renamed from src/gallium/state_trackers/wgl/shared/stw_extgallium.h)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_pixelformat.c (renamed from src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c)1
-rw-r--r--src/gallium/state_trackers/wgl/stw_ext_swapinterval.c (renamed from src/gallium/state_trackers/wgl/shared/stw_extswapinterval.c)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.c (renamed from src/gallium/state_trackers/wgl/shared/stw_framebuffer.c)208
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.h (renamed from src/gallium/state_trackers/wgl/shared/stw_framebuffer.h)16
-rw-r--r--src/gallium/state_trackers/wgl/stw_getprocaddress.c (renamed from src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c)7
-rw-r--r--src/gallium/state_trackers/wgl/stw_icd.h (renamed from src/gallium/state_trackers/wgl/icd/stw_icd.h)114
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c (renamed from src/gallium/state_trackers/wgl/shared/stw_pixelformat.c)67
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.h (renamed from src/gallium/state_trackers/wgl/shared/stw_pixelformat.h)11
-rw-r--r--src/gallium/state_trackers/wgl/stw_tls.c (renamed from src/gallium/state_trackers/wgl/shared/stw_tls.c)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_tls.h (renamed from src/gallium/state_trackers/wgl/shared/stw_tls.h)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_wgl.c (renamed from src/gallium/state_trackers/wgl/wgl/stw_wgl.c)63
-rw-r--r--src/gallium/state_trackers/wgl/stw_wgl.h (renamed from src/gallium/state_trackers/wgl/wgl/stw_wgl.h)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_winsys.h (renamed from src/gallium/state_trackers/wgl/shared/stw_winsys.h)54
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c245
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c138
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h5
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c45
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h6
-rw-r--r--src/gallium/state_trackers/xorg/xorg_xv.c212
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c3
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c2
-rw-r--r--src/gallium/winsys/drm/nouveau/xorg/Makefile61
-rw-r--r--src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c149
-rw-r--r--src/gallium/winsys/g3dvl/xsp_winsys.c1
-rw-r--r--src/gallium/winsys/gdi/SConscript60
-rw-r--r--src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c288
-rw-r--r--src/gallium/winsys/gdi/gdi_softpipe_winsys.c14
-rw-r--r--src/gallium/winsys/xlib/Makefile1
-rw-r--r--src/gallium/winsys/xlib/xlib_llvmpipe.c3
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c98
-rw-r--r--src/glx/x11/glx_pbuffer.c36
-rw-r--r--src/glx/x11/glxhash.c11
-rw-r--r--src/mesa/drivers/common/driverfuncs.c19
-rw-r--r--src/mesa/drivers/common/meta.c1025
-rw-r--r--src/mesa/drivers/common/meta.h101
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h10
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_tex.c18
-rw-r--r--src/mesa/drivers/dri/glcore/Makefile84
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_curbe.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h5
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_batch.c15
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c53
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c83
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c38
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c94
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c5
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_clear.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c16
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_generatemipmap.c25
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_copy.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_draw.c8
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c43
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c25
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c5
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c5
-rw-r--r--src/mesa/drivers/dri/r200/Makefile3
-rw-r--r--src/mesa/drivers/dri/r300/Makefile3
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program.c35
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c18
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.c18
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c46
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.h14
-rw-r--r--src/mesa/drivers/dri/r600/Makefile4
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c52
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.h54
-rw-r--r--src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h2
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c513
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.h13
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c123
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c36
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c734
-rw-r--r--src/mesa/drivers/dri/r600/r700_shader.c90
-rw-r--r--src/mesa/drivers/dri/r600/r700_shader.h1
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.c44
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.h1
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.c314
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.h28
l---------src/mesa/drivers/dri/r600/radeon_buffer_objects.c1
l---------src/mesa/drivers/dri/r600/radeon_buffer_objects.h1
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_buffer_objects.c11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_debug.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_debug.h11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c62
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c255
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c10
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_tex.c11
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c4
-rw-r--r--src/mesa/drivers/dri/tdfx/tdfx_tex.c136
-rw-r--r--src/mesa/drivers/dri/unichrome/via_tex.c5
-rw-r--r--src/mesa/drivers/osmesa/osmesa.c5
-rw-r--r--src/mesa/drivers/windows/gdi/mesa.def18
-rw-r--r--src/mesa/drivers/windows/gdi/wmesa.c5
-rw-r--r--src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c26
-rw-r--r--src/mesa/drivers/windows/icd/mesa.def18
-rw-r--r--src/mesa/drivers/x11/xm_api.c6
-rw-r--r--src/mesa/drivers/x11/xm_dd.c10
-rw-r--r--src/mesa/glapi/EXT_provoking_vertex.xml13
-rw-r--r--src/mesa/glapi/glapitemp.h6
-rw-r--r--src/mesa/glapi/glprocs.h2
-rw-r--r--src/mesa/glapi/mesadef.py18
-rw-r--r--src/mesa/main/api_exec.c49
-rw-r--r--src/mesa/main/api_validate.c45
-rw-r--r--src/mesa/main/api_validate.h6
-rw-r--r--src/mesa/main/bufferobj.c6
-rw-r--r--src/mesa/main/colortab.c57
-rw-r--r--src/mesa/main/colortab.h71
-rw-r--r--src/mesa/main/compiler.h3
-rw-r--r--src/mesa/main/context.c6
-rw-r--r--src/mesa/main/convolve.c56
-rw-r--r--src/mesa/main/convolve.h118
-rw-r--r--src/mesa/main/dlist.c659
-rw-r--r--src/mesa/main/enable.c7
-rw-r--r--src/mesa/main/enums.c4808
-rw-r--r--src/mesa/main/execmem.c7
-rw-r--r--src/mesa/main/extensions.c1
-rw-r--r--src/mesa/main/fbobject.c45
-rw-r--r--src/mesa/main/mfeatures.h32
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/main/pixel.c40
-rw-r--r--src/mesa/main/pixel.h47
-rw-r--r--src/mesa/main/state.c4
-rw-r--r--src/mesa/main/texenvprogram.c1
-rw-r--r--src/mesa/main/texgen.c9
-rw-r--r--src/mesa/main/teximage.c741
-rw-r--r--src/mesa/main/texobj.c4
-rw-r--r--src/mesa/main/texparam.c6
-rw-r--r--src/mesa/main/texrender.c13
-rw-r--r--src/mesa/main/texstate.c6
-rw-r--r--src/mesa/main/texstore.c95
-rw-r--r--src/mesa/shader/nvprogram.c72
-rw-r--r--src/mesa/shader/nvprogram.h6
-rw-r--r--src/mesa/shader/nvvertparse.c27
-rw-r--r--src/mesa/shader/prog_execute.c7
-rw-r--r--src/mesa/shader/prog_instruction.h1
-rw-r--r--src/mesa/shader/prog_parameter.c1
-rw-r--r--src/mesa/shader/program.c8
-rw-r--r--src/mesa/shader/program_parse.tab.c410
-rw-r--r--src/mesa/shader/program_parse.y12
-rw-r--r--src/mesa/shader/shader_api.c15
-rw-r--r--src/mesa/shader/slang/slang_builtin.c4
-rw-r--r--src/mesa/shader/slang/slang_codegen.c2
-rw-r--r--src/mesa/shader/slang/slang_link.c28
-rw-r--r--src/mesa/sources.mak2
-rw-r--r--src/mesa/sparc/glapi_sparc.S1
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c56
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c34
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c1
-rw-r--r--src/mesa/state_tracker/st_cb_program.c9
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c30
-rw-r--r--src/mesa/state_tracker/st_draw.c12
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c18
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c1490
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h9
-rw-r--r--src/mesa/state_tracker/st_program.c130
-rw-r--r--src/mesa/swrast/s_fragprog.c11
-rw-r--r--src/mesa/swrast/s_imaging.c196
-rw-r--r--src/mesa/swrast/s_texfilter.c12
-rw-r--r--src/mesa/swrast/s_texstore.c601
-rw-r--r--src/mesa/swrast/swrast.h54
-rw-r--r--src/mesa/vbo/vbo_exec_array.c58
-rw-r--r--src/mesa/vbo/vbo_rebase.c5
-rw-r--r--src/mesa/x86-64/glapi_x86-64.S1
-rw-r--r--src/mesa/x86/glapi_x86.S1
-rw-r--r--src/xvmc/context.c3
-rw-r--r--src/xvmc/subpicture.c5
-rw-r--r--src/xvmc/surface.c3
-rw-r--r--windows/VC7/mesa/mesa/mesa.vcproj6
-rw-r--r--windows/VC8/mesa/mesa/mesa.vcproj8
374 files changed, 20498 insertions, 13052 deletions
diff --git a/configs/default b/configs/default
index 9e4bb08ea9e..cb3ca1046f4 100644
--- a/configs/default
+++ b/configs/default
@@ -23,6 +23,7 @@ HOST_CC = $(CC)
CFLAGS = -O
CXXFLAGS = -O
LDFLAGS =
+HOST_CFLAGS = $(CFLAGS)
GLU_CFLAGS =
# Compiler for building demos/tests/etc
diff --git a/configure.ac b/configure.ac
index c5ef676e2e5..2881bb6bc25 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1148,6 +1148,11 @@ yes)
if test "$tracker" = egl && test "x$enable_egl" != xyes; then
AC_MSG_ERROR([cannot build egl state tracker without EGL library])
fi
+ if test "$tracker" = xorg; then
+ PKG_CHECK_MODULES(XEXT, [xextproto >= 7.0.99.1],
+ HAVE_XEXTPROTO_71="yes"; DEFINES="$DEFINES -DHAVE_XEXTPROTO_71"
+ HAVE_XEXTPROTO_71="no")
+ fi
done
GALLIUM_STATE_TRACKERS_DIRS="$state_trackers"
;;
@@ -1202,7 +1207,7 @@ if test "x$enable_gallium_radeon" = xyes; then
fi
dnl
-dnl Gallium Radeon configuration
+dnl Gallium Nouveau configuration
dnl
AC_ARG_ENABLE([gallium-nouveau],
[AS_HELP_STRING([--enable-gallium-nouveau],
diff --git a/docs/relnotes-7.5.2.html b/docs/relnotes-7.5.2.html
index 32100142c0c..b638c0517dd 100644
--- a/docs/relnotes-7.5.2.html
+++ b/docs/relnotes-7.5.2.html
@@ -45,6 +45,10 @@ tbd
<ul>
<li>Assorted bug fixes for i965/i945 drivers
<li>Fixed Gallium glDrawPixels(GL_STENCIL_INDEX) failure.
+<li>Fixed GLSL linker/preprocessor version directive issue seen in Wine
+ (such as bug 23946)
+<li>glUseProgram() is now compiled into display lists (bug 23746).
+<li>glUniform functions are now compiled into display lists
</ul>
diff --git a/docs/relnotes-7.6.html b/docs/relnotes-7.6.html
index 8a476378e8a..aaa36188d9d 100644
--- a/docs/relnotes-7.6.html
+++ b/docs/relnotes-7.6.html
@@ -50,6 +50,8 @@ This was written by Zack Rusin at Tungsten Graphics.
<li>Rewritten radeon/r200/r300 driver using a buffer manager
<li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with
kernel memory manager
+<li>radeon/r200/r300 support for GL_ARB_occlusion_query</li>
+<li>r300 driver supports OpenGL 1.5</li>
<li>r300 driver support for GL_EXT_vertex_array_bgra, GL_EXT_texture_sRGB
<li>i915/945 driver support for GL_ARB_point_sprite, GL_EXT_stencil_two_side
and GL_ATI_separate_stencil extensions
@@ -57,6 +59,10 @@ This was written by Zack Rusin at Tungsten Graphics.
GL_ARB_fragment_program.</li>
<li>Added configure --with-max-width=W, --with-max-height=H options to specify
max framebuffer, viewport size.
+<li>Initial version of Gallium llvmpipe driver. This is a new driver based
+ on LLVM which makes exensive use of run-time code generation. This is
+ an "alpha" stage driver. See the src/gallium/drivers/llvmpipe/README
+ file for more information.
</ul>
diff --git a/docs/relnotes-7.7.html b/docs/relnotes-7.7.html
index 755e8ac5208..ca6ec55b601 100644
--- a/docs/relnotes-7.7.html
+++ b/docs/relnotes-7.7.html
@@ -37,6 +37,7 @@ tbd
<li>GL_ARB_draw_elements_base_vertex (supported in Intel i965 and software drivers)</li>
<li>GL_ARB_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
<li>GL_NV_depth_clamp (supported in Intel i965 DRI and software drivers)</li>
+<li>GL_ARB_provoking_vertex (same as GL_EXT_provoking_vertex)</li>
</ul>
diff --git a/include/GL/gl.h b/include/GL/gl.h
index 05362b97762..5f8bc2b708c 100644
--- a/include/GL/gl.h
+++ b/include/GL/gl.h
@@ -1740,6 +1740,9 @@ GLAPI void GLAPIENTRY glSeparableFilter2D( GLenum target,
GLAPI void GLAPIENTRY glGetSeparableFilter( GLenum target, GLenum format,
GLenum type, GLvoid *row, GLvoid *column, GLvoid *span );
+typedef void (APIENTRYP PFNGLBLENDCOLORPROC) (GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONPROC) (GLenum mode);
+
/*
@@ -1945,6 +1948,18 @@ GLAPI void GLAPIENTRY glMultTransposeMatrixf( const GLfloat m[16] );
GLAPI void GLAPIENTRY glSampleCoverage( GLclampf value, GLboolean invert );
+typedef void (APIENTRYP PFNGLACTIVETEXTUREPROC) (GLenum texture);
+typedef void (APIENTRYP PFNGLSAMPLECOVERAGEPROC) (GLclampf value, GLboolean invert);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE3DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE2DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXIMAGE1DPROC) (GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) (GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid *data);
+typedef void (APIENTRYP PFNGLGETCOMPRESSEDTEXIMAGEPROC) (GLenum target, GLint level, GLvoid *img);
+
+
+
/*
* GL_ARB_multitexture (ARB extension 1 and OpenGL 1.2.1)
*/
diff --git a/progs/SConscript b/progs/SConscript
index 620dd30e69c..66eaf9e5410 100644
--- a/progs/SConscript
+++ b/progs/SConscript
@@ -10,4 +10,5 @@ SConscript([
'vpglsl/SConscript',
'fp/SConscript',
'wgl/SConscript',
+ 'perf/SConscript',
])
diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c
index 0df5ff09c33..20332b1d960 100644
--- a/progs/demos/cubemap.c
+++ b/progs/demos/cubemap.c
@@ -58,6 +58,9 @@ static GLint ClampIndex = 0;
static GLboolean supportFBO = GL_FALSE;
static GLboolean supportSeamless = GL_FALSE;
static GLboolean seamless = GL_FALSE;
+static GLuint TexObj = 0;
+static GLint T0 = 0;
+static GLint Frames = 0;
static struct {
@@ -282,6 +285,20 @@ static void draw( void )
glPopMatrix();
glutSwapBuffers();
+
+ Frames++;
+
+ {
+ GLint t = glutGet(GLUT_ELAPSED_TIME);
+ if (t - T0 >= 5000) {
+ GLfloat seconds = (t - T0) / 1000.0;
+ GLfloat fps = Frames / seconds;
+ printf("%d frames in %6.3f seconds = %6.3f FPS\n", Frames, seconds, fps);
+ fflush(stdout);
+ T0 = t;
+ Frames = 0;
+ }
+ }
}
@@ -543,6 +560,10 @@ static void init( GLboolean useImageFiles )
printf("GL_RENDERER: %s\n", (char *) glGetString(GL_RENDERER));
+
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_CUBE_MAP_ARB, TexObj);
+
if (useImageFiles) {
load_envmaps();
}
diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c
index 30b1ed13d5f..8d39bd605a7 100644
--- a/progs/demos/lodbias.c
+++ b/progs/demos/lodbias.c
@@ -43,6 +43,7 @@ static GLboolean Anim = GL_TRUE;
static GLint Bias = 0, BiasStepSign = +1; /* ints avoid fp precision problem */
static GLint BiasMin = -400, BiasMax = 400;
static int win = 0;
+static GLuint TexObj = 0;
static void
@@ -214,6 +215,9 @@ static void Init( void )
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+
if (glutExtensionSupported("GL_SGIS_generate_mipmap")) {
/* test auto mipmap generation */
GLint width, height, i;
diff --git a/progs/fp/add-sat.txt b/progs/fp/add-sat.txt
new file mode 100644
index 00000000000..2253efb0855
--- /dev/null
+++ b/progs/fp/add-sat.txt
@@ -0,0 +1,6 @@
+!!ARBfp1.0
+TEMP R0;
+MOV R0, fragment.color;
+ADD_SAT R0, R0, R0;
+MUL result.color, {0.5}.x, R0;
+END
diff --git a/progs/fp/mov-alias.txt b/progs/fp/mov-alias.txt
new file mode 100644
index 00000000000..5f04e9c76e2
--- /dev/null
+++ b/progs/fp/mov-alias.txt
@@ -0,0 +1,6 @@
+!!ARBfp1.0
+TEMP R0;
+MOV R0, fragment.color;
+MOV R0, R0.zyxw;
+MOV result.color, R0;
+END
diff --git a/progs/fp/mul-alias.txt b/progs/fp/mul-alias.txt
new file mode 100644
index 00000000000..cf7d359e780
--- /dev/null
+++ b/progs/fp/mul-alias.txt
@@ -0,0 +1,6 @@
+!!ARBfp1.0
+TEMP R0;
+MOV R0, fragment.color;
+MUL R0, R0.zyxw, fragment.color;
+MOV result.color, R0;
+END
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
index 8103a5cbca0..8928c833c0e 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -10,16 +10,15 @@ LIB_DEP = \
$(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) \
$(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME)
-LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
-
-INCLUDE_DIRS = -I$(TOP)/progs/util
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) \
+ -l$(GL_LIB) $(APP_LIB_DEPS)
# using : to avoid APP_CC pointing to CC loop
-CC:=$(APP_CC)
-CFLAGS += -I$(INCDIR)
-LDLIBS=$(LIBS)
+CC := $(APP_CC)
+CFLAGS := -I$(INCDIR) $(CFLAGS)
+LDLIBS = $(LIBS)
-DEMO_SOURCES = \
+PROG_SOURCES = \
array.c \
bitmap.c \
brick.c \
@@ -59,8 +58,8 @@ UTIL_SOURCES = \
readtex.c
UTIL_OBJS = $(UTIL_SOURCES:.c=.o)
-PROG_OBJS = $(DEMO_SOURCES:.c=.o)
-PROGS = $(DEMO_SOURCES:%.c=%)
+PROG_OBJS = $(PROG_SOURCES:.c=.o)
+PROGS = $(PROG_SOURCES:%.c=%)
##### TARGETS #####
diff --git a/progs/perf/Makefile b/progs/perf/Makefile
new file mode 100644
index 00000000000..066eb8608ec
--- /dev/null
+++ b/progs/perf/Makefile
@@ -0,0 +1,55 @@
+# progs/demos/Makefile
+
+TOP = ../..
+include $(TOP)/configs/current
+
+INCDIR = $(TOP)/include
+
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) \
+ -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS)
+
+# using : to avoid APP_CC pointing to CC loop
+CC := $(APP_CC)
+CFLAGS += -I$(INCDIR)
+LDLIBS = $(LIBS)
+
+PROG_SOURCES = \
+ copytex.c \
+ drawoverhead.c \
+ fbobind.c \
+ fill.c \
+ genmipmap.c \
+ readpixels.c \
+ swapbuffers.c \
+ teximage.c \
+ vbo.c \
+ vertexrate.c \
+
+PROG_OBJS = $(PROG_SOURCES:.c=.o)
+
+PROGS = $(PROG_SOURCES:%.c=%)
+
+
+UTIL_SOURCES = \
+ common.c \
+ glmain.c
+
+UTIL_HEADERS = \
+ common.h \
+ glmain.h
+
+UTIL_OBJS = $(UTIL_SOURCES:.c=.o)
+
+
+
+default: $(PROGS)
+
+$(PROG_OBJS): $(UTIL_HEADERS)
+
+$(PROGS): $(UTIL_OBJS)
+
+
+
+clean:
+ -rm -f $(PROGS)
+ -rm -f *.o *~
diff --git a/progs/perf/SConscript b/progs/perf/SConscript
new file mode 100644
index 00000000000..a5ec9a7c2a0
--- /dev/null
+++ b/progs/perf/SConscript
@@ -0,0 +1,32 @@
+Import('env')
+
+if not env['GLUT']:
+ Return()
+
+env = env.Clone()
+
+env.Prepend(LIBS = ['$GLUT_LIB'])
+
+progs = [
+ 'copytex',
+ 'drawoverhead',
+ 'fbobind',
+ 'fill',
+ 'genmipmap',
+ 'readpixels',
+ 'swapbuffers',
+ 'teximage',
+ 'vbo',
+ 'vertexrate',
+]
+
+for prog in progs:
+ env.Program(
+ target = prog,
+ source = [
+ prog + '.c',
+ 'common.c',
+ 'glmain.c',
+ ]
+ )
+
diff --git a/progs/perf/common.c b/progs/perf/common.c
new file mode 100644
index 00000000000..722f4b7b454
--- /dev/null
+++ b/progs/perf/common.c
@@ -0,0 +1,133 @@
+/*
+ * 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.
+ */
+
+/**
+ * Common perf code. This should be re-usable with other APIs.
+ */
+
+#include "common.h"
+#include "glmain.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+
+/* Need to add a fflush windows console with mingw, otherwise nothing
+ * shows up until program exit. May want to add logging here.
+ */
+void
+perf_printf(const char *format, ...)
+{
+ va_list ap;
+ va_start(ap, format);
+
+ fflush(stdout);
+ vfprintf(stdout, format, ap);
+ fflush(stdout);
+
+ va_end(ap);
+}
+
+
+
+/**
+ * Run function 'f' for enough iterations to reach a steady state.
+ * Return the rate (iterations/second).
+ */
+double
+PerfMeasureRate(PerfRateFunc f)
+{
+ const double minDuration = 1.0;
+ double rate = 0.0, prevRate = 0.0;
+ unsigned subiters;
+
+ /* Compute initial number of iterations to try.
+ * If the test function is pretty slow this helps to avoid
+ * extraordarily long run times.
+ */
+ subiters = 2;
+ {
+ const double t0 = PerfGetTime();
+ double t1;
+ do {
+ f(subiters); /* call the rendering function */
+ t1 = PerfGetTime();
+ subiters *= 2;
+ } while (t1 - t0 < 0.1 * minDuration);
+ }
+ /*perf_printf("initial subIters = %u\n", subiters);*/
+
+ while (1) {
+ const double t0 = PerfGetTime();
+ unsigned iters = 0;
+ double t1;
+
+ do {
+ f(subiters); /* call the rendering function */
+ t1 = PerfGetTime();
+ iters += subiters;
+ } while (t1 - t0 < minDuration);
+
+ rate = iters / (t1 - t0);
+
+ if (0)
+ perf_printf("prevRate %f rate %f ratio %f iters %u\n",
+ prevRate, rate, rate/prevRate, iters);
+
+ /* Try and speed the search up by skipping a few steps:
+ */
+ if (rate > prevRate * 1.6)
+ subiters *= 8;
+ else if (rate > prevRate * 1.2)
+ subiters *= 4;
+ else if (rate > prevRate * 1.05)
+ subiters *= 2;
+ else
+ break;
+
+ prevRate = rate;
+ }
+
+ if (0)
+ perf_printf("%s returning iters %u rate %f\n", __FUNCTION__, subiters, rate);
+ return rate;
+}
+
+
+/* Note static buffer, can only use once per printf.
+ */
+const char *
+PerfHumanFloat( double d )
+{
+ static char buf[80];
+
+ if (d > 1000000000.0)
+ snprintf(buf, sizeof(buf), "%.1f billion", d / 1000000000.0);
+ else if (d > 1000000.0)
+ snprintf(buf, sizeof(buf), "%.1f million", d / 1000000.0);
+ else if (d > 1000.0)
+ snprintf(buf, sizeof(buf), "%.1f thousand", d / 1000.0);
+ else
+ snprintf(buf, sizeof(buf), "%.1f", d);
+
+ return buf;
+}
diff --git a/progs/perf/common.h b/progs/perf/common.h
new file mode 100644
index 00000000000..6ea17402b52
--- /dev/null
+++ b/progs/perf/common.h
@@ -0,0 +1,44 @@
+/*
+ * 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 COMMON_H
+#define COMMON_H
+
+
+#include <stddef.h> /* for offsetof() */
+
+
+typedef void (*PerfRateFunc)(unsigned count);
+
+
+extern double
+PerfMeasureRate(PerfRateFunc f);
+
+const char *
+PerfHumanFloat( double d );
+
+extern void
+perf_printf(const char *format, ...);
+
+
+#endif /* COMMON_H */
+
diff --git a/progs/perf/copytex.c b/progs/perf/copytex.c
new file mode 100644
index 00000000000..f7a6b8aec39
--- /dev/null
+++ b/progs/perf/copytex.c
@@ -0,0 +1,214 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure glCopyTex[Sub]Image() rate.
+ * Create a large, off-screen framebuffer object for rendering and
+ * copying the texture data from it since we can't make really large
+ * on-screen windows.
+ *
+ * Brian Paul
+ * 22 Sep 2009
+ */
+
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO, FBO, RBO, Tex;
+
+const GLsizei MinSize = 16, MaxSize = 4096;
+static GLsizei TexSize;
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean TexSubImage4 = GL_FALSE;
+
+struct vertex
+{
+ GLfloat x, y, s, t;
+};
+
+static const struct vertex vertices[1] = {
+ { 0.0, 0.0, 0.5, 0.5 },
+};
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ const GLenum filter = GL_LINEAR;
+ GLenum stat;
+
+ if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
+ perf_printf("copytex: GL_EXT_framebuffer_object not supported\n");
+ exit(0);
+ }
+
+ /* setup VBO */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices),
+ vertices, GL_STATIC_DRAW_ARB);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ /* setup texture */
+ glGenTextures(1, &Tex);
+ glBindTexture(GL_TEXTURE_2D, Tex);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ glEnable(GL_TEXTURE_2D);
+
+ /* setup rbo */
+ glGenRenderbuffersEXT(1, &RBO);
+ glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, RBO);
+ glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_RGBA, MaxSize, MaxSize);
+
+ /* setup fbo */
+ glGenFramebuffersEXT(1, &FBO);
+ glBindFramebufferEXT(GL_FRAMEBUFFER, FBO);
+ glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_RENDERBUFFER_EXT, RBO);
+
+ stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ perf_printf("fboswitch: Error: incomplete FBO!\n");
+ exit(1);
+ }
+
+ /* clear the FBO */
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ glViewport(0, 0, MaxSize, MaxSize);
+ glClear(GL_COLOR_BUFFER_BIT);
+}
+
+
+static void
+CopyTexImage(unsigned count)
+{
+ unsigned i;
+ for (i = 1; i < count; i++) {
+ /* draw something */
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ /* copy whole texture */
+ glCopyTexImage2D(GL_TEXTURE_2D, 0,
+ GL_RGBA, 0, 0, TexSize, TexSize, 0);
+ }
+ glFinish();
+}
+
+
+static void
+CopyTexSubImage(unsigned count)
+{
+ unsigned i;
+ for (i = 1; i < count; i++) {
+ /* draw something */
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ /* copy sub texture */
+ if (TexSubImage4) {
+ /* four sub-copies */
+ GLsizei half = TexSize / 2;
+ /* lower-left */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, 0, 0, half, half);
+ /* lower-right */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ half, 0, half, 0, half, half);
+ /* upper-left */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, half, 0, half, half, half);
+ /* upper-right */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ half, half, half, half, half, half);
+ }
+ else {
+ /* one big copy */
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, 0, 0, TexSize, TexSize);
+ }
+ }
+ glFinish();
+}
+
+
+/** Called from test harness/main */
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate, mbPerSec;
+ GLint sub, maxTexSize;
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTexSize);
+
+ /* loop over whole/sub tex copy */
+ for (sub = 0; sub < 2; sub++) {
+
+ /* loop over texture sizes */
+ for (TexSize = MinSize; TexSize <= MaxSize; TexSize *= 4) {
+
+ if (TexSize <= maxTexSize) {
+ GLint bytesPerImage = 4 * TexSize * TexSize;
+
+ if (sub == 0)
+ rate = PerfMeasureRate(CopyTexImage);
+ else {
+ /* setup empty dest texture */
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ TexSize, TexSize, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ rate = PerfMeasureRate(CopyTexSubImage);
+ }
+
+ mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
+ }
+ else {
+ rate = 0.0;
+ mbPerSec = 0.0;
+ }
+
+ perf_printf(" glCopyTex%sImage(%d x %d): %.1f copies/sec, %.1f Mpixels/sec\n",
+ (sub ? "Sub" : ""), TexSize, TexSize, rate, mbPerSec);
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/drawoverhead.c b/progs/perf/drawoverhead.c
new file mode 100644
index 00000000000..f75c9bb74e8
--- /dev/null
+++ b/progs/perf/drawoverhead.c
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure drawing overhead
+ *
+ * This is the first in a series of simple performance benchmarks.
+ * The code in this file should be as simple as possible to make it
+ * easily portable to other APIs.
+ *
+ * All the window-system stuff should be contained in glmain.c (or TBDmain.c).
+ *
+ * Brian Paul
+ * 15 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+
+struct vertex
+{
+ GLfloat x, y;
+};
+
+static const struct vertex vertices[4] = {
+ { -1.0, -1.0 },
+ { 1.0, -1.0 },
+ { 1.0, 1.0 },
+ { -1.0, 1.0 }
+};
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* misc GL state */
+ glAlphaFunc(GL_ALWAYS, 0.0);
+}
+
+
+static void
+DrawNoStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+
+static void
+DrawNopStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glDisable(GL_ALPHA_TEST);
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+
+static void
+DrawStateChange(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (i & 1)
+ glEnable(GL_TEXTURE_GEN_S);
+ else
+ glDisable(GL_TEXTURE_GEN_S);
+ glDrawArrays(GL_POINTS, 0, 4);
+ }
+ glFinish();
+}
+
+void
+PerfNextRound(void)
+{
+}
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate0, rate1, rate2, overhead;
+
+ rate0 = PerfMeasureRate(DrawNoStateChange);
+ perf_printf(" Draw only: %s draws/second\n",
+ PerfHumanFloat(rate0));
+
+ rate1 = PerfMeasureRate(DrawNopStateChange);
+ overhead = 1000.0 * (1.0 / rate1 - 1.0 / rate0);
+ perf_printf(" Draw w/ nop state change: %s draws/sec (overhead: %f ms/draw)\n",
+ PerfHumanFloat(rate1), overhead);
+
+ rate2 = PerfMeasureRate(DrawStateChange);
+ overhead = 1000.0 * (1.0 / rate2 - 1.0 / rate0);
+ perf_printf(" Draw w/ state change: %s draws/sec (overhead: %f ms/draw)\n",
+ PerfHumanFloat(rate2), overhead);
+
+ exit(0);
+}
+
diff --git a/progs/perf/fbobind.c b/progs/perf/fbobind.c
new file mode 100644
index 00000000000..fb52a93a2f6
--- /dev/null
+++ b/progs/perf/fbobind.c
@@ -0,0 +1,153 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure rate of binding/switching between FBO targets.
+ * Create two framebuffer objects for rendering to two textures.
+ * Ping pong between texturing from one and drawing into the other.
+ *
+ * Brian Paul
+ * 22 Sep 2009
+ */
+
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+
+static GLuint FBO[2], Tex[2];
+
+static const GLsizei TexSize = 512;
+
+static const GLboolean DrawPoint = GL_TRUE;
+
+struct vertex
+{
+ GLfloat x, y, s, t;
+};
+
+static const struct vertex vertices[1] = {
+ { 0.0, 0.0, 0.5, 0.5 },
+};
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ const GLenum filter = GL_LINEAR;
+ GLenum stat;
+ int i;
+
+ if (!PerfExtensionSupported("GL_EXT_framebuffer_object")) {
+ perf_printf("fboswitch: GL_EXT_framebuffer_object not supported\n");
+ exit(0);
+ }
+
+ /* setup VBO */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(vertices),
+ vertices, GL_STATIC_DRAW_ARB);
+
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glGenFramebuffersEXT(2, FBO);
+ glGenTextures(2, Tex);
+
+ for (i = 0; i < 2; i++) {
+ /* setup texture */
+ glBindTexture(GL_TEXTURE_2D, Tex[i]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ TexSize, TexSize, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+
+
+ /* setup fbo */
+ glBindFramebufferEXT(GL_FRAMEBUFFER, FBO[i]);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, Tex[i], 0/*level*/);
+ stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
+ if (stat != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ perf_printf("fboswitch: Error: incomplete FBO!\n");
+ exit(1);
+ }
+
+ /* clear the FBO */
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+static void
+FBOBind(unsigned count)
+{
+ unsigned i;
+ for (i = 1; i < count; i++) {
+ const GLuint dst = i & 1;
+ const GLuint src = 1 - dst;
+
+ /* bind src texture */
+ glBindTexture(GL_TEXTURE_2D, Tex[src]);
+
+ /* bind dst fbo */
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, FBO[dst]);
+ glDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+ /* draw something */
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+/** Called from test harness/main */
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate;
+
+ rate = PerfMeasureRate(FBOBind);
+ perf_printf(" FBO Binding: %1.f binds/sec\n", rate);
+
+ exit(0);
+}
diff --git a/progs/perf/fill.c b/progs/perf/fill.c
new file mode 100644
index 00000000000..279f2b5f189
--- /dev/null
+++ b/progs/perf/fill.c
@@ -0,0 +1,248 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure fill rates.
+ *
+ * Brian Paul
+ * 21 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 1000, WinHeight = 1000;
+
+static GLuint VBO, TexObj;
+
+
+struct vertex
+{
+ GLfloat x, y, s, t, r, g, b, a;
+};
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+static const struct vertex vertices[4] = {
+ /* x y s t r g b a */
+ { -1.0, -1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.5 },
+ { 1.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.5 },
+ { 1.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.5 },
+ { -1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.5 }
+};
+
+
+static const char *VertexShader =
+ "void main() \n"
+ "{ \n"
+ " gl_Position = ftransform(); \n"
+ " gl_TexCoord[0] = gl_MultiTexCoord0; \n"
+ " gl_FrontColor = gl_Color; \n"
+ "} \n";
+
+/* simple fragment shader */
+static const char *FragmentShader1 =
+ "uniform sampler2D Tex; \n"
+ "void main() \n"
+ "{ \n"
+ " vec4 t = texture2D(Tex, gl_TexCoord[0].xy); \n"
+ " gl_FragColor = vec4(1.0) - t * gl_Color; \n"
+ "} \n";
+
+/**
+ * A more complex fragment shader (but equivalent to first shader).
+ * A good optimizer should catch some of these no-op operations, but
+ * probably not all of them.
+ */
+static const char *FragmentShader2 =
+ "uniform sampler2D Tex; \n"
+ "void main() \n"
+ "{ \n"
+ " // as above \n"
+ " vec4 t = texture2D(Tex, gl_TexCoord[0].xy); \n"
+ " t = vec4(1.0) - t * gl_Color; \n"
+
+ " vec4 u; \n"
+
+ " // no-op negate/swizzle \n"
+ " u = -t.wzyx; \n"
+ " t = -u.wzyx; \n"
+
+ " // no-op inverts \n"
+ " t = vec4(1.0) - t; \n"
+ " t = vec4(1.0) - t; \n"
+
+ " // no-op min/max \n"
+ " t = min(t, t); \n"
+ " t = max(t, t); \n"
+
+ " // no-op moves \n"
+ " u = t; \n"
+ " t = u; \n"
+ " u = t; \n"
+ " t = u; \n"
+
+ " // no-op add/mul \n"
+ " t = (t + t + t + t) * 0.25; \n"
+
+ " // no-op mul/sub \n"
+ " t = 3.0 * t - 2.0 * t; \n"
+
+ " // no-op negate/min/max \n"
+ " t = -min(-t, -t); \n"
+ " t = -max(-t, -t); \n"
+
+ " gl_FragColor = t; \n"
+ "} \n";
+
+static GLuint ShaderProg1, ShaderProg2;
+
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ GLint u;
+
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glColorPointer(4, GL_FLOAT, sizeof(struct vertex), VOFFSET(r));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ /* setup texture */
+ TexObj = PerfCheckerTexture(128, 128);
+
+ /* setup shaders */
+ ShaderProg1 = PerfShaderProgram(VertexShader, FragmentShader1);
+ glUseProgram(ShaderProg1);
+ u = glGetUniformLocation(ShaderProg1, "Tex");
+ glUniform1i(u, 0); /* texture unit 0 */
+
+ ShaderProg2 = PerfShaderProgram(VertexShader, FragmentShader2);
+ glUseProgram(ShaderProg2);
+ u = glGetUniformLocation(ShaderProg2, "Tex");
+ glUniform1i(u, 0); /* texture unit 0 */
+
+ glUseProgram(0);
+}
+
+
+static void
+Ortho(void)
+{
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glOrtho(-1.0, 1.0, -1.0, 1.0, -1.0, 1.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+}
+
+
+
+static void
+DrawQuad(unsigned count)
+{
+ unsigned i;
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ /* Avoid sending command buffers with huge numbers of fullscreen
+ * quads. Graphics schedulers don't always cope well with
+ * this...
+ */
+ if (i % 128 == 0) {
+ PerfSwapBuffers();
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ }
+
+ glFinish();
+
+ if (1)
+ PerfSwapBuffers();
+}
+
+void
+PerfNextRound(void)
+{
+}
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate;
+ double pixelsPerDraw = WinWidth * WinHeight;
+
+ Ortho();
+
+ /* simple fill */
+ rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
+ perf_printf(" Simple fill: %s pixels/second\n",
+ PerfHumanFloat(rate));
+
+ /* blended fill */
+ glEnable(GL_BLEND);
+ rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
+ glDisable(GL_BLEND);
+ perf_printf(" Blended fill: %s pixels/second\n",
+ PerfHumanFloat(rate));
+
+ /* textured fill */
+ glEnable(GL_TEXTURE_2D);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
+ glDisable(GL_TEXTURE_2D);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ perf_printf(" Textured fill: %s pixels/second\n",
+ PerfHumanFloat(rate));
+
+ /* shader1 fill */
+ glUseProgram(ShaderProg1);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
+ glUseProgram(0);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ perf_printf(" Shader1 fill: %s pixels/second\n",
+ PerfHumanFloat(rate));
+
+ /* shader2 fill */
+ glUseProgram(ShaderProg2);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ rate = PerfMeasureRate(DrawQuad) * pixelsPerDraw;
+ glUseProgram(0);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+ perf_printf(" Shader2 fill: %s pixels/second\n",
+ PerfHumanFloat(rate));
+
+ exit(0);
+}
+
diff --git a/progs/perf/genmipmap.c b/progs/perf/genmipmap.c
new file mode 100644
index 00000000000..4b7d6ad155b
--- /dev/null
+++ b/progs/perf/genmipmap.c
@@ -0,0 +1,136 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure glGenerateMipmap() speed.
+ *
+ * Brian Paul
+ * 24 Sep 2009
+ */
+
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLboolean DrawPoint = GL_TRUE;
+static GLuint VBO;
+static GLuint TexObj = 0;
+static GLint BaseLevel, MaxLevel;
+
+struct vertex
+{
+ GLfloat x, y, s, t;
+};
+
+static const struct vertex vertices[1] = {
+ { 0.0, 0.0, 0.5, 0.5 },
+};
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+static void
+GenMipmap(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ GLubyte texel[4];
+ texel[0] = texel[1] = texel[2] = texel[3] = i & 0xff;
+ /* dirty the base image */
+ glTexSubImage2D(GL_TEXTURE_2D, BaseLevel,
+ 0, 0, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, texel);
+ glGenerateMipmap(GL_TEXTURE_2D);
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+/** Called from test harness/main */
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ const GLint NumLevels = 12;
+ const GLint TexWidth = 2048, TexHeight = 2048;
+ GLubyte *img;
+ double rate;
+
+ /* Make 2K x 2K texture */
+ img = (GLubyte *) malloc(TexWidth * TexHeight * 4);
+ memset(img, 128, TexWidth * TexHeight * 4);
+ glTexImage2D(GL_TEXTURE_2D, 0,
+ GL_RGBA, TexWidth, TexHeight, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, img);
+ free(img);
+
+ perf_printf("Texture level[0] size: %d x %d, %d levels\n",
+ TexWidth, TexHeight, NumLevels);
+
+ /* loop over base levels 0, 2, 4 */
+ for (BaseLevel = 0; BaseLevel <= 4; BaseLevel += 2) {
+
+ /* loop over max level */
+ for (MaxLevel = NumLevels; MaxLevel > BaseLevel; MaxLevel--) {
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, BaseLevel);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, MaxLevel);
+
+ rate = PerfMeasureRate(GenMipmap);
+
+ perf_printf(" glGenerateMipmap(levels %d..%d): %.2f gens/sec\n",
+ BaseLevel + 1, MaxLevel, rate);
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/glmain.c b/progs/perf/glmain.c
new file mode 100644
index 00000000000..69cdbce319e
--- /dev/null
+++ b/progs/perf/glmain.c
@@ -0,0 +1,268 @@
+/*
+ * 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.
+ */
+
+/**
+ * OpenGL/GLUT common code for perf programs.
+ * Brian Paul
+ * 15 Sep 2009
+ */
+
+
+#include <stdio.h>
+#include "glmain.h"
+#include <GL/glut.h>
+
+
+static int Win;
+static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
+
+
+/** Return time in seconds */
+double
+PerfGetTime(void)
+{
+ return glutGet(GLUT_ELAPSED_TIME) * 0.001;
+}
+
+
+void
+PerfSwapBuffers(void)
+{
+ glutSwapBuffers();
+}
+
+
+/** make simple checkerboard texture object */
+GLuint
+PerfCheckerTexture(GLsizei width, GLsizei height)
+{
+ const GLenum filter = GL_NEAREST;
+ GLubyte *img = (GLubyte *) malloc(width * height * 4);
+ GLint i, j, k;
+ GLuint obj;
+
+ k = 0;
+ for (i = 0; i < height; i++) {
+ for (j = 0; j < width; j++) {
+ GLubyte color;
+ if (((i / 8) ^ (j / 8)) & 1) {
+ color = 0xff;
+ }
+ else {
+ color = 0x0;
+ }
+ img[k++] = color;
+ img[k++] = color;
+ img[k++] = color;
+ img[k++] = color;
+ }
+ }
+
+ glGenTextures(1, &obj);
+ glBindTexture(GL_TEXTURE_2D, obj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, img);
+ free(img);
+
+ return obj;
+}
+
+
+static GLuint
+CompileShader(GLenum type, const char *shader)
+{
+ GLuint sh;
+ GLint stat;
+
+ sh = glCreateShader(type);
+ glShaderSource(sh, 1, (const GLchar **) &shader, NULL);
+
+ glCompileShader(sh);
+
+ glGetShaderiv(sh, GL_COMPILE_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetShaderInfoLog(sh, 1000, &len, log);
+ fprintf(stderr, "Error: problem compiling shader: %s\n", log);
+ exit(1);
+ }
+
+ return sh;
+}
+
+
+/** Make shader program from given vert/frag shader text */
+GLuint
+PerfShaderProgram(const char *vertShader, const char *fragShader)
+{
+ GLuint prog;
+ GLint stat;
+
+ {
+ const char *version = (const char *) glGetString(GL_VERSION);
+ if ((version[0] != '2' &&
+ version[0] != '3') || version[1] != '.') {
+ fprintf(stderr, "Error: GL version 2.x or better required\n");
+ exit(1);
+ }
+ }
+
+ prog = glCreateProgram();
+
+ if (vertShader) {
+ GLuint vs = CompileShader(GL_VERTEX_SHADER, vertShader);
+ glAttachShader(prog, vs);
+ }
+ if (fragShader) {
+ GLuint fs = CompileShader(GL_FRAGMENT_SHADER, fragShader);
+ glAttachShader(prog, fs);
+ }
+
+ glLinkProgram(prog);
+ glGetProgramiv(prog, GL_LINK_STATUS, &stat);
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetProgramInfoLog(prog, 1000, &len, log);
+ fprintf(stderr, "Shader link error:\n%s\n", log);
+ exit(1);
+ }
+
+ return prog;
+}
+
+
+int
+PerfReshapeWindow( unsigned w, unsigned h )
+{
+ if (glutGet(GLUT_SCREEN_WIDTH) < w ||
+ glutGet(GLUT_SCREEN_HEIGHT) < h)
+ return 0;
+
+ glutReshapeWindow( w, h );
+ glutPostRedisplay();
+ return 1;
+}
+
+
+GLboolean
+PerfExtensionSupported(const char *ext)
+{
+ return glutExtensionSupported(ext);
+}
+
+
+static void
+Idle(void)
+{
+ PerfNextRound();
+}
+
+
+static void
+Draw(void)
+{
+ PerfDraw();
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int height)
+{
+ WinWidth = width;
+ WinHeight = height;
+ glViewport(0, 0, width, height);
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -15.0);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 'z':
+ Zrot -= step;
+ break;
+ case 'Z':
+ Zrot += step;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 3.0;
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ Xrot -= step;
+ break;
+ case GLUT_KEY_DOWN:
+ Xrot += step;
+ break;
+ case GLUT_KEY_LEFT:
+ Yrot -= step;
+ break;
+ case GLUT_KEY_RIGHT:
+ Yrot += step;
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(WinWidth, WinHeight);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_STENCIL);
+ Win = glutCreateWindow(argv[0]);
+ glewInit();
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Draw);
+ glutIdleFunc(Idle);
+ PerfInit();
+ glutMainLoop();
+ return 0;
+}
diff --git a/progs/perf/glmain.h b/progs/perf/glmain.h
new file mode 100644
index 00000000000..d9bcd5f4e21
--- /dev/null
+++ b/progs/perf/glmain.h
@@ -0,0 +1,68 @@
+/*
+ * 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 GLMAIN_H
+#define GLMAIN_H
+
+
+#define GL_GLEXT_PROTOTYPES
+#include <GL/glew.h>
+#include <stdlib.h>
+#include <math.h>
+
+
+/** Test programs can use these vars/functions */
+
+extern int WinWidth, WinHeight;
+
+extern double
+PerfGetTime(void);
+
+extern void
+PerfSwapBuffers(void);
+
+extern GLuint
+PerfCheckerTexture(GLsizei width, GLsizei height);
+
+extern GLuint
+PerfShaderProgram(const char *vertShader, const char *fragShader);
+
+extern int
+PerfReshapeWindow( unsigned w, unsigned h );
+
+extern GLboolean
+PerfExtensionSupported(const char *ext);
+
+
+/** Test programs must implement these functions **/
+
+extern void
+PerfInit(void);
+
+extern void
+PerfNextRound(void);
+
+extern void
+PerfDraw(void);
+
+
+#endif /* GLMAIN_H */
diff --git a/progs/perf/readpixels.c b/progs/perf/readpixels.c
new file mode 100644
index 00000000000..ac7dc426e93
--- /dev/null
+++ b/progs/perf/readpixels.c
@@ -0,0 +1,169 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure glReadPixels speed.
+ * XXX also read into a PBO?
+ * XXX also read from FBOs?
+ *
+ * Brian Paul
+ * 23 Sep 2009
+ */
+
+#include <string.h>
+#include <assert.h>
+#include "glmain.h"
+#include "common.h"
+
+int WinWidth = 1000, WinHeight = 1000;
+
+static GLuint VBO;
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean BufferSubDataInHalves = GL_TRUE;
+
+static const GLfloat Vertex0[2] = { 0.0, 0.0 };
+
+static GLenum HaveDepthStencil;
+
+static GLenum ReadFormat, ReadType;
+static GLint ReadWidth, ReadHeight;
+static GLvoid *ReadBuffer;
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(Vertex0), Vertex0, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ glPixelStorei(GL_PACK_ALIGNMENT, 1);
+
+ HaveDepthStencil = PerfExtensionSupported("GL_EXT_packed_depth_stencil");
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
+ glEnable(GL_DEPTH_TEST);
+ glEnable(GL_STENCIL_TEST);
+}
+
+
+static void
+ReadPixels(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ /* read from random pos */
+ GLint x, y;
+
+ x = WinWidth - ReadWidth;
+ y = WinHeight - ReadHeight;
+ if (x > 0)
+ x = rand() % x;
+ if (y > 0)
+ y = rand() % y;
+
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ glReadPixels(x, y, ReadWidth, ReadHeight,
+ ReadFormat, ReadType, ReadBuffer);
+ }
+ glFinish();
+}
+
+
+static const GLsizei Sizes[] = {
+ 10,
+ 100,
+ 500,
+ 1000,
+ 0
+};
+
+
+static const struct {
+ GLenum format;
+ GLenum type;
+ const char *name;
+ GLuint pixel_size;
+} DstFormats[] = {
+ { GL_RGBA, GL_UNSIGNED_BYTE, "RGBA/ubyte", 4 },
+ { GL_BGRA, GL_UNSIGNED_BYTE, "BGRA/ubyte", 4 },
+ { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, "RGB/565", 2 },
+ { GL_LUMINANCE, GL_UNSIGNED_BYTE, "L/ubyte", 1 },
+ { GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, "Z/uint", 4 },
+ { GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, "Z+S/uint", 4 },
+ { 0, 0, NULL, 0 }
+};
+
+
+
+/** Called from test harness/main */
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate, mbPerSec;
+ int fmt, sz;
+
+ /* loop over formats */
+ for (fmt = 0; DstFormats[fmt].format; fmt++) {
+ ReadFormat = DstFormats[fmt].format;
+ ReadType = DstFormats[fmt].type;
+
+ /* loop over sizes */
+ for (sz = 0; Sizes[sz]; sz++) {
+ int imgSize;
+
+ ReadWidth = ReadHeight = Sizes[sz];
+ imgSize = ReadWidth * ReadHeight * DstFormats[fmt].pixel_size;
+ ReadBuffer = malloc(imgSize);
+
+ if (ReadFormat == GL_DEPTH_STENCIL_EXT && !HaveDepthStencil) {
+ rate = 0.0;
+ mbPerSec = 0.0;
+ }
+ else {
+ rate = PerfMeasureRate(ReadPixels);
+ mbPerSec = rate * imgSize / (1024.0 * 1024.0);
+ }
+
+ perf_printf("glReadPixels(%d x %d, %s): %.1f images/sec, %.1f Mpixels/sec\n",
+ ReadWidth, ReadHeight,
+ DstFormats[fmt].name, rate, mbPerSec);
+
+ free(ReadBuffer);
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/swapbuffers.c b/progs/perf/swapbuffers.c
new file mode 100644
index 00000000000..63c7fc06f98
--- /dev/null
+++ b/progs/perf/swapbuffers.c
@@ -0,0 +1,161 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure SwapBuffers.
+ *
+ * Keith Whitwell
+ * 22 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+int real_WinWidth, real_WinHeight; /* don't know whats going on here */
+
+static GLuint VBO;
+
+struct vertex
+{
+ GLfloat x, y;
+};
+
+static const struct vertex vertices[4] = {
+ { -1.0, -1.0 },
+ { 1.0, -1.0 },
+ { 1.0, 1.0 },
+ { -1.0, 1.0 }
+};
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* misc GL state */
+ glAlphaFunc(GL_ALWAYS, 0.0);
+}
+
+static void
+SwapNaked(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ PerfSwapBuffers();
+ }
+}
+
+
+static void
+SwapClear(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ PerfSwapBuffers();
+ }
+}
+
+static void
+SwapClearPoint(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ glClear(GL_COLOR_BUFFER_BIT);
+ glDrawArrays(GL_POINTS, 0, 4);
+ PerfSwapBuffers();
+ }
+}
+
+
+static const struct {
+ unsigned w;
+ unsigned h;
+} sizes[] = {
+ { 320, 240 },
+ { 640, 480 },
+ { 1024, 768 },
+ { 1200, 1024 },
+ { 1600, 1200 }
+};
+
+void
+PerfNextRound(void)
+{
+ static unsigned i;
+
+ if (i < sizeof(sizes) / sizeof(sizes[0]) &&
+ PerfReshapeWindow( sizes[i].w, sizes[i].h ))
+ {
+ perf_printf("Reshape %dx%d\n", sizes[i].w, sizes[i].h);
+ real_WinWidth = sizes[i].w;
+ real_WinHeight = sizes[i].h;
+ i++;
+ }
+ else {
+ exit(0);
+ }
+}
+
+
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate0;
+
+ rate0 = PerfMeasureRate(SwapNaked);
+ perf_printf(" Swapbuffers %dx%d: %s swaps/second",
+ real_WinWidth, real_WinHeight,
+ PerfHumanFloat(rate0));
+ perf_printf(" %s pixels/second\n",
+ PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+
+
+
+ rate0 = PerfMeasureRate(SwapClear);
+ perf_printf(" Swap/Clear %dx%d: %s swaps/second",
+ real_WinWidth, real_WinHeight,
+ PerfHumanFloat(rate0));
+ perf_printf(" %s pixels/second\n",
+ PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+
+
+ rate0 = PerfMeasureRate(SwapClearPoint);
+ perf_printf(" Swap/Clear/Draw %dx%d: %s swaps/second",
+ real_WinWidth, real_WinHeight,
+ PerfHumanFloat(rate0));
+ perf_printf(" %s pixels/second\n",
+ PerfHumanFloat(rate0 * real_WinWidth * real_WinHeight));
+}
+
diff --git a/progs/perf/teximage.c b/progs/perf/teximage.c
new file mode 100644
index 00000000000..a3005d0befd
--- /dev/null
+++ b/progs/perf/teximage.c
@@ -0,0 +1,331 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure glTex[Sub]Image2D() and glGetTexImage() rate
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include "glmain.h"
+#include "common.h"
+
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+static GLuint TexObj = 0;
+static GLubyte *TexImage = NULL;
+static GLsizei TexSize;
+static GLenum TexIntFormat, TexSrcFormat, TexSrcType;
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean TexSubImage4 = GL_FALSE;
+
+enum {
+ MODE_CREATE_TEXIMAGE,
+ MODE_TEXIMAGE,
+ MODE_TEXSUBIMAGE,
+ MODE_GETTEXIMAGE,
+ MODE_COUNT
+};
+
+static const char *mode_name[MODE_COUNT] =
+{
+ "Create_TexImage",
+ "TexImage",
+ "TexSubImage",
+ "GetTexImage"
+};
+
+
+
+struct vertex
+{
+ GLfloat x, y, s, t;
+};
+
+static const struct vertex vertices[1] = {
+ { 0.0, 0.0, 0.5, 0.5 },
+};
+
+#define VOFFSET(F) ((void *) offsetof(struct vertex, F))
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO w/ vertex data */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ sizeof(vertices), vertices, GL_STATIC_DRAW_ARB);
+ glVertexPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(x));
+ glTexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), VOFFSET(s));
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ /* texture */
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ glEnable(GL_TEXTURE_2D);
+}
+
+
+
+
+static void
+CreateUploadTexImage2D(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (TexObj)
+ glDeleteTextures(1, &TexObj);
+
+ glGenTextures(1, &TexObj);
+ glBindTexture(GL_TEXTURE_2D, TexObj);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+
+ glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, TexImage);
+
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static void
+UploadTexImage2D(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ /* XXX is this equivalent to a glTexSubImage call since we're
+ * always specifying the same image size? That case isn't optimized
+ * in Mesa but may be optimized in other drivers. Note sure how
+ * much difference that might make.
+ */
+ glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, TexImage);
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static void
+UploadTexSubImage2D(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ if (TexSubImage4) {
+ GLsizei halfSize = (TexSize == 1) ? 1 : TexSize / 2;
+ GLsizei halfPos = TexSize - halfSize;
+ /* do glTexSubImage2D in four pieces */
+ /* lower-left */
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, TexSize);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* lower-right */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ halfPos, 0, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* upper-left */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, halfPos, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* upper-right */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, halfPos);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, halfPos);
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ halfPos, halfPos, halfSize, halfSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ /* reset the unpacking state */
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ }
+ else {
+ /* replace whole texture image at once */
+ glTexSubImage2D(GL_TEXTURE_2D, 0,
+ 0, 0, TexSize, TexSize,
+ TexSrcFormat, TexSrcType, TexImage);
+ }
+ if (DrawPoint)
+ glDrawArrays(GL_POINTS, 0, 1);
+ }
+ glFinish();
+}
+
+
+static void
+GetTexImage2D(unsigned count)
+{
+ unsigned i;
+ GLubyte *buf = (GLubyte *) malloc(TexSize * TexSize * 4);
+ for (i = 0; i < count; i++) {
+ glGetTexImage(GL_TEXTURE_2D, 0,
+ TexSrcFormat, TexSrcType, buf);
+ }
+ glFinish();
+ free(buf);
+}
+
+
+/* XXX any other formats to measure? */
+static const struct {
+ GLenum format, type;
+ GLenum internal_format;
+ const char *name;
+ GLuint texel_size;
+ GLboolean full_test;
+} SrcFormats[] = {
+ { GL_RGBA, GL_UNSIGNED_BYTE, GL_RGBA, "RGBA/ubyte", 4, GL_TRUE },
+ { GL_RGB, GL_UNSIGNED_BYTE, GL_RGB, "RGB/ubyte", 3, GL_FALSE },
+ { GL_RGB, GL_UNSIGNED_SHORT_5_6_5, GL_RGB, "RGB/565", 2, GL_FALSE },
+ { GL_BGRA, GL_UNSIGNED_BYTE, GL_RGBA, "BGRA/ubyte", 4, GL_FALSE },
+ { GL_LUMINANCE, GL_UNSIGNED_BYTE, GL_LUMINANCE, "L/ubyte", 1, GL_FALSE },
+ { 0, 0, 0, NULL, 0, 0 }
+};
+
+
+/** Called from test harness/main */
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ GLint maxSize;
+ double rate;
+ GLint fmt, mode;
+
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxSize);
+
+ /* loop over source data formats */
+ for (fmt = 0; SrcFormats[fmt].format; fmt++) {
+ TexIntFormat = SrcFormats[fmt].internal_format;
+ TexSrcFormat = SrcFormats[fmt].format;
+ TexSrcType = SrcFormats[fmt].type;
+
+ /* loop over glTexImage, glTexSubImage */
+ for (mode = 0; mode < MODE_COUNT; mode++) {
+ GLuint minsz, maxsz;
+
+ if (SrcFormats[fmt].full_test) {
+ minsz = 16;
+ maxsz = 4096;
+ }
+ else {
+ minsz = maxsz = 256;
+ if (mode == MODE_CREATE_TEXIMAGE)
+ continue;
+ }
+
+ /* loop over a defined range of texture sizes, test only the
+ * ones which are legal for this driver.
+ */
+ for (TexSize = minsz; TexSize <= maxsz; TexSize *= 4) {
+ double mbPerSec;
+
+ if (TexSize <= maxSize) {
+ GLint bytesPerImage;
+
+ bytesPerImage = TexSize * TexSize * SrcFormats[fmt].texel_size;
+ TexImage = malloc(bytesPerImage);
+
+ switch (mode) {
+ case MODE_TEXIMAGE:
+ rate = PerfMeasureRate(UploadTexImage2D);
+ break;
+
+ case MODE_CREATE_TEXIMAGE:
+ rate = PerfMeasureRate(CreateUploadTexImage2D);
+ break;
+
+ case MODE_TEXSUBIMAGE:
+ /* create initial, empty texture */
+ glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, NULL);
+ rate = PerfMeasureRate(UploadTexSubImage2D);
+ break;
+
+ case MODE_GETTEXIMAGE:
+ glTexImage2D(GL_TEXTURE_2D, 0, TexIntFormat,
+ TexSize, TexSize, 0,
+ TexSrcFormat, TexSrcType, TexImage);
+ rate = PerfMeasureRate(GetTexImage2D);
+ break;
+
+ default:
+ exit(1);
+ }
+
+ mbPerSec = rate * bytesPerImage / (1024.0 * 1024.0);
+ free(TexImage);
+
+
+ {
+ unsigned err;
+ err = glGetError();
+ if (err) {
+ perf_printf("non-zero glGetError() %d\n", err);
+ exit(1);
+ }
+ }
+
+ }
+ else {
+ rate = 0;
+ mbPerSec = 0;
+ }
+
+ perf_printf(" %s(%s %d x %d): "
+ "%.1f images/sec, %.1f MB/sec\n",
+ mode_name[mode],
+ SrcFormats[fmt].name, TexSize, TexSize, rate, mbPerSec);
+ }
+
+ if (SrcFormats[fmt].full_test)
+ perf_printf("\n");
+ }
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/vbo.c b/progs/perf/vbo.c
new file mode 100644
index 00000000000..b326c056ec6
--- /dev/null
+++ b/progs/perf/vbo.c
@@ -0,0 +1,246 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure VBO upload speed.
+ * That is, measure glBufferDataARB() and glBufferSubDataARB().
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+/* Copy data out of a large array to avoid caching effects:
+ */
+#define DATA_SIZE (16*1024*1024)
+
+int WinWidth = 100, WinHeight = 100;
+
+static GLuint VBO;
+
+static GLsizei VBOSize = 0;
+static GLsizei SubSize = 0;
+static GLubyte *VBOData = NULL; /* array[DATA_SIZE] */
+
+static const GLboolean DrawPoint = GL_TRUE;
+static const GLboolean BufferSubDataInHalves = GL_TRUE;
+
+static const GLfloat Vertex0[2] = { 0.0, 0.0 };
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ /* setup VBO */
+ glGenBuffersARB(1, &VBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VBO);
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
+ glEnableClientState(GL_VERTEX_ARRAY);
+}
+
+
+static void
+UploadVBO(unsigned count)
+{
+ unsigned i;
+ unsigned total = 0;
+ unsigned src = 0;
+
+ for (i = 0; i < count; i++) {
+ glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData + src, GL_STREAM_DRAW_ARB);
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ /* Throw in an occasional flush to work around a driver crash:
+ */
+ total += VBOSize;
+ if (total >= 16*1024*1024) {
+ glFlush();
+ total = 0;
+ }
+
+ src += VBOSize;
+ src %= DATA_SIZE;
+ }
+ glFinish();
+}
+
+
+static void
+UploadSubVBO(unsigned count)
+{
+ unsigned i;
+ unsigned src = 0;
+
+ for (i = 0; i < count; i++) {
+ unsigned offset = (i * SubSize) % VBOSize;
+ glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
+
+ if (DrawPoint) {
+ glDrawArrays(GL_POINTS, offset / sizeof(Vertex0), 1);
+ }
+
+ src += SubSize;
+ src %= DATA_SIZE;
+ }
+ glFinish();
+}
+
+
+/* Do multiple small SubData uploads, then call DrawArrays. This may be a
+ * fairer comparison to back-to-back BufferData calls:
+ */
+static void
+BatchUploadSubVBO(unsigned count)
+{
+ unsigned i = 0, j;
+ unsigned period = VBOSize / SubSize;
+ unsigned src = 0;
+
+ while (i < count) {
+ for (j = 0; j < period && i < count; j++, i++) {
+ unsigned offset = j * SubSize;
+ glBufferSubDataARB(GL_ARRAY_BUFFER, offset, SubSize, VBOData + src);
+ }
+
+ glDrawArrays(GL_POINTS, 0, 1);
+
+ src += SubSize;
+ src %= DATA_SIZE;
+ }
+ glFinish();
+}
+
+
+/**
+ * Test the sequence:
+ * create/load VBO
+ * draw
+ * destroy VBO
+ */
+static void
+CreateDrawDestroyVBO(unsigned count)
+{
+ unsigned i;
+ for (i = 0; i < count; i++) {
+ GLuint vbo;
+ /* create/load */
+ glGenBuffersARB(1, &vbo);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
+ glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
+ /* draw */
+ glVertexPointer(2, GL_FLOAT, sizeof(Vertex0), (void *) 0);
+ glDrawArrays(GL_POINTS, 0, 1);
+ /* destroy */
+ glDeleteBuffersARB(1, &vbo);
+ }
+ glFinish();
+}
+
+
+static const GLsizei Sizes[] = {
+ 64,
+ 1024,
+ 16*1024,
+ 256*1024,
+ 1024*1024,
+ 16*1024*1024,
+ 0 /* end of list */
+};
+
+void
+PerfNextRound(void)
+{
+}
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate, mbPerSec;
+ int i, sz;
+
+ /* Load VBOData buffer with duplicated Vertex0.
+ */
+ VBOData = calloc(DATA_SIZE, 1);
+
+ for (i = 0; i < DATA_SIZE / sizeof(Vertex0); i++) {
+ memcpy(VBOData + i * sizeof(Vertex0),
+ Vertex0,
+ sizeof(Vertex0));
+ }
+
+ /* glBufferDataARB()
+ */
+ for (sz = 0; Sizes[sz]; sz++) {
+ SubSize = VBOSize = Sizes[sz];
+ rate = PerfMeasureRate(UploadVBO);
+ mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
+ perf_printf(" glBufferDataARB(size = %d): %.1f MB/sec\n",
+ VBOSize, mbPerSec);
+ }
+
+ /* glBufferSubDataARB()
+ */
+ for (sz = 0; Sizes[sz]; sz++) {
+ SubSize = VBOSize = Sizes[sz];
+ rate = PerfMeasureRate(UploadSubVBO);
+ mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
+ perf_printf(" glBufferSubDataARB(size = %d): %.1f MB/sec\n",
+ VBOSize, mbPerSec);
+ }
+
+ /* Batch upload
+ */
+ VBOSize = 1024 * 1024;
+ glBufferDataARB(GL_ARRAY_BUFFER, VBOSize, VBOData, GL_STREAM_DRAW_ARB);
+
+ for (sz = 0; Sizes[sz] < VBOSize; sz++) {
+ SubSize = Sizes[sz];
+ rate = PerfMeasureRate(UploadSubVBO);
+ mbPerSec = rate * SubSize / (1024.0 * 1024.0);
+ perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d): %.1f MB/sec\n",
+ SubSize, VBOSize, mbPerSec);
+ }
+
+ for (sz = 0; Sizes[sz] < VBOSize; sz++) {
+ SubSize = Sizes[sz];
+ rate = PerfMeasureRate(BatchUploadSubVBO);
+ mbPerSec = rate * SubSize / (1024.0 * 1024.0);
+ perf_printf(" glBufferSubDataARB(size = %d, VBOSize = %d), batched: %.1f MB/sec\n",
+ SubSize, VBOSize, mbPerSec);
+ }
+
+ /* Create/Draw/Destroy
+ */
+ for (sz = 0; Sizes[sz]; sz++) {
+ SubSize = VBOSize = Sizes[sz];
+ rate = PerfMeasureRate(CreateDrawDestroyVBO);
+ mbPerSec = rate * VBOSize / (1024.0 * 1024.0);
+ perf_printf(" VBO Create/Draw/Destroy(size = %d): %.1f MB/sec, %.1f draws/sec\n",
+ VBOSize, mbPerSec, rate);
+ }
+
+ exit(0);
+}
diff --git a/progs/perf/vertexrate.c b/progs/perf/vertexrate.c
new file mode 100644
index 00000000000..b5355525d06
--- /dev/null
+++ b/progs/perf/vertexrate.c
@@ -0,0 +1,276 @@
+/*
+ * 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.
+ */
+
+/**
+ * Measure simple vertex processing rate via:
+ * - immediate mode
+ * - vertex arrays
+ * - VBO vertex arrays
+ * - glDrawElements
+ * - VBO glDrawElements
+ * - glDrawRangeElements
+ * - VBO glDrawRangeElements
+ *
+ * Brian Paul
+ * 16 Sep 2009
+ */
+
+#include <assert.h>
+#include <string.h>
+#include "glmain.h"
+#include "common.h"
+
+
+#define MAX_VERTS (100 * 100)
+
+/** glVertex2/3/4 size */
+#define VERT_SIZE 4
+
+int WinWidth = 500, WinHeight = 500;
+
+static GLuint VertexBO, ElementBO;
+
+static unsigned NumVerts = MAX_VERTS;
+static unsigned VertBytes = VERT_SIZE * sizeof(float);
+static float *VertexData = NULL;
+
+static unsigned NumElements = MAX_VERTS;
+static GLuint *Elements = NULL;
+
+
+/**
+ * Load VertexData buffer with a 2-D grid of points in the range [-1,1]^2.
+ */
+static void
+InitializeVertexData(void)
+{
+ unsigned i;
+ float x = -1.0, y = -1.0;
+ float dx = 2.0 / 100;
+ float dy = 2.0 / 100;
+
+ VertexData = (float *) malloc(NumVerts * VertBytes);
+
+ for (i = 0; i < NumVerts; i++) {
+ VertexData[i * VERT_SIZE + 0] = x;
+ VertexData[i * VERT_SIZE + 1] = y;
+ VertexData[i * VERT_SIZE + 2] = 0.0;
+ VertexData[i * VERT_SIZE + 3] = 1.0;
+ x += dx;
+ if (x > 1.0) {
+ x = -1.0;
+ y += dy;
+ }
+ }
+
+ Elements = (GLuint *) malloc(NumVerts * sizeof(GLuint));
+
+ for (i = 0; i < NumVerts; i++) {
+ Elements[i] = NumVerts - i - 1;
+ }
+}
+
+
+/** Called from test harness/main */
+void
+PerfInit(void)
+{
+ InitializeVertexData();
+
+ /* setup VertexBO */
+ glGenBuffersARB(1, &VertexBO);
+ glBindBufferARB(GL_ARRAY_BUFFER_ARB, VertexBO);
+ glBufferDataARB(GL_ARRAY_BUFFER_ARB,
+ NumVerts * VertBytes, VertexData, GL_STATIC_DRAW_ARB);
+ glEnableClientState(GL_VERTEX_ARRAY);
+
+ /* setup ElementBO */
+ glGenBuffersARB(1, &ElementBO);
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, ElementBO);
+ glBufferDataARB(GL_ELEMENT_ARRAY_BUFFER_ARB,
+ NumElements * sizeof(GLuint), Elements, GL_STATIC_DRAW_ARB);
+}
+
+
+static void
+DrawImmediate(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ for (i = 0; i < count; i++) {
+ unsigned j;
+ glBegin(GL_POINTS);
+ for (j = 0; j < NumVerts; j++) {
+#if VERT_SIZE == 4
+ glVertex4fv(VertexData + j * 4);
+#elif VERT_SIZE == 3
+ glVertex3fv(VertexData + j * 3);
+#elif VERT_SIZE == 2
+ glVertex2fv(VertexData + j * 2);
+#else
+ abort();
+#endif
+ }
+ glEnd();
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawArraysVBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawArrays(GL_POINTS, 0, NumVerts);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawElements(GL_POINTS, NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsMem(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
+ glBindBufferARB(GL_ARRAY_BUFFER, 0);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, VertexData);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, Elements);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+
+static void
+DrawRangeElementsBO(unsigned count)
+{
+ unsigned i;
+ glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, ElementBO);
+ glBindBufferARB(GL_ARRAY_BUFFER, VertexBO);
+ glVertexPointer(VERT_SIZE, GL_FLOAT, VertBytes, (void *) 0);
+ for (i = 0; i < count; i++) {
+ glDrawRangeElements(GL_POINTS, 0, NumVerts - 1,
+ NumVerts, GL_UNSIGNED_INT, (void *) 0);
+ }
+ glFinish();
+ PerfSwapBuffers();
+}
+
+void
+PerfNextRound(void)
+{
+}
+
+
+/** Called from test harness/main */
+void
+PerfDraw(void)
+{
+ double rate;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ perf_printf("Vertex rate (%d x Vertex%df)\n", NumVerts, VERT_SIZE);
+
+ rate = PerfMeasureRate(DrawImmediate);
+ rate *= NumVerts;
+ perf_printf(" Immediate mode: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawArraysMem);
+ rate *= NumVerts;
+ perf_printf(" glDrawArrays: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawArraysVBO);
+ rate *= NumVerts;
+ perf_printf(" VBO glDrawArrays: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawElementsMem);
+ rate *= NumVerts;
+ perf_printf(" glDrawElements: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawElementsBO);
+ rate *= NumVerts;
+ perf_printf(" VBO glDrawElements: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawRangeElementsMem);
+ rate *= NumVerts;
+ perf_printf(" glDrawRangeElements: %s verts/sec\n", PerfHumanFloat(rate));
+
+ rate = PerfMeasureRate(DrawRangeElementsBO);
+ rate *= NumVerts;
+ perf_printf(" VBO glDrawRangeElements: %s verts/sec\n", PerfHumanFloat(rate));
+
+ exit(0);
+}
diff --git a/progs/tests/zreaddraw.c b/progs/tests/zreaddraw.c
index 0821d5fb357..7dfed20cfb9 100644
--- a/progs/tests/zreaddraw.c
+++ b/progs/tests/zreaddraw.c
@@ -13,14 +13,16 @@
static GLint WinWidth = 500, WinHeight = 500;
static GLboolean Invert = GL_FALSE;
+static GLboolean TestPacking = GL_FALSE;
+static GLboolean TestList = GL_FALSE;
static void Display(void)
{
- GLfloat depth[100 * 100];
- GLfloat depth2[400 * 400];
- GLfloat min, max;
- int i;
+ GLfloat depth[100 * 100 * 2];
+ GLfloat depth2[400 * 400]; /* *2 to test pixelstore stuff */
+ GLuint list;
+ GLenum depthType = GL_FLOAT;
glClearColor(0.5, 0.5, 0.5, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -36,16 +38,32 @@ static void Display(void)
glLoadIdentity();
glutSolidSphere(1.0, 20, 10);
+ if (TestPacking) {
+ glPixelStorei(GL_PACK_ROW_LENGTH, 120);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 5);
+ }
+
/* read the depth image */
- glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
- min = max = depth[0];
- for (i = 1; i < 100 * 100; i++) {
- if (depth[i] < min)
- min = depth[i];
- if (depth[i] > max)
- max = depth[i];
+ glReadPixels(0, 0, 100, 100, GL_DEPTH_COMPONENT, depthType, depth);
+ if (depthType == GL_FLOAT) {
+ GLfloat min, max;
+ int i;
+ min = max = depth[0];
+ for (i = 1; i < 100 * 100; i++) {
+ if (depth[i] < min)
+ min = depth[i];
+ if (depth[i] > max)
+ max = depth[i];
+ }
+ printf("Depth value range: [%f, %f]\n", min, max);
+ }
+
+ if (TestPacking) {
+ glPixelStorei(GL_PACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 120);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 5);
}
- printf("Depth value range: [%f, %f]\n", min, max);
/* draw depth image with scaling (into z buffer) */
glPixelZoom(4.0, 4.0);
@@ -55,12 +73,27 @@ static void Display(void)
glPixelTransferf(GL_DEPTH_SCALE, -1.0);
glPixelTransferf(GL_DEPTH_BIAS, 1.0);
}
- glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
+ if (TestList) {
+ list = glGenLists(1);
+ glNewList(list, GL_COMPILE);
+ glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth);
+ glEndList();
+ glCallList(list);
+ glDeleteLists(list, 1);
+ }
+ else {
+ glDrawPixels(100, 100, GL_DEPTH_COMPONENT, depthType, depth);
+ }
if (Invert) {
glPixelTransferf(GL_DEPTH_SCALE, 1.0);
glPixelTransferf(GL_DEPTH_BIAS, 0.0);
}
+ if (TestPacking) {
+ glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
+ }
+
glDisable(GL_DEPTH_TEST);
/* read back scaled depth image */
@@ -89,6 +122,14 @@ static void Key(unsigned char key, int x, int y)
case 'i':
Invert = !Invert;
break;
+ case 'p':
+ TestPacking = !TestPacking;
+ printf("Test pixel pack/unpack: %d\n", TestPacking);
+ break;
+ case 'l':
+ TestList = !TestList;
+ printf("Test dlist: %d\n", TestList);
+ break;
case 27:
exit(0);
break;
diff --git a/progs/vp/vp-tris.c b/progs/vp/vp-tris.c
index 97995accdd1..1356242d971 100644
--- a/progs/vp/vp-tris.c
+++ b/progs/vp/vp-tris.c
@@ -119,6 +119,12 @@ static void Init( void )
glBindProgramARB(GL_VERTEX_PROGRAM_ARB, prognum);
glProgramStringARB(GL_VERTEX_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
sz, (const GLubyte *) buf);
+ if (glGetError()) {
+ printf("Program failed to compile:\n%s\n", buf);
+ printf("Error: %s\n",
+ (char *) glGetString(GL_PROGRAM_ERROR_STRING_ARB));
+ exit(1);
+ }
assert(glIsProgramARB(prognum));
}
diff --git a/scons/crossmingw.py b/scons/crossmingw.py
index 3aed4843502..9cb0b89e3c7 100644
--- a/scons/crossmingw.py
+++ b/scons/crossmingw.py
@@ -177,7 +177,7 @@ def generate(env):
# default in recent gcc versions
env.AppendUnique(CFLAGS = ['-gstabs'])
- env.AppendUnique(LIBS = ['iberty'])
+ #env.AppendUnique(LIBS = ['iberty'])
env.AppendUnique(SHLINKFLAGS = ['-Wl,--enable-stdcall-fixup'])
#env.AppendUnique(SHLINKFLAGS = ['-Wl,--kill-at'])
diff --git a/scons/dxsdk.py b/scons/dxsdk.py
index de090e4f991..920cc2f689d 100644
--- a/scons/dxsdk.py
+++ b/scons/dxsdk.py
@@ -52,11 +52,20 @@ def generate(env):
target_cpu = 'x64'
else:
raise SCons.Errors.InternalError, "Unsupported target machine"
- include_dir = 'Include'
+
+ include_dir = os.path.join(dxsdk_root, 'Include')
+ lib_dir = os.path.join(dxsdk_root, 'Lib', target_cpu)
env.Append(CPPDEFINES = [('HAVE_DXSDK', '1')])
- env.Prepend(CPPPATH = [os.path.join(dxsdk_root, 'Include')])
- env.Prepend(LIBPATH = [os.path.join(dxsdk_root, 'Lib', target_cpu)])
+
+ gcc = 'gcc' in os.path.basename(env['CC']).split('-')
+ if gcc:
+ # Make GCC more forgiving towards Microsoft's headers
+ env.Prepend(CPPFLAGS = ['-isystem', include_dir])
+ else:
+ env.Prepend(CPPPATH = [include_dir])
+
+ env.Prepend(LIBPATH = [lib_dir])
def exists(env):
return get_dxsdk_root(env) is not None
diff --git a/scons/gallium.py b/scons/gallium.py
index 47b07744be9..38782ac7266 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -334,7 +334,11 @@ def generate(env):
else:
ccflags += ['-O3', '-g3']
if env['profile']:
- ccflags += ['-pg']
+ # See http://code.google.com/p/jrfonseca/wiki/Gprof2Dot#Which_options_should_I_pass_to_gcc_when_compiling_for_profiling?
+ ccflags += [
+ '-fno-omit-frame-pointer',
+ '-fno-optimize-sibling-calls',
+ ]
if env['machine'] == 'x86':
ccflags += [
'-m32',
diff --git a/scons/llvm.py b/scons/llvm.py
index 46a8d829ca4..d3293bb404f 100644
--- a/scons/llvm.py
+++ b/scons/llvm.py
@@ -51,7 +51,9 @@ def generate(env):
llvm_bin_dir = os.path.join(llvm_dir, llvm_subdir, 'bin')
if not os.path.isdir(llvm_bin_dir):
- raise SCons.Errors.InternalError, "LLVM build directory not found"
+ llvm_bin_dir = os.path.join(llvm_dir, 'bin')
+ if not os.path.isdir(llvm_bin_dir):
+ raise SCons.Errors.InternalError, "LLVM binary directory not found"
env.PrependENVPath('PATH', llvm_bin_dir)
@@ -65,6 +67,8 @@ def generate(env):
except OSError:
print 'llvm-config version %s failed' % version
else:
+ if env['platform'] == 'windows':
+ env.Append(LIBS = ['imagehlp', 'psapi'])
env['LINK'] = env['CXX']
env['LLVM_VERSION'] = version
diff --git a/scons/winddk.py b/scons/winddk.py
index afcea9909a6..4dac16ee66e 100644
--- a/scons/winddk.py
+++ b/scons/winddk.py
@@ -85,8 +85,6 @@ def get_winddk_paths(env, version, root):
else:
# TODO: take in consideration the host cpu
bin_dir = os.path.join(root, 'bin', 'win64', 'x86', cpu_bin(target_cpu))
-
- env.PrependENVPath('PATH', [bin_dir])
crt_inc_dir = os.path.join(root, 'inc', 'crt')
if version_major >= 6000:
@@ -98,17 +96,33 @@ def get_winddk_paths(env, version, root):
sdk_inc_dir = os.path.join(root, 'inc', target_os)
wdm_inc_dir = os.path.join(root, 'inc', 'ddk', 'wdm', target_os)
- env.PrependENVPath('INCLUDE', [
- wdm_inc_dir,
- ddk_inc_dir,
- crt_inc_dir,
- sdk_inc_dir,
- ])
+ if env['toolchain'] == 'winddk':
+ env.PrependENVPath('PATH', [bin_dir])
+ env.PrependENVPath('INCLUDE', [
+ wdm_inc_dir,
+ ddk_inc_dir,
+ crt_inc_dir,
+ sdk_inc_dir,
+ ])
+ env.PrependENVPath('LIB', [
+ os.path.join(root, 'lib', 'crt', target_cpu),
+ os.path.join(root, 'lib', target_os, target_cpu),
+ ])
+ elif env['toolchain'] == 'crossmingw':
+ env.Prepend(CPPFLAGS = [
+ '-isystem', ddk_inc_dir,
+ '-isystem', sdk_inc_dir,
+ ])
+ else:
+ env.Prepend(CPPPATH = [
+ wdm_inc_dir,
+ ddk_inc_dir,
+ sdk_inc_dir,
+ ])
+ env.Prepend(LIBPATH = [
+ os.path.join(root, 'lib', target_os, target_cpu),
+ ])
- env.PrependENVPath('LIB', [
- os.path.join(root, 'lib', 'crt', target_cpu),
- os.path.join(root, 'lib', target_os, target_cpu),
- ])
def generate(env):
if not env.has_key('ENV'):
@@ -120,9 +134,10 @@ def generate(env):
get_winddk_paths(env, version, root)
break
- msvc_sa.generate(env)
- mslib_sa.generate(env)
- mslink_sa.generate(env)
+ if env['toolchain'] == 'winddk':
+ msvc_sa.generate(env)
+ mslib_sa.generate(env)
+ mslink_sa.generate(env)
def exists(env):
for version in versions:
diff --git a/src/gallium/auxiliary/draw/draw_pt_post_vs.c b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
index 00d7197b132..e25f16c354a 100644
--- a/src/gallium/auxiliary/draw/draw_pt_post_vs.c
+++ b/src/gallium/auxiliary/draw/draw_pt_post_vs.c
@@ -104,7 +104,7 @@ static boolean post_vs_cliptest_viewport_gl( struct pt_post_vs *pvs,
unsigned clipped = 0;
unsigned j;
- if (0) debug_printf("%s\n");
+ if (0) debug_printf("%s\n", __FUNCTION__);
for (j = 0; j < count; j++) {
float *position = out->data[pos];
diff --git a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
index 109ac7c9d63..d01f8666222 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_buffer_fenced.c
@@ -542,7 +542,7 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
debug_printf("%10p %7u %7u\n",
fenced_buf,
fenced_buf->base.base.size,
- fenced_buf->base.base.reference.count);
+ p_atomic_read(&fenced_buf->base.base.reference.count));
curr = next;
next = curr->next;
}
@@ -556,7 +556,7 @@ fenced_buffer_list_dump(struct fenced_buffer_list *fenced_list)
debug_printf("%10p %7u %7u %10p %s\n",
fenced_buf,
fenced_buf->base.base.size,
- fenced_buf->base.base.reference.count,
+ p_atomic_read(&fenced_buf->base.base.reference.count),
fenced_buf->fence,
signaled == 0 ? "y" : "n");
curr = next;
diff --git a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
index 1b4df28c707..6e3214ca9c9 100644
--- a/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
+++ b/src/gallium/auxiliary/pipebuffer/pb_bufmgr_debug.c
@@ -350,7 +350,7 @@ pb_debug_manager_dump(struct pb_debug_manager *mgr)
buf = LIST_ENTRY(struct pb_debug_buffer, curr, head);
debug_printf("buffer = %p\n", buf);
- debug_printf(" .size = %p\n", buf->base.base.size);
+ debug_printf(" .size = 0x%x\n", buf->base.base.size);
debug_backtrace_dump(buf->create_backtrace, PB_DEBUG_CREATE_BACKTRACE);
curr = next;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 8a13885da9b..53e13b30e63 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -358,7 +358,7 @@ epilog(
boolean
tgsi_sanity_check(
- struct tgsi_token *tokens )
+ const struct tgsi_token *tokens )
{
struct sanity_check_ctx ctx;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.h b/src/gallium/auxiliary/tgsi/tgsi_sanity.h
index ca45e94c7ad..52263ff8832 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.h
@@ -40,7 +40,7 @@ extern "C" {
*/
boolean
tgsi_sanity_check(
- struct tgsi_token *tokens );
+ const struct tgsi_token *tokens );
#if defined __cplusplus
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.c b/src/gallium/auxiliary/tgsi/tgsi_scan.c
index c535788819f..0db4481a3d0 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.c
@@ -132,6 +132,7 @@ tgsi_scan_shader(const struct tgsi_token *tokens,
if (file == TGSI_FILE_INPUT) {
info->input_semantic_name[reg] = (ubyte)fulldecl->Semantic.SemanticName;
info->input_semantic_index[reg] = (ubyte)fulldecl->Semantic.SemanticIndex;
+ info->input_interpolate[reg] = (ubyte)fulldecl->Declaration.Interpolate;
info->num_inputs++;
}
else if (file == TGSI_FILE_OUTPUT) {
diff --git a/src/gallium/auxiliary/tgsi/tgsi_scan.h b/src/gallium/auxiliary/tgsi/tgsi_scan.h
index 2c1a75bc812..8a7ee0c7e4f 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_scan.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_scan.h
@@ -45,6 +45,7 @@ struct tgsi_shader_info
ubyte num_outputs;
ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; /**< TGSI_SEMANTIC_x */
ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS];
+ ubyte input_interpolate[PIPE_MAX_SHADER_INPUTS];
ubyte output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; /**< TGSI_SEMANTIC_x */
ubyte output_semantic_index[PIPE_MAX_SHADER_OUTPUTS];
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index 3cdf8b9f359..5f6b83b2362 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -39,8 +39,9 @@
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
-#include "tgsi_exec.h"
-#include "tgsi_sse2.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_exec.h"
+#include "tgsi/tgsi_sse2.h"
#include "rtasm/rtasm_x86sse.h"
@@ -1360,6 +1361,32 @@ emit_store(
const struct tgsi_full_instruction *inst,
unsigned chan_index )
{
+ switch( inst->Instruction.Saturate ) {
+ case TGSI_SAT_NONE:
+ break;
+
+ case TGSI_SAT_ZERO_ONE:
+ sse_maxps(
+ func,
+ make_xmm( xmm ),
+ get_temp(
+ TGSI_EXEC_TEMP_00000000_I,
+ TGSI_EXEC_TEMP_00000000_C ) );
+
+ sse_minps(
+ func,
+ make_xmm( xmm ),
+ get_temp(
+ TGSI_EXEC_TEMP_ONE_I,
+ TGSI_EXEC_TEMP_ONE_C ) );
+ break;
+
+ case TGSI_SAT_MINUS_PLUS_ONE:
+ assert( 0 );
+ break;
+ }
+
+
switch( reg->DstRegister.File ) {
case TGSI_FILE_OUTPUT:
emit_output(
@@ -1388,19 +1415,6 @@ emit_store(
default:
assert( 0 );
}
-
- switch( inst->Instruction.Saturate ) {
- case TGSI_SAT_NONE:
- break;
-
- case TGSI_SAT_ZERO_ONE:
- /* assert( 0 ); */
- break;
-
- case TGSI_SAT_MINUS_PLUS_ONE:
- assert( 0 );
- break;
- }
}
#define STORE( FUNC, INST, XMM, INDEX, CHAN )\
@@ -1431,11 +1445,11 @@ fetch_texel( struct tgsi_sampler **sampler,
{
float rgba[NUM_CHANNELS][QUAD_SIZE];
(*sampler)->get_samples(*sampler,
- &store[0],
- &store[4],
- &store[8],
- 0.0f, /*store[12], lodbias */
- rgba);
+ &store[0], /* s */
+ &store[4], /* t */
+ &store[8], /* r */
+ store[12], /* lodbias */
+ rgba); /* results */
memcpy( store, rgba, 16 * sizeof(float));
}
@@ -1747,14 +1761,6 @@ emit_instruction(
if (indirect_temp_reference(inst))
return FALSE;
- /* we don't handle saturation/clamping yet */
- if (inst->Instruction.Saturate != TGSI_SAT_NONE)
- return FALSE;
-
- /* need to use extra temps to fix SOA dependencies : */
- if (tgsi_check_soa_dependencies(inst))
- return FALSE;
-
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -1768,8 +1774,10 @@ emit_instruction(
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( func, *inst, 0, 0, chan_index );
- STORE( func, *inst, 0, 0, chan_index );
+ FETCH( func, *inst, 4 + chan_index, 0, chan_index );
+ }
+ FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
+ STORE( func, *inst, 4 + chan_index, 0, chan_index );
}
break;
@@ -1847,7 +1855,6 @@ emit_instruction(
break;
case TGSI_OPCODE_RCP:
- /* TGSI_OPCODE_RECIP */
FETCH( func, *inst, 0, 0, CHAN_X );
emit_rcp( func, 0, 0 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -1856,7 +1863,6 @@ emit_instruction(
break;
case TGSI_OPCODE_RSQ:
- /* TGSI_OPCODE_RECIPSQRT */
FETCH( func, *inst, 0, 0, CHAN_X );
emit_abs( func, 0 );
emit_rsqrt( func, 1, 0 );
@@ -1954,7 +1960,6 @@ emit_instruction(
break;
case TGSI_OPCODE_DP3:
- /* TGSI_OPCODE_DOT3 */
FETCH( func, *inst, 0, 0, CHAN_X );
FETCH( func, *inst, 1, 1, CHAN_X );
emit_mul( func, 0, 1 );
@@ -1972,7 +1977,6 @@ emit_instruction(
break;
case TGSI_OPCODE_DP4:
- /* TGSI_OPCODE_DOT4 */
FETCH( func, *inst, 0, 0, CHAN_X );
FETCH( func, *inst, 1, 1, CHAN_X );
emit_mul( func, 0, 1 );
@@ -2043,17 +2047,14 @@ emit_instruction(
break;
case TGSI_OPCODE_SLT:
- /* TGSI_OPCODE_SETLT */
emit_setcc( func, inst, cc_LessThan );
break;
case TGSI_OPCODE_SGE:
- /* TGSI_OPCODE_SETGE */
emit_setcc( func, inst, cc_NotLessThan );
break;
case TGSI_OPCODE_MAD:
- /* TGSI_OPCODE_MADD */
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
FETCH( func, *inst, 1, 1, chan_index );
@@ -2283,7 +2284,7 @@ emit_instruction(
break;
case TGSI_OPCODE_SEQ:
- return 0;
+ emit_setcc( func, inst, cc_Equal );
break;
case TGSI_OPCODE_SFL:
@@ -2291,7 +2292,7 @@ emit_instruction(
break;
case TGSI_OPCODE_SGT:
- return 0;
+ emit_setcc( func, inst, cc_NotLessThanEqual );
break;
case TGSI_OPCODE_SIN:
@@ -2303,11 +2304,11 @@ emit_instruction(
break;
case TGSI_OPCODE_SLE:
- return 0;
+ emit_setcc( func, inst, cc_LessThanEqual );
break;
case TGSI_OPCODE_SNE:
- return 0;
+ emit_setcc( func, inst, cc_NotEqual );
break;
case TGSI_OPCODE_STR:
@@ -2371,7 +2372,6 @@ emit_instruction(
break;
case TGSI_OPCODE_SSG:
- /* TGSI_OPCODE_SGN */
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
emit_sgn( func, 0, 0 );
@@ -2929,6 +2929,22 @@ tgsi_emit_sse2(
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
+
+ if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+
+ /* XXX: we only handle src/dst aliasing in a few opcodes
+ * currently. Need to use an additional temporay to hold
+ * the result in the cases where the code is too opaque to
+ * fix.
+ */
+ if (opcode != TGSI_OPCODE_MOV &&
+ opcode != TGSI_OPCODE_SWZ) {
+ debug_printf("Warning: src/dst aliasing in instruction"
+ " is not handled:\n");
+ tgsi_dump_instruction(&parse.FullToken.FullInstruction, 1);
+ }
+ }
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
index f7096bd8e2c..654426a903d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -31,6 +31,7 @@
#include "tgsi/tgsi_ureg.h"
#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_sanity.h"
#include "util/u_memory.h"
#include "util/u_math.h"
@@ -70,6 +71,7 @@ struct ureg_tokens {
#define UREG_MAX_INPUT PIPE_MAX_ATTRIBS
#define UREG_MAX_OUTPUT PIPE_MAX_ATTRIBS
+#define UREG_MAX_CONSTANT_RANGE 32
#define UREG_MAX_IMMEDIATE 32
#define UREG_MAX_TEMP 256
#define UREG_MAX_ADDR 2
@@ -86,8 +88,10 @@ struct ureg_program
unsigned semantic_name;
unsigned semantic_index;
unsigned interp;
- } input[UREG_MAX_INPUT];
- unsigned nr_inputs;
+ } fs_input[UREG_MAX_INPUT];
+ unsigned nr_fs_inputs;
+
+ unsigned vs_inputs[UREG_MAX_INPUT/32];
struct {
unsigned semantic_name;
@@ -107,9 +111,13 @@ struct ureg_program
unsigned temps_active[UREG_MAX_TEMP / 32];
unsigned nr_temps;
- unsigned nr_addrs;
+ struct {
+ unsigned first;
+ unsigned last;
+ } constant_range[UREG_MAX_CONSTANT_RANGE];
+ unsigned nr_constant_ranges;
- unsigned nr_constants;
+ unsigned nr_addrs;
unsigned nr_instructions;
struct ureg_tokens domain[2];
@@ -119,6 +127,9 @@ static union tgsi_any_token error_tokens[32];
static void tokens_error( struct ureg_tokens *tokens )
{
+ if (tokens->tokens && tokens->tokens != error_tokens)
+ FREE(tokens->tokens);
+
tokens->tokens = error_tokens;
tokens->size = Elements(error_tokens);
tokens->count = 0;
@@ -228,25 +239,25 @@ ureg_src_register( unsigned file,
-static struct ureg_src
-ureg_DECL_input( struct ureg_program *ureg,
- unsigned name,
- unsigned index,
- unsigned interp_mode )
+struct ureg_src
+ureg_DECL_fs_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned interp_mode )
{
unsigned i;
- for (i = 0; i < ureg->nr_inputs; i++) {
- if (ureg->input[i].semantic_name == name &&
- ureg->input[i].semantic_index == index)
+ for (i = 0; i < ureg->nr_fs_inputs; i++) {
+ if (ureg->fs_input[i].semantic_name == name &&
+ ureg->fs_input[i].semantic_index == index)
goto out;
}
- if (ureg->nr_inputs < UREG_MAX_INPUT) {
- ureg->input[i].semantic_name = name;
- ureg->input[i].semantic_index = index;
- ureg->input[i].interp = interp_mode;
- ureg->nr_inputs++;
+ if (ureg->nr_fs_inputs < UREG_MAX_INPUT) {
+ ureg->fs_input[i].semantic_name = name;
+ ureg->fs_input[i].semantic_index = index;
+ ureg->fs_input[i].interp = interp_mode;
+ ureg->nr_fs_inputs++;
}
else {
set_bad( ureg );
@@ -257,25 +268,14 @@ out:
}
-
-struct ureg_src
-ureg_DECL_fs_input( struct ureg_program *ureg,
- unsigned name,
- unsigned index,
- unsigned interp )
-{
- assert(ureg->processor == TGSI_PROCESSOR_FRAGMENT);
- return ureg_DECL_input( ureg, name, index, interp );
-}
-
-
struct ureg_src
ureg_DECL_vs_input( struct ureg_program *ureg,
- unsigned name,
unsigned index )
{
assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
- return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
+
+ ureg->vs_inputs[index/32] |= 1 << (index % 32);
+ return ureg_src_register( TGSI_FILE_INPUT, index );
}
@@ -313,9 +313,57 @@ out:
* value or manage any constant_buffer contents -- that's the
* resposibility of the calling code.
*/
-struct ureg_src ureg_DECL_constant(struct ureg_program *ureg )
+struct ureg_src ureg_DECL_constant(struct ureg_program *ureg,
+ unsigned index )
{
- return ureg_src_register( TGSI_FILE_CONSTANT, ureg->nr_constants++ );
+ unsigned minconst = index, maxconst = index;
+ unsigned i;
+
+ /* Inside existing range?
+ */
+ for (i = 0; i < ureg->nr_constant_ranges; i++) {
+ if (ureg->constant_range[i].first <= index &&
+ ureg->constant_range[i].last >= index)
+ goto out;
+ }
+
+ /* Extend existing range?
+ */
+ for (i = 0; i < ureg->nr_constant_ranges; i++) {
+ if (ureg->constant_range[i].last == index - 1) {
+ ureg->constant_range[i].last = index;
+ goto out;
+ }
+
+ if (ureg->constant_range[i].first == index + 1) {
+ ureg->constant_range[i].first = index;
+ goto out;
+ }
+
+ minconst = MIN2(minconst, ureg->constant_range[i].first);
+ maxconst = MAX2(maxconst, ureg->constant_range[i].last);
+ }
+
+ /* Create new range?
+ */
+ if (ureg->nr_constant_ranges < UREG_MAX_CONSTANT_RANGE) {
+ i = ureg->nr_constant_ranges++;
+ ureg->constant_range[i].first = index;
+ ureg->constant_range[i].last = index;
+ }
+
+ /* Collapse all ranges down to one:
+ */
+ i = 0;
+ ureg->constant_range[0].first = minconst;
+ ureg->constant_range[0].last = maxconst;
+ ureg->nr_constant_ranges = 1;
+
+out:
+ assert(i < ureg->nr_constant_ranges);
+ assert(ureg->constant_range[i].first <= index);
+ assert(ureg->constant_range[i].last >= index);
+ return ureg_src_register( TGSI_FILE_CONSTANT, index );
}
@@ -566,6 +614,19 @@ ureg_emit_dst( struct ureg_program *ureg,
}
+static void validate( unsigned opcode,
+ unsigned nr_dst,
+ unsigned nr_src )
+{
+#ifdef DEBUG
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
+ assert(info);
+ if(info) {
+ assert(nr_dst == info->num_dst);
+ assert(nr_src == info->num_src);
+ }
+#endif
+}
unsigned
ureg_emit_insn(struct ureg_program *ureg,
@@ -576,6 +637,8 @@ ureg_emit_insn(struct ureg_program *ureg,
{
union tgsi_any_token *out;
+ validate( opcode, num_dst, num_src );
+
out = get_tokens( ureg, DOMAIN_INSN, 1 );
out[0].value = 0;
out[0].insn.Type = TGSI_TOKEN_TYPE_INSTRUCTION;
@@ -678,17 +741,6 @@ ureg_insn(struct ureg_program *ureg,
unsigned insn, i;
boolean saturate;
-#ifdef DEBUG
- {
- const struct tgsi_opcode_info *info = tgsi_get_opcode_info( opcode );
- assert(info);
- if(info) {
- assert(nr_dst == info->num_dst);
- assert(nr_src == info->num_src);
- }
- }
-#endif
-
saturate = nr_dst ? dst[0].Saturate : FALSE;
insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src );
@@ -702,6 +754,53 @@ ureg_insn(struct ureg_program *ureg,
ureg_fixup_insn_size( ureg, insn );
}
+void
+ureg_tex_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ unsigned target,
+ const struct ureg_src *src,
+ unsigned nr_src )
+{
+ unsigned insn, i;
+ boolean saturate;
+
+ saturate = nr_dst ? dst[0].Saturate : FALSE;
+
+ insn = ureg_emit_insn( ureg, opcode, saturate, nr_dst, nr_src );
+
+ ureg_emit_texture( ureg, insn, target ); \
+
+ for (i = 0; i < nr_dst; i++)
+ ureg_emit_dst( ureg, dst[i] );
+
+ for (i = 0; i < nr_src; i++)
+ ureg_emit_src( ureg, src[i] );
+
+ ureg_fixup_insn_size( ureg, insn );
+}
+
+
+void
+ureg_label_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_src *src,
+ unsigned nr_src,
+ unsigned *label_token )
+{
+ unsigned insn, i;
+
+ insn = ureg_emit_insn( ureg, opcode, FALSE, 0, nr_src );
+
+ ureg_emit_label( ureg, insn, label_token ); \
+
+ for (i = 0; i < nr_src; i++)
+ ureg_emit_src( ureg, src[i] );
+
+ ureg_fixup_insn_size( ureg, insn );
+}
+
static void emit_decl( struct ureg_program *ureg,
@@ -777,13 +876,22 @@ static void emit_decls( struct ureg_program *ureg )
{
unsigned i;
- for (i = 0; i < ureg->nr_inputs; i++) {
- emit_decl( ureg,
- TGSI_FILE_INPUT,
- i,
- ureg->input[i].semantic_name,
- ureg->input[i].semantic_index,
- ureg->input[i].interp );
+ if (ureg->processor == TGSI_PROCESSOR_VERTEX) {
+ for (i = 0; i < UREG_MAX_INPUT; i++) {
+ if (ureg->vs_inputs[i/32] & (1 << (i%32))) {
+ emit_decl_range( ureg, TGSI_FILE_INPUT, i, 1 );
+ }
+ }
+ }
+ else {
+ for (i = 0; i < ureg->nr_fs_inputs; i++) {
+ emit_decl( ureg,
+ TGSI_FILE_INPUT,
+ i,
+ ureg->fs_input[i].semantic_name,
+ ureg->fs_input[i].semantic_index,
+ ureg->fs_input[i].interp );
+ }
}
for (i = 0; i < ureg->nr_outputs; i++) {
@@ -801,10 +909,13 @@ static void emit_decls( struct ureg_program *ureg )
ureg->sampler[i].Index, 1 );
}
- if (ureg->nr_constants) {
- emit_decl_range( ureg,
- TGSI_FILE_CONSTANT,
- 0, ureg->nr_constants );
+ if (ureg->nr_constant_ranges) {
+ for (i = 0; i < ureg->nr_constant_ranges; i++)
+ emit_decl_range( ureg,
+ TGSI_FILE_CONSTANT,
+ ureg->constant_range[i].first,
+ (ureg->constant_range[i].last + 1 -
+ ureg->constant_range[i].first) );
}
if (ureg->nr_temps) {
@@ -890,6 +1001,15 @@ const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
ureg->domain[DOMAIN_DECL].count);
tgsi_dump( tokens, 0 );
}
+
+#if DEBUG
+ if (tokens && !tgsi_sanity_check(tokens)) {
+ debug_printf("tgsi_ureg.c, sanity check failed on generated tokens:\n");
+ tgsi_dump(tokens, 0);
+ assert(0);
+ }
+#endif
+
return tokens;
}
@@ -911,6 +1031,25 @@ void *ureg_create_shader( struct ureg_program *ureg,
}
+const struct tgsi_token *ureg_get_tokens( struct ureg_program *ureg,
+ unsigned *nr_tokens )
+{
+ const struct tgsi_token *tokens;
+
+ ureg_finalize(ureg);
+
+ tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
+
+ if (nr_tokens)
+ *nr_tokens = ureg->domain[DOMAIN_DECL].size;
+
+ ureg->domain[DOMAIN_DECL].tokens = 0;
+ ureg->domain[DOMAIN_DECL].size = 0;
+ ureg->domain[DOMAIN_DECL].order = 0;
+ ureg->domain[DOMAIN_DECL].count = 0;
+
+ return tokens;
+}
struct ureg_program *ureg_create( unsigned processor )
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
index acbca59040c..f04f443b9e7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ureg.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -82,10 +82,21 @@ ureg_create( unsigned processor );
const struct tgsi_token *
ureg_finalize( struct ureg_program * );
+/* Create and return a shader:
+ */
void *
ureg_create_shader( struct ureg_program *,
struct pipe_context *pipe );
+
+/* Alternately, return the built token stream and hand ownership of
+ * that memory to the caller:
+ */
+const struct tgsi_token *
+ureg_get_tokens( struct ureg_program *ureg,
+ unsigned *nr_tokens );
+
+
void
ureg_destroy( struct ureg_program * );
@@ -116,8 +127,7 @@ ureg_DECL_fs_input( struct ureg_program *,
struct ureg_src
ureg_DECL_vs_input( struct ureg_program *,
- unsigned semantic_name,
- unsigned semantic_index );
+ unsigned index );
struct ureg_dst
ureg_DECL_output( struct ureg_program *,
@@ -130,7 +140,8 @@ ureg_DECL_immediate( struct ureg_program *,
unsigned nr );
struct ureg_src
-ureg_DECL_constant( struct ureg_program * );
+ureg_DECL_constant( struct ureg_program *,
+ unsigned index );
struct ureg_dst
ureg_DECL_temporary( struct ureg_program * );
@@ -233,6 +244,24 @@ ureg_insn(struct ureg_program *ureg,
unsigned nr_src );
+void
+ureg_tex_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ unsigned target,
+ const struct ureg_src *src,
+ unsigned nr_src );
+
+
+void
+ureg_label_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_src *src,
+ unsigned nr_src,
+ unsigned *label);
+
+
/***********************************************************************
* Internal instruction helpers, don't call these directly:
*/
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index 1380d98d7ee..b82e7cb4d40 100644
--- a/src/gallium/auxiliary/util/u_debug.h
+++ b/src/gallium/auxiliary/util/u_debug.h
@@ -65,6 +65,11 @@ extern "C" {
#define __FUNCTION__ "???"
#endif
+#if defined(__GNUC__)
+#define _util_printf_format(fmt, list) __attribute__ ((format (printf, fmt, list)))
+#else
+#define _util_printf_format(fmt, list)
+#endif
void _debug_vprintf(const char *format, va_list ap);
@@ -82,14 +87,17 @@ _debug_printf(const char *format, ...)
/**
* Print debug messages.
*
- * The actual channel used to output debug message is platform specific. To
- * avoid misformating or truncation, follow these rules of thumb:
+ * The actual channel used to output debug message is platform specific. To
+ * avoid misformating or truncation, follow these rules of thumb:
* - output whole lines
- * - avoid outputing large strings (512 bytes is the current maximum length
+ * - avoid outputing large strings (512 bytes is the current maximum length
* that is guaranteed to be printed in all platforms)
*/
#if !defined(PIPE_OS_HAIKU)
static INLINE void
+debug_printf(const char *format, ...) _util_printf_format(1,2);
+
+static INLINE void
debug_printf(const char *format, ...)
{
#ifdef DEBUG
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
index 6e82983e586..f1bf94f17dd 100644
--- a/src/gallium/auxiliary/util/u_format.csv
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -2,7 +2,7 @@ PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw,
PIPE_FORMAT_X8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyx1, rgb
PIPE_FORMAT_B8G8R8A8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzwx, rgb
PIPE_FORMAT_B8G8R8X8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , yzw1, rgb
-PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un1 , un5 , un5 , un5 , zyxw, rgb
+PIPE_FORMAT_A1R5G5B5_UNORM , arith , 1, 1, un5 , un5 , un5 , un1 , zyxw, rgb
PIPE_FORMAT_A4R4G4B4_UNORM , arith , 1, 1, un4 , un4 , un4 , un4 , zyxw, rgb
PIPE_FORMAT_R5G6B5_UNORM , arith , 1, 1, un5 , un6 , un5 , , zyx1, rgb
PIPE_FORMAT_A2B10G10R10_UNORM , arith , 1, 1, un10, un10, un10, un2 , xyzw, rgb
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index b12c97dfb4d..cd6a9fcc091 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -283,6 +283,14 @@ util_fast_pow(float x, float y)
return util_fast_exp2(util_fast_log2(x) * y);
}
+/* Note that this counts zero as a power of two.
+ */
+static INLINE boolean
+util_is_power_of_two( unsigned v )
+{
+ return (v & (v-1)) == 0;
+}
+
/**
* Floor(x), returned as int.
@@ -354,7 +362,9 @@ util_is_pot(unsigned x)
* Find first bit set in word. Least significant bit is 1.
* Return 0 if no bits set.
*/
-#if defined(_MSC_VER) && _MSC_VER >= 1300
+#if defined(_MSC_VER) && _MSC_VER >= 1300 && (_M_IX86 || _M_AMD64 || _M_IA64)
+unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask);
+#pragma intrinsic(_BitScanForward)
static INLINE
unsigned long ffs( unsigned long u )
{
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index f01296b40fc..52382990155 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -52,8 +52,7 @@ pass_user_buffer_create(struct pipe_screen *screen,
unsigned bytes)
{
struct pipe_buffer *buffer =
- screen->winsys->user_buffer_create(screen->winsys,
- ptr, bytes);
+ screen->winsys->user_buffer_create(screen->winsys, ptr, bytes);
buffer->screen = screen;
@@ -69,9 +68,8 @@ pass_surface_buffer_create(struct pipe_screen *screen,
unsigned *stride)
{
struct pipe_buffer *buffer =
- screen->winsys->surface_buffer_create(screen->winsys,
- width, height,
- format, usage, tex_usage, stride);
+ screen->winsys->surface_buffer_create(screen->winsys, width, height,
+ format, usage, tex_usage, stride);
buffer->screen = screen;
@@ -83,8 +81,7 @@ pass_buffer_map(struct pipe_screen *screen,
struct pipe_buffer *buf,
unsigned usage)
{
- return screen->winsys->buffer_map(screen->winsys,
- buf, usage);
+ return screen->winsys->buffer_map(screen->winsys, buf, usage);
}
static void
@@ -106,8 +103,7 @@ pass_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf,
void *context_private)
{
- screen->winsys->flush_frontbuffer(screen->winsys,
- surf, context_private);
+ screen->winsys->flush_frontbuffer(screen->winsys, surf, context_private);
}
static void
@@ -115,8 +111,7 @@ pass_fence_reference(struct pipe_screen *screen,
struct pipe_fence_handle **ptr,
struct pipe_fence_handle *fence)
{
- screen->winsys->fence_reference(screen->winsys,
- ptr, fence);
+ screen->winsys->fence_reference(screen->winsys, ptr, fence);
}
static int
@@ -124,8 +119,7 @@ pass_fence_signalled(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flag)
{
- return screen->winsys->fence_signalled(screen->winsys,
- fence, flag);
+ return screen->winsys->fence_signalled(screen->winsys, fence, flag);
}
static int
@@ -133,11 +127,11 @@ pass_fence_finish(struct pipe_screen *screen,
struct pipe_fence_handle *fence,
unsigned flag)
{
- return screen->winsys->fence_finish(screen->winsys,
- fence, flag);
+ return screen->winsys->fence_finish(screen->winsys, fence, flag);
}
-void u_simple_screen_init(struct pipe_screen *screen)
+void
+u_simple_screen_init(struct pipe_screen *screen)
{
screen->buffer_create = pass_buffer_create;
screen->user_buffer_create = pass_user_buffer_create;
@@ -152,7 +146,8 @@ void u_simple_screen_init(struct pipe_screen *screen)
screen->fence_finish = pass_fence_finish;
}
-const char* u_simple_screen_winsys_name(struct pipe_screen *screen)
+const char *
+u_simple_screen_winsys_name(struct pipe_screen *screen)
{
return screen->winsys->get_name(screen->winsys);
}
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index ab754296fa8..0d706f9449d 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -34,14 +34,8 @@
#include "pipe/p_context.h"
-#include "util/u_debug.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_screen.h"
#include "pipe/p_shader_tokens.h"
-
-#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
-
#include "tgsi/tgsi_ureg.h"
@@ -67,9 +61,7 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
struct ureg_src src;
struct ureg_dst dst;
- src = ureg_DECL_vs_input( ureg,
- semantic_names[i],
- semantic_indexes[i]);
+ src = ureg_DECL_vs_input( ureg, i );
dst = ureg_DECL_output( ureg,
semantic_names[i],
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index bd48ce70050..d185c6b8497 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -41,7 +41,7 @@
static const char *
cell_get_vendor(struct pipe_screen *screen)
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
@@ -64,8 +64,6 @@ cell_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 1;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index b43f7352456..e745f3342d1 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -175,12 +175,19 @@ i915_is_buffer_referenced(struct pipe_context *pipe,
static void i915_destroy(struct pipe_context *pipe)
{
struct i915_context *i915 = i915_context(pipe);
+ int i;
draw_destroy(i915->draw);
if(i915->batch)
i915->iws->batchbuffer_destroy(i915->batch);
+ /* unbind framebuffer */
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&i915->framebuffer.cbufs[i], NULL);
+ }
+ pipe_surface_reference(&i915->framebuffer.zsbuf, NULL);
+
FREE(i915);
}
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index 9f017a14cca..c66558c320e 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -46,7 +46,7 @@
static const char *
i915_get_vendor(struct pipe_screen *screen)
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
static const char *
@@ -101,8 +101,6 @@ i915_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 0087dfa410f..7d48e6e84d5 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -588,9 +588,17 @@ static void i915_set_framebuffer_state(struct pipe_context *pipe,
const struct pipe_framebuffer_state *fb)
{
struct i915_context *i915 = i915_context(pipe);
+ int i;
+
draw_flush(i915->draw);
- i915->framebuffer = *fb; /* struct copy */
+ i915->framebuffer.width = fb->width;
+ i915->framebuffer.height = fb->height;
+ i915->framebuffer.nr_cbufs = fb->nr_cbufs;
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ pipe_surface_reference(&i915->framebuffer.cbufs[i], fb->cbufs[i]);
+ }
+ pipe_surface_reference(&i915->framebuffer.zsbuf, fb->zsbuf);
i915->dirty |= I915_NEW_FRAMEBUFFER;
}
diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c
index b22e105f106..4a84c4db23f 100644
--- a/src/gallium/drivers/i965simple/brw_screen.c
+++ b/src/gallium/drivers/i965simple/brw_screen.c
@@ -39,7 +39,7 @@
static const char *
brw_get_vendor( struct pipe_screen *screen )
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
@@ -85,8 +85,6 @@ brw_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 06c586e6bb9..cd7b6356d28 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -3,6 +3,8 @@ include $(TOP)/configs/current
LIBNAME = llvmpipe
+CFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
+
C_SOURCES = \
lp_bld_alpha.c \
lp_bld_arit.c \
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
index 498d21dea6c..89d08834a3c 100644
--- a/src/gallium/drivers/llvmpipe/README
+++ b/src/gallium/drivers/llvmpipe/README
@@ -8,13 +8,16 @@ Done so far is:
- the whole fragment pipeline is code generated in a single function
+ - input interpolation
+
- depth testing
+ - texture sampling (not all state/formats are supported)
+
- fragment shader TGSI translation
- same level of support as the TGSI SSE2 exec machine, with the exception
we don't fallback to TGSI interpretation when an unsupported opcode is
found, but just ignore it
- - texture sampling via an intrinsic call
- done in SoA layout
- input interpolation also code generated
@@ -28,16 +31,17 @@ Done so far is:
any width and length
- not all operations are implemented for these types yet though
-Most mesa/progs/demos/* work. Speed is on par with Keith's softpipe-opt branch,
-which includes hand written fast implementations for common cases.
+Most mesa/progs/demos/* work.
To do (probably by this order):
- code generate stipple and stencil testing
- - code generate texture sampling
+ - translate the remaining bits of texture sampling state
- translate TGSI control flow instructions, and all other remaining opcodes
+
+ - integrate with the draw module for VS code generation
- code generate the triangle setup and rasterization
@@ -93,7 +97,7 @@ Alternatively, you can build it with GNU make, if you prefer, by invoking it as
make linux-llvm
-but the rest of these instructions assume scons is used.
+but the rest of these instructions assume that scons is used.
Using
@@ -108,6 +112,9 @@ or
export LD_LIBRARY_PATH=$PWD/build/linux-x86-debug/lib:$LD_LIBRARY_PATH
+For performance evaluation pass debug=no to scons, and use the corresponding
+lib directory without the "-debug" suffix.
+
Unit testing
============
@@ -119,7 +126,7 @@ build/linux-???-debug/gallium/drivers/llvmpipe:
- lp_test_conv: SIMD vector conversion
- lp_test_format: pixel unpacking/packing
-Some of this tests can output results and benchmarks to a tab-seperated-file
+Some of this tests can output results and benchmarks to a tab-separated-file
for posterior analysis, e.g.:
build/linux-x86_64-debug/gallium/drivers/llvmpipe/lp_test_blend -o blend.tsv
@@ -133,10 +140,10 @@ Development Notes
at the top of the lp_bld_*.c functions.
- All lp_bld_*.[ch] are isolated from the rest of the driver, and could/may be
- put in a standalone Gallium state -> LLVM IR translation module.
+ put in a stand-alone Gallium state -> LLVM IR translation module.
- We use LLVM-C bindings for now. They are not documented, but follow the C++
interfaces very closely, and appear to be complete enough for code
generation. See
http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
- for a standalone example.
+ for a stand-alone example.
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
index dea4b703c45..f4a9a3b22e2 100644
--- a/src/gallium/drivers/llvmpipe/SConscript
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -3,7 +3,7 @@ Import('*')
env = env.Clone()
env.Tool('llvm')
-if env.has_key('LLVM_VERSION') is False:
+if not env.has_key('LLVM_VERSION'):
print 'warning: LLVM not found: not building llvmpipe'
Return()
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
index 49c2f911af7..2b4bc5c819d 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
@@ -45,7 +45,7 @@
void
lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
- union lp_type type,
+ struct lp_type type,
struct lp_build_mask_context *mask,
LLVMValueRef alpha,
LLVMValueRef ref)
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
index 9dbcdb4daab..634575670db 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
@@ -38,14 +38,14 @@
#include <llvm-c/Core.h>
struct pipe_alpha_state;
-union lp_type;
+struct lp_type;
struct lp_build_mask_context;
void
lp_build_alpha_test(LLVMBuilderRef builder,
const struct pipe_alpha_state *state,
- union lp_type type,
+ struct lp_type type,
struct lp_build_mask_context *mask,
LLVMValueRef alpha,
LLVMValueRef ref);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
index be7442d00ae..31433318a7e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
@@ -65,7 +65,7 @@ lp_build_min_simple(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
const char *intrinsic = NULL;
LLVMValueRef cond;
@@ -113,7 +113,7 @@ lp_build_max_simple(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
const char *intrinsic = NULL;
LLVMValueRef cond;
@@ -159,7 +159,7 @@ LLVMValueRef
lp_build_comp(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
if(a == bld->one)
return bld->zero;
@@ -188,7 +188,7 @@ lp_build_add(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMValueRef res;
if(a == bld->zero)
@@ -241,7 +241,7 @@ lp_build_sub(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMValueRef res;
if(b == bld->zero)
@@ -405,7 +405,7 @@ lp_build_mul(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
if(a == bld->zero)
return bld->zero;
@@ -477,7 +477,7 @@ lp_build_div(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
if(a == bld->zero)
return bld->zero;
@@ -590,7 +590,7 @@ LLVMValueRef
lp_build_abs(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
if(!type.sign)
@@ -623,6 +623,47 @@ lp_build_abs(struct lp_build_context *bld,
}
+LLVMValueRef
+lp_build_sgn(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ LLVMValueRef cond;
+ LLVMValueRef res;
+
+ /* Handle non-zero case */
+ if(!type.sign) {
+ /* if not zero then sign must be positive */
+ res = bld->one;
+ }
+ else if(type.floating) {
+ /* Take the sign bit and add it to 1 constant */
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ LLVMValueRef mask = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ LLVMValueRef sign;
+ LLVMValueRef one;
+ sign = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ sign = LLVMBuildAnd(bld->builder, sign, mask, "");
+ one = LLVMConstBitCast(bld->one, int_vec_type);
+ res = LLVMBuildOr(bld->builder, sign, one, "");
+ res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ }
+ else
+ {
+ LLVMValueRef minus_one = lp_build_const_scalar(type, -1.0);
+ cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, bld->zero);
+ res = lp_build_select(bld, cond, bld->one, minus_one);
+ }
+
+ /* Handle zero */
+ cond = lp_build_cmp(bld, PIPE_FUNC_EQUAL, a, bld->zero);
+ res = lp_build_select(bld, cond, bld->zero, bld->one);
+
+ return res;
+}
+
+
enum lp_build_round_sse41_mode
{
LP_BUILD_ROUND_SSE41_NEAREST = 0,
@@ -637,7 +678,7 @@ lp_build_round_sse41(struct lp_build_context *bld,
LLVMValueRef a,
enum lp_build_round_sse41_mode mode)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
const char *intrinsic;
@@ -662,10 +703,28 @@ lp_build_round_sse41(struct lp_build_context *bld,
LLVMValueRef
+lp_build_round(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ assert(type.floating);
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_NEAREST);
+#endif
+
+ /* FIXME */
+ assert(0);
+ return bld->undef;
+}
+
+
+LLVMValueRef
lp_build_floor(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
assert(type.floating);
@@ -679,6 +738,42 @@ lp_build_floor(struct lp_build_context *bld,
}
+LLVMValueRef
+lp_build_ceil(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ assert(type.floating);
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_CEIL);
+#endif
+
+ /* FIXME */
+ assert(0);
+ return bld->undef;
+}
+
+
+LLVMValueRef
+lp_build_trunc(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ assert(type.floating);
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ return lp_build_round_sse41(bld, a, LP_BUILD_ROUND_SSE41_TRUNCATE);
+#endif
+
+ /* FIXME */
+ assert(0);
+ return bld->undef;
+}
+
+
/**
* Convert to integer, through whichever rounding method that's fastest,
* typically truncating to zero.
@@ -687,7 +782,7 @@ LLVMValueRef
lp_build_int(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
assert(type.floating);
@@ -710,7 +805,7 @@ LLVMValueRef
lp_build_sqrt(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
char intrinsic[32];
@@ -728,7 +823,7 @@ LLVMValueRef
lp_build_rcp(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
if(a == bld->zero)
return bld->undef;
@@ -759,7 +854,7 @@ LLVMValueRef
lp_build_rsqrt(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
assert(type.floating);
@@ -780,7 +875,7 @@ LLVMValueRef
lp_build_cos(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
char intrinsic[32];
@@ -800,7 +895,7 @@ LLVMValueRef
lp_build_sin(struct lp_build_context *bld,
LLVMValueRef a)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
char intrinsic[32];
@@ -823,7 +918,8 @@ lp_build_pow(struct lp_build_context *bld,
{
/* TODO: optimize the constant case */
if(LLVMIsConstant(x) && LLVMIsConstant(y))
- debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
return lp_build_exp2(bld, lp_build_mul(bld, lp_build_log2(bld, x), y));
}
@@ -871,13 +967,14 @@ lp_build_polynomial(struct lp_build_context *bld,
const double *coeffs,
unsigned num_coeffs)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMValueRef res = NULL;
unsigned i;
/* TODO: optimize the constant case */
if(LLVMIsConstant(x))
- debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
for (i = num_coeffs; i--; ) {
LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]);
@@ -919,7 +1016,7 @@ lp_build_exp2_approx(struct lp_build_context *bld,
LLVMValueRef *p_frac_part,
LLVMValueRef *p_exp2)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef ipart = NULL;
@@ -931,7 +1028,8 @@ lp_build_exp2_approx(struct lp_build_context *bld,
if(p_exp2_int_part || p_frac_part || p_exp2) {
/* TODO: optimize the constant case */
if(LLVMIsConstant(x))
- debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
assert(type.floating && type.width == 32);
@@ -1012,7 +1110,7 @@ lp_build_log2_approx(struct lp_build_context *bld,
LLVMValueRef *p_floor_log2,
LLVMValueRef *p_log2)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
@@ -1030,7 +1128,8 @@ lp_build_log2_approx(struct lp_build_context *bld,
if(p_exp || p_floor_log2 || p_log2) {
/* TODO: optimize the constant case */
if(LLVMIsConstant(x))
- debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n",
+ __FUNCTION__);
assert(type.floating && type.width == 32);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/drivers/llvmpipe/lp_bld_arit.h
index 383c3c3313b..d68a97c4b87 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_arit.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.h
@@ -40,7 +40,7 @@
#include <llvm-c/Core.h>
-union lp_type type;
+struct lp_type type;
struct lp_build_context;
@@ -106,10 +106,26 @@ lp_build_abs(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
+lp_build_sgn(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_round(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
lp_build_floor(struct lp_build_context *bld,
LLVMValueRef a);
LLVMValueRef
+lp_build_ceil(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_trunc(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
lp_build_int(struct lp_build_context *bld,
LLVMValueRef a);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
index d19e18846c2..da272e549f3 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
@@ -46,7 +46,7 @@
struct pipe_blend_state;
-union lp_type;
+struct lp_type;
struct lp_build_context;
@@ -74,7 +74,7 @@ lp_build_blend_func(struct lp_build_context *bld,
LLVMValueRef
lp_build_blend_aos(LLVMBuilderRef builder,
const struct pipe_blend_state *blend,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef src,
LLVMValueRef dst,
LLVMValueRef const_,
@@ -84,7 +84,7 @@ lp_build_blend_aos(LLVMBuilderRef builder,
void
lp_build_blend_soa(LLVMBuilderRef builder,
const struct pipe_blend_state *blend,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef src[4],
LLVMValueRef dst[4],
LLVMValueRef const_[4],
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
index c11a9398f87..d14f468ba93 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -303,7 +303,7 @@ lp_build_blend_func(struct lp_build_context *bld,
LLVMValueRef
lp_build_blend_aos(LLVMBuilderRef builder,
const struct pipe_blend_state *blend,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef src,
LLVMValueRef dst,
LLVMValueRef const_,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
index b92254a7d6f..9511299d558 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
@@ -199,7 +199,7 @@ lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld,
void
lp_build_blend_soa(LLVMBuilderRef builder,
const struct pipe_blend_state *blend,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef src[4],
LLVMValueRef dst[4],
LLVMValueRef con[4],
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/drivers/llvmpipe/lp_bld_const.c
index 21487365eae..c8eaa8c3940 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_const.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.c
@@ -42,7 +42,7 @@
unsigned
-lp_mantissa(union lp_type type)
+lp_mantissa(struct lp_type type)
{
assert(type.floating);
@@ -72,7 +72,7 @@ lp_mantissa(union lp_type type)
* Same as lp_const_scale(), but in terms of shifts.
*/
unsigned
-lp_const_shift(union lp_type type)
+lp_const_shift(struct lp_type type)
{
if(type.floating)
return 0;
@@ -86,7 +86,7 @@ lp_const_shift(union lp_type type)
unsigned
-lp_const_offset(union lp_type type)
+lp_const_offset(struct lp_type type)
{
if(type.floating || type.fixed)
return 0;
@@ -104,7 +104,7 @@ lp_const_offset(union lp_type type)
* else for the fixed points types and normalized integers.
*/
double
-lp_const_scale(union lp_type type)
+lp_const_scale(struct lp_type type)
{
unsigned long long llscale;
double dscale;
@@ -122,7 +122,7 @@ lp_const_scale(union lp_type type)
* Minimum value representable by the type.
*/
double
-lp_const_min(union lp_type type)
+lp_const_min(struct lp_type type)
{
unsigned bits;
@@ -158,7 +158,7 @@ lp_const_min(union lp_type type)
* Maximum value representable by the type.
*/
double
-lp_const_max(union lp_type type)
+lp_const_max(struct lp_type type)
{
unsigned bits;
@@ -190,7 +190,7 @@ lp_const_max(union lp_type type)
double
-lp_const_eps(union lp_type type)
+lp_const_eps(struct lp_type type)
{
if (type.floating) {
switch(type.width) {
@@ -211,7 +211,7 @@ lp_const_eps(union lp_type type)
LLVMValueRef
-lp_build_undef(union lp_type type)
+lp_build_undef(struct lp_type type)
{
LLVMTypeRef vec_type = lp_build_vec_type(type);
return LLVMGetUndef(vec_type);
@@ -219,7 +219,7 @@ lp_build_undef(union lp_type type)
LLVMValueRef
-lp_build_zero(union lp_type type)
+lp_build_zero(struct lp_type type)
{
LLVMTypeRef vec_type = lp_build_vec_type(type);
return LLVMConstNull(vec_type);
@@ -227,7 +227,7 @@ lp_build_zero(union lp_type type)
LLVMValueRef
-lp_build_one(union lp_type type)
+lp_build_one(struct lp_type type)
{
LLVMTypeRef elem_type;
LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
@@ -269,7 +269,7 @@ lp_build_one(union lp_type type)
LLVMValueRef
-lp_build_const_scalar(union lp_type type,
+lp_build_const_scalar(struct lp_type type,
double val)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
@@ -295,7 +295,7 @@ lp_build_const_scalar(union lp_type type,
LLVMValueRef
-lp_build_int_const_scalar(union lp_type type,
+lp_build_int_const_scalar(struct lp_type type,
long long val)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
@@ -312,7 +312,7 @@ lp_build_int_const_scalar(union lp_type type,
LLVMValueRef
-lp_build_const_aos(union lp_type type,
+lp_build_const_aos(struct lp_type type,
double r, double g, double b, double a,
const unsigned char *swizzle)
{
@@ -352,8 +352,8 @@ lp_build_const_aos(union lp_type type,
LLVMValueRef
-lp_build_const_mask_aos(union lp_type type,
- boolean cond[4])
+lp_build_const_mask_aos(struct lp_type type,
+ const boolean cond[4])
{
LLVMTypeRef elem_type = LLVMIntType(type.width);
LLVMValueRef masks[LP_MAX_VECTOR_LENGTH];
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/drivers/llvmpipe/lp_bld_const.h
index 1934530ea3c..ffb302f7366 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_const.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.h
@@ -42,67 +42,67 @@
#include <pipe/p_compiler.h>
-union lp_type type;
+struct lp_type type;
unsigned
-lp_mantissa(union lp_type type);
+lp_mantissa(struct lp_type type);
unsigned
-lp_const_shift(union lp_type type);
+lp_const_shift(struct lp_type type);
unsigned
-lp_const_offset(union lp_type type);
+lp_const_offset(struct lp_type type);
double
-lp_const_scale(union lp_type type);
+lp_const_scale(struct lp_type type);
double
-lp_const_min(union lp_type type);
+lp_const_min(struct lp_type type);
double
-lp_const_max(union lp_type type);
+lp_const_max(struct lp_type type);
double
-lp_const_eps(union lp_type type);
+lp_const_eps(struct lp_type type);
LLVMValueRef
-lp_build_undef(union lp_type type);
+lp_build_undef(struct lp_type type);
LLVMValueRef
-lp_build_zero(union lp_type type);
+lp_build_zero(struct lp_type type);
LLVMValueRef
-lp_build_one(union lp_type type);
+lp_build_one(struct lp_type type);
LLVMValueRef
-lp_build_const_scalar(union lp_type type,
+lp_build_const_scalar(struct lp_type type,
double val);
LLVMValueRef
-lp_build_int_const_scalar(union lp_type type,
+lp_build_int_const_scalar(struct lp_type type,
long long val);
LLVMValueRef
-lp_build_const_aos(union lp_type type,
+lp_build_const_aos(struct lp_type type,
double r, double g, double b, double a,
const unsigned char *swizzle);
LLVMValueRef
-lp_build_const_mask_aos(union lp_type type,
- boolean cond[4]);
+lp_build_const_mask_aos(struct lp_type type,
+ const boolean cond[4]);
#endif /* !LP_BLD_CONST_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.c b/src/gallium/drivers/llvmpipe/lp_bld_conv.c
index c8954c8a34f..186cac70f62 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c
@@ -86,7 +86,7 @@
*/
LLVMValueRef
lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
- union lp_type src_type,
+ struct lp_type src_type,
unsigned dst_width,
LLVMValueRef src)
{
@@ -122,7 +122,7 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
int shift = dst_width - n;
res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
- /* Fill in the empty lower bits for added precision? */
+ /* TODO: Fill in the empty lower bits for additional precision? */
#if 0
{
LLVMValueRef msb;
@@ -152,7 +152,7 @@ lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
LLVMValueRef
lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
unsigned src_width,
- union lp_type dst_type,
+ struct lp_type dst_type,
LLVMValueRef src)
{
LLVMTypeRef vec_type = lp_build_vec_type(dst_type);
@@ -244,12 +244,12 @@ lp_build_const_pack_shuffle(unsigned n)
* Expand the bit width.
*
* This will only change the number of bits the values are represented, not the
- * values themselved.
+ * values themselves.
*/
static void
lp_build_expand(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
LLVMValueRef src,
LLVMValueRef *dst, unsigned num_dsts)
{
@@ -266,7 +266,7 @@ lp_build_expand(LLVMBuilderRef builder,
dst[0] = src;
while(src_type.width < dst_type.width) {
- union lp_type new_type = src_type;
+ struct lp_type new_type = src_type;
LLVMTypeRef new_vec_type;
new_type.width *= 2;
@@ -314,8 +314,8 @@ lp_build_expand(LLVMBuilderRef builder,
*/
static LLVMValueRef
lp_build_pack2(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
boolean clamped,
LLVMValueRef lo,
LLVMValueRef hi)
@@ -391,11 +391,11 @@ lp_build_pack2(LLVMBuilderRef builder,
* TODO: Handle saturation consistently.
*/
static LLVMValueRef
-lp_build_trunc(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
- boolean clamped,
- const LLVMValueRef *src, unsigned num_srcs)
+lp_build_pack(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ boolean clamped,
+ const LLVMValueRef *src, unsigned num_srcs)
{
LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
unsigned i;
@@ -410,7 +410,7 @@ lp_build_trunc(LLVMBuilderRef builder,
tmp[i] = src[i];
while(src_type.width > dst_type.width) {
- union lp_type new_type = src_type;
+ struct lp_type new_type = src_type;
new_type.width /= 2;
new_type.length *= 2;
@@ -442,12 +442,12 @@ lp_build_trunc(LLVMBuilderRef builder,
*/
void
lp_build_conv(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
const LLVMValueRef *src, unsigned num_srcs,
LLVMValueRef *dst, unsigned num_dsts)
{
- union lp_type tmp_type;
+ struct lp_type tmp_type;
LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
unsigned num_tmps;
unsigned i;
@@ -470,7 +470,7 @@ lp_build_conv(LLVMBuilderRef builder,
* Clamp if necessary
*/
- if(src_type.value != dst_type.value) {
+ if(memcmp(&src_type, &dst_type, sizeof src_type) != 0) {
struct lp_build_context bld;
double src_min = lp_const_min(src_type);
double dst_min = lp_const_min(dst_type);
@@ -565,7 +565,7 @@ lp_build_conv(LLVMBuilderRef builder,
if(tmp_type.width > dst_type.width) {
assert(num_dsts == 1);
- tmp[0] = lp_build_trunc(builder, tmp_type, dst_type, TRUE, tmp, num_tmps);
+ 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;
@@ -656,8 +656,8 @@ lp_build_conv(LLVMBuilderRef builder,
*/
void
lp_build_conv_mask(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
const LLVMValueRef *src, unsigned num_srcs,
LLVMValueRef *dst, unsigned num_dsts)
{
@@ -689,7 +689,7 @@ lp_build_conv_mask(LLVMBuilderRef builder,
if(src_type.width > dst_type.width) {
assert(num_dsts == 1);
- dst[0] = lp_build_trunc(builder, src_type, dst_type, TRUE, src, num_srcs);
+ dst[0] = lp_build_pack(builder, src_type, dst_type, TRUE, src, num_srcs);
}
else if(src_type.width < dst_type.width) {
assert(num_srcs == 1);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.h b/src/gallium/drivers/llvmpipe/lp_bld_conv.h
index 05c1ef2a100..ca378804d2a 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_conv.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.h
@@ -40,33 +40,33 @@
#include <llvm-c/Core.h>
-union lp_type type;
+struct lp_type type;
LLVMValueRef
lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
- union lp_type src_type,
+ struct lp_type src_type,
unsigned dst_width,
LLVMValueRef src);
LLVMValueRef
lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
unsigned src_width,
- union lp_type dst_type,
+ struct lp_type dst_type,
LLVMValueRef src);
void
lp_build_conv(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
const LLVMValueRef *srcs, unsigned num_srcs,
LLVMValueRef *dsts, unsigned num_dsts);
void
lp_build_conv_mask(LLVMBuilderRef builder,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
const LLVMValueRef *src, unsigned num_srcs,
LLVMValueRef *dst, unsigned num_dsts);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
index 3f88a14b5d3..21c665c4d4c 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
@@ -71,11 +71,11 @@
/**
* Return a type appropriate for depth/stencil testing.
*/
-union lp_type
+struct lp_type
lp_depth_type(const struct util_format_description *format_desc,
unsigned length)
{
- union lp_type type;
+ struct lp_type type;
unsigned swizzle;
assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
@@ -85,7 +85,7 @@ lp_depth_type(const struct util_format_description *format_desc,
swizzle = format_desc->swizzle[0];
assert(swizzle < 4);
- type.value = 0;
+ memset(&type, 0, sizeof type);
type.width = format_desc->block.bits;
if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) {
@@ -114,7 +114,7 @@ lp_depth_type(const struct util_format_description *format_desc,
void
lp_build_depth_test(LLVMBuilderRef builder,
const struct pipe_depth_state *state,
- union lp_type type,
+ struct lp_type type,
const struct util_format_description *format_desc,
struct lp_build_mask_context *mask,
LLVMValueRef src,
@@ -211,5 +211,6 @@ lp_build_depth_test(LLVMBuilderRef builder,
LLVMBuildStore(builder, dst, dst_ptr);
}
+ /* FIXME */
assert(!state->occlusion_count);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.h b/src/gallium/drivers/llvmpipe/lp_bld_depth.h
index 5d2e042fcc5..79d6981bb51 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_depth.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h
@@ -41,11 +41,11 @@
struct pipe_depth_state;
struct util_format_description;
-union lp_type;
+struct lp_type;
struct lp_build_mask_context;
-union lp_type
+struct lp_type
lp_depth_type(const struct util_format_description *format_desc,
unsigned length);
@@ -53,7 +53,7 @@ lp_depth_type(const struct util_format_description *format_desc,
void
lp_build_depth_test(LLVMBuilderRef builder,
const struct pipe_depth_state *state,
- union lp_type type,
+ struct lp_type type,
const struct util_format_description *format_desc,
struct lp_build_mask_context *mask,
LLVMValueRef src,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
index 69ed014ff3d..dcc25fbff86 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_flow.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
@@ -405,7 +405,7 @@ lp_build_mask_check(struct lp_build_mask_context *mask)
void
lp_build_mask_begin(struct lp_build_mask_context *mask,
struct lp_build_flow_context *flow,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef value)
{
memset(mask, 0, sizeof *mask);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.h b/src/gallium/drivers/llvmpipe/lp_bld_flow.h
index 9d76e3064dd..e61999ff06b 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_flow.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.h
@@ -38,7 +38,7 @@
#include <llvm-c/Core.h>
-union lp_type;
+struct lp_type;
struct lp_build_flow_context;
@@ -84,7 +84,7 @@ struct lp_build_mask_context
void
lp_build_mask_begin(struct lp_build_mask_context *mask,
struct lp_build_flow_context *flow,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef value);
/**
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format.h b/src/gallium/drivers/llvmpipe/lp_bld_format.h
index 5ee06560932..6d3f6926193 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_format.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format.h
@@ -39,7 +39,7 @@
#include "pipe/p_format.h"
struct util_format_description;
-union lp_type;
+struct lp_type;
/**
@@ -103,7 +103,7 @@ lp_build_gather(LLVMBuilderRef builder,
void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba);
@@ -111,7 +111,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba);
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c
index 569e8d10a31..b5ff434e1ae 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c
@@ -84,7 +84,7 @@ lp_build_gather(LLVMBuilderRef builder,
static LLVMValueRef
-lp_build_format_swizzle(union lp_type type,
+lp_build_format_swizzle(struct lp_type type,
const LLVMValueRef *inputs,
enum util_format_swizzle swizzle)
{
@@ -110,7 +110,7 @@ lp_build_format_swizzle(union lp_type type,
void
lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef packed,
LLVMValueRef *rgba)
{
@@ -188,7 +188,7 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
void
lp_build_load_rgba_soa(LLVMBuilderRef builder,
const struct util_format_description *format_desc,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef base_ptr,
LLVMValueRef offsets,
LLVMValueRef *rgba)
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
index cfe20a0d75b..338dbca6d1e 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
@@ -292,7 +292,7 @@ void
lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
const struct tgsi_token *tokens,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
index 9194f6233a7..9c57a10879b 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_interp.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
@@ -83,7 +83,7 @@ void
lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
const struct tgsi_token *tokens,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef a0_ptr,
LLVMValueRef dadx_ptr,
LLVMValueRef dady_ptr,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
index 8631efd6c3e..6b6f8207697 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_logic.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
@@ -45,7 +45,7 @@ lp_build_cmp(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMTypeRef vec_type = lp_build_vec_type(type);
LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
LLVMValueRef zeros = LLVMConstNull(int_vec_type);
@@ -301,7 +301,7 @@ lp_build_select(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b)
{
- union lp_type type = bld->type;
+ struct lp_type type = bld->type;
LLVMValueRef res;
if(a == b)
@@ -313,8 +313,6 @@ lp_build_select(struct lp_build_context *bld,
b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
}
- /* TODO: On SSE4 we could do this with a single instruction -- PBLENDVB */
-
a = LLVMBuildAnd(bld->builder, a, mask, "");
/* This often gets translated to PANDN, but sometimes the NOT is
@@ -339,9 +337,9 @@ LLVMValueRef
lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b,
- boolean cond[4])
+ const boolean cond[4])
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
const unsigned n = type.length;
unsigned i, j;
@@ -376,9 +374,9 @@ lp_build_select_aos(struct lp_build_context *bld,
return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
}
+ else {
#if 0
- else if(0) {
- /* FIXME: Unfortunately select of vectors do not work */
+ /* XXX: Unfortunately select of vectors do not work */
/* Use a select */
LLVMTypeRef elem_type = LLVMInt1Type();
LLVMValueRef cond[LP_MAX_VECTOR_LENGTH];
@@ -388,10 +386,9 @@ lp_build_select_aos(struct lp_build_context *bld,
cond[j + i] = LLVMConstInt(elem_type, cond[i] ? 1 : 0, 0);
return LLVMBuildSelect(bld->builder, LLVMConstVector(cond, n), a, b, "");
- }
-#endif
- else {
+#else
LLVMValueRef mask = lp_build_const_mask_aos(type, cond);
return lp_build_select(bld, mask, a, b);
+#endif
}
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.h b/src/gallium/drivers/llvmpipe/lp_bld_logic.h
index 29b9e1c45b8..a4ee7723b5f 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_logic.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.h
@@ -42,7 +42,7 @@
#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
-union lp_type type;
+struct lp_type type;
struct lp_build_context;
@@ -66,7 +66,7 @@ LLVMValueRef
lp_build_select_aos(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b,
- boolean cond[4]);
+ const boolean cond[4]);
#endif /* !LP_BLD_LOGIC_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample.h b/src/gallium/drivers/llvmpipe/lp_bld_sample.h
index 6f565af76d1..403d0e48367 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_sample.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample.h
@@ -40,7 +40,7 @@
struct pipe_texture;
struct pipe_sampler_state;
-union lp_type;
+struct lp_type;
/**
@@ -123,7 +123,7 @@ void
lp_build_sample_soa(LLVMBuilderRef builder,
const struct lp_sampler_static_state *static_state,
struct lp_sampler_dynamic_state *dynamic_state,
- union lp_type fp_type,
+ struct lp_type fp_type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
index 2913b17d3f8..8ca1be6f1be 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
@@ -97,15 +97,15 @@ struct lp_build_sample_context
const struct util_format_description *format_desc;
/** Incoming coordinates type and build context */
- union lp_type coord_type;
+ struct lp_type coord_type;
struct lp_build_context coord_bld;
/** Integer coordinates */
- union lp_type int_coord_type;
+ struct lp_type int_coord_type;
struct lp_build_context int_coord_bld;
/** Output texels type and build context */
- union lp_type texel_type;
+ struct lp_type texel_type;
struct lp_build_context texel_bld;
};
@@ -207,6 +207,12 @@ lp_build_sample_wrap(struct lp_build_sample_context *bld,
case PIPE_TEX_WRAP_MIRROR_CLAMP:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ /* FIXME */
+ _debug_printf("warning: failed to translate texture wrap mode %u\n", wrap_mode);
+ coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
+ coord = lp_build_min(int_coord_bld, coord, length_minus_one);
+ break;
+
default:
assert(0);
}
@@ -336,7 +342,7 @@ void
lp_build_sample_soa(LLVMBuilderRef builder,
const struct lp_sampler_static_state *static_state,
struct lp_sampler_dynamic_state *dynamic_state,
- union lp_type type,
+ struct lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
@@ -398,7 +404,13 @@ lp_build_sample_soa(LLVMBuilderRef builder,
case PIPE_TEX_FILTER_ANISO:
lp_build_sample_2d_linear_soa(&bld, s, t, width, height, stride, data_ptr, texel);
break;
+ default:
+ assert(0);
}
+ /* FIXME: respect static_state->min_mip_filter */;
+ /* FIXME: respect static_state->mag_img_filter */;
+ /* FIXME: respect static_state->prefilter */;
+
lp_build_sample_compare(&bld, p, texel);
}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
index ac7eed9379a..64e81f7b1fe 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
@@ -64,7 +64,7 @@ LLVMValueRef
lp_build_broadcast_scalar(struct lp_build_context *bld,
LLVMValueRef scalar)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
LLVMValueRef res;
unsigned i;
@@ -83,7 +83,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
LLVMValueRef a,
unsigned channel)
{
- const union lp_type type = bld->type;
+ const struct lp_type type = bld->type;
const unsigned n = type.length;
unsigned i, j;
@@ -115,7 +115,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
* YY00 YY00 .... YY00
* YYYY YYYY .... YYYY <= output
*/
- union lp_type type4 = type;
+ struct lp_type type4 = type;
const char shifts[4][2] = {
{ 1, 2},
{-1, 2},
@@ -161,7 +161,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
LLVMValueRef
lp_build_swizzle1_aos(struct lp_build_context *bld,
LLVMValueRef a,
- unsigned char swizzle[4])
+ const unsigned char swizzle[4])
{
const unsigned n = bld->type.length;
unsigned i, j;
@@ -192,7 +192,7 @@ LLVMValueRef
lp_build_swizzle2_aos(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b,
- unsigned char swizzle[4])
+ const unsigned char swizzle[4])
{
const unsigned n = bld->type.length;
unsigned i, j;
@@ -201,11 +201,12 @@ lp_build_swizzle2_aos(struct lp_build_context *bld,
return lp_build_swizzle1_aos(bld, a, swizzle);
if(a == b) {
- swizzle[0] %= 4;
- swizzle[1] %= 4;
- swizzle[2] %= 4;
- swizzle[3] %= 4;
- return lp_build_swizzle1_aos(bld, a, swizzle);
+ 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);
}
if(swizzle[0] % 4 == 0 &&
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h
index d7dd6a8a604..1f6da804488 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h
@@ -40,7 +40,7 @@
#include <llvm-c/Core.h>
-union lp_type type;
+struct lp_type type;
struct lp_build_context;
@@ -73,7 +73,7 @@ lp_build_broadcast_aos(struct lp_build_context *bld,
LLVMValueRef
lp_build_swizzle1_aos(struct lp_build_context *bld,
LLVMValueRef a,
- unsigned char swizzle[4]);
+ const unsigned char swizzle[4]);
/**
@@ -85,7 +85,7 @@ LLVMValueRef
lp_build_swizzle2_aos(struct lp_build_context *bld,
LLVMValueRef a,
LLVMValueRef b,
- unsigned char swizzle[4]);
+ const unsigned char swizzle[4]);
#endif /* !LP_BLD_SWIZZLE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
index 10c251c4162..eddb7a83fa2 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
@@ -39,7 +39,7 @@
struct tgsi_token;
-union lp_type;
+struct lp_type;
struct lp_build_context;
struct lp_build_mask_context;
@@ -60,7 +60,7 @@ struct lp_build_sampler_soa
void
(*emit_fetch_texel)( struct lp_build_sampler_soa *sampler,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
@@ -72,7 +72,7 @@ struct lp_build_sampler_soa
void
lp_build_tgsi_soa(LLVMBuilderRef builder,
const struct tgsi_token *tokens,
- union lp_type type,
+ struct lp_type type,
struct lp_build_mask_context *mask,
LLVMValueRef consts_ptr,
const LLVMValueRef *pos,
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
index 3ce379de12f..adc81569ed5 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -78,6 +78,11 @@
#define CHAN_Z 2
#define CHAN_W 3
+#define QUAD_TOP_LEFT 0
+#define QUAD_TOP_RIGHT 1
+#define QUAD_BOTTOM_LEFT 2
+#define QUAD_BOTTOM_RIGHT 3
+
struct lp_build_tgsi_soa_context
{
@@ -97,6 +102,51 @@ struct lp_build_tgsi_soa_context
};
+static const unsigned char
+swizzle_left[4] = {
+ QUAD_TOP_LEFT, QUAD_TOP_LEFT,
+ QUAD_BOTTOM_LEFT, QUAD_BOTTOM_LEFT
+};
+
+static const unsigned char
+swizzle_right[4] = {
+ QUAD_TOP_RIGHT, QUAD_TOP_RIGHT,
+ QUAD_BOTTOM_RIGHT, QUAD_BOTTOM_RIGHT
+};
+
+static const unsigned char
+swizzle_top[4] = {
+ QUAD_TOP_LEFT, QUAD_TOP_RIGHT,
+ QUAD_TOP_LEFT, QUAD_TOP_RIGHT
+};
+
+static const unsigned char
+swizzle_bottom[4] = {
+ QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT,
+ QUAD_BOTTOM_LEFT, QUAD_BOTTOM_RIGHT
+};
+
+
+static LLVMValueRef
+emit_ddx(struct lp_build_tgsi_soa_context *bld,
+ LLVMValueRef src)
+{
+ LLVMValueRef src_left = lp_build_swizzle1_aos(&bld->base, src, swizzle_left);
+ LLVMValueRef src_right = lp_build_swizzle1_aos(&bld->base, src, swizzle_right);
+ return lp_build_sub(&bld->base, src_right, src_left);
+}
+
+
+static LLVMValueRef
+emit_ddy(struct lp_build_tgsi_soa_context *bld,
+ LLVMValueRef src)
+{
+ LLVMValueRef src_top = lp_build_swizzle1_aos(&bld->base, src, swizzle_top);
+ LLVMValueRef src_bottom = lp_build_swizzle1_aos(&bld->base, src, swizzle_bottom);
+ return lp_build_sub(&bld->base, src_top, src_bottom);
+}
+
+
/**
* Register fetch.
*/
@@ -167,6 +217,7 @@ emit_fetch(
break;
case TGSI_UTIL_SIGN_SET:
+ /* TODO: Use bitwese OR for floating point */
res = lp_build_abs( &bld->base, res );
res = LLVMBuildNeg( bld->base.builder, res, "" );
break;
@@ -184,6 +235,36 @@ emit_fetch(
/**
+ * Register fetch with derivatives.
+ */
+static void
+emit_fetch_deriv(
+ struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ unsigned index,
+ const unsigned chan_index,
+ LLVMValueRef *res,
+ LLVMValueRef *ddx,
+ LLVMValueRef *ddy)
+{
+ LLVMValueRef src;
+
+ src = emit_fetch(bld, inst, index, chan_index);
+
+ if(res)
+ *res = src;
+
+ /* TODO: use interpolation coeffs for inputs */
+
+ if(ddx)
+ *ddx = emit_ddx(bld, src);
+
+ if(ddy)
+ *ddy = emit_ddy(bld, src);
+}
+
+
+/**
* Register store.
*/
static void
@@ -238,17 +319,18 @@ emit_store(
* High-level instruction translators.
*/
+
static void
emit_tex( struct lp_build_tgsi_soa_context *bld,
const struct tgsi_full_instruction *inst,
boolean apply_lodbias,
- boolean projected)
+ boolean projected,
+ LLVMValueRef *texel)
{
const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
LLVMValueRef lodbias;
LLVMValueRef oow;
LLVMValueRef coords[3];
- LLVMValueRef texel[4];
unsigned num_coords;
unsigned i;
@@ -293,10 +375,6 @@ emit_tex( struct lp_build_tgsi_soa_context *bld,
bld->base.type,
unit, num_coords, coords, lodbias,
texel);
-
- FOR_EACH_DST0_ENABLED_CHANNEL( inst, i ) {
- emit_store( bld, inst, 0, i, texel[i] );
- }
}
@@ -349,14 +427,6 @@ emit_kil(
}
-static void
-emit_kilp(
- struct lp_build_tgsi_soa_context *bld )
-{
- /* XXX todo / fix me */
-}
-
-
/**
* Check if inst src/dest regs use indirect addressing into temporary
* register file.
@@ -384,25 +454,35 @@ indirect_temp_reference(const struct tgsi_full_instruction *inst)
static int
emit_instruction(
struct lp_build_tgsi_soa_context *bld,
- struct tgsi_full_instruction *inst )
+ const struct tgsi_full_instruction *inst,
+ const struct tgsi_opcode_info *info)
{
unsigned chan_index;
LLVMValueRef src0, src1, src2;
LLVMValueRef tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7;
- LLVMValueRef dst0;
+ LLVMValueRef res;
+ LLVMValueRef dst0[NUM_CHANNELS];
/* we can't handle indirect addressing into temp register file yet */
if (indirect_temp_reference(inst))
return FALSE;
+ assert(info->num_dst <= 1);
+ if(info->num_dst) {
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = bld->base.undef;
+ }
+ }
+
switch (inst->Instruction.Opcode) {
#if 0
case TGSI_OPCODE_ARL:
+ /* FIXME */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
emit_flr(bld, 0, 0);
emit_f2it( bld, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
#endif
@@ -410,19 +490,17 @@ emit_instruction(
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
}
break;
case TGSI_OPCODE_LIT:
if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
- emit_store( bld, inst, 0, CHAN_X, bld->base.one);
+ dst0[CHAN_X] = bld->base.one;
}
if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
src0 = emit_fetch( bld, inst, 0, CHAN_X );
- dst0 = lp_build_max( &bld->base, src0, bld->base.zero);
- emit_store( bld, inst, 0, CHAN_Y, dst0);
+ dst0[CHAN_Y] = lp_build_max( &bld->base, src0, bld->base.zero);
}
if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
/* XMM[1] = SrcReg[0].yyyy */
@@ -434,20 +512,19 @@ emit_instruction(
tmp1 = lp_build_pow( &bld->base, tmp1, tmp2);
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
tmp2 = lp_build_cmp(&bld->base, PIPE_FUNC_GREATER, tmp0, bld->base.zero);
- dst0 = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
- emit_store( bld, inst, 0, CHAN_Z, dst0);
+ dst0[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
}
if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
- emit_store( bld, inst, 0, CHAN_W, bld->base.one);
+ dst0[CHAN_W] = bld->base.one;
}
break;
case TGSI_OPCODE_RCP:
/* TGSI_OPCODE_RECIP */
src0 = emit_fetch( bld, inst, 0, CHAN_X );
- dst0 = lp_build_rcp(&bld->base, src0);
+ res = lp_build_rcp(&bld->base, src0);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, dst0 );
+ dst0[chan_index] = res;
}
break;
@@ -455,9 +532,9 @@ emit_instruction(
/* TGSI_OPCODE_RECIPSQRT */
src0 = emit_fetch( bld, inst, 0, CHAN_X );
src0 = lp_build_abs(&bld->base, src0);
- dst0 = lp_build_rsqrt(&bld->base, src0);
+ res = lp_build_rsqrt(&bld->base, src0);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, dst0 );
+ dst0[chan_index] = res;
}
break;
@@ -481,16 +558,15 @@ emit_instruction(
lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
- emit_store( bld, inst, 0, CHAN_X, tmp0);
+ dst0[CHAN_X] = tmp0;
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
- emit_store( bld, inst, 0, CHAN_Y, tmp1);
+ dst0[CHAN_Y] = tmp1;
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
- emit_store( bld, inst, 0, CHAN_Z, tmp2);
+ dst0[CHAN_Z] = tmp2;
}
/* dst.w = 1.0 */
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
- tmp0 = bld->base.one;
- emit_store( bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = bld->base.one;
}
break;
@@ -516,20 +592,18 @@ emit_instruction(
/* dst.x = floor(lg2(abs(src.x))) */
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
- emit_store( bld, inst, 0, CHAN_X, tmp0);
+ dst0[CHAN_X] = tmp0;
/* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
- tmp1 = lp_build_div( &bld->base, src0, tmp1);
- emit_store( bld, inst, 0, CHAN_Y, tmp1);
+ dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
}
/* dst.z = lg2(abs(src.x)) */
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
- emit_store( bld, inst, 0, CHAN_Z, tmp2);
+ dst0[CHAN_Z] = tmp2;
}
/* dst.w = 1.0 */
if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
- tmp0 = bld->base.one;
- emit_store( bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = bld->base.one;
}
break;
@@ -537,8 +611,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
- dst0 = lp_build_mul(&bld->base, src0, src1);
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_mul(&bld->base, src0, src1);
}
break;
@@ -546,8 +619,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
- dst0 = lp_build_add(&bld->base, src0, src1);
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_add(&bld->base, src0, src1);
}
break;
@@ -565,7 +637,7 @@ emit_instruction(
tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
@@ -587,28 +659,24 @@ emit_instruction(
tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
case TGSI_OPCODE_DST:
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
- tmp0 = bld->base.one;
- emit_store( bld, inst, 0, CHAN_X, tmp0);
+ dst0[CHAN_X] = bld->base.one;
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
tmp1 = emit_fetch( bld, inst, 1, CHAN_Y );
- tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
- emit_store( bld, inst, 0, CHAN_Y, tmp0);
+ dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
- tmp0 = emit_fetch( bld, inst, 0, CHAN_Z );
- emit_store( bld, inst, 0, CHAN_Z, tmp0);
+ dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
- tmp0 = emit_fetch( bld, inst, 1, CHAN_W );
- emit_store( bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
}
break;
@@ -616,8 +684,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
- dst0 = lp_build_min( &bld->base, src0, src1 );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_min( &bld->base, src0, src1 );
}
break;
@@ -625,8 +692,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
- dst0 = lp_build_max( &bld->base, src0, src1 );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_max( &bld->base, src0, src1 );
}
break;
@@ -636,8 +702,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
@@ -647,8 +712,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GEQUAL, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
@@ -660,7 +724,7 @@ emit_instruction(
tmp2 = emit_fetch( bld, inst, 2, chan_index );
tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
@@ -668,8 +732,7 @@ emit_instruction(
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
tmp1 = emit_fetch( bld, inst, 1, chan_index );
- tmp0 = lp_build_sub( &bld->base, tmp0, tmp1);
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
}
break;
@@ -680,13 +743,19 @@ emit_instruction(
src2 = emit_fetch( bld, inst, 2, chan_index );
tmp0 = lp_build_sub( &bld->base, src1, src2 );
tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
- dst0 = lp_build_add( &bld->base, tmp0, src2 );
- emit_store( bld, inst, 0, chan_index, dst0 );
+ dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
}
break;
case TGSI_OPCODE_CND:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ src0 = emit_fetch( bld, inst, 0, chan_index );
+ src1 = emit_fetch( bld, inst, 1, chan_index );
+ src2 = emit_fetch( bld, inst, 2, chan_index );
+ tmp1 = lp_build_const_scalar(bld->base.type, 0.5);
+ tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src2, tmp1);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, src0, src1 );
+ }
break;
case TGSI_OPCODE_DP2A:
@@ -700,45 +769,49 @@ emit_instruction(
tmp1 = emit_fetch( bld, inst, 2, CHAN_X ); /* xmm1 = src[2].x */
tmp0 = lp_build_add( &bld->base, tmp0, tmp1); /* xmm0 = xmm0 + xmm1 */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0); /* dest[ch] = xmm0 */
+ dst0[chan_index] = tmp0; /* dest[ch] = xmm0 */
}
break;
-#if 0
case TGSI_OPCODE_FRC:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_frc( bld, 0, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ src0 = emit_fetch( bld, inst, 0, chan_index );
+ tmp0 = lp_build_floor(&bld->base, src0);
+ tmp0 = lp_build_sub(&bld->base, tmp0, src0);
+ dst0[chan_index] = tmp0;
}
break;
case TGSI_OPCODE_CLAMP:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ src1 = emit_fetch( bld, inst, 1, chan_index );
+ src2 = emit_fetch( bld, inst, 2, chan_index );
+ tmp0 = lp_build_max(&bld->base, tmp0, src1);
+ tmp0 = lp_build_min(&bld->base, tmp0, src2);
+ dst0[chan_index] = tmp0;
+ }
break;
case TGSI_OPCODE_FLR:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_flr( bld, 0, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_floor(&bld->base, tmp0);
}
break;
case TGSI_OPCODE_ROUND:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_rnd( bld, 0, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_round(&bld->base, tmp0);
}
break;
-#endif
case TGSI_OPCODE_EX2: {
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
tmp0 = lp_build_exp2( &bld->base, tmp0);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
}
@@ -747,16 +820,16 @@ emit_instruction(
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
tmp0 = lp_build_log2( &bld->base, tmp0);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
case TGSI_OPCODE_POW:
src0 = emit_fetch( bld, inst, 0, CHAN_X );
src1 = emit_fetch( bld, inst, 1, CHAN_X );
- dst0 = lp_build_pow( &bld->base, src0, src1 );
+ res = lp_build_pow( &bld->base, src0, src1 );
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, dst0 );
+ dst0[chan_index] = res;
}
break;
@@ -777,7 +850,7 @@ emit_instruction(
tmp5 = tmp3;
tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
- emit_store( bld, inst, 0, CHAN_X, tmp2);
+ dst0[CHAN_X] = tmp2;
}
if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
@@ -788,31 +861,30 @@ emit_instruction(
tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
- emit_store( bld, inst, 0, CHAN_Y, tmp3);
+ dst0[CHAN_Y] = tmp3;
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
tmp0 = lp_build_mul( &bld->base, tmp0, tmp2);
tmp5 = lp_build_sub( &bld->base, tmp5, tmp0);
- emit_store( bld, inst, 0, CHAN_Z, tmp5);
+ dst0[CHAN_Z] = tmp5;
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
- tmp0 = bld->base.one;
- emit_store( bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = bld->base.one;
}
break;
case TGSI_OPCODE_ABS:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
- tmp0 = lp_build_abs( &bld->base, tmp0 ) ;
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
}
break;
case TGSI_OPCODE_RCC:
+ /* deprecated? */
+ assert(0);
return 0;
- break;
case TGSI_OPCODE_DPH:
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
@@ -829,7 +901,7 @@ emit_instruction(
tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
@@ -837,25 +909,27 @@ emit_instruction(
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
tmp0 = lp_build_cos( &bld->base, tmp0 );
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
case TGSI_OPCODE_DDX:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ emit_fetch_deriv( bld, inst, 0, chan_index, NULL, &dst0[chan_index], NULL);
+ }
break;
case TGSI_OPCODE_DDY:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
+ }
break;
-#if 0
case TGSI_OPCODE_KILP:
/* predicated kill */
- emit_kilp( bld );
- return 0; /* XXX fix me */
+ /* FIXME */
+ return 0;
break;
-#endif
case TGSI_OPCODE_KIL:
/* conditional kill */
@@ -887,13 +961,14 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_EQUAL, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
case TGSI_OPCODE_SFL:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = bld->base.zero;
+ }
break;
case TGSI_OPCODE_SGT:
@@ -901,8 +976,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_GREATER, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
@@ -910,7 +984,7 @@ emit_instruction(
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
tmp0 = lp_build_sin( &bld->base, tmp0 );
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
@@ -919,8 +993,7 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LEQUAL, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
@@ -929,85 +1002,99 @@ emit_instruction(
src0 = emit_fetch( bld, inst, 0, chan_index );
src1 = emit_fetch( bld, inst, 1, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_NOTEQUAL, src0, src1 );
- dst0 = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
}
break;
case TGSI_OPCODE_STR:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = bld->base.one;
+ }
break;
case TGSI_OPCODE_TEX:
- emit_tex( bld, inst, FALSE, FALSE );
+ emit_tex( bld, inst, FALSE, FALSE, dst0 );
break;
case TGSI_OPCODE_TXD:
+ /* FIXME */
return 0;
break;
case TGSI_OPCODE_UP2H:
+ /* deprecated */
+ assert (0);
return 0;
break;
case TGSI_OPCODE_UP2US:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_UP4B:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_UP4UB:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_X2D:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_ARA:
+ /* deprecated */
+ assert(0);
return 0;
break;
#if 0
case TGSI_OPCODE_ARR:
+ /* FIXME */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
emit_rnd( bld, 0, 0 );
emit_f2it( bld, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = tmp0;
}
break;
#endif
case TGSI_OPCODE_BRA:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_CAL:
+ /* FIXME */
return 0;
break;
-#if 0
case TGSI_OPCODE_RET:
- emit_ret( bld );
+ /* FIXME */
+ return 0;
break;
-#endif
case TGSI_OPCODE_END:
break;
-#if 0
case TGSI_OPCODE_SSG:
/* TGSI_OPCODE_SGN */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_sgn( bld, 0, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
}
break;
-#endif
case TGSI_OPCODE_CMP:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
@@ -1015,34 +1102,29 @@ emit_instruction(
src1 = emit_fetch( bld, inst, 1, chan_index );
src2 = emit_fetch( bld, inst, 2, chan_index );
tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
- dst0 = lp_build_select( &bld->base, tmp0, src1, src2);
- emit_store( bld, inst, 0, chan_index, dst0);
+ dst0[chan_index] = lp_build_select( &bld->base, tmp0, src1, src2);
}
break;
case TGSI_OPCODE_SCS:
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
- tmp0 = lp_build_cos( &bld->base, tmp0 );
- emit_store( bld, inst, 0, CHAN_X, tmp0);
+ dst0[CHAN_X] = lp_build_cos( &bld->base, tmp0 );
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
- tmp0 = lp_build_sin( &bld->base, tmp0 );
- emit_store( bld, inst, 0, CHAN_Y, tmp0);
+ dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
- tmp0 = bld->base.zero;
- emit_store( bld, inst, 0, CHAN_Z, tmp0);
+ dst0[CHAN_Z] = bld->base.zero;
}
IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
- tmp0 = bld->base.one;
- emit_store( bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = bld->base.one;
}
break;
case TGSI_OPCODE_TXB:
- emit_tex( bld, inst, TRUE, FALSE );
+ emit_tex( bld, inst, TRUE, FALSE, dst0 );
break;
case TGSI_OPCODE_NRM:
@@ -1101,38 +1183,35 @@ emit_instruction(
/* dst.x = xmm1 * src.x */
if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
- tmp4 = lp_build_mul( &bld->base, tmp4, tmp1);
- emit_store(bld, inst, 0, CHAN_X, tmp4);
+ dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
}
/* dst.y = xmm1 * src.y */
if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
- tmp5 = lp_build_mul( &bld->base, tmp5, tmp1);
- emit_store(bld, inst, 0, CHAN_Y, tmp5);
+ dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
}
/* dst.z = xmm1 * src.z */
if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
- tmp6 = lp_build_mul( &bld->base, tmp6, tmp1);
- emit_store(bld, inst, 0, CHAN_Z, tmp6);
+ dst0[CHAN_Z] = lp_build_mul( &bld->base, tmp6, tmp1);
}
/* dst.w = xmm1 * src.w */
if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) && dims == 4) {
- tmp7 = lp_build_mul( &bld->base, tmp7, tmp1);
- emit_store(bld, inst, 0, CHAN_W, tmp7);
+ dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
}
}
- /* dst0.w = 1.0 */
+ /* dst.w = 1.0 */
if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
- tmp0 = bld->base.one;
- emit_store(bld, inst, 0, CHAN_W, tmp0);
+ dst0[CHAN_W] = bld->base.one;
}
}
break;
case TGSI_OPCODE_DIV:
+ /* deprecated */
+ assert( 0 );
return 0;
break;
@@ -1145,118 +1224,157 @@ emit_instruction(
tmp1 = lp_build_mul( &bld->base, tmp1, tmp2); /* xmm1 = xmm1 * xmm2 */
tmp0 = lp_build_add( &bld->base, tmp0, tmp1); /* xmm0 = xmm0 + xmm1 */
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
- emit_store( bld, inst, 0, chan_index, tmp0); /* dest[ch] = xmm0 */
+ dst0[chan_index] = tmp0; /* dest[ch] = xmm0 */
}
break;
case TGSI_OPCODE_TXL:
- emit_tex( bld, inst, TRUE, FALSE );
+ emit_tex( bld, inst, TRUE, FALSE, dst0 );
break;
case TGSI_OPCODE_TXP:
- emit_tex( bld, inst, FALSE, TRUE );
+ emit_tex( bld, inst, FALSE, TRUE, dst0 );
break;
case TGSI_OPCODE_BRK:
+ /* FIXME */
return 0;
break;
case TGSI_OPCODE_IF:
+ /* FIXME */
return 0;
break;
case TGSI_OPCODE_BGNFOR:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_REP:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_ELSE:
+ /* FIXME */
return 0;
break;
case TGSI_OPCODE_ENDIF:
+ /* FIXME */
return 0;
break;
case TGSI_OPCODE_ENDFOR:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_ENDREP:
+ /* deprecated */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_PUSHA:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_POPA:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_CEIL:
- return 0;
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ dst0[chan_index] = lp_build_ceil(&bld->base, tmp0);
+ }
break;
case TGSI_OPCODE_I2F:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_NOT:
+ /* deprecated? */
+ assert(0);
return 0;
break;
-#if 0
case TGSI_OPCODE_TRUNC:
FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
tmp0 = emit_fetch( bld, inst, 0, chan_index );
- emit_f2it( bld, 0 );
- emit_i2f( bld, 0 );
- emit_store( bld, inst, 0, chan_index, tmp0);
+ dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
}
break;
-#endif
case TGSI_OPCODE_SHL:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_SHR:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_AND:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_OR:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_MOD:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_XOR:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_SAD:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_TXF:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_TXQ:
+ /* deprecated? */
+ assert(0);
return 0;
break;
case TGSI_OPCODE_CONT:
+ /* deprecated? */
+ assert(0);
return 0;
break;
@@ -1268,10 +1386,28 @@ emit_instruction(
return 0;
break;
+ case TGSI_OPCODE_NOISE1:
+ case TGSI_OPCODE_NOISE2:
+ case TGSI_OPCODE_NOISE3:
+ case TGSI_OPCODE_NOISE4:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = bld->base.zero;
+ }
+ break;
+
+ case TGSI_OPCODE_NOP:
+ break;
+
default:
return 0;
}
+ if(info->num_dst) {
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ emit_store( bld, inst, 0, chan_index, dst0[chan_index]);
+ }
+ }
+
return 1;
}
@@ -1279,7 +1415,7 @@ emit_instruction(
void
lp_build_tgsi_soa(LLVMBuilderRef builder,
const struct tgsi_token *tokens,
- union lp_type type,
+ struct lp_type type,
struct lp_build_mask_context *mask,
LLVMValueRef consts_ptr,
const LLVMValueRef *pos,
@@ -1309,16 +1445,18 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
switch( parse.FullToken.Token.Type ) {
case TGSI_TOKEN_TYPE_DECLARATION:
- /* Input already interpolated */
+ /* Inputs already interpolated */
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
- if (!emit_instruction( &bld, &parse.FullToken.FullInstruction )) {
+ {
unsigned opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
const struct tgsi_opcode_info *info = tgsi_get_opcode_info(opcode);
- _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
- info ? info->mnemonic : "<invalid>");
- }
+ if (!emit_instruction( &bld, &parse.FullToken.FullInstruction, info ))
+ _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
+ info ? info->mnemonic : "<invalid>");
+ }
+
break;
case TGSI_TOKEN_TYPE_IMMEDIATE:
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.c b/src/gallium/drivers/llvmpipe/lp_bld_type.c
index 577644b7ab8..606243d6c5a 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_type.c
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.c
@@ -33,7 +33,7 @@
LLVMTypeRef
-lp_build_elem_type(union lp_type type)
+lp_build_elem_type(struct lp_type type)
{
if (type.floating) {
switch(type.width) {
@@ -55,7 +55,7 @@ lp_build_elem_type(union lp_type type)
LLVMTypeRef
-lp_build_vec_type(union lp_type type)
+lp_build_vec_type(struct lp_type type)
{
LLVMTypeRef elem_type = lp_build_elem_type(type);
return LLVMVectorType(elem_type, type.length);
@@ -69,7 +69,7 @@ lp_build_vec_type(union lp_type type)
* type and check for identity.
*/
boolean
-lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type)
+lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type)
{
LLVMTypeKind elem_kind;
@@ -107,7 +107,7 @@ lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type)
boolean
-lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type)
+lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type)
{
LLVMTypeRef elem_type;
@@ -128,7 +128,7 @@ lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type)
boolean
-lp_check_value(union lp_type type, LLVMValueRef val)
+lp_check_value(struct lp_type type, LLVMValueRef val)
{
LLVMTypeRef vec_type;
@@ -143,25 +143,26 @@ lp_check_value(union lp_type type, LLVMValueRef val)
LLVMTypeRef
-lp_build_int_elem_type(union lp_type type)
+lp_build_int_elem_type(struct lp_type type)
{
return LLVMIntType(type.width);
}
LLVMTypeRef
-lp_build_int_vec_type(union lp_type type)
+lp_build_int_vec_type(struct lp_type type)
{
LLVMTypeRef elem_type = lp_build_int_elem_type(type);
return LLVMVectorType(elem_type, type.length);
}
-union lp_type
-lp_int_type(union lp_type type)
+struct lp_type
+lp_int_type(struct lp_type type)
{
- union lp_type int_type;
- int_type.value = 0;
+ struct lp_type int_type;
+
+ memset(&int_type, 0, sizeof int_type);
int_type.width = type.width;
int_type.length = type.length;
return int_type;
@@ -171,7 +172,7 @@ lp_int_type(union lp_type type)
void
lp_build_context_init(struct lp_build_context *bld,
LLVMBuilderRef builder,
- union lp_type type)
+ struct lp_type type)
{
bld->builder = builder;
bld->type = type;
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.h b/src/gallium/drivers/llvmpipe/lp_bld_type.h
index 9933e0b45c3..ee5ca3483c1 100644
--- a/src/gallium/drivers/llvmpipe/lp_bld_type.h
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.h
@@ -56,58 +56,55 @@
* on the types used for intermediate computations, such as signed vs unsigned,
* normalized values, or fixed point.
*/
-union lp_type {
- struct {
- /**
- * Floating-point. Cannot be used with fixed. Integer numbers are
- * represented by this zero.
- */
- unsigned floating:1;
-
- /**
- * Fixed-point. Cannot be used with floating. Integer numbers are
- * represented by this zero.
- */
- unsigned fixed:1;
-
- /**
- * Whether it can represent negative values or not.
- *
- * If this is not set for floating point, it means that all values are
- * assumed to be positive.
- */
- unsigned sign:1;
-
- /**
- * Whether values are normalized to fit [0, 1] interval, or [-1, 1]
- * interval for signed types.
- *
- * For integer types it means the representable integer range should be
- * interpreted as the interval above.
- *
- * For floating and fixed point formats it means the values should be
- * clamped to the interval above.
- */
- unsigned norm:1;
-
- /**
- * Element width.
- *
- * For fixed point values, the fixed point is assumed to be at half the
- * width.
- */
- unsigned width:14;
-
- /**
- * Vector length.
- *
- * width*length should be a power of two greater or equal to eight.
- *
- * @sa LP_MAX_VECTOR_LENGTH
- */
- unsigned length:14;
- };
- uint32_t value;
+struct lp_type {
+ /**
+ * Floating-point. Cannot be used with fixed. Integer numbers are
+ * represented by this zero.
+ */
+ unsigned floating:1;
+
+ /**
+ * Fixed-point. Cannot be used with floating. Integer numbers are
+ * represented by this zero.
+ */
+ unsigned fixed:1;
+
+ /**
+ * Whether it can represent negative values or not.
+ *
+ * If this is not set for floating point, it means that all values are
+ * assumed to be positive.
+ */
+ unsigned sign:1;
+
+ /**
+ * Whether values are normalized to fit [0, 1] interval, or [-1, 1]
+ * interval for signed types.
+ *
+ * For integer types it means the representable integer range should be
+ * interpreted as the interval above.
+ *
+ * For floating and fixed point formats it means the values should be
+ * clamped to the interval above.
+ */
+ unsigned norm:1;
+
+ /**
+ * Element width.
+ *
+ * For fixed point values, the fixed point is assumed to be at half the
+ * width.
+ */
+ unsigned width:14;
+
+ /**
+ * Vector length.
+ *
+ * width*length should be a power of two greater or equal to eight.
+ *
+ * @sa LP_MAX_VECTOR_LENGTH
+ */
+ unsigned length:14;
};
@@ -124,7 +121,7 @@ struct lp_build_context
* This not only describes the input/output LLVM types, but also whether
* to normalize/clamp the results.
*/
- union lp_type type;
+ struct lp_type type;
/** Same as lp_build_undef(type) */
LLVMValueRef undef;
@@ -138,41 +135,41 @@ struct lp_build_context
LLVMTypeRef
-lp_build_elem_type(union lp_type type);
+lp_build_elem_type(struct lp_type type);
LLVMTypeRef
-lp_build_vec_type(union lp_type type);
+lp_build_vec_type(struct lp_type type);
boolean
-lp_check_elem_type(union lp_type type, LLVMTypeRef elem_type);
+lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type);
boolean
-lp_check_vec_type(union lp_type type, LLVMTypeRef vec_type);
+lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type);
boolean
-lp_check_value(union lp_type type, LLVMValueRef val);
+lp_check_value(struct lp_type type, LLVMValueRef val);
LLVMTypeRef
-lp_build_int_elem_type(union lp_type type);
+lp_build_int_elem_type(struct lp_type type);
LLVMTypeRef
-lp_build_int_vec_type(union lp_type type);
+lp_build_int_vec_type(struct lp_type type);
-union lp_type
-lp_int_type(union lp_type type);
+struct lp_type
+lp_int_type(struct lp_type type);
void
lp_build_context_init(struct lp_build_context *bld,
LLVMBuilderRef builder,
- union lp_type type);
+ struct lp_type type);
#endif /* !LP_BLD_TYPE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c
index 580cca5b463..bdcff94b9bf 100644
--- a/src/gallium/drivers/llvmpipe/lp_clear.c
+++ b/src/gallium/drivers/llvmpipe/lp_clear.c
@@ -67,6 +67,7 @@ llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
util_pack_color(rgba, ps->format, &cv);
lp_tile_cache_clear(llvmpipe->cbuf_cache[i], rgba, cv);
}
+ llvmpipe->dirty_render_cache = TRUE;
}
if (buffers & PIPE_CLEAR_DEPTHSTENCIL) {
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
index 233d1df0e10..a4b2bd8c2ad 100644
--- a/src/gallium/drivers/llvmpipe/lp_context.c
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -141,8 +141,6 @@ llvmpipe_is_texture_referenced( struct pipe_context *pipe,
return PIPE_REFERENCED_FOR_WRITE;
}
- /* FIXME: we also need to do the same for the texture cache */
-
return PIPE_UNREFERENCED;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 9465f763d50..b4a22ff4a97 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -152,7 +152,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen)
screen->provider = LLVMCreateModuleProviderForExistingModule(screen->module);
if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
- fprintf(stderr, "%s\n", error);
+ _debug_printf("%s\n", error);
LLVMDisposeMessage(error);
abort();
}
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
index c3e3e1af672..58f716ede29 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.h
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -80,10 +80,9 @@ struct lp_jit_context
struct tgsi_sampler **samplers;
- /* TODO: alpha reference value */
float alpha_ref_value;
- /* TODO: blend constant color */
+ /* FIXME: store (also?) in floats */
uint8_t *blend_color;
struct lp_jit_texture textures[PIPE_MAX_SAMPLERS];
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 125035771e5..05189274589 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -27,8 +27,6 @@
#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_defines.h"
#include "pipe/p_screen.h"
@@ -67,8 +65,6 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 1;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
@@ -86,7 +82,7 @@ llvmpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 13; /* max 4Kx4K */
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return 9; /* max 256x256x256 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 13; /* max 4Kx4K */
case PIPE_CAP_TGSI_CONT_SUPPORTED:
@@ -196,8 +192,7 @@ static void
llvmpipe_destroy_screen( struct pipe_screen *_screen )
{
struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
-
- struct pipe_winsys *winsys = _screen->winsys;
+ struct llvmpipe_winsys *winsys = screen->winsys;
lp_jit_screen_cleanup(screen);
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
index f9e254efcae..2d2fc19a65f 100644
--- a/src/gallium/drivers/llvmpipe/lp_setup.c
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -163,8 +163,6 @@ shade_quads(struct llvmpipe_context *llvmpipe,
else
depth = NULL;
- /* TODO: blend color */
-
/* XXX: This will most likely fail on 32bit x86 without -mstackrealign */
assert(lp_check_alignment(mask, 16));
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
index e87976b9f36..30fb41ea65d 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_derived.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -93,6 +93,23 @@ llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
vinfo->num_attribs = 0;
for (i = 0; i < lpfs->info.num_inputs; i++) {
int src;
+ enum interp_mode interp;
+
+ switch (lpfs->info.input_interpolate[i]) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ interp = INTERP_CONSTANT;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ interp = INTERP_LINEAR;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ interp = INTERP_PERSPECTIVE;
+ break;
+ default:
+ assert(0);
+ interp = INTERP_LINEAR;
+ }
+
switch (lpfs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
src = draw_find_vs_output(llvmpipe->draw,
@@ -108,7 +125,7 @@ llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
case TGSI_SEMANTIC_FOG:
src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
break;
case TGSI_SEMANTIC_GENERIC:
@@ -116,7 +133,7 @@ llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
/* this includes texcoords and varying vars */
src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_GENERIC,
lpfs->info.input_semantic_index[i]);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
break;
default:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 618cf1ffb8d..9faed5a0b18 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -133,13 +133,13 @@ generate_pos0(LLVMBuilderRef builder,
static void
generate_depth(LLVMBuilderRef builder,
const struct lp_fragment_shader_variant_key *key,
- union lp_type src_type,
+ struct lp_type src_type,
struct lp_build_mask_context *mask,
LLVMValueRef src,
LLVMValueRef dst_ptr)
{
const struct util_format_description *format_desc;
- union lp_type dst_type;
+ struct lp_type dst_type;
if(!key->depth.enabled)
return;
@@ -181,7 +181,7 @@ generate_fs(struct llvmpipe_context *lp,
struct lp_fragment_shader *shader,
const struct lp_fragment_shader_variant_key *key,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef context_ptr,
unsigned i,
const struct lp_build_interp_soa_context *interp,
@@ -299,7 +299,7 @@ generate_fs(struct llvmpipe_context *lp,
static void
generate_blend(const struct pipe_blend_state *blend,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
LLVMValueRef context_ptr,
LLVMValueRef mask,
LLVMValueRef *src,
@@ -364,8 +364,8 @@ generate_fragment(struct llvmpipe_context *lp,
{
struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
struct lp_fragment_shader_variant *variant;
- union lp_type fs_type;
- union lp_type blend_type;
+ struct lp_type fs_type;
+ struct lp_type blend_type;
LLVMTypeRef fs_elem_type;
LLVMTypeRef fs_vec_type;
LLVMTypeRef fs_int_vec_type;
@@ -431,7 +431,7 @@ generate_fragment(struct llvmpipe_context *lp,
/* TODO: actually pick these based on the fs and color buffer
* characteristics. */
- fs_type.value = 0;
+ memset(&fs_type, 0, sizeof fs_type);
fs_type.floating = TRUE; /* floating point values */
fs_type.sign = TRUE; /* values are signed */
fs_type.norm = FALSE; /* values are not limited to [0,1] or [-1,1] */
@@ -439,7 +439,7 @@ generate_fragment(struct llvmpipe_context *lp,
fs_type.length = 4; /* 4 element per vector */
num_fs = 4;
- blend_type.value = 0;
+ memset(&blend_type, 0, sizeof blend_type);
blend_type.floating = FALSE; /* values are integers */
blend_type.sign = FALSE; /* values are unsigned */
blend_type.norm = TRUE; /* values are in [0,1] or [-1,1] */
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
index 69aaae26e0a..a88e110c663 100644
--- a/src/gallium/drivers/llvmpipe/lp_test.h
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -86,43 +86,43 @@ random_float(void);
void
-dump_type(FILE *fp, union lp_type type);
+dump_type(FILE *fp, struct lp_type type);
double
-read_elem(union lp_type type, const void *src, unsigned index);
+read_elem(struct lp_type type, const void *src, unsigned index);
void
-write_elem(union lp_type type, void *dst, unsigned index, double src);
+write_elem(struct lp_type type, void *dst, unsigned index, double src);
void
-random_elem(union lp_type type, void *dst, unsigned index);
+random_elem(struct lp_type type, void *dst, unsigned index);
void
-read_vec(union lp_type type, const void *src, double *dst);
+read_vec(struct lp_type type, const void *src, double *dst);
void
-write_vec(union lp_type type, void *dst, const double *src);
+write_vec(struct lp_type type, void *dst, const double *src);
void
-random_vec(union lp_type type, void *dst);
+random_vec(struct lp_type type, void *dst);
boolean
-compare_vec_with_eps(union lp_type type, const void *res, const void *ref, double eps);
+compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps);
boolean
-compare_vec(union lp_type type, const void *res, const void *ref);
+compare_vec(struct lp_type type, const void *res, const void *ref);
void
-dump_vec(FILE *fp, union lp_type type, const void *src);
+dump_vec(FILE *fp, struct lp_type type, const void *src);
#endif /* !LP_TEST_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c
index 8dfad468e3c..94b661dcba4 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_blend.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -80,7 +80,7 @@ static void
write_tsv_row(FILE *fp,
const struct pipe_blend_state *blend,
enum vector_mode mode,
- union lp_type type,
+ struct lp_type type,
double cycles,
boolean success)
{
@@ -125,7 +125,7 @@ static void
dump_blend_type(FILE *fp,
const struct pipe_blend_state *blend,
enum vector_mode mode,
- union lp_type type)
+ struct lp_type type)
{
fprintf(fp, "%s", mode ? "soa" : "aos");
@@ -153,7 +153,7 @@ static LLVMValueRef
add_blend_test(LLVMModuleRef module,
const struct pipe_blend_state *blend,
enum vector_mode mode,
- union lp_type type)
+ struct lp_type type)
{
LLVMTypeRef ret_type;
LLVMTypeRef vec_type;
@@ -467,7 +467,7 @@ test_one(unsigned verbose,
FILE *fp,
const struct pipe_blend_state *blend,
enum vector_mode mode,
- union lp_type type)
+ struct lp_type type)
{
LLVMModuleRef module = NULL;
LLVMValueRef func = NULL;
@@ -765,10 +765,10 @@ blend_funcs[] = {
};
-const union lp_type blend_types[] = {
+const struct lp_type blend_types[] = {
/* float, fixed, sign, norm, width, len */
- {{ TRUE, FALSE, FALSE, TRUE, 32, 4 }}, /* f32 x 4 */
- {{ FALSE, FALSE, FALSE, TRUE, 8, 16 }}, /* u8n x 16 */
+ { TRUE, FALSE, FALSE, TRUE, 32, 4 }, /* f32 x 4 */
+ { FALSE, FALSE, FALSE, TRUE, 8, 16 }, /* u8n x 16 */
};
@@ -788,7 +788,7 @@ test_all(unsigned verbose, FILE *fp)
const unsigned *alpha_dst_factor;
struct pipe_blend_state blend;
enum vector_mode mode;
- const union lp_type *type;
+ const struct lp_type *type;
bool success = TRUE;
for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
@@ -841,27 +841,27 @@ test_some(unsigned verbose, FILE *fp, unsigned long n)
const unsigned *alpha_dst_factor;
struct pipe_blend_state blend;
enum vector_mode mode;
- const union lp_type *type;
+ const struct lp_type *type;
unsigned long i;
bool success = TRUE;
for(i = 0; i < n; ++i) {
- rgb_func = &blend_funcs[random() % num_funcs];
- alpha_func = &blend_funcs[random() % num_funcs];
- rgb_src_factor = &blend_factors[random() % num_factors];
- alpha_src_factor = &blend_factors[random() % num_factors];
+ rgb_func = &blend_funcs[rand() % num_funcs];
+ alpha_func = &blend_funcs[rand() % num_funcs];
+ rgb_src_factor = &blend_factors[rand() % num_factors];
+ alpha_src_factor = &blend_factors[rand() % num_factors];
do {
- rgb_dst_factor = &blend_factors[random() % num_factors];
+ rgb_dst_factor = &blend_factors[rand() % num_factors];
} while(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
do {
- alpha_dst_factor = &blend_factors[random() % num_factors];
+ alpha_dst_factor = &blend_factors[rand() % num_factors];
} while(*alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
- mode = random() & 1;
+ mode = rand() & 1;
- type = &blend_types[random() % num_types];
+ type = &blend_types[rand() % num_types];
memset(&blend, 0, sizeof blend);
blend.blend_enable = 1;
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
index e6489834af5..9dcf58e5dcd 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_conv.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -59,8 +59,8 @@ write_tsv_header(FILE *fp)
static void
write_tsv_row(FILE *fp,
- union lp_type src_type,
- union lp_type dst_type,
+ struct lp_type src_type,
+ struct lp_type dst_type,
double cycles,
boolean success)
{
@@ -80,8 +80,8 @@ write_tsv_row(FILE *fp,
static void
dump_conv_types(FILE *fp,
- union lp_type src_type,
- union lp_type dst_type)
+ struct lp_type src_type,
+ struct lp_type dst_type)
{
fprintf(fp, "src_type=");
dump_type(fp, src_type);
@@ -96,8 +96,8 @@ dump_conv_types(FILE *fp,
static LLVMValueRef
add_conv_test(LLVMModuleRef module,
- union lp_type src_type, unsigned num_srcs,
- union lp_type dst_type, unsigned num_dsts)
+ struct lp_type src_type, unsigned num_srcs,
+ struct lp_type dst_type, unsigned num_dsts)
{
LLVMTypeRef args[2];
LLVMValueRef func;
@@ -145,8 +145,8 @@ add_conv_test(LLVMModuleRef module,
static boolean
test_one(unsigned verbose,
FILE *fp,
- union lp_type src_type,
- union lp_type dst_type)
+ struct lp_type src_type,
+ struct lp_type dst_type)
{
LLVMModuleRef module = NULL;
LLVMValueRef func = NULL;
@@ -343,35 +343,35 @@ test_one(unsigned verbose,
}
-const union lp_type conv_types[] = {
+const struct lp_type conv_types[] = {
/* float, fixed, sign, norm, width, len */
- {{ TRUE, FALSE, TRUE, TRUE, 32, 4 }},
- {{ TRUE, FALSE, TRUE, FALSE, 32, 4 }},
- {{ TRUE, FALSE, FALSE, TRUE, 32, 4 }},
- {{ TRUE, FALSE, FALSE, FALSE, 32, 4 }},
+ { TRUE, FALSE, TRUE, TRUE, 32, 4 },
+ { TRUE, FALSE, TRUE, FALSE, 32, 4 },
+ { TRUE, FALSE, FALSE, TRUE, 32, 4 },
+ { TRUE, FALSE, FALSE, FALSE, 32, 4 },
/* TODO: test fixed formats too */
- {{ FALSE, FALSE, TRUE, TRUE, 16, 8 }},
- {{ FALSE, FALSE, TRUE, FALSE, 16, 8 }},
- {{ FALSE, FALSE, FALSE, TRUE, 16, 8 }},
- {{ FALSE, FALSE, FALSE, FALSE, 16, 8 }},
-
- {{ FALSE, FALSE, TRUE, TRUE, 32, 4 }},
- {{ FALSE, FALSE, TRUE, FALSE, 32, 4 }},
- {{ FALSE, FALSE, FALSE, TRUE, 32, 4 }},
- {{ FALSE, FALSE, FALSE, FALSE, 32, 4 }},
-
- {{ FALSE, FALSE, TRUE, TRUE, 16, 8 }},
- {{ FALSE, FALSE, TRUE, FALSE, 16, 8 }},
- {{ FALSE, FALSE, FALSE, TRUE, 16, 8 }},
- {{ FALSE, FALSE, FALSE, FALSE, 16, 8 }},
-
- {{ FALSE, FALSE, TRUE, TRUE, 8, 16 }},
- {{ FALSE, FALSE, TRUE, FALSE, 8, 16 }},
- {{ FALSE, FALSE, FALSE, TRUE, 8, 16 }},
- {{ FALSE, FALSE, FALSE, FALSE, 8, 16 }},
+ { FALSE, FALSE, TRUE, TRUE, 16, 8 },
+ { FALSE, FALSE, TRUE, FALSE, 16, 8 },
+ { FALSE, FALSE, FALSE, TRUE, 16, 8 },
+ { FALSE, FALSE, FALSE, FALSE, 16, 8 },
+
+ { FALSE, FALSE, TRUE, TRUE, 32, 4 },
+ { FALSE, FALSE, TRUE, FALSE, 32, 4 },
+ { FALSE, FALSE, FALSE, TRUE, 32, 4 },
+ { FALSE, FALSE, FALSE, FALSE, 32, 4 },
+
+ { FALSE, FALSE, TRUE, TRUE, 16, 8 },
+ { FALSE, FALSE, TRUE, FALSE, 16, 8 },
+ { FALSE, FALSE, FALSE, TRUE, 16, 8 },
+ { FALSE, FALSE, FALSE, FALSE, 16, 8 },
+
+ { FALSE, FALSE, TRUE, TRUE, 8, 16 },
+ { FALSE, FALSE, TRUE, FALSE, 8, 16 },
+ { FALSE, FALSE, FALSE, TRUE, 8, 16 },
+ { FALSE, FALSE, FALSE, FALSE, 8, 16 },
};
@@ -381,8 +381,8 @@ const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
boolean
test_all(unsigned verbose, FILE *fp)
{
- const union lp_type *src_type;
- const union lp_type *dst_type;
+ const struct lp_type *src_type;
+ const struct lp_type *dst_type;
bool success = TRUE;
for(src_type = conv_types; src_type < &conv_types[num_types]; ++src_type) {
@@ -407,16 +407,16 @@ test_all(unsigned verbose, FILE *fp)
boolean
test_some(unsigned verbose, FILE *fp, unsigned long n)
{
- const union lp_type *src_type;
- const union lp_type *dst_type;
+ const struct lp_type *src_type;
+ const struct lp_type *dst_type;
unsigned long i;
bool success = TRUE;
for(i = 0; i < n; ++i) {
- src_type = &conv_types[random() % num_types];
+ src_type = &conv_types[rand() % num_types];
do {
- dst_type = &conv_types[random() % num_types];
+ dst_type = &conv_types[rand() % num_types];
} while (src_type == dst_type || src_type->norm != dst_type->norm);
if(!test_one(verbose, fp, *src_type, *dst_type))
diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c
index 49213fb4f0b..4592dc0b2d0 100644
--- a/src/gallium/drivers/llvmpipe/lp_test_main.c
+++ b/src/gallium/drivers/llvmpipe/lp_test_main.c
@@ -40,7 +40,7 @@
void
dump_type(FILE *fp,
- union lp_type type)
+ struct lp_type type)
{
fprintf(fp, "%s%s%u%sx%u",
type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
@@ -52,7 +52,7 @@ dump_type(FILE *fp,
double
-read_elem(union lp_type type, const void *src, unsigned index)
+read_elem(struct lp_type type, const void *src, unsigned index)
{
double scale = lp_const_scale(type);
double value;
@@ -115,7 +115,7 @@ read_elem(union lp_type type, const void *src, unsigned index)
void
-write_elem(union lp_type type, void *dst, unsigned index, double value)
+write_elem(struct lp_type type, void *dst, unsigned index, double value)
{
assert(index < type.length);
if(!type.sign && value < 0.0)
@@ -184,11 +184,11 @@ write_elem(union lp_type type, void *dst, unsigned index, double value)
void
-random_elem(union lp_type type, void *dst, unsigned index)
+random_elem(struct lp_type type, void *dst, unsigned index)
{
double value;
assert(index < type.length);
- value = (double)random()/(double)RAND_MAX;
+ value = (double)rand()/(double)RAND_MAX;
if(!type.norm) {
unsigned long long mask;
if (type.floating)
@@ -199,17 +199,17 @@ random_elem(union lp_type type, void *dst, unsigned index)
mask = ((unsigned long long)1 << (type.width - 1)) - 1;
else
mask = ((unsigned long long)1 << type.width) - 1;
- value += (double)(mask & random());
+ value += (double)(mask & rand());
}
if(!type.sign)
- if(random() & 1)
+ if(rand() & 1)
value = -value;
write_elem(type, dst, index, value);
}
void
-read_vec(union lp_type type, const void *src, double *dst)
+read_vec(struct lp_type type, const void *src, double *dst)
{
unsigned i;
for (i = 0; i < type.length; ++i)
@@ -218,7 +218,7 @@ read_vec(union lp_type type, const void *src, double *dst)
void
-write_vec(union lp_type type, void *dst, const double *src)
+write_vec(struct lp_type type, void *dst, const double *src)
{
unsigned i;
for (i = 0; i < type.length; ++i)
@@ -229,12 +229,12 @@ write_vec(union lp_type type, void *dst, const double *src)
float
random_float(void)
{
- return (float)((double)random()/(double)RAND_MAX);
+ return (float)((double)rand()/(double)RAND_MAX);
}
void
-random_vec(union lp_type type, void *dst)
+random_vec(struct lp_type type, void *dst)
{
unsigned i;
for (i = 0; i < type.length; ++i)
@@ -243,7 +243,7 @@ random_vec(union lp_type type, void *dst)
boolean
-compare_vec_with_eps(union lp_type type, const void *res, const void *ref, double eps)
+compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps)
{
unsigned i;
for (i = 0; i < type.length; ++i) {
@@ -259,7 +259,7 @@ compare_vec_with_eps(union lp_type type, const void *res, const void *ref, doubl
boolean
-compare_vec(union lp_type type, const void *res, const void *ref)
+compare_vec(struct lp_type type, const void *res, const void *ref)
{
double eps = lp_const_eps(type);
return compare_vec_with_eps(type, res, ref, eps);
@@ -267,7 +267,7 @@ compare_vec(union lp_type type, const void *res, const void *ref)
void
-dump_vec(FILE *fp, union lp_type type, const void *src)
+dump_vec(FILE *fp, struct lp_type type, const void *src)
{
unsigned i;
for (i = 0; i < type.length; ++i) {
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
index 9a876f404df..a1365a045f1 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
@@ -1654,7 +1654,7 @@ lp_c_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
static void
lp_c_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *_sampler,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
index 7d31705d014..d2a6ae21f57 100644
--- a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -149,7 +149,7 @@ lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
static void
lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base,
LLVMBuilderRef builder,
- union lp_type type,
+ struct lp_type type,
unsigned unit,
unsigned num_coords,
const LLVMValueRef *coords,
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
index 143afec3d35..0c06b659a1f 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_cache.c
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
@@ -44,10 +44,53 @@
#include "lp_tile_cache.h"
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 4096
+
+
+enum llvmpipe_tile_status
+{
+ LP_TILE_STATUS_UNDEFINED = 0,
+ LP_TILE_STATUS_CLEAR = 1,
+ LP_TILE_STATUS_DEFINED = 2
+};
+
+
+struct llvmpipe_cached_tile
+{
+ enum llvmpipe_tile_status status;
+
+ /** color in SOA format */
+ uint8_t *color;
+};
+
+
+struct llvmpipe_tile_cache
+{
+ struct pipe_screen *screen;
+ struct pipe_surface *surface; /**< the surface we're caching */
+ struct pipe_transfer *transfer;
+ void *transfer_map;
+
+ struct llvmpipe_cached_tile entries[MAX_WIDTH/TILE_SIZE][MAX_HEIGHT/TILE_SIZE];
+
+ uint8_t clear_color[4]; /**< for color bufs */
+ uint clear_val; /**< for z+stencil, or packed color clear value */
+
+ struct llvmpipe_cached_tile *last_tile; /**< most recently retrieved tile */
+};
+
+
struct llvmpipe_tile_cache *
lp_create_tile_cache( struct pipe_screen *screen )
{
struct llvmpipe_tile_cache *tc;
+ int maxLevels, maxTexSize;
+
+ /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
+ maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ maxTexSize = 1 << (maxLevels - 1);
+ assert(MAX_WIDTH >= maxTexSize);
tc = CALLOC_STRUCT( llvmpipe_tile_cache );
if(!tc)
@@ -225,11 +268,14 @@ lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
tc->clear_val);
screen->transfer_unmap(screen, pt);
+
+ tile->status = LP_TILE_STATUS_UNDEFINED;
break;
}
case LP_TILE_STATUS_DEFINED:
lp_put_tile_rgba_soa(pt, x, y, tile->color);
+ tile->status = LP_TILE_STATUS_UNDEFINED;
break;
}
}
@@ -257,7 +303,7 @@ lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
case LP_TILE_STATUS_UNDEFINED:
/* get new tile data from transfer */
- lp_get_tile_rgba_soa(pt, x, y, tile->color);
+ lp_get_tile_rgba_soa(pt, x & ~(TILE_SIZE - 1), y & ~(TILE_SIZE - 1), tile->color);
tile->status = LP_TILE_STATUS_DEFINED;
break;
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h
index 6d8ba5ece7a..161bab37991 100644
--- a/src/gallium/drivers/llvmpipe/lp_tile_cache.h
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h
@@ -33,42 +33,7 @@
#include "lp_tile_soa.h"
-enum llvmpipe_tile_status
-{
- LP_TILE_STATUS_UNDEFINED = 0,
- LP_TILE_STATUS_CLEAR = 1,
- LP_TILE_STATUS_DEFINED = 2
-};
-
-
-struct llvmpipe_cached_tile
-{
- enum llvmpipe_tile_status status;
-
- /** color in SOA format */
- uint8_t *color;
-};
-
-
-/** XXX move these */
-#define MAX_WIDTH 2048
-#define MAX_HEIGHT 2048
-
-
-struct llvmpipe_tile_cache
-{
- struct pipe_screen *screen;
- struct pipe_surface *surface; /**< the surface we're caching */
- struct pipe_transfer *transfer;
- void *transfer_map;
-
- struct llvmpipe_cached_tile entries[MAX_WIDTH/TILE_SIZE][MAX_HEIGHT/TILE_SIZE];
-
- uint8_t clear_color[4]; /**< for color bufs */
- uint clear_val; /**< for z+stencil, or packed color clear value */
-
- struct llvmpipe_cached_tile *last_tile; /**< most recently retrieved tile */
-};
+struct llvmpipe_tile_cache; /* opaque */
extern struct llvmpipe_tile_cache *
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index ff2febb668e..170ce3eb7e5 100644
--- a/src/gallium/drivers/nv04/nv04_screen.c
+++ b/src/gallium/drivers/nv04/nv04_screen.c
@@ -16,8 +16,6 @@ nv04_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index 4469b22d91a..ee5901e743e 100644
--- a/src/gallium/drivers/nv10/nv10_screen.c
+++ b/src/gallium/drivers/nv10/nv10_screen.c
@@ -15,8 +15,6 @@ nv10_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/nv20/nv20_screen.c b/src/gallium/drivers/nv20/nv20_screen.c
index e6924ad71eb..4eeacd1afd5 100644
--- a/src/gallium/drivers/nv20/nv20_screen.c
+++ b/src/gallium/drivers/nv20/nv20_screen.c
@@ -15,8 +15,6 @@ nv20_screen_get_param(struct pipe_screen *screen, int param)
return 0;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c
index f8285e4455f..41af38450b5 100644
--- a/src/gallium/drivers/nv30/nv30_screen.c
+++ b/src/gallium/drivers/nv30/nv30_screen.c
@@ -22,8 +22,6 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 5d2a4216c5a..bd13dfddd1c 100644
--- a/src/gallium/drivers/nv40/nv40_screen.c
+++ b/src/gallium/drivers/nv40/nv40_screen.c
@@ -21,8 +21,6 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
diff --git a/src/gallium/drivers/nv50/nv50_context.c b/src/gallium/drivers/nv50/nv50_context.c
index 6e8f4f9750d..fca078b174a 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -37,11 +37,12 @@ nv50_flush(struct pipe_context *pipe, unsigned flags,
/* We need this in the ddx for reliable composite, not sure what we're
* actually flushing. We generate all our own flushes with flags = 0. */
- WAIT_RING(chan, 3);
+ WAIT_RING(chan, 2);
BEGIN_RING(chan, eng2d, 0x0110, 1);
OUT_RING (chan, 0);
- FIRE_RING(chan);
+ if (flags & PIPE_FLUSH_FRAME)
+ FIRE_RING(chan);
}
static void
@@ -110,6 +111,9 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
nv50->pipe.is_texture_referenced = nv50_is_texture_referenced;
nv50->pipe.is_buffer_referenced = nv50_is_buffer_referenced;
+ screen->base.channel->user_private = nv50;
+ screen->base.channel->flush_notify = nv50_state_flush_notify;
+
nv50_init_surface_functions(nv50);
nv50_init_state_functions(nv50);
nv50_init_query_functions(nv50);
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 1e9e8e49bfb..4608854d711 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -116,6 +116,7 @@ struct nv50_state {
unsigned miptree_nr;
struct nouveau_stateobj *vertprog;
struct nouveau_stateobj *fragprog;
+ struct nouveau_stateobj *programs;
struct nouveau_stateobj *vtxfmt;
struct nouveau_stateobj *vtxbuf;
struct nouveau_stateobj *vtxattr;
@@ -190,10 +191,12 @@ extern void nv50_clear(struct pipe_context *pipe, unsigned buffers,
/* nv50_program.c */
extern void nv50_vertprog_validate(struct nv50_context *nv50);
extern void nv50_fragprog_validate(struct nv50_context *nv50);
+extern void nv50_linkage_validate(struct nv50_context *nv50);
extern void nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p);
/* nv50_state_validate.c */
extern boolean nv50_state_validate(struct nv50_context *nv50);
+extern void nv50_state_flush_notify(struct nouveau_channel *chan);
/* nv50_tex.c */
extern void nv50_tex_validate(struct nv50_context *);
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 4a838529de7..576d075318f 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -90,6 +90,10 @@ struct nv50_reg {
int acc; /* instruction where this reg is last read (first insn == 1) */
};
+/* arbitrary limits */
+#define MAX_IF_DEPTH 4
+#define MAX_LOOP_DEPTH 4
+
struct nv50_pc {
struct nv50_program *p;
@@ -112,11 +116,22 @@ struct nv50_pc {
struct nv50_reg *temp_temp[16];
unsigned temp_temp_nr;
+ /* broadcast and destination replacement regs */
+ struct nv50_reg *r_brdc;
+ struct nv50_reg *r_dst[4];
+
unsigned interp_mode[32];
/* perspective interpolation registers */
struct nv50_reg *iv_p;
struct nv50_reg *iv_c;
+ struct nv50_program_exec *if_cond;
+ struct nv50_program_exec *if_insn[MAX_IF_DEPTH];
+ struct nv50_program_exec *br_join[MAX_IF_DEPTH];
+ struct nv50_program_exec *br_loop[MAX_LOOP_DEPTH]; /* for BRK branch */
+ int if_lvl, loop_lvl;
+ unsigned loop_pos[MAX_LOOP_DEPTH];
+
/* current instruction and total number of insns */
unsigned insn_cur;
unsigned insn_nr;
@@ -124,6 +139,25 @@ struct nv50_pc {
boolean allow32;
};
+static INLINE void
+ctor_reg(struct nv50_reg *reg, unsigned type, int index, int hw)
+{
+ reg->type = type;
+ reg->index = index;
+ reg->hw = hw;
+ reg->neg = 0;
+ reg->rhw = -1;
+ reg->acc = 0;
+}
+
+static INLINE unsigned
+popcnt4(uint32_t val)
+{
+ static const unsigned cnt[16]
+ = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
+ return cnt[val & 0xf];
+}
+
static void
alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
{
@@ -173,6 +207,10 @@ alloc_reg(struct nv50_pc *pc, struct nv50_reg *reg)
assert(0);
}
+/* XXX: For shaders that aren't executed linearly (e.g. shaders that
+ * contain loops), we need to assign all hw regs to TGSI TEMPs early,
+ * lest we risk temp_temps overwriting regs alloc'd "later".
+ */
static struct nv50_reg *
alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
{
@@ -184,11 +222,8 @@ alloc_temp(struct nv50_pc *pc, struct nv50_reg *dst)
for (i = 0; i < NV50_SU_MAX_TEMP; i++) {
if (!pc->r_temp[i]) {
- r = CALLOC_STRUCT(nv50_reg);
- r->type = P_TEMP;
- r->index = -1;
- r->hw = i;
- r->rhw = -1;
+ r = MALLOC_STRUCT(nv50_reg);
+ ctor_reg(r, P_TEMP, -1, i);
pc->r_temp[i] = r;
return r;
}
@@ -254,10 +289,8 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx)
return alloc_temp4(pc, dst, idx + 4);
for (i = 0; i < 4; i++) {
- dst[i] = CALLOC_STRUCT(nv50_reg);
- dst[i]->type = P_TEMP;
- dst[i]->index = -1;
- dst[i]->hw = idx + i;
+ dst[i] = MALLOC_STRUCT(nv50_reg);
+ ctor_reg(dst[i], P_TEMP, -1, idx + i);
pc->r_temp[idx + i] = dst[i];
}
@@ -309,7 +342,7 @@ ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w)
static struct nv50_reg *
alloc_immd(struct nv50_pc *pc, float f)
{
- struct nv50_reg *r = CALLOC_STRUCT(nv50_reg);
+ struct nv50_reg *r = MALLOC_STRUCT(nv50_reg);
unsigned hw;
for (hw = 0; hw < pc->immd_nr * 4; hw++)
@@ -319,9 +352,7 @@ alloc_immd(struct nv50_pc *pc, float f)
if (hw == pc->immd_nr * 4)
hw = ctor_immd(pc, f, -f, 0.5 * f, 0) * 4;
- r->type = P_IMMD;
- r->hw = hw;
- r->index = -1;
+ ctor_reg(r, P_IMMD, -1, hw);
return r;
}
@@ -543,6 +574,22 @@ check_swap_src_0_1(struct nv50_pc *pc,
}
static void
+set_src_0_restricted(struct nv50_pc *pc, struct nv50_reg *src,
+ struct nv50_program_exec *e)
+{
+ struct nv50_reg *temp;
+
+ if (src->type != P_TEMP) {
+ temp = temp_temp(pc);
+ emit_mov(pc, temp, src);
+ src = temp;
+ }
+
+ alloc_reg(pc, src);
+ e->inst[0] |= (src->hw << 9);
+}
+
+static void
set_src_0(struct nv50_pc *pc, struct nv50_reg *src, struct nv50_program_exec *e)
{
if (src->type == P_ATTR) {
@@ -744,7 +791,11 @@ emit_flop(struct nv50_pc *pc, unsigned sub,
}
set_dst(pc, dst, e);
- set_src_0(pc, src, e);
+
+ if (sub == 0 || sub == 2)
+ set_src_0_restricted(pc, src, e);
+ else
+ set_src_0(pc, src, e);
emit(pc, e);
}
@@ -786,16 +837,20 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
#define CVTOP_SAT 0x08
#define CVTOP_ABS 0x10
+/* 0x04 == 32 bit */
+/* 0x40 == dst is float */
+/* 0x80 == src is float */
#define CVT_F32_F32 0xc4
#define CVT_F32_S32 0x44
#define CVT_F32_U32 0x64
#define CVT_S32_F32 0x8c
#define CVT_S32_S32 0x0c
-#define CVT_F32_F32_ROP 0xcc
+#define CVT_NEG 0x20
+#define CVT_RI 0x08
static void
emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src,
- int wp, unsigned cop, unsigned fmt)
+ int wp, unsigned cvn, unsigned fmt)
{
struct nv50_program_exec *e;
@@ -804,7 +859,7 @@ emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src,
e->inst[0] |= 0xa0000000;
e->inst[1] |= 0x00004000;
- e->inst[1] |= (cop << 16);
+ e->inst[1] |= (cvn << 16);
e->inst[1] |= (fmt << 24);
set_src_0(pc, src, e);
@@ -821,53 +876,85 @@ emit_cvt(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src,
emit(pc, e);
}
+/* nv50 Condition codes:
+ * 0x1 = LT
+ * 0x2 = EQ
+ * 0x3 = LE
+ * 0x4 = GT
+ * 0x5 = NE
+ * 0x6 = GE
+ * 0x7 = set condition code ? (used before bra.lt/le/gt/ge)
+ * 0x8 = unordered bit (allows NaN)
+ */
static void
-emit_set(struct nv50_pc *pc, unsigned c_op, struct nv50_reg *dst,
+emit_set(struct nv50_pc *pc, unsigned ccode, struct nv50_reg *dst, int wp,
struct nv50_reg *src0, struct nv50_reg *src1)
{
+ static const unsigned cc_swapped[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
+
struct nv50_program_exec *e = exec(pc);
- unsigned inv_cop[8] = { 0, 4, 2, 6, 1, 5, 3, 7 };
struct nv50_reg *rdst;
- assert(c_op <= 7);
+ assert(ccode < 16);
if (check_swap_src_0_1(pc, &src0, &src1))
- c_op = inv_cop[c_op];
+ ccode = cc_swapped[ccode & 7] | (ccode & 8);
rdst = dst;
- if (dst->type != P_TEMP)
+ if (dst && dst->type != P_TEMP)
dst = alloc_temp(pc, NULL);
/* set.u32 */
set_long(pc, e);
e->inst[0] |= 0xb0000000;
- e->inst[1] |= (3 << 29);
- e->inst[1] |= (c_op << 14);
- /*XXX: breaks things, .u32 by default?
- * decuda will disasm as .u16 and use .lo/.hi regs, but this
- * doesn't seem to match what the hw actually does.
- inst[1] |= 0x04000000; << breaks things.. .u32 by default?
+ e->inst[1] |= 0x60000000 | (ccode << 14);
+
+ /* XXX: decuda will disasm as .u16 and use .lo/.hi regs, but
+ * that doesn't seem to match what the hw actually does
+ e->inst[1] |= 0x04000000; << breaks things, u32 by default ?
*/
- set_dst(pc, dst, e);
+
+ if (wp >= 0)
+ set_pred_wr(pc, 1, wp, e);
+ if (dst)
+ set_dst(pc, dst, e);
+ else {
+ e->inst[0] |= 0x000001fc;
+ e->inst[1] |= 0x00000008;
+ }
+
set_src_0(pc, src0, e);
set_src_1(pc, src1, e);
- emit(pc, e);
- /* cvt.f32.u32 */
- e = exec(pc);
- e->inst[0] = 0xa0000001;
- e->inst[1] = 0x64014780;
- set_dst(pc, rdst, e);
- set_src_0(pc, dst, e);
emit(pc, e);
+ pc->if_cond = pc->p->exec_tail; /* record for OPCODE_IF */
- if (dst != rdst)
+ /* cvt.f32.u32/s32 (?) if we didn't only write the predicate */
+ if (rdst)
+ emit_cvt(pc, rdst, dst, -1, CVTOP_ABS | CVTOP_RN, CVT_F32_S32);
+ if (rdst && rdst != dst)
free_temp(pc, dst);
}
+static INLINE unsigned
+map_tgsi_setop_cc(unsigned op)
+{
+ switch (op) {
+ case TGSI_OPCODE_SLT: return 0x1;
+ case TGSI_OPCODE_SGE: return 0x6;
+ case TGSI_OPCODE_SEQ: return 0x2;
+ case TGSI_OPCODE_SGT: return 0x4;
+ case TGSI_OPCODE_SLE: return 0x3;
+ case TGSI_OPCODE_SNE: return 0xd;
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
static INLINE void
emit_flr(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
{
- emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32_ROP);
+ emit_cvt(pc, dst, src, -1, CVTOP_FLOOR, CVT_F32_F32 | CVT_RI);
}
static void
@@ -890,6 +977,12 @@ emit_abs(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
emit_cvt(pc, dst, src, -1, CVTOP_ABS, CVT_F32_F32);
}
+static INLINE void
+emit_sat(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
+{
+ emit_cvt(pc, dst, src, -1, CVTOP_SAT, CVT_F32_F32);
+}
+
static void
emit_lit(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
struct nv50_reg **src)
@@ -1073,10 +1166,11 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
emit(pc, e);
#if 1
- if (mask & 1) emit_mov(pc, dst[0], t[0]);
- if (mask & 2) emit_mov(pc, dst[1], t[1]);
- if (mask & 4) emit_mov(pc, dst[2], t[2]);
- if (mask & 8) emit_mov(pc, dst[3], t[3]);
+ c = 0;
+ if (mask & 1) emit_mov(pc, dst[0], t[c++]);
+ if (mask & 2) emit_mov(pc, dst[1], t[c++]);
+ if (mask & 4) emit_mov(pc, dst[2], t[c++]);
+ if (mask & 8) emit_mov(pc, dst[3], t[c]);
free_temp4(pc, t);
#else
@@ -1093,6 +1187,38 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
}
static void
+emit_branch(struct nv50_pc *pc, int pred, unsigned cc,
+ struct nv50_program_exec **join)
+{
+ struct nv50_program_exec *e = exec(pc);
+
+ if (join) {
+ set_long(pc, e);
+ e->inst[0] |= 0xa0000002;
+ emit(pc, e);
+ *join = e;
+ e = exec(pc);
+ }
+
+ set_long(pc, e);
+ e->inst[0] |= 0x10000002;
+ if (pred >= 0)
+ set_pred(pc, cc, pred, e);
+ emit(pc, e);
+}
+
+static void
+emit_nop(struct nv50_pc *pc)
+{
+ struct nv50_program_exec *e = exec(pc);
+
+ e->inst[0] = 0xf0000000;
+ set_long(pc, e);
+ e->inst[1] = 0xe0000000;
+ emit(pc, e);
+}
+
+static void
convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
{
unsigned q = 0, m = ~0;
@@ -1159,6 +1285,70 @@ negate_supported(const struct tgsi_full_instruction *insn, int i)
}
}
+/* Return a read mask for source registers deduced from opcode & write mask. */
+static unsigned
+nv50_tgsi_src_mask(const struct tgsi_full_instruction *insn, int c)
+{
+ unsigned x, mask = insn->FullDstRegisters[0].DstRegister.WriteMask;
+
+ switch (insn->Instruction.Opcode) {
+ case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_SIN:
+ return (mask & 0x8) | ((mask & 0x7) ? 0x1 : 0x0);
+ case TGSI_OPCODE_DP3:
+ return 0x7;
+ case TGSI_OPCODE_DP4:
+ case TGSI_OPCODE_DPH:
+ case TGSI_OPCODE_KIL: /* WriteMask ignored */
+ return 0xf;
+ case TGSI_OPCODE_DST:
+ return mask & (c ? 0xa : 0x6);
+ case TGSI_OPCODE_EX2:
+ case TGSI_OPCODE_LG2:
+ case TGSI_OPCODE_POW:
+ case TGSI_OPCODE_RCP:
+ case TGSI_OPCODE_RSQ:
+ case TGSI_OPCODE_SCS:
+ return 0x1;
+ case TGSI_OPCODE_LIT:
+ return 0xb;
+ case TGSI_OPCODE_TEX:
+ case TGSI_OPCODE_TXP:
+ {
+ const struct tgsi_instruction_ext_texture *tex;
+
+ assert(insn->Instruction.Extended);
+ tex = &insn->InstructionExtTexture;
+
+ mask = 0x7;
+ if (insn->Instruction.Opcode == TGSI_OPCODE_TXP)
+ mask |= 0x8;
+
+ switch (tex->Texture) {
+ case TGSI_TEXTURE_1D:
+ mask &= 0x9;
+ break;
+ case TGSI_TEXTURE_2D:
+ mask &= 0xb;
+ break;
+ default:
+ break;
+ }
+ }
+ return mask;
+ case TGSI_OPCODE_XPD:
+ x = 0;
+ if (mask & 1) x |= 0x6;
+ if (mask & 2) x |= 0x5;
+ if (mask & 4) x |= 0x3;
+ return x;
+ default:
+ break;
+ }
+
+ return mask;
+}
+
static struct nv50_reg *
tgsi_dst(struct nv50_pc *pc, int c, const struct tgsi_full_dst_register *dst)
{
@@ -1258,93 +1448,175 @@ tgsi_src(struct nv50_pc *pc, int chan, const struct tgsi_full_src_register *src,
return r;
}
-/* returns TRUE if instruction can overwrite sources before they're read */
+/* return TRUE for ops that produce only a single result */
static boolean
-direct2dest_op(const struct tgsi_full_instruction *insn)
+is_scalar_op(unsigned op)
{
- if (insn->Instruction.Saturate)
- return FALSE;
-
- switch (insn->Instruction.Opcode) {
+ switch (op) {
case TGSI_OPCODE_COS:
+ case TGSI_OPCODE_DP2:
case TGSI_OPCODE_DP3:
case TGSI_OPCODE_DP4:
case TGSI_OPCODE_DPH:
- case TGSI_OPCODE_KIL:
- case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_EX2:
+ case TGSI_OPCODE_LG2:
case TGSI_OPCODE_POW:
case TGSI_OPCODE_RCP:
case TGSI_OPCODE_RSQ:
- case TGSI_OPCODE_SCS:
case TGSI_OPCODE_SIN:
+ /*
+ case TGSI_OPCODE_KIL:
+ case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_SCS:
+ */
+ return TRUE;
+ default:
+ return FALSE;
+ }
+}
+
+/* Returns a bitmask indicating which dst components depend
+ * on source s, component c (reverse of nv50_tgsi_src_mask).
+ */
+static unsigned
+nv50_tgsi_dst_revdep(unsigned op, int s, int c)
+{
+ if (is_scalar_op(op))
+ return 0x1;
+
+ switch (op) {
+ case TGSI_OPCODE_DST:
+ return (1 << c) & (s ? 0xa : 0x6);
+ case TGSI_OPCODE_XPD:
+ switch (c) {
+ case 0: return 0x6;
+ case 1: return 0x5;
+ case 2: return 0x3;
+ case 3: return 0x0;
+ default:
+ assert(0);
+ return 0x0;
+ }
+ case TGSI_OPCODE_LIT:
+ case TGSI_OPCODE_SCS:
case TGSI_OPCODE_TEX:
case TGSI_OPCODE_TXP:
- return FALSE;
+ /* these take care of dangerous swizzles themselves */
+ return 0x0;
+ case TGSI_OPCODE_IF:
+ case TGSI_OPCODE_KIL:
+ /* don't call this function for these ops */
+ assert(0);
+ return 0;
default:
- return TRUE;
+ /* linear vector instruction */
+ return (1 << c);
}
}
+static INLINE boolean
+has_pred(struct nv50_program_exec *e, unsigned cc)
+{
+ if (!is_long(e) || is_immd(e))
+ return FALSE;
+ return ((e->inst[1] & 0x780) == (cc << 7));
+}
+
+/* on ENDIF see if we can do "@p0.neu single_op" instead of:
+ * join_at ENDIF
+ * @p0.eq bra ENDIF
+ * single_op
+ * ENDIF: nop.join
+ */
static boolean
-nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
+nv50_kill_branch(struct nv50_pc *pc)
{
- const struct tgsi_full_instruction *inst = &tok->FullInstruction;
- struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp;
+ int lvl = pc->if_lvl;
+
+ if (pc->if_insn[lvl]->next != pc->p->exec_tail)
+ return FALSE;
+
+ /* if ccode == 'true', the BRA is from an ELSE and the predicate
+ * reg may no longer be valid, since we currently always use $p0
+ */
+ if (has_pred(pc->if_insn[lvl], 0xf))
+ return FALSE;
+ assert(pc->if_insn[lvl] && pc->br_join[lvl]);
+
+ /* We'll use the exec allocated for JOIN_AT (as we can't easily
+ * update prev's next); if exec_tail is BRK, update the pointer.
+ */
+ if (pc->loop_lvl && pc->br_loop[pc->loop_lvl - 1] == pc->p->exec_tail)
+ pc->br_loop[pc->loop_lvl - 1] = pc->br_join[lvl];
+
+ pc->p->exec_size -= 4; /* remove JOIN_AT and BRA */
+
+ *pc->br_join[lvl] = *pc->p->exec_tail;
+
+ FREE(pc->if_insn[lvl]);
+ FREE(pc->p->exec_tail);
+
+ pc->p->exec_tail = pc->br_join[lvl];
+ pc->p->exec_tail->next = NULL;
+ set_pred(pc, 0xd, 0, pc->p->exec_tail);
+
+ return TRUE;
+}
+
+static boolean
+nv50_program_tx_insn(struct nv50_pc *pc,
+ const struct tgsi_full_instruction *inst)
+{
+ struct nv50_reg *rdst[4], *dst[4], *brdc, *src[3][4], *temp;
unsigned mask, sat, unit;
- boolean assimilate = FALSE;
int i, c;
mask = inst->FullDstRegisters[0].DstRegister.WriteMask;
sat = inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE;
+ memset(src, 0, sizeof(src));
+
for (c = 0; c < 4; c++) {
- if (mask & (1 << c))
+ if ((mask & (1 << c)) && !pc->r_dst[c])
dst[c] = tgsi_dst(pc, c, &inst->FullDstRegisters[0]);
else
- dst[c] = NULL;
- rdst[c] = NULL;
- src[0][c] = NULL;
- src[1][c] = NULL;
- src[2][c] = NULL;
+ dst[c] = pc->r_dst[c];
+ rdst[c] = dst[c];
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
const struct tgsi_full_src_register *fs = &inst->FullSrcRegisters[i];
+ unsigned src_mask;
+ boolean neg_supp;
+
+ src_mask = nv50_tgsi_src_mask(inst, i);
+ neg_supp = negate_supported(inst, i);
if (fs->SrcRegister.File == TGSI_FILE_SAMPLER)
unit = fs->SrcRegister.Index;
for (c = 0; c < 4; c++)
- src[i][c] = tgsi_src(pc, c, fs,
- negate_supported(inst, i));
+ if (src_mask & (1 << c))
+ src[i][c] = tgsi_src(pc, c, fs, neg_supp);
}
- if (sat) {
- for (c = 0; c < 4; c++) {
- rdst[c] = dst[c];
- dst[c] = temp_temp(pc);
- }
+ brdc = temp = pc->r_brdc;
+ if (brdc && brdc->type != P_TEMP) {
+ temp = temp_temp(pc);
+ if (sat)
+ brdc = temp;
} else
- if (direct2dest_op(inst)) {
+ if (sat) {
for (c = 0; c < 4; c++) {
- if (!dst[c] || dst[c]->type != P_TEMP)
- continue;
-
- for (i = c + 1; i < 4; i++) {
- if (dst[c] == src[0][i] ||
- dst[c] == src[1][i] ||
- dst[c] == src[2][i])
- break;
- }
- if (i == 4)
+ if (!(mask & (1 << c)) || dst[c]->type == P_TEMP)
continue;
-
- assimilate = TRUE;
rdst[c] = dst[c];
- dst[c] = alloc_temp(pc, NULL);
+ dst[c] = temp_temp(pc);
}
}
+ assert(brdc || !is_scalar_op(inst->Instruction.Opcode));
+
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ABS:
for (c = 0; c < 4; c++) {
@@ -1360,74 +1632,91 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
emit_add(pc, dst[c], src[0][c], src[1][c]);
}
break;
- case TGSI_OPCODE_COS:
- temp = temp_temp(pc);
- emit_precossin(pc, temp, src[0][0]);
- emit_flop(pc, 5, temp, temp);
+ case TGSI_OPCODE_BGNLOOP:
+ pc->loop_pos[pc->loop_lvl++] = pc->p->exec_size;
+ break;
+ case TGSI_OPCODE_BRK:
+ emit_branch(pc, -1, 0, NULL);
+ assert(pc->loop_lvl > 0);
+ pc->br_loop[pc->loop_lvl - 1] = pc->p->exec_tail;
+ break;
+ case TGSI_OPCODE_CEIL:
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
- emit_mov(pc, dst[c], temp);
+ emit_cvt(pc, dst[c], src[0][c], -1,
+ CVTOP_CEIL, CVT_F32_F32 | CVT_RI);
+ }
+ break;
+ case TGSI_OPCODE_COS:
+ if (mask & 8) {
+ emit_precossin(pc, temp, src[0][3]);
+ emit_flop(pc, 5, dst[3], temp);
+ if (!(mask &= 7))
+ break;
+ if (temp == dst[3])
+ temp = brdc = temp_temp(pc);
}
+ emit_precossin(pc, temp, src[0][0]);
+ emit_flop(pc, 5, brdc, temp);
break;
case TGSI_OPCODE_DP3:
- temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
- emit_mad(pc, temp, src[0][2], src[1][2], temp);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_mad(pc, brdc, src[0][2], src[1][2], temp);
break;
case TGSI_OPCODE_DP4:
- temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
emit_mad(pc, temp, src[0][2], src[1][2], temp);
- emit_mad(pc, temp, src[0][3], src[1][3], temp);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_mad(pc, brdc, src[0][3], src[1][3], temp);
break;
case TGSI_OPCODE_DPH:
- temp = temp_temp(pc);
emit_mul(pc, temp, src[0][0], src[1][0]);
emit_mad(pc, temp, src[0][1], src[1][1], temp);
emit_mad(pc, temp, src[0][2], src[1][2], temp);
- emit_add(pc, temp, src[1][3], temp);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_add(pc, brdc, src[1][3], temp);
break;
case TGSI_OPCODE_DST:
- {
- struct nv50_reg *one = alloc_immd(pc, 1.0);
- if (mask & (1 << 0))
- emit_mov(pc, dst[0], one);
if (mask & (1 << 1))
emit_mul(pc, dst[1], src[0][1], src[1][1]);
if (mask & (1 << 2))
emit_mov(pc, dst[2], src[0][2]);
if (mask & (1 << 3))
emit_mov(pc, dst[3], src[1][3]);
- FREE(one);
- }
+ if (mask & (1 << 0))
+ emit_mov_immdval(pc, dst[0], 1.0f);
+ break;
+ case TGSI_OPCODE_ELSE:
+ emit_branch(pc, -1, 0, NULL);
+ pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size;
+ pc->if_insn[pc->if_lvl++] = pc->p->exec_tail;
+ break;
+ case TGSI_OPCODE_ENDIF:
+ pc->if_insn[--pc->if_lvl]->param.index = pc->p->exec_size;
+
+ /* try to replace branch over 1 insn with a predicated insn */
+ if (nv50_kill_branch(pc) == TRUE)
+ break;
+
+ if (pc->br_join[pc->if_lvl]) {
+ pc->br_join[pc->if_lvl]->param.index = pc->p->exec_size;
+ pc->br_join[pc->if_lvl] = NULL;
+ }
+ /* emit a NOP as join point, we could set it on the next
+ * one, but would have to make sure it is long and !immd
+ */
+ emit_nop(pc);
+ pc->p->exec_tail->inst[1] |= 2;
+ break;
+ case TGSI_OPCODE_ENDLOOP:
+ emit_branch(pc, -1, 0, NULL);
+ pc->p->exec_tail->param.index = pc->loop_pos[--pc->loop_lvl];
+ pc->br_loop[pc->loop_lvl]->param.index = pc->p->exec_size;
break;
case TGSI_OPCODE_EX2:
- temp = temp_temp(pc);
emit_preex2(pc, temp, src[0][0]);
- emit_flop(pc, 6, temp, temp);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_flop(pc, 6, brdc, temp);
break;
case TGSI_OPCODE_FLR:
for (c = 0; c < 4; c++) {
@@ -1445,24 +1734,24 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
emit_sub(pc, dst[c], src[0][c], temp);
}
break;
+ case TGSI_OPCODE_IF:
+ /* emitting a join_at may not be necessary */
+ assert(pc->if_lvl < MAX_IF_DEPTH);
+ set_pred_wr(pc, 1, 0, pc->if_cond);
+ emit_branch(pc, 0, 2, &pc->br_join[pc->if_lvl]);
+ pc->if_insn[pc->if_lvl++] = pc->p->exec_tail;
+ break;
case TGSI_OPCODE_KIL:
emit_kil(pc, src[0][0]);
emit_kil(pc, src[0][1]);
emit_kil(pc, src[0][2]);
emit_kil(pc, src[0][3]);
- pc->p->cfg.fp.regs[2] |= 0x00100000;
break;
case TGSI_OPCODE_LIT:
emit_lit(pc, &dst[0], mask, &src[0][0]);
break;
case TGSI_OPCODE_LG2:
- temp = temp_temp(pc);
- emit_flop(pc, 3, temp, src[0][0]);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_flop(pc, 3, brdc, src[0][0]);
break;
case TGSI_OPCODE_LRP:
temp = temp_temp(pc);
@@ -1510,31 +1799,18 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_POW:
- temp = temp_temp(pc);
- emit_pow(pc, temp, src[0][0], src[1][0]);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
- }
+ emit_pow(pc, brdc, src[0][0], src[1][0]);
break;
case TGSI_OPCODE_RCP:
- for (c = 3; c >= 0; c--) {
- if (!(mask & (1 << c)))
- continue;
- emit_flop(pc, 0, dst[c], src[0][0]);
- }
+ emit_flop(pc, 0, brdc, src[0][0]);
break;
case TGSI_OPCODE_RSQ:
- for (c = 3; c >= 0; c--) {
- if (!(mask & (1 << c)))
- continue;
- emit_flop(pc, 2, dst[c], src[0][0]);
- }
+ emit_flop(pc, 2, brdc, src[0][0]);
break;
case TGSI_OPCODE_SCS:
temp = temp_temp(pc);
- emit_precossin(pc, temp, src[0][0]);
+ if (mask & 3)
+ emit_precossin(pc, temp, src[0][0]);
if (mask & (1 << 0))
emit_flop(pc, 5, dst[0], temp);
if (mask & (1 << 1))
@@ -1544,28 +1820,29 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
if (mask & (1 << 3))
emit_mov_immdval(pc, dst[3], 1.0);
break;
- case TGSI_OPCODE_SGE:
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_set(pc, 6, dst[c], src[0][c], src[1][c]);
- }
- break;
case TGSI_OPCODE_SIN:
- temp = temp_temp(pc);
- emit_precossin(pc, temp, src[0][0]);
- emit_flop(pc, 4, temp, temp);
- for (c = 0; c < 4; c++) {
- if (!(mask & (1 << c)))
- continue;
- emit_mov(pc, dst[c], temp);
+ if (mask & 8) {
+ emit_precossin(pc, temp, src[0][3]);
+ emit_flop(pc, 4, dst[3], temp);
+ if (!(mask &= 7))
+ break;
+ if (temp == dst[3])
+ temp = brdc = temp_temp(pc);
}
+ emit_precossin(pc, temp, src[0][0]);
+ emit_flop(pc, 4, brdc, temp);
break;
case TGSI_OPCODE_SLT:
+ case TGSI_OPCODE_SGE:
+ case TGSI_OPCODE_SEQ:
+ case TGSI_OPCODE_SGT:
+ case TGSI_OPCODE_SLE:
+ case TGSI_OPCODE_SNE:
+ i = map_tgsi_setop_cc(inst->Instruction.Opcode);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
- emit_set(pc, 1, dst[c], src[0][c], src[1][c]);
+ emit_set(pc, i, dst[c], -1, src[0][c], src[1][c]);
}
break;
case TGSI_OPCODE_SUB:
@@ -1583,6 +1860,14 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
emit_tex(pc, dst, mask, src[0], unit,
inst->InstructionExtTexture.Texture, TRUE);
break;
+ case TGSI_OPCODE_TRUNC:
+ for (c = 0; c < 4; c++) {
+ if (!(mask & (1 << c)))
+ continue;
+ emit_cvt(pc, dst[c], src[0][c], -1,
+ CVTOP_TRUNC, CVT_F32_F32 | CVT_RI);
+ }
+ break;
case TGSI_OPCODE_XPD:
temp = temp_temp(pc);
if (mask & (1 << 0)) {
@@ -1607,17 +1892,22 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
return FALSE;
}
+ if (brdc) {
+ if (sat)
+ emit_sat(pc, brdc, brdc);
+ for (c = 0; c < 4; c++)
+ if ((mask & (1 << c)) && dst[c] != brdc)
+ emit_mov(pc, dst[c], brdc);
+ } else
if (sat) {
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
- emit_cvt(pc, rdst[c], dst[c], -1, CVTOP_SAT,
- CVT_F32_F32);
+ /* in this case we saturate later */
+ if (dst[c]->type == P_TEMP && dst[c]->index < 0)
+ continue;
+ emit_sat(pc, rdst[c], dst[c]);
}
- } else if (assimilate) {
- for (c = 0; c < 4; c++)
- if (rdst[c])
- assimilate_temp(pc, rdst[c], dst[c]);
}
for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
@@ -1626,9 +1916,6 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
continue;
if (src[i][c]->index == -1 && src[i][c]->type == P_IMMD)
FREE(src[i][c]);
- else
- if (src[i][c]->acc == pc->insn_cur)
- release_hw(pc, src[i][c]);
}
}
@@ -1636,180 +1923,271 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
return TRUE;
}
-/* Adjust a bitmask that indicates what components of a source are used,
- * we use this in tx_prep so we only load interpolants that are needed.
- */
-static void
-insn_adjust_mask(const struct tgsi_full_instruction *insn, unsigned *mask)
-{
- const struct tgsi_instruction_ext_texture *tex;
-
- switch (insn->Instruction.Opcode) {
- case TGSI_OPCODE_DP3:
- *mask = 0x7;
- break;
- case TGSI_OPCODE_DP4:
- case TGSI_OPCODE_DPH:
- *mask = 0xF;
- break;
- case TGSI_OPCODE_LIT:
- *mask = 0xB;
- break;
- case TGSI_OPCODE_RCP:
- case TGSI_OPCODE_RSQ:
- *mask = 0x1;
- break;
- case TGSI_OPCODE_TEX:
- case TGSI_OPCODE_TXP:
- assert(insn->Instruction.Extended);
- tex = &insn->InstructionExtTexture;
-
- *mask = 0x7;
- if (tex->Texture == TGSI_TEXTURE_1D)
- *mask = 0x1;
- else
- if (tex->Texture == TGSI_TEXTURE_2D)
- *mask = 0x3;
-
- if (insn->Instruction.Opcode == TGSI_OPCODE_TXP)
- *mask |= 0x8;
- break;
- default:
- break;
- }
-}
-
static void
-prep_inspect_insn(struct nv50_pc *pc, const union tgsi_full_token *tok,
- unsigned *r_usage[2])
+prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)
{
- const struct tgsi_full_instruction *insn;
+ struct nv50_reg *reg = NULL;
const struct tgsi_full_src_register *src;
const struct tgsi_dst_register *dst;
+ unsigned i, c, k, mask;
- unsigned i, c, k, n, mask, *acc_p;
-
- insn = &tok->FullInstruction;
dst = &insn->FullDstRegisters[0].DstRegister;
mask = dst->WriteMask;
- if (!r_usage[0])
- r_usage[0] = CALLOC(pc->temp_nr * 4, sizeof(unsigned));
- if (!r_usage[1])
- r_usage[1] = CALLOC(pc->attr_nr * 4, sizeof(unsigned));
+ if (dst->File == TGSI_FILE_TEMPORARY)
+ reg = pc->temp;
+ else
+ if (dst->File == TGSI_FILE_OUTPUT)
+ reg = pc->result;
- if (dst->File == TGSI_FILE_TEMPORARY) {
+ if (reg) {
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
- r_usage[0][dst->Index * 4 + c] = pc->insn_nr;
+ reg[dst->Index * 4 + c].acc = pc->insn_nr;
}
}
for (i = 0; i < insn->Instruction.NumSrcRegs; i++) {
src = &insn->FullSrcRegisters[i];
- switch (src->SrcRegister.File) {
- case TGSI_FILE_TEMPORARY:
- acc_p = r_usage[0];
- break;
- case TGSI_FILE_INPUT:
- acc_p = r_usage[1];
- break;
- default:
+ if (src->SrcRegister.File == TGSI_FILE_TEMPORARY)
+ reg = pc->temp;
+ else
+ if (src->SrcRegister.File == TGSI_FILE_INPUT)
+ reg = pc->attr;
+ else
continue;
- }
- insn_adjust_mask(insn, &mask);
+ mask = nv50_tgsi_src_mask(insn, i);
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
-
k = tgsi_util_get_full_src_register_extswizzle(src, c);
- switch (k) {
- case TGSI_EXTSWIZZLE_X:
- case TGSI_EXTSWIZZLE_Y:
- case TGSI_EXTSWIZZLE_Z:
- case TGSI_EXTSWIZZLE_W:
- n = src->SrcRegister.Index * 4 + k;
- acc_p[n] = pc->insn_nr;
- break;
- default:
- break;
- }
+
+ if (k > TGSI_EXTSWIZZLE_W)
+ continue;
+
+ reg[src->SrcRegister.Index * 4 + k].acc = pc->insn_nr;
}
}
}
+/* Returns a bitmask indicating which dst components need to be
+ * written to temporaries first to avoid 'corrupting' sources.
+ *
+ * m[i] (out) indicate component to write in the i-th position
+ * rdep[c] (in) bitmasks of dst[i] that require dst[c] as source
+ */
+static unsigned
+nv50_revdep_reorder(unsigned m[4], unsigned rdep[4])
+{
+ unsigned i, c, x, unsafe;
+
+ for (c = 0; c < 4; c++)
+ m[c] = c;
+
+ /* Swap as long as a dst component written earlier is depended on
+ * by one written later, but the next one isn't depended on by it.
+ */
+ for (c = 0; c < 3; c++) {
+ if (rdep[m[c + 1]] & (1 << m[c]))
+ continue; /* if next one is depended on by us */
+ for (i = c + 1; i < 4; i++)
+ /* if we are depended on by a later one */
+ if (rdep[m[c]] & (1 << m[i]))
+ break;
+ if (i == 4)
+ continue;
+ /* now, swap */
+ x = m[c];
+ m[c] = m[c + 1];
+ m[c + 1] = x;
+
+ /* restart */
+ c = 0;
+ }
+
+ /* mark dependencies that could not be resolved by reordering */
+ for (i = 0; i < 3; ++i)
+ for (c = i + 1; c < 4; ++c)
+ if (rdep[m[i]] & (1 << m[c]))
+ unsafe |= (1 << i);
+
+ /* NOTE: $unsafe is with respect to order, not component */
+ return unsafe;
+}
+
+/* Select a suitable dst register for broadcasting scalar results,
+ * or return NULL if we have to allocate an extra TEMP.
+ *
+ * If e.g. only 1 component is written, we may also emit the final
+ * result to a write-only register.
+ */
+static struct nv50_reg *
+tgsi_broadcast_dst(struct nv50_pc *pc,
+ const struct tgsi_full_dst_register *fd, unsigned mask)
+{
+ if (fd->DstRegister.File == TGSI_FILE_TEMPORARY) {
+ int c = ffs(~mask & fd->DstRegister.WriteMask);
+ if (c)
+ return tgsi_dst(pc, c - 1, fd);
+ } else {
+ int c = ffs(fd->DstRegister.WriteMask) - 1;
+ if ((1 << c) == fd->DstRegister.WriteMask)
+ return tgsi_dst(pc, c, fd);
+ }
+
+ return NULL;
+}
+
+/* Scan source swizzles and return a bitmask indicating dst regs that
+ * also occur among the src regs, and fill rdep for nv50_revdep_reoder.
+ */
static unsigned
-load_fp_attrib(struct nv50_pc *pc, int i, unsigned *acc, int *mid,
- int *aid, int *p_oid)
+nv50_tgsi_scan_swizzle(const struct tgsi_full_instruction *insn,
+ unsigned rdep[4])
{
- struct nv50_reg *iv;
- int oid, c, n;
- unsigned mask = 0;
+ const struct tgsi_full_dst_register *fd = &insn->FullDstRegisters[0];
+ const struct tgsi_full_src_register *fs;
+ unsigned i, deqs = 0;
- iv = (pc->interp_mode[i] & INTERP_CENTROID) ? pc->iv_c : pc->iv_p;
+ for (i = 0; i < 4; ++i)
+ rdep[i] = 0;
- for (c = 0, n = i * 4; c < 4; c++, n++) {
- oid = (*p_oid)++;
- pc->attr[n].type = P_TEMP;
- pc->attr[n].index = i;
+ for (i = 0; i < insn->Instruction.NumSrcRegs; i++) {
+ unsigned chn, mask = nv50_tgsi_src_mask(insn, i);
+ boolean neg_supp = negate_supported(insn, i);
- if (pc->attr[n].acc == acc[n])
+ fs = &insn->FullSrcRegisters[i];
+ if (fs->SrcRegister.File != fd->DstRegister.File ||
+ fs->SrcRegister.Index != fd->DstRegister.Index)
continue;
- mask |= (1 << c);
- pc->attr[n].acc = acc[n];
- pc->attr[n].rhw = pc->attr[n].hw = -1;
- alloc_reg(pc, &pc->attr[n]);
+ for (chn = 0; chn < 4; ++chn) {
+ unsigned s, c;
+
+ if (!(mask & (1 << chn))) /* src is not read */
+ continue;
+ c = tgsi_util_get_full_src_register_extswizzle(fs, chn);
+ s = tgsi_util_get_full_src_register_sign_mode(fs, chn);
- pc->attr[n].rhw = (*aid)++;
- emit_interp(pc, &pc->attr[n], iv, pc->interp_mode[i]);
+ if (c > TGSI_EXTSWIZZLE_W ||
+ !(fd->DstRegister.WriteMask & (1 << c)))
+ continue;
- pc->p->cfg.fp.map[(*mid) / 4] |= oid << (8 * ((*mid) % 4));
- (*mid)++;
- pc->p->cfg.fp.regs[1] += 0x00010001;
+ /* no danger if src is copied to TEMP first */
+ if ((s != TGSI_UTIL_SIGN_KEEP) &&
+ (s != TGSI_UTIL_SIGN_TOGGLE || !neg_supp))
+ continue;
+
+ rdep[c] |= nv50_tgsi_dst_revdep(
+ insn->Instruction.Opcode, i, chn);
+ deqs |= (1 << c);
+ }
}
- return mask;
+ return deqs;
}
static boolean
-nv50_program_tx_prep(struct nv50_pc *pc)
+nv50_tgsi_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
{
- struct tgsi_parse_context p;
- boolean ret = FALSE;
- unsigned i, c;
- unsigned fcol, bcol, fcrd, depr;
+ struct tgsi_full_instruction insn = tok->FullInstruction;
+ const struct tgsi_full_dst_register *fd;
+ unsigned i, deqs, rdep[4], m[4];
+
+ fd = &tok->FullInstruction.FullDstRegisters[0];
+ deqs = nv50_tgsi_scan_swizzle(&insn, rdep);
+
+ if (is_scalar_op(insn.Instruction.Opcode)) {
+ pc->r_brdc = tgsi_broadcast_dst(pc, fd, deqs);
+ if (!pc->r_brdc)
+ pc->r_brdc = temp_temp(pc);
+ return nv50_program_tx_insn(pc, &insn);
+ }
+ pc->r_brdc = NULL;
+
+ if (!deqs)
+ return nv50_program_tx_insn(pc, &insn);
+
+ deqs = nv50_revdep_reorder(m, rdep);
+
+ for (i = 0; i < 4; ++i) {
+ assert(pc->r_dst[m[i]] == NULL);
+
+ insn.FullDstRegisters[0].DstRegister.WriteMask =
+ fd->DstRegister.WriteMask & (1 << m[i]);
+
+ if (!insn.FullDstRegisters[0].DstRegister.WriteMask)
+ continue;
+
+ if (deqs & (1 << i))
+ pc->r_dst[m[i]] = alloc_temp(pc, NULL);
+
+ if (!nv50_program_tx_insn(pc, &insn))
+ return FALSE;
+ }
- /* count (centroid) perspective interpolations */
- unsigned centroid_loads = 0;
- unsigned perspect_loads = 0;
+ for (i = 0; i < 4; i++) {
+ struct nv50_reg *reg = pc->r_dst[i];
+ if (!reg)
+ continue;
+ pc->r_dst[i] = NULL;
+
+ if (insn.Instruction.Saturate == TGSI_SAT_ZERO_ONE)
+ emit_sat(pc, tgsi_dst(pc, i, fd), reg);
+ else
+ emit_mov(pc, tgsi_dst(pc, i, fd), reg);
+ free_temp(pc, reg);
+ }
- /* track register access for temps and attrs */
- unsigned *r_usage[2];
- r_usage[0] = NULL;
- r_usage[1] = NULL;
+ return TRUE;
+}
- depr = fcol = bcol = fcrd = 0xffff;
+static void
+load_interpolant(struct nv50_pc *pc, struct nv50_reg *reg)
+{
+ struct nv50_reg *iv, **ppiv;
+ unsigned mode = pc->interp_mode[reg->index];
- if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- pc->p->cfg.fp.regs[0] = 0x01000404;
- pc->p->cfg.fp.regs[1] = 0x00000400;
+ ppiv = (mode & INTERP_CENTROID) ? &pc->iv_c : &pc->iv_p;
+ iv = *ppiv;
+
+ if ((mode & INTERP_PERSPECTIVE) && !iv) {
+ iv = *ppiv = alloc_temp(pc, NULL);
+ iv->rhw = popcnt4(pc->p->cfg.regs[1] >> 24) - 1;
+
+ emit_interp(pc, iv, NULL, mode & INTERP_CENTROID);
+ emit_flop(pc, 0, iv, iv);
+
+ /* XXX: when loading interpolants dynamically, move these
+ * to the program head, or make sure it can't be skipped.
+ */
}
- tgsi_parse_init(&p, pc->p->pipe.tokens);
- while (!tgsi_parse_end_of_tokens(&p)) {
- const union tgsi_full_token *tok = &p.FullToken;
+ emit_interp(pc, reg, iv, mode);
+}
+
+static boolean
+nv50_program_tx_prep(struct nv50_pc *pc)
+{
+ struct tgsi_parse_context tp;
+ struct nv50_program *p = pc->p;
+ boolean ret = FALSE;
+ unsigned i, c, flat_nr = 0;
+
+ tgsi_parse_init(&tp, pc->p->pipe.tokens);
+ while (!tgsi_parse_end_of_tokens(&tp)) {
+ const union tgsi_full_token *tok = &tp.FullToken;
- tgsi_parse_token(&p);
+ tgsi_parse_token(&tp);
switch (tok->Token.Type) {
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
const struct tgsi_full_immediate *imm =
- &p.FullToken.FullImmediate;
+ &tp.FullToken.FullImmediate;
ctor_immd(pc, imm->u[0].Float,
imm->u[1].Float,
@@ -1820,78 +2198,61 @@ nv50_program_tx_prep(struct nv50_pc *pc)
case TGSI_TOKEN_TYPE_DECLARATION:
{
const struct tgsi_full_declaration *d;
- unsigned last, first, mode;
+ unsigned si, last, first, mode;
- d = &p.FullToken.FullDeclaration;
+ d = &tp.FullToken.FullDeclaration;
first = d->DeclarationRange.First;
last = d->DeclarationRange.Last;
switch (d->Declaration.File) {
case TGSI_FILE_TEMPORARY:
- if (pc->temp_nr < (last + 1))
- pc->temp_nr = last + 1;
break;
case TGSI_FILE_OUTPUT:
- if (pc->result_nr < (last + 1))
- pc->result_nr = last + 1;
-
- if (!d->Declaration.Semantic)
+ if (!d->Declaration.Semantic ||
+ p->type == PIPE_SHADER_FRAGMENT)
break;
+ si = d->Semantic.SemanticIndex;
switch (d->Semantic.SemanticName) {
- case TGSI_SEMANTIC_POSITION:
- depr = first;
- pc->p->cfg.fp.regs[2] |= 0x00000100;
- pc->p->cfg.fp.regs[3] |= 0x00000011;
+ case TGSI_SEMANTIC_BCOLOR:
+ p->cfg.two_side[si].hw = first;
+ if (p->cfg.io_nr > first)
+ p->cfg.io_nr = first;
+ break;
+ case TGSI_SEMANTIC_PSIZE:
+ p->cfg.psiz = first;
+ if (p->cfg.io_nr > first)
+ p->cfg.io_nr = first;
break;
+ /*
+ case TGSI_SEMANTIC_CLIP_DISTANCE:
+ p->cfg.clpd = MIN2(p->cfg.clpd, first);
+ break;
+ */
default:
break;
}
-
break;
case TGSI_FILE_INPUT:
{
- if (pc->attr_nr < (last + 1))
- pc->attr_nr = last + 1;
-
- if (pc->p->type != PIPE_SHADER_FRAGMENT)
+ if (p->type != PIPE_SHADER_FRAGMENT)
break;
switch (d->Declaration.Interpolate) {
case TGSI_INTERPOLATE_CONSTANT:
mode = INTERP_FLAT;
+ flat_nr++;
break;
case TGSI_INTERPOLATE_PERSPECTIVE:
mode = INTERP_PERSPECTIVE;
+ p->cfg.regs[1] |= 0x08 << 24;
break;
default:
mode = INTERP_LINEAR;
break;
}
-
- if (d->Declaration.Semantic) {
- switch (d->Semantic.SemanticName) {
- case TGSI_SEMANTIC_POSITION:
- fcrd = first;
- break;
- case TGSI_SEMANTIC_COLOR:
- fcol = first;
- mode = INTERP_PERSPECTIVE;
- break;
- case TGSI_SEMANTIC_BCOLOR:
- bcol = first;
- mode = INTERP_PERSPECTIVE;
- break;
- }
- }
-
- if (d->Declaration.Centroid) {
+ if (d->Declaration.Centroid)
mode |= INTERP_CENTROID;
- if (mode & INTERP_PERSPECTIVE)
- centroid_loads++;
- } else
- if (mode & INTERP_PERSPECTIVE)
- perspect_loads++;
assert(last < 32);
for (i = first; i <= last; i++)
@@ -1899,8 +2260,6 @@ nv50_program_tx_prep(struct nv50_pc *pc)
}
break;
case TGSI_FILE_CONSTANT:
- if (pc->param_nr < (last + 1))
- pc->param_nr = last + 1;
break;
case TGSI_FILE_SAMPLER:
break;
@@ -1913,182 +2272,157 @@ nv50_program_tx_prep(struct nv50_pc *pc)
break;
case TGSI_TOKEN_TYPE_INSTRUCTION:
pc->insn_nr++;
- prep_inspect_insn(pc, tok, r_usage);
+ prep_inspect_insn(pc, &tok->FullInstruction);
break;
default:
break;
}
}
- if (pc->temp_nr) {
- pc->temp = CALLOC(pc->temp_nr * 4, sizeof(struct nv50_reg));
- if (!pc->temp)
- goto out_err;
+ if (p->type == PIPE_SHADER_VERTEX) {
+ int rid = 0;
- for (i = 0; i < pc->temp_nr; i++) {
- for (c = 0; c < 4; c++) {
- pc->temp[i*4+c].type = P_TEMP;
- pc->temp[i*4+c].hw = -1;
- pc->temp[i*4+c].rhw = -1;
- pc->temp[i*4+c].index = i;
- pc->temp[i*4+c].acc = r_usage[0][i*4+c];
+ for (i = 0; i < pc->attr_nr * 4; ++i) {
+ if (pc->attr[i].acc) {
+ pc->attr[i].hw = rid++;
+ p->cfg.attr[i / 32] |= 1 << (i % 32);
}
}
- }
-
- if (pc->attr_nr) {
- int oid = 4, mid = 4, aid = 0;
- /* oid = VP output id
- * aid = FP attribute/interpolant id
- * mid = VP output mapping field ID
- */
- pc->attr = CALLOC(pc->attr_nr * 4, sizeof(struct nv50_reg));
- if (!pc->attr)
- goto out_err;
-
- if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- /* position should be loaded first */
- if (fcrd != 0xffff) {
- unsigned mask;
- mid = 0;
- mask = load_fp_attrib(pc, fcrd, r_usage[1],
- &mid, &aid, &oid);
- oid = 0;
- pc->p->cfg.fp.regs[1] |= (mask << 24);
- pc->p->cfg.fp.map[0] = 0x04040404 * fcrd;
- }
- pc->p->cfg.fp.map[0] += 0x03020100;
-
- /* should do MAD fcrd.xy, fcrd, SOME_CONST, fcrd */
-
- if (perspect_loads) {
- pc->iv_p = alloc_temp(pc, NULL);
-
- if (!(pc->p->cfg.fp.regs[1] & 0x08000000)) {
- pc->p->cfg.fp.regs[1] |= 0x08000000;
- pc->iv_p->rhw = aid++;
- emit_interp(pc, pc->iv_p, NULL,
- INTERP_LINEAR);
- emit_flop(pc, 0, pc->iv_p, pc->iv_p);
- } else {
- pc->iv_p->rhw = aid - 1;
- emit_flop(pc, 0, pc->iv_p,
- &pc->attr[fcrd * 4 + 3]);
- }
- }
+ for (i = 0, rid = 0; i < pc->result_nr; ++i) {
+ p->cfg.io[i].hw = rid;
+ p->cfg.io[i].id_vp = i;
- if (centroid_loads) {
- pc->iv_c = alloc_temp(pc, NULL);
- pc->iv_c->rhw = pc->iv_p ? aid - 1 : aid++;
- emit_interp(pc, pc->iv_c, NULL,
- INTERP_CENTROID);
- emit_flop(pc, 0, pc->iv_c, pc->iv_c);
- pc->p->cfg.fp.regs[1] |= 0x08000000;
+ for (c = 0; c < 4; ++c) {
+ int n = i * 4 + c;
+ if (!pc->result[n].acc)
+ continue;
+ pc->result[n].hw = rid++;
+ p->cfg.io[i].mask |= 1 << c;
}
+ }
- for (c = 0; c < 4; c++) {
- /* I don't know what these values do, but
- * let's set them like the blob does:
- */
- if (fcol != 0xffff && r_usage[1][fcol * 4 + c])
- pc->p->cfg.fp.regs[0] += 0x00010000;
- if (bcol != 0xffff && r_usage[1][bcol * 4 + c])
- pc->p->cfg.fp.regs[0] += 0x00010000;
- }
+ for (c = 0; c < 2; ++c)
+ if (p->cfg.two_side[c].hw < 0x40)
+ p->cfg.two_side[c] = p->cfg.io[
+ p->cfg.two_side[c].hw];
- for (i = 0; i < pc->attr_nr; i++)
- load_fp_attrib(pc, i, r_usage[1],
- &mid, &aid, &oid);
+ if (p->cfg.psiz < 0x40)
+ p->cfg.psiz = p->cfg.io[p->cfg.psiz].hw;
+ } else
+ if (p->type == PIPE_SHADER_FRAGMENT) {
+ int rid, aid;
+ unsigned n = 0, m = pc->attr_nr - flat_nr;
- if (pc->iv_p)
- free_temp(pc, pc->iv_p);
- if (pc->iv_c)
- free_temp(pc, pc->iv_c);
+ int base = (TGSI_SEMANTIC_POSITION ==
+ p->info.input_semantic_name[0]) ? 0 : 1;
- pc->p->cfg.fp.high_map = (mid / 4);
- pc->p->cfg.fp.high_map += ((mid % 4) ? 1 : 0);
- } else {
- /* vertex program */
- for (i = 0; i < pc->attr_nr * 4; i++) {
- pc->p->cfg.vp.attr[aid / 32] |=
- (1 << (aid % 32));
- pc->attr[i].type = P_ATTR;
- pc->attr[i].hw = aid++;
- pc->attr[i].index = i / 4;
+ /* non-flat interpolants have to be mapped to
+ * the lower hardware IDs, so sort them:
+ */
+ for (i = 0; i < pc->attr_nr; i++) {
+ if (pc->interp_mode[i] == INTERP_FLAT) {
+ p->cfg.io[m].id_vp = i + base;
+ p->cfg.io[m++].id_fp = i;
+ } else {
+ if (!(pc->interp_mode[i] & INTERP_PERSPECTIVE))
+ p->cfg.io[n].linear = TRUE;
+ p->cfg.io[n].id_vp = i + base;
+ p->cfg.io[n++].id_fp = i;
}
}
- }
- if (pc->result_nr) {
- int rid = 0;
+ if (!base) /* set w-coordinate mask from perspective interp */
+ p->cfg.io[0].mask |= p->cfg.regs[1] >> 24;
- pc->result = CALLOC(pc->result_nr * 4, sizeof(struct nv50_reg));
- if (!pc->result)
- goto out_err;
+ aid = popcnt4( /* if fcrd isn't contained in cfg.io */
+ base ? (p->cfg.regs[1] >> 24) : p->cfg.io[0].mask);
- for (i = 0; i < pc->result_nr; i++) {
- for (c = 0; c < 4; c++) {
- if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- pc->result[i*4+c].type = P_TEMP;
- pc->result[i*4+c].hw = -1;
- pc->result[i*4+c].rhw = (i == depr) ?
- -1 : rid++;
- } else {
- pc->result[i*4+c].type = P_RESULT;
- pc->result[i*4+c].hw = rid++;
- }
- pc->result[i*4+c].index = i;
- }
+ for (n = 0; n < pc->attr_nr; ++n) {
+ p->cfg.io[n].hw = rid = aid;
+ i = p->cfg.io[n].id_fp;
- if (pc->p->type == PIPE_SHADER_FRAGMENT &&
- depr != 0xffff) {
- pc->result[depr * 4 + 2].rhw =
- (pc->result_nr - 1) * 4;
+ for (c = 0; c < 4; ++c) {
+ if (!pc->attr[i * 4 + c].acc)
+ continue;
+ pc->attr[i * 4 + c].rhw = rid++;
+ p->cfg.io[n].mask |= 1 << c;
+
+ load_interpolant(pc, &pc->attr[i * 4 + c]);
}
+ aid += popcnt4(p->cfg.io[n].mask);
}
- }
- if (pc->param_nr) {
- int rid = 0;
+ if (!base)
+ p->cfg.regs[1] |= p->cfg.io[0].mask << 24;
- pc->param = CALLOC(pc->param_nr * 4, sizeof(struct nv50_reg));
- if (!pc->param)
- goto out_err;
+ m = popcnt4(p->cfg.regs[1] >> 24);
+
+ /* set count of non-position inputs and of non-flat
+ * non-position inputs for FP_INTERPOLANT_CTRL
+ */
+ p->cfg.regs[1] |= aid - m;
+
+ if (flat_nr) {
+ i = p->cfg.io[pc->attr_nr - flat_nr].hw;
+ p->cfg.regs[1] |= (i - m) << 16;
+ } else
+ p->cfg.regs[1] |= p->cfg.regs[1] << 16;
+
+ /* mark color semantic for light-twoside */
+ n = 0x40;
+ for (i = 0; i < pc->attr_nr; i++) {
+ ubyte si, sn;
- for (i = 0; i < pc->param_nr; i++) {
- for (c = 0; c < 4; c++) {
- pc->param[i*4+c].type = P_CONST;
- pc->param[i*4+c].hw = rid++;
- pc->param[i*4+c].index = i;
+ sn = p->info.input_semantic_name[p->cfg.io[i].id_fp];
+ si = p->info.input_semantic_index[p->cfg.io[i].id_fp];
+
+ if (sn == TGSI_SEMANTIC_COLOR) {
+ p->cfg.two_side[si] = p->cfg.io[i];
+
+ /* increase colour count */
+ p->cfg.regs[0] += popcnt4(
+ p->cfg.two_side[si].mask) << 16;
+
+ n = MIN2(n, p->cfg.io[i].hw - m);
}
}
+ if (n < 0x40)
+ p->cfg.regs[0] += n;
+
+ /* Initialize FP results:
+ * FragDepth is always first TGSI and last hw output
+ */
+ i = p->info.writes_z ? 4 : 0;
+ for (rid = 0; i < pc->result_nr * 4; i++)
+ pc->result[i].rhw = rid++;
+ if (p->info.writes_z)
+ pc->result[2].rhw = rid;
+
+ p->cfg.high_result = rid;
}
if (pc->immd_nr) {
int rid = 0;
- pc->immd = CALLOC(pc->immd_nr * 4, sizeof(struct nv50_reg));
+ pc->immd = MALLOC(pc->immd_nr * 4 * sizeof(struct nv50_reg));
if (!pc->immd)
goto out_err;
for (i = 0; i < pc->immd_nr; i++) {
- for (c = 0; c < 4; c++) {
- pc->immd[i*4+c].type = P_IMMD;
- pc->immd[i*4+c].hw = rid++;
- pc->immd[i*4+c].index = i;
- }
+ for (c = 0; c < 4; c++, rid++)
+ ctor_reg(&pc->immd[rid], P_IMMD, i, rid);
}
}
ret = TRUE;
out_err:
- if (r_usage[0])
- FREE(r_usage[0]);
- if (r_usage[1])
- FREE(r_usage[1]);
+ if (pc->iv_p)
+ free_temp(pc, pc->iv_p);
+ if (pc->iv_c)
+ free_temp(pc, pc->iv_c);
- tgsi_parse_free(&p);
+ tgsi_parse_free(&tp);
return ret;
}
@@ -2110,18 +2444,165 @@ free_nv50_pc(struct nv50_pc *pc)
}
static boolean
+ctor_nv50_pc(struct nv50_pc *pc, struct nv50_program *p)
+{
+ int i, c;
+ unsigned rtype[2] = { P_ATTR, P_RESULT };
+
+ pc->p = p;
+ pc->temp_nr = p->info.file_max[TGSI_FILE_TEMPORARY] + 1;
+ pc->attr_nr = p->info.file_max[TGSI_FILE_INPUT] + 1;
+ pc->result_nr = p->info.file_max[TGSI_FILE_OUTPUT] + 1;
+ pc->param_nr = p->info.file_max[TGSI_FILE_CONSTANT] + 1;
+
+ p->cfg.high_temp = 4;
+
+ p->cfg.two_side[0].hw = 0x40;
+ p->cfg.two_side[1].hw = 0x40;
+
+ switch (p->type) {
+ case PIPE_SHADER_VERTEX:
+ p->cfg.psiz = 0x40;
+ p->cfg.clpd = 0x40;
+ p->cfg.io_nr = pc->result_nr;
+ break;
+ case PIPE_SHADER_FRAGMENT:
+ rtype[0] = rtype[1] = P_TEMP;
+
+ p->cfg.regs[0] = 0x01000004;
+ p->cfg.io_nr = pc->attr_nr;
+
+ if (p->info.writes_z) {
+ p->cfg.regs[2] |= 0x00000100;
+ p->cfg.regs[3] |= 0x00000011;
+ }
+ if (p->info.uses_kill)
+ p->cfg.regs[2] |= 0x00100000;
+ break;
+ }
+
+ if (pc->temp_nr) {
+ pc->temp = MALLOC(pc->temp_nr * 4 * sizeof(struct nv50_reg));
+ if (!pc->temp)
+ return FALSE;
+
+ for (i = 0; i < pc->temp_nr * 4; ++i)
+ ctor_reg(&pc->temp[i], P_TEMP, i / 4, -1);
+ }
+
+ if (pc->attr_nr) {
+ pc->attr = MALLOC(pc->attr_nr * 4 * sizeof(struct nv50_reg));
+ if (!pc->attr)
+ return FALSE;
+
+ for (i = 0; i < pc->attr_nr * 4; ++i)
+ ctor_reg(&pc->attr[i], rtype[0], i / 4, -1);
+ }
+
+ if (pc->result_nr) {
+ unsigned nr = pc->result_nr * 4;
+
+ pc->result = MALLOC(nr * sizeof(struct nv50_reg));
+ if (!pc->result)
+ return FALSE;
+
+ for (i = 0; i < nr; ++i)
+ ctor_reg(&pc->result[i], rtype[1], i / 4, -1);
+ }
+
+ if (pc->param_nr) {
+ int rid = 0;
+
+ pc->param = MALLOC(pc->param_nr * 4 * sizeof(struct nv50_reg));
+ if (!pc->param)
+ return FALSE;
+
+ for (i = 0; i < pc->param_nr; ++i)
+ for (c = 0; c < 4; ++c, ++rid)
+ ctor_reg(&pc->param[rid], P_CONST, i, rid);
+ }
+
+ return TRUE;
+}
+
+static void
+nv50_fp_move_results(struct nv50_pc *pc)
+{
+ struct nv50_reg reg;
+ unsigned i;
+
+ ctor_reg(&reg, P_TEMP, -1, -1);
+
+ for (i = 0; i < pc->result_nr * 4; ++i) {
+ if (pc->result[i].rhw < 0 || pc->result[i].hw < 0)
+ continue;
+ if (pc->result[i].rhw != pc->result[i].hw) {
+ reg.hw = pc->result[i].rhw;
+ emit_mov(pc, &reg, &pc->result[i]);
+ }
+ }
+}
+
+static void
+nv50_program_fixup_insns(struct nv50_pc *pc)
+{
+ struct nv50_program_exec *e, *prev = NULL, **bra_list;
+ unsigned i, n, pos;
+
+ bra_list = CALLOC(pc->p->exec_size, sizeof(struct nv50_program_exec *));
+
+ /* Collect branch instructions, we need to adjust their offsets
+ * when converting 32 bit instructions to 64 bit ones
+ */
+ for (n = 0, e = pc->p->exec_head; e; e = e->next)
+ if (e->param.index >= 0 && !e->param.mask)
+ bra_list[n++] = e;
+
+ /* Make sure we don't have any single 32 bit instructions. */
+ for (e = pc->p->exec_head, pos = 0; e; e = e->next) {
+ pos += is_long(e) ? 2 : 1;
+
+ if ((pos & 1) && (!e->next || is_long(e->next))) {
+ for (i = 0; i < n; ++i)
+ if (bra_list[i]->param.index >= pos)
+ bra_list[i]->param.index += 1;
+ convert_to_long(pc, e);
+ ++pos;
+ }
+ if (e->next)
+ prev = e;
+ }
+
+ assert(!is_immd(pc->p->exec_head));
+ assert(!is_immd(pc->p->exec_tail));
+
+ /* last instruction must be long so it can have the end bit set */
+ if (!is_long(pc->p->exec_tail)) {
+ convert_to_long(pc, pc->p->exec_tail);
+ if (prev)
+ convert_to_long(pc, prev);
+ }
+ assert(!(pc->p->exec_tail->inst[1] & 2));
+ /* set the end-bit */
+ pc->p->exec_tail->inst[1] |= 1;
+
+ FREE(bra_list);
+}
+
+static boolean
nv50_program_tx(struct nv50_program *p)
{
struct tgsi_parse_context parse;
struct nv50_pc *pc;
- unsigned k;
boolean ret;
pc = CALLOC_STRUCT(nv50_pc);
if (!pc)
return FALSE;
- pc->p = p;
- pc->p->cfg.high_temp = 4;
+
+ ret = ctor_nv50_pc(pc, p);
+ if (ret == FALSE)
+ goto out_cleanup;
ret = nv50_program_tx_prep(pc);
if (ret == FALSE)
@@ -2141,7 +2622,7 @@ nv50_program_tx(struct nv50_program *p)
switch (tok->Token.Type) {
case TGSI_TOKEN_TYPE_INSTRUCTION:
++pc->insn_cur;
- ret = nv50_program_tx_insn(pc, tok);
+ ret = nv50_tgsi_insn(pc, tok);
if (ret == FALSE)
goto out_err;
break;
@@ -2150,48 +2631,10 @@ nv50_program_tx(struct nv50_program *p)
}
}
- if (p->type == PIPE_SHADER_FRAGMENT) {
- struct nv50_reg out;
-
- out.type = P_TEMP;
- for (k = 0; k < pc->result_nr * 4; k++) {
- if (pc->result[k].rhw == -1)
- continue;
- if (pc->result[k].hw != pc->result[k].rhw) {
- out.hw = pc->result[k].rhw;
- emit_mov(pc, &out, &pc->result[k]);
- }
- if (pc->p->cfg.high_result < (pc->result[k].rhw + 1))
- pc->p->cfg.high_result = pc->result[k].rhw + 1;
- }
- }
-
- /* look for single half instructions and make them long */
- struct nv50_program_exec *e, *e_prev;
+ if (pc->p->type == PIPE_SHADER_FRAGMENT)
+ nv50_fp_move_results(pc);
- for (k = 0, e = pc->p->exec_head, e_prev = NULL; e; e = e->next) {
- if (!is_long(e))
- k++;
-
- if (!e->next || is_long(e->next)) {
- if (k & 1)
- convert_to_long(pc, e);
- k = 0;
- }
-
- if (e->next)
- e_prev = e;
- }
-
- if (!is_long(pc->p->exec_tail)) {
- /* this may occur if moving FP results */
- assert(e_prev && !is_long(e_prev));
- convert_to_long(pc, e_prev);
- convert_to_long(pc, pc->p->exec_tail);
- }
-
- assert(is_long(pc->p->exec_tail) && !is_immd(pc->p->exec_head));
- pc->p->exec_tail->inst[1] |= 0x00000001;
+ nv50_program_fixup_insns(pc);
p->param_nr = pc->param_nr * 4;
p->immd_nr = pc->immd_nr * 4;
@@ -2258,30 +2701,19 @@ nv50_program_validate_data(struct nv50_context *nv50, struct nv50_program *p)
p->immd_nr, NV50_CB_PMISC);
}
- if (!p->data[1] && p->param_nr) {
- struct nouveau_resource *heap =
- nv50->screen->parm_heap[p->type];
-
- if (nouveau_resource_alloc(heap, p->param_nr, p, &p->data[1])) {
- while (heap->next && heap->size < p->param_nr) {
- struct nv50_program *evict = heap->next->priv;
- nouveau_resource_free(&evict->data[1]);
- }
-
- if (nouveau_resource_alloc(heap, p->param_nr, p,
- &p->data[1]))
- assert(0);
- }
- }
+ assert(p->param_nr <= 128);
if (p->param_nr) {
- unsigned cbuf = NV50_CB_PVP;
+ unsigned cb;
float *map = pipe_buffer_map(pscreen, nv50->constbuf[p->type],
PIPE_BUFFER_USAGE_CPU_READ);
- if (p->type == PIPE_SHADER_FRAGMENT)
- cbuf = NV50_CB_PFP;
- nv50_program_upload_data(nv50, map, p->data[1]->start,
- p->param_nr, cbuf);
+
+ if (p->type == PIPE_SHADER_VERTEX)
+ cb = NV50_CB_PVP;
+ else
+ cb = NV50_CB_PFP;
+
+ nv50_program_upload_data(nv50, map, 0, p->param_nr, cb);
pipe_buffer_unmap(pscreen, nv50->constbuf[p->type]);
}
}
@@ -2303,32 +2735,41 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
upload = TRUE;
}
- if ((p->data[0] && p->data[0]->start != p->data_start[0]) ||
- (p->data[1] && p->data[1]->start != p->data_start[1])) {
- for (e = p->exec_head; e; e = e->next) {
- unsigned ei, ci, bs;
+ if (p->data[0] && p->data[0]->start != p->data_start[0])
+ upload = TRUE;
- if (e->param.index < 0)
- continue;
- bs = (e->inst[1] >> 22) & 0x07;
- assert(bs < 2);
- ei = e->param.shift >> 5;
- ci = e->param.index + p->data[bs]->start;
+ if (!upload)
+ return;
+
+ for (e = p->exec_head; e; e = e->next) {
+ unsigned ei, ci, bs;
+
+ if (e->param.index < 0)
+ continue;
+
+ if (e->param.mask == 0) {
+ assert(!(e->param.index & 1));
+ /* seem to be 8 byte steps */
+ ei = (e->param.index >> 1) + 0 /* START_ID */;
- e->inst[ei] &= ~e->param.mask;
- e->inst[ei] |= (ci << e->param.shift);
+ e->inst[0] &= 0xf0000fff;
+ e->inst[0] |= ei << 12;
+ continue;
}
- if (p->data[0])
- p->data_start[0] = p->data[0]->start;
- if (p->data[1])
- p->data_start[1] = p->data[1]->start;
+ bs = (e->inst[1] >> 22) & 0x07;
+ assert(bs < 2);
+ ei = e->param.shift >> 5;
+ ci = e->param.index;
+ if (bs == 0)
+ ci += p->data[bs]->start;
- upload = TRUE;
+ e->inst[ei] &= ~e->param.mask;
+ e->inst[ei] |= (ci << e->param.shift);
}
- if (!upload)
- return;
+ if (p->data[0])
+ p->data_start[0] = p->data[0]->start;
#ifdef NV50_PROGRAM_DUMP
NOUVEAU_ERR("-------\n");
@@ -2402,8 +2843,8 @@ nv50_vertprog_validate(struct nv50_context *nv50)
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2);
- so_data (so, p->cfg.vp.attr[0]);
- so_data (so, p->cfg.vp.attr[1]);
+ so_data (so, p->cfg.attr[0]);
+ so_data (so, p->cfg.attr[1]);
so_method(so, tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
so_data (so, p->cfg.high_result);
so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2);
@@ -2421,7 +2862,6 @@ nv50_fragprog_validate(struct nv50_context *nv50)
struct nouveau_grobj *tesla = nv50->screen->tesla;
struct nv50_program *p = nv50->fragprog;
struct nouveau_stateobj *so;
- unsigned i;
if (!p->translated) {
nv50_program_validate(nv50, p);
@@ -2438,29 +2878,186 @@ nv50_fragprog_validate(struct nv50_context *nv50)
NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, p->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_RD |
NOUVEAU_BO_LOW, 0, 0);
- so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4);
- so_data (so, p->cfg.fp.regs[0]); /* 0x01000404 / 0x00040404 */
- so_data (so, 0x00000004);
- so_data (so, 0x00000000);
- so_data (so, 0x00000000);
- so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), p->cfg.fp.high_map);
- for (i = 0; i < p->cfg.fp.high_map; i++)
- so_data(so, p->cfg.fp.map[i]);
- so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 2);
- so_data (so, p->cfg.fp.regs[1]); /* 0x08040404 / 0x0f000401 */
+ so_method(so, tesla, NV50TCL_FP_REG_ALLOC_TEMP, 1);
so_data (so, p->cfg.high_temp);
so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1);
so_data (so, p->cfg.high_result);
so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1);
- so_data (so, p->cfg.fp.regs[2]);
+ so_data (so, p->cfg.regs[2]);
so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1);
- so_data (so, p->cfg.fp.regs[3]);
+ so_data (so, p->cfg.regs[3]);
so_method(so, tesla, NV50TCL_FP_START_ID, 1);
so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.fragprog);
so_ref(NULL, &so);
}
+static void
+nv50_pntc_replace(struct nv50_context *nv50, uint32_t pntc[8], unsigned base)
+{
+ struct nv50_program *fp = nv50->fragprog;
+ struct nv50_program *vp = nv50->vertprog;
+ unsigned i, c, m = base;
+
+ /* XXX: This can't work correctly in all cases yet, we either
+ * have to create TGSI_SEMANTIC_PNTC or sprite_coord_mode has
+ * to be per FP input instead of per VP output
+ */
+ memset(pntc, 0, 8 * sizeof(uint32_t));
+
+ for (i = 0; i < fp->cfg.io_nr; i++) {
+ uint8_t sn, si;
+ uint8_t j = fp->cfg.io[i].id_vp, k = fp->cfg.io[i].id_fp;
+ unsigned n = popcnt4(fp->cfg.io[i].mask);
+
+ if (fp->info.input_semantic_name[k] != TGSI_SEMANTIC_GENERIC) {
+ m += n;
+ continue;
+ }
+
+ sn = vp->info.input_semantic_name[j];
+ si = vp->info.input_semantic_index[j];
+
+ if (j < fp->cfg.io_nr && sn == TGSI_SEMANTIC_GENERIC) {
+ ubyte mode =
+ nv50->rasterizer->pipe.sprite_coord_mode[si];
+
+ if (mode == PIPE_SPRITE_COORD_NONE) {
+ m += n;
+ continue;
+ }
+ }
+
+ /* this is either PointCoord or replaced by sprite coords */
+ for (c = 0; c < 4; c++) {
+ if (!(fp->cfg.io[i].mask & (1 << c)))
+ continue;
+ pntc[m / 8] |= (c + 1) << ((m % 8) * 4);
+ ++m;
+ }
+ }
+}
+
+static int
+nv50_sreg4_map(uint32_t *p_map, int mid, uint32_t lin[4],
+ struct nv50_sreg4 *fpi, struct nv50_sreg4 *vpo)
+{
+ int c;
+ uint8_t mv = vpo->mask, mf = fpi->mask, oid = vpo->hw;
+ uint8_t *map = (uint8_t *)p_map;
+
+ for (c = 0; c < 4; ++c) {
+ if (mf & 1) {
+ if (fpi->linear == TRUE)
+ lin[mid / 32] |= 1 << (mid % 32);
+ map[mid++] = (mv & 1) ? oid : ((c == 3) ? 0x41 : 0x40);
+ }
+
+ oid += mv & 1;
+ mf >>= 1;
+ mv >>= 1;
+ }
+
+ return mid;
+}
+
+void
+nv50_linkage_validate(struct nv50_context *nv50)
+{
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nv50_program *vp = nv50->vertprog;
+ struct nv50_program *fp = nv50->fragprog;
+ struct nouveau_stateobj *so;
+ struct nv50_sreg4 dummy, *vpo;
+ int i, n, c, m = 0;
+ uint32_t map[16], lin[4], reg[5], pcrd[8];
+
+ memset(map, 0, sizeof(map));
+ memset(lin, 0, sizeof(lin));
+
+ reg[1] = 0x00000004; /* low and high clip distance map ids */
+ reg[2] = 0x00000000; /* layer index map id (disabled, GP only) */
+ reg[3] = 0x00000000; /* point size map id & enable */
+ reg[0] = fp->cfg.regs[0]; /* colour semantic reg */
+ reg[4] = fp->cfg.regs[1]; /* interpolant info */
+
+ dummy.linear = FALSE;
+ dummy.mask = 0xf; /* map all components of HPOS */
+ m = nv50_sreg4_map(map, m, lin, &dummy, &vp->cfg.io[0]);
+
+ dummy.mask = 0x0;
+
+ if (vp->cfg.clpd < 0x40) {
+ for (c = 0; c < vp->cfg.clpd_nr; ++c)
+ map[m++] = vp->cfg.clpd + c;
+ reg[1] = (m << 8);
+ }
+
+ reg[0] |= m << 8; /* adjust BFC0 id */
+
+ /* if light_twoside is active, it seems FFC0_ID == BFC0_ID is bad */
+ if (nv50->rasterizer->pipe.light_twoside) {
+ vpo = &vp->cfg.two_side[0];
+
+ m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[0], &vpo[0]);
+ m = nv50_sreg4_map(map, m, lin, &fp->cfg.two_side[1], &vpo[1]);
+ }
+
+ reg[0] += m - 4; /* adjust FFC0 id */
+ reg[4] |= m << 8; /* set mid where 'normal' FP inputs start */
+
+ i = 0;
+ if (fp->info.input_semantic_name[0] == TGSI_SEMANTIC_POSITION)
+ i = 1;
+ for (; i < fp->cfg.io_nr; i++) {
+ ubyte sn = fp->info.input_semantic_name[fp->cfg.io[i].id_fp];
+ ubyte si = fp->info.input_semantic_index[fp->cfg.io[i].id_fp];
+
+ n = fp->cfg.io[i].id_vp;
+ if (n >= vp->cfg.io_nr ||
+ vp->info.output_semantic_name[n] != sn ||
+ vp->info.output_semantic_index[n] != si)
+ vpo = &dummy;
+ else
+ vpo = &vp->cfg.io[n];
+
+ m = nv50_sreg4_map(map, m, lin, &fp->cfg.io[i], vpo);
+ }
+
+ if (nv50->rasterizer->pipe.point_size_per_vertex) {
+ map[m / 4] |= vp->cfg.psiz << ((m % 4) * 8);
+ reg[3] = (m++ << 4) | 1;
+ }
+
+ /* now fill the stateobj */
+ so = so_new(64, 0);
+
+ n = (m + 3) / 4;
+ so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 1);
+ so_data (so, m);
+ so_method(so, tesla, NV50TCL_VP_RESULT_MAP(0), n);
+ so_datap (so, map, n);
+
+ so_method(so, tesla, NV50TCL_MAP_SEMANTIC_0, 4);
+ so_datap (so, reg, 4);
+
+ so_method(so, tesla, NV50TCL_FP_INTERPOLANT_CTRL, 1);
+ so_data (so, reg[4]);
+
+ so_method(so, tesla, 0x1540, 4);
+ so_datap (so, lin, 4);
+
+ if (nv50->rasterizer->pipe.point_sprite) {
+ nv50_pntc_replace(nv50, pcrd, (reg[4] >> 8) & 0xff);
+
+ so_method(so, tesla, NV50TCL_POINT_COORD_REPLACE_MAP(0), 8);
+ so_datap (so, pcrd, 8);
+ }
+
+ so_ref(so, &nv50->state.programs);
+ so_ref(NULL, &so);
+}
+
void
nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
{
@@ -2476,7 +3073,6 @@ nv50_program_destroy(struct nv50_context *nv50, struct nv50_program *p)
nouveau_bo_ref(NULL, &p->bo);
nouveau_resource_free(&p->data[0]);
- nouveau_resource_free(&p->data[1]);
p->translated = 0;
}
diff --git a/src/gallium/drivers/nv50/nv50_program.h b/src/gallium/drivers/nv50/nv50_program.h
index 096e0476aab..d78dee083f1 100644
--- a/src/gallium/drivers/nv50/nv50_program.h
+++ b/src/gallium/drivers/nv50/nv50_program.h
@@ -15,6 +15,15 @@ struct nv50_program_exec {
} param;
};
+struct nv50_sreg4 {
+ uint8_t hw;
+ uint8_t id_vp;
+ uint8_t id_fp;
+
+ uint8_t mask;
+ boolean linear;
+};
+
struct nv50_program {
struct pipe_shader_state pipe;
struct tgsi_shader_info info;
@@ -24,8 +33,8 @@ struct nv50_program {
struct nv50_program_exec *exec_head;
struct nv50_program_exec *exec_tail;
unsigned exec_size;
- struct nouveau_resource *data[2];
- unsigned data_start[2];
+ struct nouveau_resource *data[1];
+ unsigned data_start[1];
struct nouveau_bo *bo;
@@ -36,14 +45,20 @@ struct nv50_program {
struct {
unsigned high_temp;
unsigned high_result;
- struct {
- unsigned attr[2];
- } vp;
- struct {
- unsigned regs[4];
- unsigned map[5];
- unsigned high_map;
- } fp;
+
+ uint32_t attr[2];
+ uint32_t regs[4];
+
+ /* for VPs, io_nr doesn't count 'private' results (PSIZ etc.) */
+ unsigned io_nr;
+ struct nv50_sreg4 io[PIPE_MAX_SHADER_OUTPUTS];
+
+ /* FP colour inputs, VP/GP back colour outputs */
+ struct nv50_sreg4 two_side[2];
+
+ /* VP only */
+ uint8_t clpd, clpd_nr;
+ uint8_t psiz;
} cfg;
};
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index c7f80a22037..3b08e1b89fb 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -87,12 +87,10 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param)
return 1;
case PIPE_CAP_GLSL:
return 0;
- case PIPE_CAP_S3TC:
- return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
- return 0;
+ return 1;
case PIPE_CAP_MAX_RENDER_TARGETS:
return 8;
case PIPE_CAP_OCCLUSION_QUERY:
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 4283808ed93..81fa3e34c59 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -276,6 +276,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
so_method(so, tesla, 0x1684, 1);
so_data (so, cso->flatshade_first ? 0 : 1);
+ so_method(so, tesla, NV50TCL_VERTEX_TWO_SIDE_ENABLE, 1);
+ so_data (so, cso->light_twoside);
+
so_method(so, tesla, NV50TCL_LINE_WIDTH, 1);
so_data (so, fui(cso->line_width));
so_method(so, tesla, NV50TCL_LINE_SMOOTH_ENABLE, 1);
@@ -294,6 +297,9 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
so_method(so, tesla, NV50TCL_POINT_SIZE, 1);
so_data (so, fui(cso->point_size));
+ so_method(so, tesla, NV50TCL_POINT_SPRITE_ENABLE, 1);
+ so_data (so, cso->point_sprite);
+
so_method(so, tesla, NV50TCL_POLYGON_MODE_FRONT, 3);
if (cso->front_winding == PIPE_WINDING_CCW) {
so_data(so, nvgl_polygon_mode(cso->fill_ccw));
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index d294356f75d..4ed76973c4b 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -189,6 +189,8 @@ nv50_state_emit(struct nv50_context *nv50)
so_emit(chan, nv50->state.vertprog);
if (nv50->state.dirty & NV50_NEW_FRAGPROG)
so_emit(chan, nv50->state.fragprog);
+ if (nv50->state.dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG))
+ so_emit(chan, nv50->state.programs);
if (nv50->state.dirty & NV50_NEW_RASTERIZER)
so_emit(chan, nv50->state.rast);
if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR)
@@ -210,6 +212,12 @@ nv50_state_emit(struct nv50_context *nv50)
so_emit(chan, nv50->state.vtxattr);
}
nv50->state.dirty = 0;
+}
+
+void
+nv50_state_flush_notify(struct nouveau_channel *chan)
+{
+ struct nv50_context *nv50 = chan->user_private;
so_emit_reloc_markers(chan, nv50->state.fb);
so_emit_reloc_markers(chan, nv50->state.vertprog);
@@ -240,6 +248,9 @@ nv50_state_validate(struct nv50_context *nv50)
if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_FRAGPROG_CB))
nv50_fragprog_validate(nv50);
+ if (nv50->dirty & (NV50_NEW_FRAGPROG | NV50_NEW_VERTPROG))
+ nv50_linkage_validate(nv50);
+
if (nv50->dirty & NV50_NEW_RASTERIZER)
so_ref(nv50->rasterizer->so, &nv50->state.rast);
@@ -301,7 +312,7 @@ scissor_uptodate:
goto viewport_uptodate;
nv50->state.viewport_bypass = bypass;
- so = so_new(12, 0);
+ so = so_new(14, 0);
if (!bypass) {
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
so_data (so, fui(nv50->viewport.translate[0]));
@@ -314,12 +325,21 @@ scissor_uptodate:
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);
} else {
so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 0);
+ so_method(so, tesla, NV50TCL_VIEW_VOLUME_CLIP_CTRL, 1);
+ so_data (so, 0x0000);
so_method(so, tesla, 0x0f90, 1);
so_data (so, 1);
}
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index e9c3562194b..bb7731855cd 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -89,14 +89,14 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
if (src_bo->tile_flags) {
BEGIN_RING(chan, m2mf,
NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1);
- OUT_RING (chan, (sy << 16) | sx);
+ OUT_RING (chan, (sy << 16) | (sx * cpp));
} else {
src_offset += (line_count * src_pitch);
}
if (dst_bo->tile_flags) {
BEGIN_RING(chan, m2mf,
NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1);
- OUT_RING (chan, (dy << 16) | dx);
+ OUT_RING (chan, (dy << 16) | (dx * cpp));
} else {
dst_offset += (line_count * dst_pitch);
}
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 6c5914baa35..52b1c9a6b26 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -184,8 +184,15 @@ struct r300_texture {
/* Offsets into the buffer. */
unsigned offset[PIPE_MAX_TEXTURE_LEVELS];
- /* Stride (pitch?) of this texture in bytes */
- unsigned stride;
+ /**
+ * If non-zero, override the natural texture layout with
+ * a custom stride (in bytes).
+ *
+ * \note Mipmapping fails for textures with a non-natural layout!
+ *
+ * \sa r300_texture_get_stride
+ */
+ unsigned stride_override;
/* Total size of this texture, in bytes. */
unsigned size;
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 1bc35c24867..a1b36ba2ed1 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -283,7 +283,7 @@ void r300_emit_fb_state(struct r300_context* r300,
for (i = 0; i < fb->nr_cbufs; i++) {
tex = (struct r300_texture*)fb->cbufs[i]->texture;
assert(tex && tex->buffer && "cbuf is marked, but NULL!");
- pixpitch = tex->stride / tex->tex.block.size;
+ pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0 + (4 * i), 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
@@ -300,7 +300,7 @@ void r300_emit_fb_state(struct r300_context* r300,
if (fb->zsbuf) {
tex = (struct r300_texture*)fb->zsbuf->texture;
assert(tex && tex->buffer && "zsbuf is marked, but NULL!");
- pixpitch = tex->stride / tex->tex.block.size;
+ pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;
OUT_CS_REG_SEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_CS_RELOC(tex->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index d05a736dd96..737396d8d97 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -31,6 +31,7 @@
#include "r300_state_derived.h"
/* r300_render: Vertex and index buffer primitive emission. */
+#define R300_MAX_VBO_SIZE (1024 * 1024)
struct r300_render {
/* Parent class */
@@ -46,7 +47,10 @@ struct r300_render {
/* VBO */
struct pipe_buffer* vbo;
- size_t vbo_alloc_size;
+ size_t vbo_size;
+ size_t vbo_offset;
+ size_t vbo_max_used;
+ void * vbo_ptr;
};
static INLINE struct r300_render*
@@ -75,19 +79,18 @@ static boolean r300_render_allocate_vertices(struct vbuf_render* render,
struct pipe_screen* screen = r300->context.screen;
size_t size = (size_t)vertex_size * (size_t)count;
- if (r300render->vbo && (size > r300render->vbo_alloc_size)) {
- pipe_buffer_reference(&r300render->vbo, NULL);
- }
-
- if (!r300render->vbo) {
+ if (size + r300render->vbo_offset > r300render->vbo_size)
+ {
r300render->vbo = pipe_buffer_create(screen,
64,
PIPE_BUFFER_USAGE_VERTEX,
- size);
+ R300_MAX_VBO_SIZE);
+ r300render->vbo_size = R300_MAX_VBO_SIZE;
}
- r300render->vbo_alloc_size = MAX2(size, r300render->vbo_alloc_size);
r300render->vertex_size = vertex_size;
+ r300->vbo = r300render->vbo;
+ r300->vbo_offset = r300render->vbo_offset;
return (r300render->vbo) ? TRUE : FALSE;
}
@@ -97,8 +100,10 @@ static void* r300_render_map_vertices(struct vbuf_render* render)
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
- return (unsigned char*)pipe_buffer_map(screen, r300render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ r300render->vbo_ptr = pipe_buffer_map(screen, r300render->vbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+
+ return (r300render->vbo_ptr + r300render->vbo_offset);
}
static void r300_render_unmap_vertices(struct vbuf_render* render,
@@ -107,15 +112,24 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
{
struct r300_render* r300render = r300_render(render);
struct pipe_screen* screen = r300render->r300->context.screen;
+ CS_LOCALS(r300render->r300);
+ BEGIN_CS(2);
+ OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max);
+ END_CS;
+ r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
+ r300render->vertex_size * (max + 1));
pipe_buffer_unmap(screen, r300render->vbo);
}
static void r300_render_release_vertices(struct vbuf_render* render)
{
struct r300_render* r300render = r300_render(render);
+ struct r300_context* r300 = r300render->r300;
- pipe_buffer_reference(&r300render->vbo, NULL);
+ r300render->vbo_offset += r300render->vbo_max_used;
+ r300render->vbo_max_used = 0;
+ r300->vbo = NULL;
}
static boolean r300_render_set_primitive(struct vbuf_render* render,
@@ -163,14 +177,12 @@ static boolean r300_render_set_primitive(struct vbuf_render* render,
return TRUE;
}
-static void prepare_render(struct r300_render* render, unsigned count)
+static void r300_prepare_render(struct r300_render* render, unsigned count)
{
struct r300_context* r300 = render->r300;
CS_LOCALS(r300);
- r300->vbo = render->vbo;
-
r300_emit_dirty_state(r300);
}
@@ -183,7 +195,7 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
- prepare_render(r300render, count);
+ r300_prepare_render(r300render, count);
DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
@@ -208,7 +220,7 @@ static void r300_render_draw(struct vbuf_render* render,
CS_LOCALS(r300);
- prepare_render(r300render, count);
+ r300_prepare_render(r300render, count);
/* Send our indices into an index buffer. */
index_buffer = pipe_buffer_create(screen, 64, PIPE_BUFFER_USAGE_VERTEX,
@@ -217,25 +229,7 @@ static void r300_render_draw(struct vbuf_render* render,
return;
}
-/*
- index_map = pipe_buffer_map(screen, index_buffer,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- memcpy(index_map, indices, count);
- pipe_buffer_unmap(screen, index_buffer);
-
- debug_printf("r300: Doing indexbuf render, count %d\n", count);
-
- BEGIN_CS(8);
- OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, 0);
- OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
- r300render->hwprim);
- OUT_CS_PKT3(R300_PACKET3_INDX_BUFFER, 2);
- OUT_CS(R300_INDX_BUFFER_ONE_REG_WR | (R300_VAP_PORT_IDX0 >> 2));
- OUT_CS_INDEX_RELOC(index_buffer, 0, count, RADEON_GEM_DOMAIN_GTT, 0, 0);
- END_CS; */
-
- BEGIN_CS(4 + (count+1)/2);
- OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count);
+ BEGIN_CS(2 + (count+1)/2);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
r300render->hwprim);
@@ -273,6 +267,10 @@ static struct vbuf_render* r300_render_create(struct r300_context* r300)
r300render->base.release_vertices = r300_render_release_vertices;
r300render->base.destroy = r300_render_destroy;
+ r300render->vbo = NULL;
+ r300render->vbo_size = 0;
+ r300render->vbo_offset = 0;
+
return &r300render->base;
}
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 15740f61252..3b5b1bbd37f 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -93,8 +93,6 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
} else {
return 0;
}
- case PIPE_CAP_S3TC:
- return 1;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 1;
case PIPE_CAP_POINT_SPRITE:
@@ -323,13 +321,14 @@ r300_get_tex_transfer(struct pipe_screen *screen,
if (trans) {
pipe_texture_reference(&trans->transfer.texture, texture);
trans->transfer.format = texture->format;
+ trans->transfer.x = x;
+ trans->transfer.y = y;
trans->transfer.width = w;
trans->transfer.height = h;
trans->transfer.block = texture->block;
trans->transfer.nblocksx = texture->nblocksx[level];
trans->transfer.nblocksy = texture->nblocksy[level];
- trans->transfer.stride = align(pf_get_stride(&trans->transfer.block,
- texture->width[level]), 32);
+ trans->transfer.stride = r300_texture_get_stride(tex, level);
trans->transfer.usage = usage;
trans->offset = offset;
}
@@ -356,7 +355,7 @@ static void* r300_transfer_map(struct pipe_screen* screen,
if (transfer->usage != PIPE_TRANSFER_READ) {
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
}
-
+
map = pipe_buffer_map(screen, tex->buffer, flags);
if (!map) {
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index 96e6e4a77d4..cc6288cb519 100644
--- a/src/gallium/drivers/r300/r300_surface.c
+++ b/src/gallium/drivers/r300/r300_surface.c
@@ -29,7 +29,7 @@ static void r300_surface_setup(struct r300_context* r300,
unsigned w, unsigned h)
{
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
- unsigned pixpitch = dest->stride / dest->tex.block.size;
+ unsigned pixpitch = r300_texture_get_stride(dest, 0) / dest->tex.block.size;
CS_LOCALS(r300);
r300_emit_blend_state(r300, &blend_clear_state);
@@ -100,7 +100,7 @@ static void r300_surface_fill(struct pipe_context* pipe,
struct r300_context* r300 = r300_context(pipe);
struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
struct r300_texture* tex = (struct r300_texture*)dest->texture;
- unsigned pixpitch = tex->stride / tex->tex.block.size;
+ unsigned pixpitch = r300_texture_get_stride(tex, 0) / tex->tex.block.size;
boolean invalid = FALSE;
CS_LOCALS(r300);
@@ -233,7 +233,7 @@ static void r300_surface_copy(struct pipe_context* pipe,
struct r300_capabilities* caps = r300_screen(pipe->screen)->caps;
struct r300_texture* srctex = (struct r300_texture*)src->texture;
struct r300_texture* desttex = (struct r300_texture*)dest->texture;
- unsigned pixpitch = srctex->stride / srctex->tex.block.size;
+ unsigned pixpitch = r300_texture_get_stride(srctex, 0) / srctex->tex.block.size;
boolean invalid = FALSE;
float fsrcx = srcx, fsrcy = srcy, fdestx = destx, fdesty = desty;
CS_LOCALS(r300);
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 590052509cc..7c041d17f71 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -25,7 +25,6 @@
static void r300_setup_texture_state(struct r300_texture* tex,
unsigned width,
unsigned height,
- unsigned pitch,
unsigned levels)
{
struct r300_texture_state* state = &tex->state;
@@ -38,7 +37,7 @@ static void r300_setup_texture_state(struct r300_texture* tex,
/* XXX */
state->format1 = r300_translate_texformat(tex->tex.format);
- state->format2 = pitch - 1;
+ state->format2 = r300_texture_get_stride(tex, 0);
/* Assume (somewhat foolishly) that oversized textures will
* not be permitted by the state tracker. */
@@ -49,14 +48,31 @@ static void r300_setup_texture_state(struct r300_texture* tex,
state->format2 |= R500_TXHEIGHT_BIT11;
}
- debug_printf("r300: Set texture state (%dx%d, pitch %d, %d levels)\n",
- width, height, pitch, levels);
+ debug_printf("r300: Set texture state (%dx%d, %d levels)\n",
+ width, height, levels);
+}
+
+/**
+ * Return the stride, in bytes, of the texture images of the given texture
+ * at the given level.
+ */
+unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level)
+{
+ if (tex->stride_override)
+ return tex->stride_override;
+
+ if (level > tex->tex.last_level) {
+ debug_printf("%s: level (%u) > last_level (%u)\n", __FUNCTION__, level, tex->tex.last_level);
+ return 0;
+ }
+
+ return align(pf_get_stride(&tex->tex.block, tex->tex.width[level]), 32);
}
static void r300_setup_miptree(struct r300_texture* tex)
{
struct pipe_texture* base = &tex->tex;
- int stride, size, offset;
+ int stride, size;
int i;
for (i = 0; i <= base->last_level; i++) {
@@ -74,7 +90,7 @@ static void r300_setup_miptree(struct r300_texture* tex)
* XXX
* POT, uncompressed, unmippmapped textures can be aligned to 32,
* instead of 64. */
- stride = align(pf_get_stride(&base->block, base->width[i]), 32);
+ stride = r300_texture_get_stride(tex, i);
size = stride * base->nblocksy[i] * base->depth[i];
tex->offset[i] = align(tex->size, 32);
@@ -84,10 +100,6 @@ static void r300_setup_miptree(struct r300_texture* tex)
"(%dx%dx%d px, pitch %d bytes)\n",
i, base->width[i], base->height[i], base->depth[i],
stride);
- /* Save stride of first level to the texture. */
- if (i == 0) {
- tex->stride = stride;
- }
}
}
@@ -109,7 +121,7 @@ static struct pipe_texture*
r300_setup_miptree(tex);
r300_setup_texture_state(tex, template->width[0], template->height[0],
- template->width[0], template->last_level);
+ template->last_level);
tex->buffer = screen->buffer_create(screen, 1024,
PIPE_BUFFER_USAGE_PIXEL,
@@ -189,11 +201,10 @@ static struct pipe_texture*
pipe_reference_init(&tex->tex.reference, 1);
tex->tex.screen = screen;
- tex->stride = *stride;
+ tex->stride_override = *stride;
/* XXX */
- r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0],
- tex->stride, 0);
+ r300_setup_texture_state(tex, tex->tex.width[0], tex->tex.height[0], 0);
pipe_buffer_reference(&tex->buffer, buffer);
@@ -221,7 +232,7 @@ boolean r300_get_texture_buffer(struct pipe_texture* texture,
pipe_buffer_reference(buffer, tex->buffer);
if (stride) {
- *stride = tex->stride;
+ *stride = r300_texture_get_stride(tex, 0);
}
return TRUE;
diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h
index 3b56f0307c0..697669147d8 100644
--- a/src/gallium/drivers/r300/r300_texture.h
+++ b/src/gallium/drivers/r300/r300_texture.h
@@ -30,8 +30,12 @@
#include "r300_context.h"
#include "r300_reg.h"
+struct r300_texture;
+
void r300_init_screen_texture_functions(struct pipe_screen* screen);
+unsigned r300_texture_get_stride(struct r300_texture* tex, unsigned level);
+
/* Note the signature of R300_EASY_TX_FORMAT(A, R, G, B, FORMAT)... */
static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
{
@@ -68,6 +72,9 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format)
/* W24_FP */
case PIPE_FORMAT_Z24S8_UNORM:
return R300_EASY_TX_FORMAT(X, X, X, X, W24_FP);
+ /* Z5_Y6_X5 */
+ case PIPE_FORMAT_R16_SNORM:
+ return R300_EASY_TX_FORMAT(X, X, X, X, Z5Y6X5);
default:
debug_printf("r300: Implementation error: "
"Got unsupported texture format %s in %s\n",
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
index d68a1041063..0913ca1bd5b 100644
--- a/src/gallium/drivers/r300/r300_tgsi_to_rc.c
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -158,7 +158,6 @@ static unsigned translate_saturate(unsigned saturate)
switch(saturate) {
case TGSI_SAT_NONE: return SATURATE_OFF;
case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE;
- case TGSI_SAT_MINUS_PLUS_ONE: return SATURATE_PLUS_MINUS_ONE;
}
fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
diff --git a/src/gallium/drivers/softpipe/Makefile b/src/gallium/drivers/softpipe/Makefile
index 516e3992fdd..6ab37537628 100644
--- a/src/gallium/drivers/softpipe/Makefile
+++ b/src/gallium/drivers/softpipe/Makefile
@@ -6,26 +6,17 @@ LIBNAME = softpipe
C_SOURCES = \
sp_fs_exec.c \
sp_fs_sse.c \
- sp_fs_llvm.c \
sp_clear.c \
sp_flush.c \
sp_query.c \
sp_context.c \
sp_draw_arrays.c \
- sp_prim_setup.c \
sp_prim_vbuf.c \
sp_quad_pipe.c \
- sp_quad_alpha_test.c \
- sp_quad_blend.c \
- sp_quad_colormask.c \
- sp_quad_coverage.c \
+ sp_quad_stipple.c \
sp_quad_depth_test.c \
- sp_quad_earlyz.c \
sp_quad_fs.c \
- sp_quad_occlusion.c \
- sp_quad_output.c \
- sp_quad_stencil.c \
- sp_quad_stipple.c \
+ sp_quad_blend.c \
sp_screen.c \
sp_setup.c \
sp_state_blend.c \
@@ -38,6 +29,7 @@ C_SOURCES = \
sp_state_vertex.c \
sp_texture.c \
sp_tex_sample.c \
+ sp_tex_tile_cache.c \
sp_tile_cache.c \
sp_surface.c
diff --git a/src/gallium/drivers/softpipe/SConscript b/src/gallium/drivers/softpipe/SConscript
index f8720638a76..950c3d9955b 100644
--- a/src/gallium/drivers/softpipe/SConscript
+++ b/src/gallium/drivers/softpipe/SConscript
@@ -7,25 +7,16 @@ softpipe = env.ConvenienceLibrary(
source = [
'sp_fs_exec.c',
'sp_fs_sse.c',
- 'sp_fs_llvm.c',
'sp_clear.c',
'sp_context.c',
'sp_draw_arrays.c',
'sp_flush.c',
- 'sp_prim_setup.c',
'sp_prim_vbuf.c',
'sp_setup.c',
- 'sp_quad_alpha_test.c',
'sp_quad_blend.c',
'sp_quad_pipe.c',
- 'sp_quad_colormask.c',
- 'sp_quad_coverage.c',
'sp_quad_depth_test.c',
- 'sp_quad_earlyz.c',
'sp_quad_fs.c',
- 'sp_quad_occlusion.c',
- 'sp_quad_output.c',
- 'sp_quad_stencil.c',
'sp_quad_stipple.c',
'sp_query.c',
'sp_screen.c',
@@ -39,6 +30,7 @@ softpipe = env.ConvenienceLibrary(
'sp_state_vertex.c',
'sp_surface.c',
'sp_tex_sample.c',
+ 'sp_tex_tile_cache.c',
'sp_texture.c',
'sp_tile_cache.c',
])
diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c
index d3af18e162b..8fac8e6e05f 100644
--- a/src/gallium/drivers/softpipe/sp_clear.c
+++ b/src/gallium/drivers/softpipe/sp_clear.c
@@ -36,8 +36,6 @@
#include "util/u_pack_color.h"
#include "sp_clear.h"
#include "sp_context.h"
-#include "sp_surface.h"
-#include "sp_state.h"
#include "sp_tile_cache.h"
diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h
index 2e450672f58..9be3b86fe9f 100644
--- a/src/gallium/drivers/softpipe/sp_clear.h
+++ b/src/gallium/drivers/softpipe/sp_clear.h
@@ -32,7 +32,6 @@
#ifndef SP_CLEAR_H
#define SP_CLEAR_H
-#include "pipe/p_state.h"
struct pipe_context;
extern void
diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c
index 86df320ea8a..e1e31ab047a 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -31,17 +31,18 @@
*/
#include "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
#include "pipe/p_defines.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "sp_clear.h"
#include "sp_context.h"
#include "sp_flush.h"
-#include "sp_prim_setup.h"
#include "sp_prim_vbuf.h"
#include "sp_state.h"
#include "sp_surface.h"
#include "sp_tile_cache.h"
+#include "sp_tex_tile_cache.h"
#include "sp_texture.h"
#include "sp_winsys.h"
#include "sp_query.h"
@@ -72,18 +73,16 @@ softpipe_unmap_transfers(struct softpipe_context *sp)
{
uint i;
- for (i = 0; i < sp->framebuffer.nr_cbufs; i++)
- sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
- sp_flush_tile_cache(sp, sp->zsbuf_cache);
-
for (i = 0; i < sp->framebuffer.nr_cbufs; i++) {
sp_tile_cache_unmap_transfers(sp->cbuf_cache[i]);
}
+
sp_tile_cache_unmap_transfers(sp->zsbuf_cache);
}
-static void softpipe_destroy( struct pipe_context *pipe )
+static void
+softpipe_destroy( struct pipe_context *pipe )
{
struct softpipe_context *softpipe = softpipe_context( pipe );
uint i;
@@ -91,26 +90,16 @@ static void softpipe_destroy( struct pipe_context *pipe )
if (softpipe->draw)
draw_destroy( softpipe->draw );
- for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
- softpipe->quad[i].polygon_stipple->destroy( softpipe->quad[i].polygon_stipple );
- softpipe->quad[i].earlyz->destroy( softpipe->quad[i].earlyz );
- softpipe->quad[i].shade->destroy( softpipe->quad[i].shade );
- softpipe->quad[i].alpha_test->destroy( softpipe->quad[i].alpha_test );
- softpipe->quad[i].depth_test->destroy( softpipe->quad[i].depth_test );
- softpipe->quad[i].stencil_test->destroy( softpipe->quad[i].stencil_test );
- softpipe->quad[i].occlusion->destroy( softpipe->quad[i].occlusion );
- softpipe->quad[i].coverage->destroy( softpipe->quad[i].coverage );
- softpipe->quad[i].blend->destroy( softpipe->quad[i].blend );
- softpipe->quad[i].colormask->destroy( softpipe->quad[i].colormask );
- softpipe->quad[i].output->destroy( softpipe->quad[i].output );
- }
+ softpipe->quad.shade->destroy( softpipe->quad.shade );
+ softpipe->quad.depth_test->destroy( softpipe->quad.depth_test );
+ softpipe->quad.blend->destroy( softpipe->quad.blend );
for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
sp_destroy_tile_cache(softpipe->cbuf_cache[i]);
sp_destroy_tile_cache(softpipe->zsbuf_cache);
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- sp_destroy_tile_cache(softpipe->tex_cache[i]);
+ sp_destroy_tex_tile_cache(softpipe->tex_cache[i]);
for (i = 0; i < Elements(softpipe->constants); i++) {
if (softpipe->constants[i].buffer) {
@@ -121,6 +110,15 @@ static void softpipe_destroy( struct pipe_context *pipe )
FREE( softpipe );
}
+
+/**
+ * if (the texture is being used as a framebuffer surface)
+ * return PIPE_REFERENCED_FOR_WRITE
+ * else if (the texture is a bound texture source)
+ * return PIPE_REFERENCED_FOR_READ XXX not done yet
+ * else
+ * return PIPE_UNREFERENCED
+ */
static unsigned int
softpipe_is_texture_referenced( struct pipe_context *pipe,
struct pipe_texture *texture,
@@ -129,15 +127,17 @@ softpipe_is_texture_referenced( struct pipe_context *pipe,
struct softpipe_context *softpipe = softpipe_context( pipe );
unsigned i;
- if(softpipe->dirty_render_cache) {
+ if (softpipe->dirty_render_cache) {
for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
- if(softpipe->framebuffer.cbufs[i] &&
- softpipe->framebuffer.cbufs[i]->texture == texture)
+ if (softpipe->framebuffer.cbufs[i] &&
+ softpipe->framebuffer.cbufs[i]->texture == texture) {
return PIPE_REFERENCED_FOR_WRITE;
+ }
}
- if(softpipe->framebuffer.zsbuf &&
- softpipe->framebuffer.zsbuf->texture == texture)
+ if (softpipe->framebuffer.zsbuf &&
+ softpipe->framebuffer.zsbuf->texture == texture) {
return PIPE_REFERENCED_FOR_WRITE;
+ }
}
/* FIXME: we also need to do the same for the texture cache */
@@ -145,6 +145,7 @@ softpipe_is_texture_referenced( struct pipe_context *pipe,
return PIPE_UNREFERENCED;
}
+
static unsigned int
softpipe_is_buffer_referenced( struct pipe_context *pipe,
struct pipe_buffer *buf)
@@ -152,6 +153,7 @@ softpipe_is_buffer_referenced( struct pipe_context *pipe,
return PIPE_UNREFERENCED;
}
+
struct pipe_context *
softpipe_create( struct pipe_screen *screen )
{
@@ -222,7 +224,6 @@ softpipe_create( struct pipe_screen *screen )
softpipe->pipe.is_buffer_referenced = softpipe_is_buffer_referenced;
softpipe_init_query_funcs( softpipe );
- softpipe_init_texture_funcs( softpipe );
/*
* Alloc caches for accessing drawing surfaces and textures.
@@ -233,41 +234,14 @@ softpipe_create( struct pipe_screen *screen )
softpipe->zsbuf_cache = sp_create_tile_cache( screen );
for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
- softpipe->tex_cache[i] = sp_create_tile_cache( screen );
+ softpipe->tex_cache[i] = sp_create_tex_tile_cache( screen );
/* setup quad rendering stages */
- for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
- softpipe->quad[i].polygon_stipple = sp_quad_polygon_stipple_stage(softpipe);
- softpipe->quad[i].earlyz = sp_quad_earlyz_stage(softpipe);
- softpipe->quad[i].shade = sp_quad_shade_stage(softpipe);
- softpipe->quad[i].alpha_test = sp_quad_alpha_test_stage(softpipe);
- softpipe->quad[i].depth_test = sp_quad_depth_test_stage(softpipe);
- softpipe->quad[i].stencil_test = sp_quad_stencil_test_stage(softpipe);
- softpipe->quad[i].occlusion = sp_quad_occlusion_stage(softpipe);
- softpipe->quad[i].coverage = sp_quad_coverage_stage(softpipe);
- softpipe->quad[i].blend = sp_quad_blend_stage(softpipe);
- softpipe->quad[i].colormask = sp_quad_colormask_stage(softpipe);
- softpipe->quad[i].output = sp_quad_output_stage(softpipe);
- }
-
- /* vertex shader samplers */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- softpipe->tgsi.vert_samplers[i].base.get_samples = sp_get_samples_vertex;
- softpipe->tgsi.vert_samplers[i].unit = i;
- softpipe->tgsi.vert_samplers[i].sp = softpipe;
- softpipe->tgsi.vert_samplers[i].cache = softpipe->tex_cache[i];
- softpipe->tgsi.vert_samplers_list[i] = &softpipe->tgsi.vert_samplers[i];
- }
+ softpipe->quad.shade = sp_quad_shade_stage(softpipe);
+ softpipe->quad.depth_test = sp_quad_depth_test_stage(softpipe);
+ softpipe->quad.blend = sp_quad_blend_stage(softpipe);
- /* fragment shader samplers */
- for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
- softpipe->tgsi.frag_samplers[i].base.get_samples = sp_get_samples_fragment;
- softpipe->tgsi.frag_samplers[i].unit = i;
- softpipe->tgsi.frag_samplers[i].sp = softpipe;
- softpipe->tgsi.frag_samplers[i].cache = softpipe->tex_cache[i];
- softpipe->tgsi.frag_samplers_list[i] = &softpipe->tgsi.frag_samplers[i];
- }
/*
* Create drawing context and plug our rendering stage into it.
@@ -281,30 +255,28 @@ softpipe_create( struct pipe_screen *screen )
(struct tgsi_sampler **)
softpipe->tgsi.vert_samplers_list);
- softpipe->setup = sp_draw_render_stage(softpipe);
- if (!softpipe->setup)
- goto fail;
-
if (debug_get_bool_option( "SP_NO_RAST", FALSE ))
softpipe->no_rast = TRUE;
- if (debug_get_bool_option( "SP_NO_VBUF", FALSE )) {
- /* Deprecated path -- vbuf is the intended interface to the draw module:
- */
- draw_set_rasterize_stage(softpipe->draw, softpipe->setup);
- }
- else {
- sp_init_vbuf(softpipe);
- }
+ softpipe->vbuf_backend = sp_create_vbuf_backend(softpipe);
+ if (!softpipe->vbuf_backend)
+ goto fail;
+
+ softpipe->vbuf = draw_vbuf_stage(softpipe->draw, softpipe->vbuf_backend);
+ if (!softpipe->vbuf)
+ goto fail;
+
+ draw_set_rasterize_stage(softpipe->draw, softpipe->vbuf);
+ draw_set_render(softpipe->draw, softpipe->vbuf_backend);
+
+
/* plug in AA line/point stages */
draw_install_aaline_stage(softpipe->draw, &softpipe->pipe);
draw_install_aapoint_stage(softpipe->draw, &softpipe->pipe);
-#if USE_DRAW_STAGE_PSTIPPLE
/* Do polygon stipple w/ texture map + frag prog? */
draw_install_pstipple_stage(softpipe->draw, &softpipe->pipe);
-#endif
sp_init_surface_functions(softpipe);
diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h
index 7888c2f644b..43a195c8ef5 100644
--- a/src/gallium/drivers/softpipe/sp_context.h
+++ b/src/gallium/drivers/softpipe/sp_context.h
@@ -36,24 +36,13 @@
#include "draw/draw_vertex.h"
#include "sp_quad_pipe.h"
-#include "sp_tex_sample.h"
-/**
- * This is a temporary variable for testing draw-stage polygon stipple.
- * If zero, do stipple in sp_quad_stipple.c
- */
-#define USE_DRAW_STAGE_PSTIPPLE 1
-
-/* Number of threads working on individual quads.
- * Setting to 1 disables this feature.
- */
-#define SP_NUM_QUAD_THREADS 1
-
struct softpipe_vbuf_render;
struct draw_context;
struct draw_stage;
struct softpipe_tile_cache;
+struct softpipe_tex_tile_cache;
struct sp_fragment_shader;
struct sp_vertex_shader;
@@ -62,12 +51,12 @@ struct softpipe_context {
struct pipe_context pipe; /**< base class */
/** Constant state objects */
- const struct pipe_blend_state *blend;
- const struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
- const struct pipe_depth_stencil_alpha_state *depth_stencil;
- const struct pipe_rasterizer_state *rasterizer;
- const struct sp_fragment_shader *fs;
- const struct sp_vertex_shader *vs;
+ struct pipe_blend_state *blend;
+ struct pipe_sampler_state *sampler[PIPE_MAX_SAMPLERS];
+ struct pipe_depth_stencil_alpha_state *depth_stencil;
+ struct pipe_rasterizer_state *rasterizer;
+ struct sp_fragment_shader *fs;
+ struct sp_vertex_shader *vs;
/** Other rendering state */
struct pipe_blend_color blend_color;
@@ -107,7 +96,16 @@ struct softpipe_context {
/** Which vertex shader output slot contains point size */
int psize_slot;
- unsigned reduced_api_prim; /**< PIPE_PRIM_POINTS, _LINES or _TRIANGLES */
+ /* The reduced version of the primitive supplied by the state
+ * tracker.
+ */
+ unsigned reduced_api_prim;
+
+ /* The reduced primitive after unfilled triangles, wide-line
+ * decomposition, etc, are taken into account. This is the
+ * primitive actually rasterized.
+ */
+ unsigned reduced_prim;
/** Derived from scissor and surface bounds: */
struct pipe_scissor_state cliprect;
@@ -116,41 +114,33 @@ struct softpipe_context {
/** Software quad rendering pipeline */
struct {
- struct quad_stage *polygon_stipple;
- struct quad_stage *earlyz;
struct quad_stage *shade;
- struct quad_stage *alpha_test;
- struct quad_stage *stencil_test;
struct quad_stage *depth_test;
- struct quad_stage *occlusion;
- struct quad_stage *coverage;
struct quad_stage *blend;
- struct quad_stage *colormask;
- struct quad_stage *output;
struct quad_stage *first; /**< points to one of the above stages */
- } quad[SP_NUM_QUAD_THREADS];
+ } quad;
/** TGSI exec things */
struct {
- struct sp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
- struct sp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
- struct sp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
- struct sp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_sampler_varient *vert_samplers_list[PIPE_MAX_SAMPLERS];
+ struct sp_sampler_varient *frag_samplers_list[PIPE_MAX_SAMPLERS];
} tgsi;
/** The primitive drawing context */
struct draw_context *draw;
- struct draw_stage *setup;
+
+ /** Draw module backend */
+ struct vbuf_render *vbuf_backend;
struct draw_stage *vbuf;
- struct softpipe_vbuf_render *vbuf_render;
boolean dirty_render_cache;
struct softpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
struct softpipe_tile_cache *zsbuf_cache;
-
- struct softpipe_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+
+ unsigned tex_timestamp;
+ struct softpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
unsigned use_sse : 1;
unsigned dump_fs : 1;
@@ -164,5 +154,9 @@ softpipe_context( struct pipe_context *pipe )
return (struct softpipe_context *)pipe;
}
+void
+softpipe_reset_sampler_varients(struct softpipe_context *softpipe);
+
+
#endif /* SP_CONTEXT_H */
diff --git a/src/gallium/drivers/softpipe/sp_flush.c b/src/gallium/drivers/softpipe/sp_flush.c
index 4a14d49686e..e38b767cf2c 100644
--- a/src/gallium/drivers/softpipe/sp_flush.c
+++ b/src/gallium/drivers/softpipe/sp_flush.c
@@ -37,6 +37,7 @@
#include "sp_surface.h"
#include "sp_state.h"
#include "sp_tile_cache.h"
+#include "sp_tex_tile_cache.h"
#include "sp_winsys.h"
@@ -52,17 +53,19 @@ softpipe_flush( struct pipe_context *pipe,
if (flags & PIPE_FLUSH_TEXTURE_CACHE) {
for (i = 0; i < softpipe->num_textures; i++) {
- sp_flush_tile_cache(softpipe, softpipe->tex_cache[i]);
+ sp_flush_tex_tile_cache(softpipe->tex_cache[i]);
}
}
- if (flags & PIPE_FLUSH_RENDER_CACHE) {
+ if (flags & PIPE_FLUSH_SWAPBUFFERS) {
+ /* If this is a swapbuffers, just flush color buffers.
+ *
+ * The zbuffer changes are not discarded, but held in the cache
+ * in the hope that a later clear will wipe them out.
+ */
for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
if (softpipe->cbuf_cache[i])
- sp_flush_tile_cache(softpipe, softpipe->cbuf_cache[i]);
-
- if (softpipe->zsbuf_cache)
- sp_flush_tile_cache(softpipe, softpipe->zsbuf_cache);
+ sp_flush_tile_cache(softpipe->cbuf_cache[i]);
/* Need this call for hardware buffers before swapbuffers.
*
@@ -71,7 +74,15 @@ softpipe_flush( struct pipe_context *pipe,
* to unmap surfaces when flushing.
*/
softpipe_unmap_transfers(softpipe);
-
+ }
+ else if (flags & PIPE_FLUSH_RENDER_CACHE) {
+ for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++)
+ if (softpipe->cbuf_cache[i])
+ sp_flush_tile_cache(softpipe->cbuf_cache[i]);
+
+ if (softpipe->zsbuf_cache)
+ sp_flush_tile_cache(softpipe->zsbuf_cache);
+
softpipe->dirty_render_cache = FALSE;
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index 9ee86fe7878..4076114d392 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -59,15 +59,34 @@ sp_exec_fragment_shader(const struct sp_fragment_shader *base)
}
+static void
+exec_prepare( const struct sp_fragment_shader *base,
+ struct tgsi_exec_machine *machine,
+ struct tgsi_sampler **samplers )
+{
+ /*
+ * Bind tokens/shader to the interpreter's machine state.
+ * Avoid redundant binding.
+ */
+ if (machine->Tokens != base->shader.tokens) {
+ tgsi_exec_machine_bind_shader( machine,
+ base->shader.tokens,
+ PIPE_MAX_SAMPLERS,
+ samplers );
+ }
+}
+
+
+
/**
* Compute quad X,Y,Z,W for the four fragments in a quad.
*
* This should really be part of the compiled shader.
*/
-void
-sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
- float x, float y,
- struct tgsi_exec_vector *quadpos)
+static void
+setup_pos_vector(const struct tgsi_interp_coef *coef,
+ float x, float y,
+ struct tgsi_exec_vector *quadpos)
{
uint chan;
/* do X */
@@ -95,24 +114,6 @@ sp_setup_pos_vector(const struct tgsi_interp_coef *coef,
}
-static void
-exec_prepare( const struct sp_fragment_shader *base,
- struct tgsi_exec_machine *machine,
- struct tgsi_sampler **samplers )
-{
- /*
- * Bind tokens/shader to the interpreter's machine state.
- * Avoid redundant binding.
- */
- if (machine->Tokens != base->shader.tokens) {
- tgsi_exec_machine_bind_shader( machine,
- base->shader.tokens,
- PIPE_MAX_SAMPLERS,
- samplers );
- }
-}
-
-
/* TODO: hide the machine struct in here somewhere, remove from this
* interface:
*/
@@ -122,11 +123,43 @@ exec_run( const struct sp_fragment_shader *base,
struct quad_header *quad )
{
/* Compute X, Y, Z, W vals for this quad */
- sp_setup_pos_vector(quad->posCoef,
- (float)quad->input.x0, (float)quad->input.y0,
- &machine->QuadPos);
+ setup_pos_vector(quad->posCoef,
+ (float)quad->input.x0, (float)quad->input.y0,
+ &machine->QuadPos);
- return tgsi_exec_machine_run( machine );
+ quad->inout.mask &= tgsi_exec_machine_run( machine );
+ if (quad->inout.mask == 0)
+ return FALSE;
+
+ /* store outputs */
+ {
+ const ubyte *sem_name = base->info.output_semantic_name;
+ const ubyte *sem_index = base->info.output_semantic_index;
+ const uint n = base->info.num_outputs;
+ uint i;
+ for (i = 0; i < n; i++) {
+ switch (sem_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ {
+ uint cbuf = sem_index[i];
+ memcpy(quad->output.color[cbuf],
+ &machine->Outputs[i].xyzw[0].f[0],
+ sizeof(quad->output.color[0]) );
+ }
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ {
+ uint j;
+ for (j = 0; j < 4; j++) {
+ quad->output.depth[j] = machine->Outputs[i].xyzw[2].f[j];
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_llvm.c b/src/gallium/drivers/softpipe/sp_fs_llvm.c
deleted file mode 100644
index 95c0d982d12..00000000000
--- a/src/gallium/drivers/softpipe/sp_fs_llvm.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/**************************************************************************
- *
- * 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.
- *
- **************************************************************************/
-
-/**
- * Execute fragment shader using LLVM code generation.
- * Authors:
- * Zack Rusin
- */
-
-#include "sp_context.h"
-#include "sp_state.h"
-#include "sp_fs.h"
-
-#include "pipe/p_state.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "tgsi/tgsi_sse2.h"
-
-#if 0
-
-/**
- * Subclass of sp_fragment_shader
- */
-struct sp_llvm_fragment_shader
-{
- struct sp_fragment_shader base;
- struct gallivm_prog *llvm_prog;
-};
-
-
-static void
-shade_quad_llvm(struct quad_stage *qs,
- struct quad_header *quad)
-{
- struct quad_shade_stage *qss = quad_shade_stage(qs);
- struct softpipe_context *softpipe = qs->softpipe;
- float dests[4][16][4] ALIGN16_ATTRIB;
- float inputs[4][16][4] ALIGN16_ATTRIB;
- const float fx = (float) quad->x0;
- const float fy = (float) quad->y0;
- struct gallivm_prog *llvm = qss->llvm_prog;
-
- inputs[0][0][0] = fx;
- inputs[1][0][0] = fx + 1.0f;
- inputs[2][0][0] = fx;
- inputs[3][0][0] = fx + 1.0f;
-
- inputs[0][0][1] = fy;
- inputs[1][0][1] = fy;
- inputs[2][0][1] = fy + 1.0f;
- inputs[3][0][1] = fy + 1.0f;
-
-
- gallivm_prog_inputs_interpolate(llvm, inputs, quad->coef);
-
-#if DLLVM
- debug_printf("MASK = %d\n", quad->mask);
- for (int i = 0; i < 4; ++i) {
- for (int j = 0; j < 2; ++j) {
- debug_printf("IN(%d,%d) [%f %f %f %f]\n", i, j,
- inputs[i][j][0], inputs[i][j][1], inputs[i][j][2], inputs[i][j][3]);
- }
- }
-#endif
-
- quad->mask &=
- gallivm_fragment_shader_exec(llvm, fx, fy, dests, inputs,
- softpipe->mapped_constants[PIPE_SHADER_FRAGMENT],
- qss->samplers);
-#if DLLVM
- debug_printf("OUT LLVM = 1[%f %f %f %f], 2[%f %f %f %f]\n",
- dests[0][0][0], dests[0][0][1], dests[0][0][2], dests[0][0][3],
- dests[0][1][0], dests[0][1][1], dests[0][1][2], dests[0][1][3]);
-#endif
-
- /* store result color */
- if (qss->colorOutSlot >= 0) {
- unsigned i;
- /* XXX need to handle multiple color outputs someday */
- allvmrt(qss->stage.softpipe->fs->info.output_semantic_name[qss->colorOutSlot]
- == TGSI_SEMANTIC_COLOR);
- for (i = 0; i < QUAD_SIZE; ++i) {
- quad->outputs.color[0][0][i] = dests[i][qss->colorOutSlot][0];
- quad->outputs.color[0][1][i] = dests[i][qss->colorOutSlot][1];
- quad->outputs.color[0][2][i] = dests[i][qss->colorOutSlot][2];
- quad->outputs.color[0][3][i] = dests[i][qss->colorOutSlot][3];
- }
- }
-#if DLLVM
- for (int i = 0; i < QUAD_SIZE; ++i) {
- debug_printf("QLLVM%d(%d) [%f, %f, %f, %f]\n", i, qss->colorOutSlot,
- quad->outputs.color[0][0][i],
- quad->outputs.color[0][1][i],
- quad->outputs.color[0][2][i],
- quad->outputs.color[0][3][i]);
- }
-#endif
-
- /* store result Z */
- if (qss->depthOutSlot >= 0) {
- /* output[slot] is new Z */
- uint i;
- for (i = 0; i < 4; i++) {
- quad->outputs.depth[i] = dests[i][0][2];
- }
- }
- else {
- /* copy input Z (which was interpolated by the executor) to output Z */
- uint i;
- for (i = 0; i < 4; i++) {
- quad->outputs.depth[i] = inputs[i][0][2];
- }
- }
-#if DLLVM
- debug_printf("D [%f, %f, %f, %f] mask = %d\n",
- quad->outputs.depth[0],
- quad->outputs.depth[1],
- quad->outputs.depth[2],
- quad->outputs.depth[3], quad->mask);
-#endif
-
- /* shader may cull fragments */
- if( quad->mask ) {
- qs->next->run( qs->next, quad );
- }
-}
-
-
-unsigned
-run_llvm_fs( const struct sp_fragment_shader *base,
- struct foo *machine )
-{
-}
-
-
-void
-delete_llvm_fs( struct sp_fragment_shader *base )
-{
- FREE(base);
-}
-
-
-struct sp_fragment_shader *
-softpipe_create_fs_llvm(struct softpipe_context *softpipe,
- const struct pipe_shader_state *templ)
-{
- struct sp_llvm_fragment_shader *shader = NULL;
-
- /* LLVM fragment shaders currently disabled:
- */
- state = CALLOC_STRUCT(sp_llvm_shader_state);
- if (!state)
- return NULL;
-
- state->llvm_prog = 0;
-
- if (!gallivm_global_cpu_engine()) {
- gallivm_cpu_engine_create(state->llvm_prog);
- }
- else
- gallivm_cpu_jit_compile(gallivm_global_cpu_engine(), state->llvm_prog);
-
- if (shader) {
- shader->base.run = run_llvm_fs;
- shader->base.delete = delete_llvm_fs;
- }
-
- return shader;
-}
-
-
-#else
-
-struct sp_fragment_shader *
-softpipe_create_fs_llvm(struct softpipe_context *softpipe,
- const struct pipe_shader_state *templ)
-{
- return NULL;
-}
-
-#endif
diff --git a/src/gallium/drivers/softpipe/sp_fs_sse.c b/src/gallium/drivers/softpipe/sp_fs_sse.c
index f4fa0905d74..9d3e4670eef 100644
--- a/src/gallium/drivers/softpipe/sp_fs_sse.c
+++ b/src/gallium/drivers/softpipe/sp_fs_sse.c
@@ -76,6 +76,43 @@ fs_sse_prepare( const struct sp_fragment_shader *base,
}
+
+/**
+ * Compute quad X,Y,Z,W for the four fragments in a quad.
+ *
+ * This should really be part of the compiled shader.
+ */
+static void
+setup_pos_vector(const struct tgsi_interp_coef *coef,
+ float x, float y,
+ struct tgsi_exec_vector *quadpos)
+{
+ uint chan;
+ /* do X */
+ quadpos->xyzw[0].f[0] = x;
+ quadpos->xyzw[0].f[1] = x + 1;
+ quadpos->xyzw[0].f[2] = x;
+ quadpos->xyzw[0].f[3] = x + 1;
+
+ /* do Y */
+ quadpos->xyzw[1].f[0] = y;
+ quadpos->xyzw[1].f[1] = y;
+ quadpos->xyzw[1].f[2] = y + 1;
+ quadpos->xyzw[1].f[3] = y + 1;
+
+ /* do Z and W for all fragments in the quad */
+ for (chan = 2; chan < 4; chan++) {
+ const float dadx = coef->dadx[chan];
+ const float dady = coef->dady[chan];
+ const float a0 = coef->a0[chan] + dadx * x + dady * y;
+ quadpos->xyzw[chan].f[0] = a0;
+ quadpos->xyzw[chan].f[1] = a0 + dadx;
+ quadpos->xyzw[chan].f[2] = a0 + dady;
+ quadpos->xyzw[chan].f[3] = a0 + dadx + dady;
+ }
+}
+
+
/* TODO: codegenerate the whole run function, skip this wrapper.
* TODO: break dependency on tgsi_exec_machine struct
* TODO: push Position calculation into the generated shader
@@ -89,9 +126,9 @@ fs_sse_run( const struct sp_fragment_shader *base,
struct sp_sse_fragment_shader *shader = sp_sse_fragment_shader(base);
/* Compute X, Y, Z, W vals for this quad -- place in temp[0] for now */
- sp_setup_pos_vector(quad->posCoef,
- (float)quad->input.x0, (float)quad->input.y0,
- machine->Temps);
+ setup_pos_vector(quad->posCoef,
+ (float)quad->input.x0, (float)quad->input.y0,
+ machine->Temps);
/* init kill mask */
tgsi_set_kill_mask(machine, 0x0);
@@ -104,7 +141,39 @@ fs_sse_run( const struct sp_fragment_shader *base,
// , &machine->QuadPos
);
- return ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
+ quad->inout.mask &= ~(machine->Temps[TGSI_EXEC_TEMP_KILMASK_I].xyzw[TGSI_EXEC_TEMP_KILMASK_C].u[0]);
+ if (quad->inout.mask == 0)
+ return FALSE;
+
+ /* store outputs */
+ {
+ const ubyte *sem_name = base->info.output_semantic_name;
+ const ubyte *sem_index = base->info.output_semantic_index;
+ const uint n = base->info.num_outputs;
+ uint i;
+ for (i = 0; i < n; i++) {
+ switch (sem_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ {
+ uint cbuf = sem_index[i];
+ memcpy(quad->output.color[cbuf],
+ &machine->Outputs[i].xyzw[0].f[0],
+ sizeof(quad->output.color[0]) );
+ }
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ {
+ uint j;
+ for (j = 0; j < 4; j++) {
+ quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j];
+ }
+ }
+ break;
+ }
+ }
+ }
+
+ return TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.c b/src/gallium/drivers/softpipe/sp_prim_setup.c
deleted file mode 100644
index 038ff04d4f1..00000000000
--- a/src/gallium/drivers/softpipe/sp_prim_setup.c
+++ /dev/null
@@ -1,190 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \brief A draw stage that drives our triangle setup routines from
- * within the draw pipeline. One of two ways to drive setup, the
- * other being in sp_prim_vbuf.c.
- *
- * \author Keith Whitwell <[email protected]>
- * \author Brian Paul
- */
-
-
-#include "sp_context.h"
-#include "sp_setup.h"
-#include "sp_state.h"
-#include "sp_prim_setup.h"
-#include "draw/draw_pipe.h"
-#include "draw/draw_vertex.h"
-#include "util/u_memory.h"
-
-/**
- * Triangle setup info (derived from draw_stage).
- * Also used for line drawing (taking some liberties).
- */
-struct setup_stage {
- struct draw_stage stage; /**< This must be first (base class) */
-
- struct setup_context *setup;
-};
-
-
-
-/**
- * Basically a cast wrapper.
- */
-static INLINE struct setup_stage *setup_stage( struct draw_stage *stage )
-{
- return (struct setup_stage *)stage;
-}
-
-
-typedef const float (*cptrf4)[4];
-
-static void
-do_tri(struct draw_stage *stage, struct prim_header *prim)
-{
- struct setup_stage *setup = setup_stage( stage );
-
- setup_tri( setup->setup,
- (cptrf4)prim->v[0]->data,
- (cptrf4)prim->v[1]->data,
- (cptrf4)prim->v[2]->data );
-}
-
-static void
-do_line(struct draw_stage *stage, struct prim_header *prim)
-{
- struct setup_stage *setup = setup_stage( stage );
-
- setup_line( setup->setup,
- (cptrf4)prim->v[0]->data,
- (cptrf4)prim->v[1]->data );
-}
-
-static void
-do_point(struct draw_stage *stage, struct prim_header *prim)
-{
- struct setup_stage *setup = setup_stage( stage );
-
- setup_point( setup->setup,
- (cptrf4)prim->v[0]->data );
-}
-
-
-
-
-static void setup_begin( struct draw_stage *stage )
-{
- struct setup_stage *setup = setup_stage(stage);
-
- setup_prepare( setup->setup );
-
- stage->point = do_point;
- stage->line = do_line;
- stage->tri = do_tri;
-}
-
-
-static void setup_first_point( struct draw_stage *stage,
- struct prim_header *header )
-{
- setup_begin(stage);
- stage->point( stage, header );
-}
-
-static void setup_first_line( struct draw_stage *stage,
- struct prim_header *header )
-{
- setup_begin(stage);
- stage->line( stage, header );
-}
-
-
-static void setup_first_tri( struct draw_stage *stage,
- struct prim_header *header )
-{
- setup_begin(stage);
- stage->tri( stage, header );
-}
-
-
-
-static void setup_flush( struct draw_stage *stage,
- unsigned flags )
-{
- stage->point = setup_first_point;
- stage->line = setup_first_line;
- stage->tri = setup_first_tri;
-}
-
-
-static void reset_stipple_counter( struct draw_stage *stage )
-{
-}
-
-
-static void render_destroy( struct draw_stage *stage )
-{
- struct setup_stage *ssetup = setup_stage(stage);
- setup_destroy_context(ssetup->setup);
- FREE( stage );
-}
-
-
-/**
- * Create a new primitive setup/render stage.
- */
-struct draw_stage *sp_draw_render_stage( struct softpipe_context *softpipe )
-{
- struct setup_stage *sstage = CALLOC_STRUCT(setup_stage);
-
- sstage->setup = setup_create_context(softpipe);
- sstage->stage.draw = softpipe->draw;
- sstage->stage.point = setup_first_point;
- sstage->stage.line = setup_first_line;
- sstage->stage.tri = setup_first_tri;
- sstage->stage.flush = setup_flush;
- sstage->stage.reset_stipple_counter = reset_stipple_counter;
- sstage->stage.destroy = render_destroy;
-
- return (struct draw_stage *)sstage;
-}
-
-struct setup_context *
-sp_draw_setup_context( struct draw_stage *stage )
-{
- struct setup_stage *ssetup = setup_stage(stage);
- return ssetup->setup;
-}
-
-void
-sp_draw_flush( struct draw_stage *stage )
-{
- stage->flush( stage, 0 );
-}
diff --git a/src/gallium/drivers/softpipe/sp_prim_setup.h b/src/gallium/drivers/softpipe/sp_prim_setup.h
deleted file mode 100644
index 49bdd98ed87..00000000000
--- a/src/gallium/drivers/softpipe/sp_prim_setup.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-#ifndef SP_PRIM_SETUP_H
-#define SP_PRIM_SETUP_H
-
-
-/**
- * vbuf is a special stage to gather the stream of triangles, lines, points
- * together and reconstruct vertex buffers for hardware upload.
- *
- * First attempt, work in progress.
- *
- * TODO:
- * - separate out vertex buffer building and primitive emit, ie >1 draw per vb.
- * - tell vbuf stage how to build hw vertices directly
- * - pass vbuf stage a buffer pointer for direct emit to agp/vram.
- *
- *
- *
- * Vertices are just an array of floats, with all the attributes
- * packed. We currently assume a layout like:
- *
- * attr[0][0..3] - window position
- * attr[1..n][0..3] - remaining attributes.
- *
- * Attributes are assumed to be 4 floats wide but are packed so that
- * all the enabled attributes run contiguously.
- */
-
-
-struct draw_stage;
-struct softpipe_context;
-
-
-typedef void (*vbuf_draw_func)( struct pipe_context *pipe,
- unsigned prim,
- const ushort *elements,
- unsigned nr_elements,
- const void *vertex_buffer,
- unsigned nr_vertices );
-
-
-extern struct draw_stage *
-sp_draw_render_stage( struct softpipe_context *softpipe );
-
-extern struct setup_context *
-sp_draw_setup_context( struct draw_stage * );
-
-extern void
-sp_draw_flush( struct draw_stage * );
-
-
-extern struct draw_stage *
-sp_draw_vbuf_stage( struct draw_context *draw_context,
- struct pipe_context *pipe,
- vbuf_draw_func draw );
-
-
-#endif /* SP_PRIM_SETUP_H */
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.c b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
index 42021789ea8..e603c20fc4c 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.c
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.c
@@ -37,13 +37,13 @@
#include "sp_context.h"
+#include "sp_setup.h"
#include "sp_state.h"
#include "sp_prim_vbuf.h"
-#include "sp_prim_setup.h"
-#include "sp_setup.h"
#include "draw/draw_context.h"
#include "draw/draw_vbuf.h"
#include "util/u_memory.h"
+#include "util/u_prim.h"
#define SP_MAX_VBUF_INDEXES 1024
@@ -58,6 +58,8 @@ struct softpipe_vbuf_render
{
struct vbuf_render base;
struct softpipe_context *softpipe;
+ struct setup_context *setup;
+
uint prim;
uint vertex_size;
uint nr_vertices;
@@ -74,6 +76,11 @@ softpipe_vbuf_render(struct vbuf_render *vbr)
}
+
+
+
+
+
static const struct vertex_info *
sp_vbuf_get_vertex_info(struct vbuf_render *vbr)
{
@@ -104,36 +111,6 @@ sp_vbuf_allocate_vertices(struct vbuf_render *vbr,
static void
sp_vbuf_release_vertices(struct vbuf_render *vbr)
{
-#if 0
- {
- struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- const struct vertex_info *info =
- softpipe_get_vbuf_vertex_info(cvbr->softpipe);
- const float *vtx = (const float *) cvbr->vertex_buffer;
- uint i, j;
- debug_printf("%s (vtx_size = %u, vtx_used = %u)\n",
- __FUNCTION__, cvbr->vertex_size, cvbr->nr_vertices);
- for (i = 0; i < cvbr->nr_vertices; i++) {
- for (j = 0; j < info->num_attribs; j++) {
- uint k;
- switch (info->attrib[j].emit) {
- case EMIT_4F: k = 4; break;
- case EMIT_3F: k = 3; break;
- case EMIT_2F: k = 2; break;
- case EMIT_1F: k = 1; break;
- default: assert(0);
- }
- debug_printf("Vert %u attr %u: ", i, j);
- while (k-- > 0) {
- debug_printf("%g ", vtx[0]);
- vtx++;
- }
- debug_printf("\n");
- }
- }
- }
-#endif
-
/* keep the old allocation for next time */
}
@@ -159,14 +136,11 @@ static boolean
sp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
-
- /* XXX: break this dependency - make setup_context live under
- * softpipe, rename the old "setup" draw stage to something else.
- */
- struct setup_context *setup_ctx = sp_draw_setup_context(cvbr->softpipe->setup);
+ struct setup_context *setup_ctx = cvbr->setup;
setup_prepare( setup_ctx );
+ cvbr->softpipe->reduced_prim = u_reduced_prim(prim);
cvbr->prim = prim;
return TRUE;
@@ -191,14 +165,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
struct softpipe_context *softpipe = cvbr->softpipe;
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
const void *vertex_buffer = cvbr->vertex_buffer;
+ struct setup_context *setup_ctx = cvbr->setup;
unsigned i;
- /* XXX: break this dependency - make setup_context live under
- * softpipe, rename the old "setup" draw stage to something else.
- */
- struct draw_stage *setup = softpipe->setup;
- struct setup_context *setup_ctx = sp_draw_setup_context(setup);
-
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < nr; i++) {
@@ -237,14 +206,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_TRIANGLES:
- for (i = 2; i < nr; i += 3) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 3) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-1], stride),
get_vert(vertex_buffer, indices[i-0], stride),
get_vert(vertex_buffer, indices[i-2], stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i += 3) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-1], stride),
@@ -254,14 +225,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_TRIANGLE_STRIP:
- for (i = 2; i < nr; i += 1) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i+(i&1)-1], stride),
get_vert(vertex_buffer, indices[i-(i&1)], stride),
get_vert(vertex_buffer, indices[i-2], stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
@@ -271,14 +244,16 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- for (i = 2; i < nr; i += 1) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-0], stride),
get_vert(vertex_buffer, indices[0], stride),
get_vert(vertex_buffer, indices[i-1], stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[0], stride),
get_vert(vertex_buffer, indices[i-1], stride),
@@ -288,8 +263,8 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUADS:
- for (i = 3; i < nr; i += 4) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-2], stride),
get_vert(vertex_buffer, indices[i-1], stride),
@@ -299,7 +274,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
get_vert(vertex_buffer, indices[i-0], stride),
get_vert(vertex_buffer, indices[i-3], stride) );
}
- else {
+ }
+ else {
+ for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
@@ -314,8 +291,8 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
break;
case PIPE_PRIM_QUAD_STRIP:
- for (i = 3; i < nr; i += 2) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 2) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-0], stride),
get_vert(vertex_buffer, indices[i-1], stride),
@@ -325,7 +302,9 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
get_vert(vertex_buffer, indices[i-0], stride),
get_vert(vertex_buffer, indices[i-3], stride) );
}
- else {
+ }
+ else {
+ for (i = 3; i < nr; i += 2) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, indices[i-3], stride),
get_vert(vertex_buffer, indices[i-2], stride),
@@ -355,11 +334,6 @@ sp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
default:
assert(0);
}
-
- /* XXX: why are we calling this??? If we had to call something, it
- * would be a function in sp_setup.c:
- */
- sp_draw_flush( setup );
}
@@ -372,17 +346,12 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
struct softpipe_context *softpipe = cvbr->softpipe;
+ struct setup_context *setup_ctx = cvbr->setup;
const unsigned stride = softpipe->vertex_info_vbuf.size * sizeof(float);
const void *vertex_buffer =
(void *) get_vert(cvbr->vertex_buffer, start, stride);
unsigned i;
- /* XXX: break this dependency - make setup_context live under
- * softpipe, rename the old "setup" draw stage to something else.
- */
- struct draw_stage *setup = softpipe->setup;
- struct setup_context *setup_ctx = sp_draw_setup_context(setup);
-
switch (cvbr->prim) {
case PIPE_PRIM_POINTS:
for (i = 0; i < nr; i++) {
@@ -421,14 +390,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_TRIANGLES:
- for (i = 2; i < nr; i += 3) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 3) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-1, stride),
get_vert(vertex_buffer, i-0, stride),
get_vert(vertex_buffer, i-2, stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i += 3) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-1, stride),
@@ -438,14 +409,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_TRIANGLE_STRIP:
- for (i = 2; i < nr; i++) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i++) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i+(i&1)-1, stride),
get_vert(vertex_buffer, i-(i&1), stride),
get_vert(vertex_buffer, i-2, stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i++) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i+(i&1)-2, stride),
get_vert(vertex_buffer, i-(i&1)-1, stride),
@@ -455,14 +428,16 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_TRIANGLE_FAN:
- for (i = 2; i < nr; i += 1) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-0, stride),
get_vert(vertex_buffer, 0, stride),
get_vert(vertex_buffer, i-1, stride) );
}
- else {
+ }
+ else {
+ for (i = 2; i < nr; i += 1) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, 0, stride),
get_vert(vertex_buffer, i-1, stride),
@@ -472,8 +447,8 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUADS:
- for (i = 3; i < nr; i += 4) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-2, stride),
get_vert(vertex_buffer, i-1, stride),
@@ -483,7 +458,9 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
get_vert(vertex_buffer, i-0, stride),
get_vert(vertex_buffer, i-3, stride) );
}
- else {
+ }
+ else {
+ for (i = 3; i < nr; i += 4) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
@@ -497,8 +474,8 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
break;
case PIPE_PRIM_QUAD_STRIP:
- for (i = 3; i < nr; i += 2) {
- if (softpipe->rasterizer->flatshade_first) {
+ if (softpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 2) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-0, stride),
get_vert(vertex_buffer, i-1, stride),
@@ -508,7 +485,9 @@ sp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
get_vert(vertex_buffer, i-0, stride),
get_vert(vertex_buffer, i-3, stride) );
}
- else {
+ }
+ else {
+ for (i = 3; i < nr; i += 2) {
setup_tri( setup_ctx,
get_vert(vertex_buffer, i-3, stride),
get_vert(vertex_buffer, i-2, stride),
@@ -546,40 +525,38 @@ static void
sp_vbuf_destroy(struct vbuf_render *vbr)
{
struct softpipe_vbuf_render *cvbr = softpipe_vbuf_render(vbr);
- cvbr->softpipe->vbuf_render = NULL;
+ setup_destroy_context(cvbr->setup);
FREE(cvbr);
}
/**
- * Initialize the post-transform vertex buffer information for the given
- * context.
+ * Create the post-transform vertex handler for the given context.
*/
-void
-sp_init_vbuf(struct softpipe_context *sp)
+struct vbuf_render *
+sp_create_vbuf_backend(struct softpipe_context *sp)
{
- assert(sp->draw);
+ struct softpipe_vbuf_render *cvbr = CALLOC_STRUCT(softpipe_vbuf_render);
- sp->vbuf_render = CALLOC_STRUCT(softpipe_vbuf_render);
+ assert(sp->draw);
- sp->vbuf_render->base.max_indices = SP_MAX_VBUF_INDEXES;
- sp->vbuf_render->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
- sp->vbuf_render->base.get_vertex_info = sp_vbuf_get_vertex_info;
- sp->vbuf_render->base.allocate_vertices = sp_vbuf_allocate_vertices;
- sp->vbuf_render->base.map_vertices = sp_vbuf_map_vertices;
- sp->vbuf_render->base.unmap_vertices = sp_vbuf_unmap_vertices;
- sp->vbuf_render->base.set_primitive = sp_vbuf_set_primitive;
- sp->vbuf_render->base.draw = sp_vbuf_draw;
- sp->vbuf_render->base.draw_arrays = sp_vbuf_draw_arrays;
- sp->vbuf_render->base.release_vertices = sp_vbuf_release_vertices;
- sp->vbuf_render->base.destroy = sp_vbuf_destroy;
+ cvbr->base.max_indices = SP_MAX_VBUF_INDEXES;
+ cvbr->base.max_vertex_buffer_bytes = SP_MAX_VBUF_SIZE;
- sp->vbuf_render->softpipe = sp;
+ cvbr->base.get_vertex_info = sp_vbuf_get_vertex_info;
+ cvbr->base.allocate_vertices = sp_vbuf_allocate_vertices;
+ cvbr->base.map_vertices = sp_vbuf_map_vertices;
+ cvbr->base.unmap_vertices = sp_vbuf_unmap_vertices;
+ cvbr->base.set_primitive = sp_vbuf_set_primitive;
+ cvbr->base.draw = sp_vbuf_draw;
+ cvbr->base.draw_arrays = sp_vbuf_draw_arrays;
+ cvbr->base.release_vertices = sp_vbuf_release_vertices;
+ cvbr->base.destroy = sp_vbuf_destroy;
- sp->vbuf = draw_vbuf_stage(sp->draw, &sp->vbuf_render->base);
+ cvbr->softpipe = sp;
- draw_set_rasterize_stage(sp->draw, sp->vbuf);
+ cvbr->setup = setup_create_context(cvbr->softpipe);
- draw_set_render(sp->draw, &sp->vbuf_render->base);
+ return &cvbr->base;
}
diff --git a/src/gallium/drivers/softpipe/sp_prim_vbuf.h b/src/gallium/drivers/softpipe/sp_prim_vbuf.h
index 1de9cc2a894..ad01cc2f289 100644
--- a/src/gallium/drivers/softpipe/sp_prim_vbuf.h
+++ b/src/gallium/drivers/softpipe/sp_prim_vbuf.h
@@ -31,8 +31,8 @@
struct softpipe_context;
-extern void
-sp_init_vbuf(struct softpipe_context *softpipe);
+extern struct vbuf_render *
+sp_create_vbuf_backend(struct softpipe_context *softpipe);
#endif /* SP_VBUF_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad.h b/src/gallium/drivers/softpipe/sp_quad.h
index bd6c6cb9123..a3236bd1169 100644
--- a/src/gallium/drivers/softpipe/sp_quad.h
+++ b/src/gallium/drivers/softpipe/sp_quad.h
@@ -97,10 +97,10 @@ struct quad_header {
struct quad_header_inout inout;
struct quad_header_output output;
- const struct tgsi_interp_coef *coef;
+ /* Redundant/duplicated:
+ */
const struct tgsi_interp_coef *posCoef;
-
- unsigned nr_attrs;
+ const struct tgsi_interp_coef *coef;
};
#endif /* SP_QUAD_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c b/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
deleted file mode 100644
index 0845bae0e68..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_alpha_test.c
+++ /dev/null
@@ -1,108 +0,0 @@
-
-/**
- * quad alpha test
- */
-
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_quad_pipe.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-
-
-static void
-alpha_test_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
- const float ref = softpipe->depth_stencil->alpha.ref_value;
- unsigned passMask = 0x0, j;
- const uint cbuf = 0; /* only output[0].alpha is tested */
- const float *aaaa = quad->output.color[cbuf][3];
-
- switch (softpipe->depth_stencil->alpha.func) {
- case PIPE_FUNC_NEVER:
- break;
- case PIPE_FUNC_LESS:
- /*
- * If mask were an array [4] we could do this SIMD-style:
- * passMask = (quad->outputs.color[0][3] <= vec4(ref));
- */
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] < ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_EQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] == ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_LEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] <= ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_GREATER:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] > ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_NOTEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] != ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_GEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (aaaa[j] >= ref) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_ALWAYS:
- passMask = MASK_ALL;
- break;
- default:
- assert(0);
- }
-
- quad->inout.mask &= passMask;
-
- if (quad->inout.mask)
- qs->next->run(qs->next, quad);
-}
-
-
-static void alpha_test_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void alpha_test_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *
-sp_quad_alpha_test_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = alpha_test_begin;
- stage->run = alpha_test_quad;
- stage->destroy = alpha_test_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_blend.c b/src/gallium/drivers/softpipe/sp_quad_blend.c
index b1e18805c70..e243c63fa23 100644
--- a/src/gallium/drivers/softpipe/sp_quad_blend.c
+++ b/src/gallium/drivers/softpipe/sp_quad_blend.c
@@ -117,644 +117,865 @@ do { \
static void
-logicop_quad(struct quad_stage *qs, struct quad_header *quad)
+logicop_quad(struct quad_stage *qs,
+ float (*quadColor)[4],
+ float (*dest)[4])
{
struct softpipe_context *softpipe = qs->softpipe;
- uint cbuf;
+ ubyte src[4][4], dst[4][4], res[4][4];
+ uint *src4 = (uint *) src;
+ uint *dst4 = (uint *) dst;
+ uint *res4 = (uint *) res;
+ uint j;
+
+
+ /* convert to ubyte */
+ for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
+ dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
+ dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
+ dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
+ dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
+
+ src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
+ src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
+ src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
+ src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
+ }
- /* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
- float dest[4][QUAD_SIZE];
- ubyte src[4][4], dst[4][4], res[4][4];
- uint *src4 = (uint *) src;
- uint *dst4 = (uint *) dst;
- uint *res4 = (uint *) res;
- struct softpipe_cached_tile *
- tile = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[cbuf],
- quad->input.x0, quad->input.y0);
- float (*quadColor)[4] = quad->output.color[cbuf];
- uint i, j;
+ switch (softpipe->blend->logicop_func) {
+ case PIPE_LOGICOP_CLEAR:
+ for (j = 0; j < 4; j++)
+ res4[j] = 0;
+ break;
+ case PIPE_LOGICOP_NOR:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] | dst4[j]);
+ break;
+ case PIPE_LOGICOP_AND_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j] & dst4[j];
+ break;
+ case PIPE_LOGICOP_COPY_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j];
+ break;
+ case PIPE_LOGICOP_AND_REVERSE:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] & ~dst4[j];
+ break;
+ case PIPE_LOGICOP_INVERT:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~dst4[j];
+ break;
+ case PIPE_LOGICOP_XOR:
+ for (j = 0; j < 4; j++)
+ res4[j] = dst4[j] ^ src4[j];
+ break;
+ case PIPE_LOGICOP_NAND:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] & dst4[j]);
+ break;
+ case PIPE_LOGICOP_AND:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] & dst4[j];
+ break;
+ case PIPE_LOGICOP_EQUIV:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~(src4[j] ^ dst4[j]);
+ break;
+ case PIPE_LOGICOP_NOOP:
+ for (j = 0; j < 4; j++)
+ res4[j] = dst4[j];
+ break;
+ case PIPE_LOGICOP_OR_INVERTED:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~src4[j] | dst4[j];
+ break;
+ case PIPE_LOGICOP_COPY:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j];
+ break;
+ case PIPE_LOGICOP_OR_REVERSE:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] | ~dst4[j];
+ break;
+ case PIPE_LOGICOP_OR:
+ for (j = 0; j < 4; j++)
+ res4[j] = src4[j] | dst4[j];
+ break;
+ case PIPE_LOGICOP_SET:
+ for (j = 0; j < 4; j++)
+ res4[j] = ~0;
+ break;
+ default:
+ assert(0);
+ }
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
- }
- }
+ for (j = 0; j < 4; j++) {
+ quadColor[j][0] = ubyte_to_float(res[j][0]);
+ quadColor[j][1] = ubyte_to_float(res[j][1]);
+ quadColor[j][2] = ubyte_to_float(res[j][2]);
+ quadColor[j][3] = ubyte_to_float(res[j][3]);
+ }
+}
- /* convert to ubyte */
- for (j = 0; j < 4; j++) { /* loop over R,G,B,A channels */
- dst[j][0] = float_to_ubyte(dest[j][0]); /* P0 */
- dst[j][1] = float_to_ubyte(dest[j][1]); /* P1 */
- dst[j][2] = float_to_ubyte(dest[j][2]); /* P2 */
- dst[j][3] = float_to_ubyte(dest[j][3]); /* P3 */
-
- src[j][0] = float_to_ubyte(quadColor[j][0]); /* P0 */
- src[j][1] = float_to_ubyte(quadColor[j][1]); /* P1 */
- src[j][2] = float_to_ubyte(quadColor[j][2]); /* P2 */
- src[j][3] = float_to_ubyte(quadColor[j][3]); /* P3 */
- }
- switch (softpipe->blend->logicop_func) {
- case PIPE_LOGICOP_CLEAR:
- for (j = 0; j < 4; j++)
- res4[j] = 0;
- break;
- case PIPE_LOGICOP_NOR:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] | dst4[j]);
- break;
- case PIPE_LOGICOP_AND_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j] & dst4[j];
- break;
- case PIPE_LOGICOP_COPY_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j];
- break;
- case PIPE_LOGICOP_AND_REVERSE:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] & ~dst4[j];
- break;
- case PIPE_LOGICOP_INVERT:
- for (j = 0; j < 4; j++)
- res4[j] = ~dst4[j];
- break;
- case PIPE_LOGICOP_XOR:
- for (j = 0; j < 4; j++)
- res4[j] = dst4[j] ^ src4[j];
- break;
- case PIPE_LOGICOP_NAND:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] & dst4[j]);
- break;
- case PIPE_LOGICOP_AND:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] & dst4[j];
- break;
- case PIPE_LOGICOP_EQUIV:
- for (j = 0; j < 4; j++)
- res4[j] = ~(src4[j] ^ dst4[j]);
- break;
- case PIPE_LOGICOP_NOOP:
- for (j = 0; j < 4; j++)
- res4[j] = dst4[j];
- break;
- case PIPE_LOGICOP_OR_INVERTED:
- for (j = 0; j < 4; j++)
- res4[j] = ~src4[j] | dst4[j];
- break;
- case PIPE_LOGICOP_COPY:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j];
- break;
- case PIPE_LOGICOP_OR_REVERSE:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] | ~dst4[j];
- break;
- case PIPE_LOGICOP_OR:
- for (j = 0; j < 4; j++)
- res4[j] = src4[j] | dst4[j];
- break;
- case PIPE_LOGICOP_SET:
- for (j = 0; j < 4; j++)
- res4[j] = ~0;
- break;
- default:
- assert(0);
- }
- for (j = 0; j < 4; j++) {
- quadColor[j][0] = ubyte_to_float(res[j][0]);
- quadColor[j][1] = ubyte_to_float(res[j][1]);
- quadColor[j][2] = ubyte_to_float(res[j][2]);
- quadColor[j][3] = ubyte_to_float(res[j][3]);
- }
+static void
+blend_quad(struct quad_stage *qs,
+ float (*quadColor)[4],
+ float (*dest)[4])
+{
+ static const float zero[4] = { 0, 0, 0, 0 };
+ static const float one[4] = { 1, 1, 1, 1 };
+ struct softpipe_context *softpipe = qs->softpipe;
+ float source[4][QUAD_SIZE];
+
+ /*
+ * Compute src/first term RGB
+ */
+ switch (softpipe->blend->rgb_src_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ VEC4_COPY(source[0], quadColor[0]); /* R */
+ VEC4_COPY(source[1], quadColor[1]); /* G */
+ VEC4_COPY(source[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
+ VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
+ VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ {
+ const float *alpha = quadColor[3];
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
+ VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
+ VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ {
+ const float *alpha = dest[3];
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ {
+ const float *alpha = quadColor[3];
+ float diff[4], temp[4];
+ VEC4_SUB(diff, one, dest[3]);
+ VEC4_MIN(temp, alpha, diff);
+ VEC4_MUL(source[0], quadColor[0], temp); /* R */
+ VEC4_MUL(source[1], quadColor[1], temp); /* G */
+ VEC4_MUL(source[2], quadColor[2], temp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], comp); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], comp); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float alpha[4];
+ VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(source[0], zero); /* R */
+ VEC4_COPY(source[1], zero); /* G */
+ VEC4_COPY(source[2], zero); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, quadColor[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[0]); /* R */
+ VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, dest[1]); /* G */
+ VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, dest[2]); /* B */
+ VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ {
+ float inv_comp[4];
+ /* R */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_MUL(source[0], quadColor[0], inv_comp);
+ /* G */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_MUL(source[1], quadColor[1], inv_comp);
+ /* B */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_MUL(source[2], quadColor[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ assert(0); /* to do */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ assert(0); /* to do */
+ break;
+ default:
+ assert(0);
+ }
+
+ /*
+ * Compute src/first term A
+ */
+ switch (softpipe->blend->alpha_src_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ VEC4_COPY(source[3], quadColor[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ {
+ const float *alpha = quadColor[3];
+ VEC4_MUL(source[3], quadColor[3], alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ /* multiply alpha by 1.0 */
+ VEC4_COPY(source[3], quadColor[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(source[3], quadColor[3], comp); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(source[3], zero); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, quadColor[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_alpha[4];
+ VEC4_SUB(inv_alpha, one, dest[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ /* A */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(source[3], quadColor[3], inv_comp);
+ }
+ break;
+ default:
+ assert(0);
}
- /* pass quad to next stage */
- qs->next->run(qs->next, quad);
-}
+ /*
+ * Compute dest/second term RGB
+ */
+ switch (softpipe->blend->rgb_dst_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
+ VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
+ VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
+ VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
+ VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
+ VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
+ VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
+ VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
+ VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ assert(0); /* illegal */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
+ VEC4_MUL(dest[0], dest[0], comp); /* R */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
+ VEC4_MUL(dest[1], dest[1], comp); /* G */
+ VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
+ VEC4_MUL(dest[2], dest[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(dest[0], dest[0], comp); /* R */
+ VEC4_MUL(dest[1], dest[1], comp); /* G */
+ VEC4_MUL(dest[2], dest[2], comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(dest[0], zero); /* R */
+ VEC4_COPY(dest[1], zero); /* G */
+ VEC4_COPY(dest[2], zero); /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ /* XXX what are these? */
+ assert(0);
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
+ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+ VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
+ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+ VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
+ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float one_minus_alpha[QUAD_SIZE];
+ VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+ VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
+ VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
+ VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[3]); /* A */
+ VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
+ VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
+ VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[0]); /* R */
+ VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
+ VEC4_SUB(inv_comp, one, dest[1]); /* G */
+ VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
+ VEC4_SUB(inv_comp, one, dest[2]); /* B */
+ VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ {
+ float inv_comp[4];
+ /* R */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
+ VEC4_MUL(dest[0], dest[0], inv_comp);
+ /* G */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
+ VEC4_MUL(dest[1], dest[1], inv_comp);
+ /* B */
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
+ VEC4_MUL(dest[2], dest[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(dest[0], dest[0], inv_comp);
+ VEC4_MUL(dest[1], dest[1], inv_comp);
+ VEC4_MUL(dest[2], dest[2], inv_comp);
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ /* XXX what are these? */
+ assert(0);
+ break;
+ default:
+ assert(0);
+ }
+ /*
+ * Compute dest/second term A
+ */
+ switch (softpipe->blend->alpha_dst_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ /* dest = dest * 1 NO-OP, leave dest as-is */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ assert(0); /* illegal */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ {
+ float comp[4];
+ VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
+ VEC4_MUL(dest[3], dest[3], comp); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ VEC4_COPY(dest[3], zero); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ {
+ float one_minus_alpha[QUAD_SIZE];
+ VEC4_SUB(one_minus_alpha, one, quadColor[3]);
+ VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SUB(inv_comp, one, dest[3]); /* A */
+ VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
+ }
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ /* fall-through */
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ {
+ float inv_comp[4];
+ VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
+ VEC4_MUL(dest[3], dest[3], inv_comp);
+ }
+ break;
+ default:
+ assert(0);
+ }
+ /*
+ * Combine RGB terms
+ */
+ switch (softpipe->blend->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 */
+ VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
+ VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
+ VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
+ break;
+ case PIPE_BLEND_MIN:
+ VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ case PIPE_BLEND_MAX:
+ VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
+ break;
+ default:
+ assert(0);
+ }
+
+ /*
+ * Combine A terms
+ */
+ switch (softpipe->blend->alpha_func) {
+ case PIPE_BLEND_ADD:
+ VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
+ break;
+ case PIPE_BLEND_MIN:
+ VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ case PIPE_BLEND_MAX:
+ VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
+ break;
+ default:
+ assert(0);
+ }
+}
static void
-blend_quad(struct quad_stage *qs, struct quad_header *quad)
+colormask_quad(struct quad_stage *qs,
+ float (*quadColor)[4],
+ float (*dest)[4])
{
- static const float zero[4] = { 0, 0, 0, 0 };
- static const float one[4] = { 1, 1, 1, 1 };
+ struct softpipe_context *softpipe = qs->softpipe;
+ /* R */
+ if (!(softpipe->blend->colormask & PIPE_MASK_R))
+ COPY_4V(quadColor[0], dest[0]);
+
+ /* G */
+ if (!(softpipe->blend->colormask & PIPE_MASK_G))
+ COPY_4V(quadColor[1], dest[1]);
+
+ /* B */
+ if (!(softpipe->blend->colormask & PIPE_MASK_B))
+ COPY_4V(quadColor[2], dest[2]);
+
+ /* A */
+ if (!(softpipe->blend->colormask & PIPE_MASK_A))
+ COPY_4V(quadColor[3], dest[3]);
+}
+
+
+static void
+blend_fallback(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
struct softpipe_context *softpipe = qs->softpipe;
- uint cbuf;
+ const struct pipe_blend_state *blend = softpipe->blend;
+ unsigned cbuf;
+
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++)
+ {
+ float dest[4][QUAD_SIZE];
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(softpipe->cbuf_cache[cbuf],
+ quads[0]->input.x0,
+ quads[0]->input.y0);
+ uint q, i, j;
+
+ for (q = 0; q < nr; q++) {
+ struct quad_header *quad = quads[q];
+ float (*quadColor)[4] = quad->output.color[cbuf];
+ const int itx = (quad->input.x0 & (TILE_SIZE-1));
+ const int ity = (quad->input.y0 & (TILE_SIZE-1));
+
+ /* get/swizzle dest colors
+ */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) {
+ dest[i][j] = tile->data.color[y][x][i];
+ }
+ }
- if (softpipe->blend->logicop_enable) {
- logicop_quad(qs, quad);
- return;
+
+ if (blend->logicop_enable) {
+ logicop_quad( qs, quadColor, dest );
+ }
+ else if (blend->blend_enable) {
+ blend_quad( qs, quadColor, dest );
+ }
+
+ if (blend->colormask != 0xf)
+ colormask_quad( qs, quadColor, dest );
+
+ /* Output color values
+ */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->inout.mask & (1 << j)) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) { /* loop over color chans */
+ tile->data.color[y][x][i] = quadColor[i][j];
+ }
+ }
+ }
+ }
}
+}
- /* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
- float source[4][QUAD_SIZE], dest[4][QUAD_SIZE];
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[cbuf],
- quad->input.x0, quad->input.y0);
- float (*quadColor)[4] = quad->output.color[cbuf];
- uint i, j;
+static void
+blend_single_add_src_alpha_inv_src_alpha(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ static const float one[4] = { 1, 1, 1, 1 };
+ float one_minus_alpha[QUAD_SIZE];
+ float dest[4][QUAD_SIZE];
+ float source[4][QUAD_SIZE];
+ uint i, j, q;
+
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
+ quads[0]->input.x0,
+ quads[0]->input.y0);
+
+ for (q = 0; q < nr; q++) {
+ struct quad_header *quad = quads[q];
+ float (*quadColor)[4] = quad->output.color[0];
+ const float *alpha = quadColor[3];
+ const int itx = (quad->input.x0 & (TILE_SIZE-1));
+ const int ity = (quad->input.y0 & (TILE_SIZE-1));
+
/* get/swizzle dest colors */
for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
for (i = 0; i < 4; i++) {
dest[i][j] = tile->data.color[y][x][i];
}
}
- /*
- * Compute src/first term RGB
- */
- switch (softpipe->blend->rgb_src_factor) {
- case PIPE_BLENDFACTOR_ONE:
- VEC4_COPY(source[0], quadColor[0]); /* R */
- VEC4_COPY(source[1], quadColor[1]); /* G */
- VEC4_COPY(source[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- VEC4_MUL(source[0], quadColor[0], quadColor[0]); /* R */
- VEC4_MUL(source[1], quadColor[1], quadColor[1]); /* G */
- VEC4_MUL(source[2], quadColor[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- {
- const float *alpha = quadColor[3];
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- VEC4_MUL(source[0], quadColor[0], dest[0]); /* R */
- VEC4_MUL(source[1], quadColor[1], dest[1]); /* G */
- VEC4_MUL(source[2], quadColor[2], dest[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- {
- const float *alpha = dest[3];
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- {
- const float *alpha = quadColor[3];
- float diff[4], temp[4];
- VEC4_SUB(diff, one, dest[3]);
- VEC4_MIN(temp, alpha, diff);
- VEC4_MUL(source[0], quadColor[0], temp); /* R */
- VEC4_MUL(source[1], quadColor[1], temp); /* G */
- VEC4_MUL(source[2], quadColor[2], temp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float alpha[4];
- VEC4_SCALAR(alpha, softpipe->blend_color.color[3]);
- VEC4_MUL(source[0], quadColor[0], alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(source[0], zero); /* R */
- VEC4_COPY(source[1], zero); /* G */
- VEC4_COPY(source[2], zero); /* B */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, quadColor[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[0]); /* R */
- VEC4_MUL(source[0], quadColor[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, dest[1]); /* G */
- VEC4_MUL(source[1], quadColor[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, dest[2]); /* B */
- VEC4_MUL(source[2], quadColor[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- {
- float inv_comp[4];
- /* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
- VEC4_MUL(source[0], quadColor[0], inv_comp);
- /* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
- VEC4_MUL(source[1], quadColor[1], inv_comp);
- /* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
- VEC4_MUL(source[2], quadColor[2], inv_comp);
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SCALAR(inv_alpha, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(source[0], quadColor[0], inv_alpha); /* R */
- VEC4_MUL(source[1], quadColor[1], inv_alpha); /* G */
- VEC4_MUL(source[2], quadColor[2], inv_alpha); /* B */
+ VEC4_MUL(source[0], quadColor[0], alpha); /* R */
+ VEC4_MUL(source[1], quadColor[1], alpha); /* G */
+ VEC4_MUL(source[2], quadColor[2], alpha); /* B */
+ VEC4_MUL(source[3], quadColor[3], alpha); /* A */
+
+ VEC4_SUB(one_minus_alpha, one, alpha);
+ VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
+ VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
+ VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
+ VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* B */
+
+ VEC4_ADD_SAT(quadColor[0], source[0], dest[0]); /* R */
+ VEC4_ADD_SAT(quadColor[1], source[1], dest[1]); /* G */
+ VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
+ VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->inout.mask & (1 << j)) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) { /* loop over color chans */
+ tile->data.color[y][x][i] = quadColor[i][j];
+ }
}
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- assert(0); /* to do */
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- assert(0); /* to do */
- break;
- default:
- assert(0);
}
+ }
+}
- /*
- * Compute src/first term A
- */
- switch (softpipe->blend->alpha_src_factor) {
- case PIPE_BLENDFACTOR_ONE:
- VEC4_COPY(source[3], quadColor[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- {
- const float *alpha = quadColor[3];
- VEC4_MUL(source[3], quadColor[3], alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(source[3], quadColor[3], dest[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- /* multiply alpha by 1.0 */
- VEC4_COPY(source[3], quadColor[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(source[3], quadColor[3], comp); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(source[3], zero); /* A */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, quadColor[3]);
- VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_alpha[4];
- VEC4_SUB(inv_alpha, one, dest[3]);
- VEC4_MUL(source[3], quadColor[3], inv_alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- /* A */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(source[3], quadColor[3], inv_comp);
+static void
+blend_single_add_one_one(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ float dest[4][QUAD_SIZE];
+ uint i, j, q;
+
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
+ quads[0]->input.x0,
+ quads[0]->input.y0);
+
+ for (q = 0; q < nr; q++) {
+ struct quad_header *quad = quads[q];
+ float (*quadColor)[4] = quad->output.color[0];
+ const int itx = (quad->input.x0 & (TILE_SIZE-1));
+ const int ity = (quad->input.y0 & (TILE_SIZE-1));
+
+ /* get/swizzle dest colors */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) {
+ dest[i][j] = tile->data.color[y][x][i];
}
- break;
- default:
- assert(0);
}
+
+ VEC4_ADD_SAT(quadColor[0], quadColor[0], dest[0]); /* R */
+ VEC4_ADD_SAT(quadColor[1], quadColor[1], dest[1]); /* G */
+ VEC4_ADD_SAT(quadColor[2], quadColor[2], dest[2]); /* B */
+ VEC4_ADD_SAT(quadColor[3], quadColor[3], dest[3]); /* A */
-
- /*
- * Compute dest/second term RGB
- */
- switch (softpipe->blend->rgb_dst_factor) {
- case PIPE_BLENDFACTOR_ONE:
- /* dest = dest * 1 NO-OP, leave dest as-is */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- VEC4_MUL(dest[0], dest[0], quadColor[0]); /* R */
- VEC4_MUL(dest[1], dest[1], quadColor[1]); /* G */
- VEC4_MUL(dest[2], dest[2], quadColor[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- VEC4_MUL(dest[0], dest[0], quadColor[3]); /* R * A */
- VEC4_MUL(dest[1], dest[1], quadColor[3]); /* G * A */
- VEC4_MUL(dest[2], dest[2], quadColor[3]); /* B * A */
- break;
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[0], dest[0], dest[3]); /* R * A */
- VEC4_MUL(dest[1], dest[1], dest[3]); /* G * A */
- VEC4_MUL(dest[2], dest[2], dest[3]); /* B * A */
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- VEC4_MUL(dest[0], dest[0], dest[0]); /* R */
- VEC4_MUL(dest[1], dest[1], dest[1]); /* G */
- VEC4_MUL(dest[2], dest[2], dest[2]); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- assert(0); /* illegal */
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[0]); /* R */
- VEC4_MUL(dest[0], dest[0], comp); /* R */
- VEC4_SCALAR(comp, softpipe->blend_color.color[1]); /* G */
- VEC4_MUL(dest[1], dest[1], comp); /* G */
- VEC4_SCALAR(comp, softpipe->blend_color.color[2]); /* B */
- VEC4_MUL(dest[2], dest[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(dest[0], dest[0], comp); /* R */
- VEC4_MUL(dest[1], dest[1], comp); /* G */
- VEC4_MUL(dest[2], dest[2], comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(dest[0], zero); /* R */
- VEC4_COPY(dest[1], zero); /* G */
- VEC4_COPY(dest[2], zero); /* B */
- break;
- case PIPE_BLENDFACTOR_SRC1_COLOR:
- case PIPE_BLENDFACTOR_SRC1_ALPHA:
- /* XXX what are these? */
- assert(0);
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, quadColor[0]); /* R */
- VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
- VEC4_SUB(inv_comp, one, quadColor[1]); /* G */
- VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
- VEC4_SUB(inv_comp, one, quadColor[2]); /* B */
- VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float one_minus_alpha[QUAD_SIZE];
- VEC4_SUB(one_minus_alpha, one, quadColor[3]);
- VEC4_MUL(dest[0], dest[0], one_minus_alpha); /* R */
- VEC4_MUL(dest[1], dest[1], one_minus_alpha); /* G */
- VEC4_MUL(dest[2], dest[2], one_minus_alpha); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[3]); /* A */
- VEC4_MUL(dest[0], inv_comp, dest[0]); /* R */
- VEC4_MUL(dest[1], inv_comp, dest[1]); /* G */
- VEC4_MUL(dest[2], inv_comp, dest[2]); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[0]); /* R */
- VEC4_MUL(dest[0], dest[0], inv_comp); /* R */
- VEC4_SUB(inv_comp, one, dest[1]); /* G */
- VEC4_MUL(dest[1], dest[1], inv_comp); /* G */
- VEC4_SUB(inv_comp, one, dest[2]); /* B */
- VEC4_MUL(dest[2], dest[2], inv_comp); /* B */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- {
- float inv_comp[4];
- /* R */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[0]);
- VEC4_MUL(dest[0], dest[0], inv_comp);
- /* G */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[1]);
- VEC4_MUL(dest[1], dest[1], inv_comp);
- /* B */
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[2]);
- VEC4_MUL(dest[2], dest[2], inv_comp);
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(dest[0], dest[0], inv_comp);
- VEC4_MUL(dest[1], dest[1], inv_comp);
- VEC4_MUL(dest[2], dest[2], inv_comp);
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->inout.mask & (1 << j)) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) { /* loop over color chans */
+ tile->data.color[y][x][i] = quadColor[i][j];
+ }
}
- break;
- case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
- case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
- /* XXX what are these? */
- assert(0);
- break;
- default:
- assert(0);
}
+ }
+}
- /*
- * Compute dest/second term A
- */
- switch (softpipe->blend->alpha_dst_factor) {
- case PIPE_BLENDFACTOR_ONE:
- /* dest = dest * 1 NO-OP, leave dest as-is */
- break;
- case PIPE_BLENDFACTOR_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_SRC_ALPHA:
- VEC4_MUL(dest[3], dest[3], quadColor[3]); /* A * A */
- break;
- case PIPE_BLENDFACTOR_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_DST_ALPHA:
- VEC4_MUL(dest[3], dest[3], dest[3]); /* A */
- break;
- case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
- assert(0); /* illegal */
- break;
- case PIPE_BLENDFACTOR_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_CONST_ALPHA:
- {
- float comp[4];
- VEC4_SCALAR(comp, softpipe->blend_color.color[3]); /* A */
- VEC4_MUL(dest[3], dest[3], comp); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_ZERO:
- VEC4_COPY(dest[3], zero); /* A */
- break;
- case PIPE_BLENDFACTOR_INV_SRC_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
- {
- float one_minus_alpha[QUAD_SIZE];
- VEC4_SUB(one_minus_alpha, one, quadColor[3]);
- VEC4_MUL(dest[3], dest[3], one_minus_alpha); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_DST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_DST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SUB(inv_comp, one, dest[3]); /* A */
- VEC4_MUL(dest[3], inv_comp, dest[3]); /* A */
- }
- break;
- case PIPE_BLENDFACTOR_INV_CONST_COLOR:
- /* fall-through */
- case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
- {
- float inv_comp[4];
- VEC4_SCALAR(inv_comp, 1.0f - softpipe->blend_color.color[3]);
- VEC4_MUL(dest[3], dest[3], inv_comp);
+
+static void
+single_output_color(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ uint i, j, q;
+
+ struct softpipe_cached_tile *tile
+ = sp_get_cached_tile(qs->softpipe->cbuf_cache[0],
+ quads[0]->input.x0,
+ quads[0]->input.y0);
+
+ for (q = 0; q < nr; q++) {
+ struct quad_header *quad = quads[q];
+ float (*quadColor)[4] = quad->output.color[0];
+ const int itx = (quad->input.x0 & (TILE_SIZE-1));
+ const int ity = (quad->input.y0 & (TILE_SIZE-1));
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (quad->inout.mask & (1 << j)) {
+ int x = itx + (j & 1);
+ int y = ity + (j >> 1);
+ for (i = 0; i < 4; i++) { /* loop over color chans */
+ tile->data.color[y][x][i] = quadColor[i][j];
+ }
}
- break;
- default:
- assert(0);
}
+ }
+}
+
+static void
+blend_noop(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+}
- /*
- * Combine RGB terms
- */
- switch (softpipe->blend->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 */
- VEC4_ADD_SAT(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_SUBTRACT:
- VEC4_SUB_SAT(quadColor[0], source[0], dest[0]); /* R */
- VEC4_SUB_SAT(quadColor[1], source[1], dest[1]); /* G */
- VEC4_SUB_SAT(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB_SAT(quadColor[0], dest[0], source[0]); /* R */
- VEC4_SUB_SAT(quadColor[1], dest[1], source[1]); /* G */
- VEC4_SUB_SAT(quadColor[2], dest[2], source[2]); /* B */
- break;
- case PIPE_BLEND_MIN:
- VEC4_MIN(quadColor[0], source[0], dest[0]); /* R */
- VEC4_MIN(quadColor[1], source[1], dest[1]); /* G */
- VEC4_MIN(quadColor[2], source[2], dest[2]); /* B */
- break;
- case PIPE_BLEND_MAX:
- VEC4_MAX(quadColor[0], source[0], dest[0]); /* R */
- VEC4_MAX(quadColor[1], source[1], dest[1]); /* G */
- VEC4_MAX(quadColor[2], source[2], dest[2]); /* B */
- break;
- default:
- assert(0);
- }
- /*
- * Combine A terms
- */
- switch (softpipe->blend->alpha_func) {
- case PIPE_BLEND_ADD:
- VEC4_ADD_SAT(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_SUBTRACT:
- VEC4_SUB_SAT(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_REVERSE_SUBTRACT:
- VEC4_SUB_SAT(quadColor[3], dest[3], source[3]); /* A */
- break;
- case PIPE_BLEND_MIN:
- VEC4_MIN(quadColor[3], source[3], dest[3]); /* A */
- break;
- case PIPE_BLEND_MAX:
- VEC4_MAX(quadColor[3], source[3], dest[3]); /* A */
- break;
- default:
- assert(0);
+static void
+choose_blend_quad(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ struct softpipe_context *softpipe = qs->softpipe;
+ const struct pipe_blend_state *blend = softpipe->blend;
+
+ qs->run = blend_fallback;
+
+ if (softpipe->framebuffer.nr_cbufs == 0) {
+ qs->run = blend_noop;
+ }
+ else if (!softpipe->blend->logicop_enable &&
+ softpipe->blend->colormask == 0xf)
+ {
+ if (!blend->blend_enable) {
+ qs->run = single_output_color;
}
+ else if (blend->rgb_src_factor == blend->alpha_src_factor &&
+ blend->rgb_dst_factor == blend->alpha_dst_factor &&
+ blend->rgb_func == blend->alpha_func &&
+ softpipe->framebuffer.nr_cbufs == 1)
+ {
+ if (blend->alpha_func == PIPE_BLEND_ADD) {
+ if (blend->rgb_src_factor == PIPE_BLENDFACTOR_ONE &&
+ blend->rgb_dst_factor == PIPE_BLENDFACTOR_ONE) {
+ qs->run = blend_single_add_one_one;
+ }
+ else if (blend->rgb_src_factor == PIPE_BLENDFACTOR_SRC_ALPHA &&
+ blend->rgb_dst_factor == PIPE_BLENDFACTOR_INV_SRC_ALPHA)
+ qs->run = blend_single_add_src_alpha_inv_src_alpha;
- } /* cbuf loop */
+ }
+ }
+ }
- /* pass blended quad to next stage */
- qs->next->run(qs->next, quad);
+ qs->run(qs, quads, nr);
}
static void blend_begin(struct quad_stage *qs)
{
- qs->next->begin(qs->next);
+ qs->run = choose_blend_quad;
}
@@ -770,7 +991,7 @@ struct quad_stage *sp_quad_blend_stage( struct softpipe_context *softpipe )
stage->softpipe = softpipe;
stage->begin = blend_begin;
- stage->run = blend_quad;
+ stage->run = choose_blend_quad;
stage->destroy = blend_destroy;
return stage;
diff --git a/src/gallium/drivers/softpipe/sp_quad_bufloop.c b/src/gallium/drivers/softpipe/sp_quad_bufloop.c
deleted file mode 100644
index 953d8516b90..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_bufloop.c
+++ /dev/null
@@ -1,74 +0,0 @@
-
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-
-
-/**
- * Loop over colorbuffers, passing quad to next stage each time.
- */
-static void
-cbuf_loop_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
- float tmp[PIPE_MAX_COLOR_BUFS][4][QUAD_SIZE];
- unsigned i;
-
- assert(sizeof(quad->outputs.color) == sizeof(tmp));
- assert(softpipe->framebuffer.nr_cbufs <= PIPE_MAX_COLOR_BUFS);
-
- /* make copy of original colors since they can get modified
- * by blending and masking.
- * XXX we won't have to do this if the fragment program actually emits
- * N separate colors and we're drawing to N color buffers (MRT).
- * But if we emitted one color and glDrawBuffer(GL_FRONT_AND_BACK) is
- * in effect, we need to save/restore colors like this.
- */
- memcpy(tmp, quad->outputs.color, sizeof(tmp));
-
- for (i = 0; i < softpipe->framebuffer.nr_cbufs; i++) {
- /* set current cbuffer */
-#if 0 /* obsolete & going away */
- softpipe->current_cbuf = i;
-#endif
-
- /* pass blended quad to next stage */
- qs->next->run(qs->next, quad);
-
- /* restore quad's colors for next buffer */
- memcpy(quad->outputs.color, tmp, sizeof(tmp));
- }
-}
-
-
-static void cbuf_loop_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void cbuf_loop_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-/**
- * Create the colorbuffer loop stage.
- * This is used to implement multiple render targets and GL_FRONT_AND_BACK
- * rendering.
- */
-struct quad_stage *sp_quad_bufloop_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = cbuf_loop_begin;
- stage->run = cbuf_loop_quad;
- stage->destroy = cbuf_loop_destroy;
-
- return stage;
-}
-
diff --git a/src/gallium/drivers/softpipe/sp_quad_colormask.c b/src/gallium/drivers/softpipe/sp_quad_colormask.c
deleted file mode 100644
index dc90e5d5e99..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_colormask.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \brief quad colormask stage
- * \author Brian Paul
- */
-
-#include "pipe/p_defines.h"
-#include "util/u_math.h"
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-#include "sp_tile_cache.h"
-
-
-
-/**
- * XXX colormask could be rolled into blending...
- */
-static void
-colormask_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
- uint cbuf;
-
- /* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
- float dest[4][QUAD_SIZE];
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[cbuf],
- quad->input.x0, quad->input.y0);
- float (*quadColor)[4] = quad->output.color[cbuf];
- uint i, j;
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- int x = (quad->input.x0 & (TILE_SIZE-1)) + (j & 1);
- int y = (quad->input.y0 & (TILE_SIZE-1)) + (j >> 1);
- for (i = 0; i < 4; i++) {
- dest[i][j] = tile->data.color[y][x][i];
- }
- }
-
- /* R */
- if (!(softpipe->blend->colormask & PIPE_MASK_R))
- COPY_4V(quadColor[0], dest[0]);
-
- /* G */
- if (!(softpipe->blend->colormask & PIPE_MASK_G))
- COPY_4V(quadColor[1], dest[1]);
-
- /* B */
- if (!(softpipe->blend->colormask & PIPE_MASK_B))
- COPY_4V(quadColor[2], dest[2]);
-
- /* A */
- if (!(softpipe->blend->colormask & PIPE_MASK_A))
- COPY_4V(quadColor[3], dest[3]);
- }
-
- /* pass quad to next stage */
- qs->next->run(qs->next, quad);
-}
-
-
-static void colormask_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void colormask_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_colormask_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = colormask_begin;
- stage->run = colormask_quad;
- stage->destroy = colormask_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_coverage.c b/src/gallium/drivers/softpipe/sp_quad_coverage.c
deleted file mode 100644
index 4aeee858705..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_coverage.c
+++ /dev/null
@@ -1,94 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * \brief Apply AA coverage to quad alpha valus
- * \author Brian Paul
- */
-
-
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_quad_pipe.h"
-
-
-/**
- * Multiply quad's alpha values by the fragment coverage.
- */
-static void
-coverage_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
- const uint prim = quad->input.prim;
-
- if ((softpipe->rasterizer->poly_smooth && prim == QUAD_PRIM_TRI) ||
- (softpipe->rasterizer->line_smooth && prim == QUAD_PRIM_LINE) ||
- (softpipe->rasterizer->point_smooth && prim == QUAD_PRIM_POINT)) {
- uint cbuf;
-
- /* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
- float (*quadColor)[4] = quad->output.color[cbuf];
- unsigned j;
- for (j = 0; j < QUAD_SIZE; j++) {
- assert(quad->input.coverage[j] >= 0.0);
- assert(quad->input.coverage[j] <= 1.0);
- quadColor[3][j] *= quad->input.coverage[j];
- }
- }
- }
-
- qs->next->run(qs->next, quad);
-}
-
-
-static void coverage_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void coverage_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_coverage_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = coverage_begin;
- stage->run = coverage_quad;
- stage->destroy = coverage_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
index d463930bae1..0ca86c4e1cb 100644
--- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c
+++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c
@@ -31,61 +31,109 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
+#include "tgsi/tgsi_scan.h"
#include "sp_context.h"
#include "sp_quad.h"
#include "sp_surface.h"
#include "sp_quad_pipe.h"
#include "sp_tile_cache.h"
+#include "sp_state.h" /* for sp_fragment_shader */
-/**
- * Do depth testing for a quad.
- * Not static since it's used by the stencil code.
- */
+struct depth_data {
+ struct pipe_surface *ps;
+ enum pipe_format format;
+ unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
+ unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
+ ubyte stencilVals[QUAD_SIZE];
+ struct softpipe_cached_tile *tile;
+};
-/*
- * To increase efficiency, we should probably have multiple versions
- * of this function that are specifically for Z16, Z32 and FP Z buffers.
- * Try to effectively do that with codegen...
- */
-void
-sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
+
+static void
+get_depth_stencil_values( struct depth_data *data,
+ const struct quad_header *quad )
{
- struct softpipe_context *softpipe = qs->softpipe;
- struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
- const enum pipe_format format = ps->format;
- unsigned bzzzz[QUAD_SIZE]; /**< Z values fetched from depth buffer */
- unsigned qzzzz[QUAD_SIZE]; /**< Z values from the quad */
- unsigned zmask = 0;
unsigned j;
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->input.x0, quad->input.y0);
+ const struct softpipe_cached_tile *tile = data->tile;
+
+ switch (data->format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ 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] = tile->data.depth16[y][x];
+ }
+ break;
+ case PIPE_FORMAT_Z32_UNORM:
+ 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] = tile->data.depth32[y][x];
+ }
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
+ 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] = tile->data.depth32[y][x] & 0xffffff;
+ data->stencilVals[j] = tile->data.depth32[y][x] >> 24;
+ }
+ break;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z24S8_UNORM:
+ 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] = tile->data.depth32[y][x] >> 8;
+ data->stencilVals[j] = tile->data.depth32[y][x] & 0xff;
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
- assert(ps); /* shouldn't get here if there's no zbuffer */
+/* If the shader has not been run, interpolate the depth values
+ * ourselves.
+ */
+static void
+interpolate_quad_depth( struct quad_header *quad )
+{
+ const float fx = (float) quad->input.x0;
+ const float fy = (float) quad->input.y0;
+ const float dzdx = quad->posCoef->dadx[2];
+ const float dzdy = quad->posCoef->dady[2];
+ const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
- /*
- * Convert quad's float depth values to int depth values (qzzzz).
+ quad->output.depth[0] = z0;
+ quad->output.depth[1] = z0 + dzdx;
+ quad->output.depth[2] = z0 + dzdy;
+ quad->output.depth[3] = z0 + dzdx + dzdy;
+}
+
+
+static void
+convert_quad_depth( struct depth_data *data,
+ const struct quad_header *quad )
+{
+ unsigned j;
+
+ /* Convert quad's float depth values to int depth values (qzzzz).
* If the Z buffer stores integer values, we _have_ to do the depth
* compares with integers (not floats). Otherwise, the float->int->float
* conversion of Z values (which isn't an identity function) will cause
* Z-fighting errors.
- *
- * Also, get the zbuffer values (bzzzz) from the cached tile.
*/
- switch (format) {
+ switch (data->format) {
case PIPE_FORMAT_Z16_UNORM:
{
float scale = 65535.0;
for (j = 0; j < QUAD_SIZE; j++) {
- qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
- }
-
- 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);
- bzzzz[j] = tile->data.depth16[y][x];
+ data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
}
}
break;
@@ -94,47 +142,247 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
double scale = (double) (uint) ~0UL;
for (j = 0; j < QUAD_SIZE; j++) {
- qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
- }
-
- 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);
- bzzzz[j] = tile->data.depth32[y][x];
+ data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
}
}
break;
case PIPE_FORMAT_X8Z24_UNORM:
- /* fall-through */
case PIPE_FORMAT_S8Z24_UNORM:
{
float scale = (float) ((1 << 24) - 1);
for (j = 0; j < QUAD_SIZE; j++) {
- qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
- }
-
- 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);
- bzzzz[j] = tile->data.depth32[y][x] & 0xffffff;
+ data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
}
}
break;
case PIPE_FORMAT_Z24X8_UNORM:
- /* fall-through */
case PIPE_FORMAT_Z24S8_UNORM:
{
float scale = (float) ((1 << 24) - 1);
for (j = 0; j < QUAD_SIZE; j++) {
- qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
+ data->qzzzz[j] = (unsigned) (quad->output.depth[j] * scale);
}
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
- 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);
- bzzzz[j] = tile->data.depth32[y][x] >> 8;
+
+
+static void
+write_depth_stencil_values( struct depth_data *data,
+ struct quad_header *quad )
+{
+ struct softpipe_cached_tile *tile = data->tile;
+ unsigned j;
+
+ /* put updated Z values back into cached tile */
+ switch (data->format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ 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.depth16[y][x] = (ushort) data->bzzzz[j];
+ }
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_Z32_UNORM:
+ 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.depth32[y][x] = data->bzzzz[j];
+ }
+ break;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ 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.depth32[y][x] = (data->stencilVals[j] << 24) | data->bzzzz[j];
+ }
+ break;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ 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.depth32[y][x] = (data->bzzzz[j] << 8) | data->stencilVals[j];
+ }
+ break;
+ case PIPE_FORMAT_Z24X8_UNORM:
+ 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.depth32[y][x] = data->bzzzz[j] << 8;
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+
+
+/** Only 8-bit stencil supported */
+#define STENCIL_MAX 0xff
+
+
+/**
+ * Do the basic stencil test (compare stencil buffer values against the
+ * reference value.
+ *
+ * \param data->stencilVals the stencil values from the stencil buffer
+ * \param func the stencil func (PIPE_FUNC_x)
+ * \param ref the stencil reference value
+ * \param valMask the stencil value mask indicating which bits of the stencil
+ * values and ref value are to be used.
+ * \return mask indicating which pixels passed the stencil test
+ */
+static unsigned
+do_stencil_test(struct depth_data *data,
+ unsigned func,
+ unsigned ref, unsigned valMask)
+{
+ unsigned passMask = 0x0;
+ unsigned j;
+
+ ref &= valMask;
+
+ switch (func) {
+ case PIPE_FUNC_NEVER:
+ /* passMask = 0x0 */
+ break;
+ case PIPE_FUNC_LESS:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref < (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_EQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref == (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_LEQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref <= (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_GREATER:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref > (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref != (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_GEQUAL:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (ref >= (data->stencilVals[j] & valMask)) {
+ passMask |= (1 << j);
+ }
+ }
+ break;
+ case PIPE_FUNC_ALWAYS:
+ passMask = MASK_ALL;
+ break;
+ default:
+ assert(0);
+ }
+
+ return passMask;
+}
+
+
+/**
+ * Apply the stencil operator to stencil values.
+ *
+ * \param data->stencilVals the stencil buffer values (read and written)
+ * \param mask indicates which pixels to update
+ * \param op the stencil operator (PIPE_STENCIL_OP_x)
+ * \param ref the stencil reference value
+ * \param wrtMask writemask controlling which bits are changed in the
+ * stencil values
+ */
+static void
+apply_stencil_op(struct depth_data *data,
+ unsigned mask, unsigned op, ubyte ref, ubyte wrtMask)
+{
+ unsigned j;
+ ubyte newstencil[QUAD_SIZE];
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ newstencil[j] = data->stencilVals[j];
+ }
+
+ switch (op) {
+ case PIPE_STENCIL_OP_KEEP:
+ /* no-op */
+ break;
+ case PIPE_STENCIL_OP_ZERO:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ newstencil[j] = 0;
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_REPLACE:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ newstencil[j] = ref;
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_INCR:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ if (data->stencilVals[j] < STENCIL_MAX) {
+ newstencil[j] = data->stencilVals[j] + 1;
+ }
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_DECR:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ if (data->stencilVals[j] > 0) {
+ newstencil[j] = data->stencilVals[j] - 1;
+ }
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_INCR_WRAP:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ newstencil[j] = data->stencilVals[j] + 1;
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_DECR_WRAP:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ newstencil[j] = data->stencilVals[j] - 1;
+ }
+ }
+ break;
+ case PIPE_STENCIL_OP_INVERT:
+ for (j = 0; j < QUAD_SIZE; j++) {
+ if (mask & (1 << j)) {
+ newstencil[j] = ~data->stencilVals[j];
}
}
break;
@@ -142,6 +390,39 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
assert(0);
}
+ /*
+ * update the stencil values
+ */
+ if (wrtMask != STENCIL_MAX) {
+ /* apply bit-wise stencil buffer writemask */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ data->stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & data->stencilVals[j]);
+ }
+ }
+ else {
+ for (j = 0; j < QUAD_SIZE; j++) {
+ data->stencilVals[j] = newstencil[j];
+ }
+ }
+}
+
+
+
+/*
+ * To increase efficiency, we should probably have multiple versions
+ * of this function that are specifically for Z16, Z32 and FP Z buffers.
+ * Try to effectively do that with codegen...
+ */
+
+static boolean
+depth_test_quad(struct quad_stage *qs,
+ struct depth_data *data,
+ struct quad_header *quad)
+{
+ struct softpipe_context *softpipe = qs->softpipe;
+ unsigned zmask = 0;
+ unsigned j;
+
switch (softpipe->depth_stencil->depth.func) {
case PIPE_FUNC_NEVER:
/* zmask = 0 */
@@ -151,37 +432,37 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
* Like this: quad->mask &= (quad->outputs.depth < zzzz);
*/
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] < bzzzz[j])
+ if (data->qzzzz[j] < data->bzzzz[j])
zmask |= 1 << j;
}
break;
case PIPE_FUNC_EQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] == bzzzz[j])
+ if (data->qzzzz[j] == data->bzzzz[j])
zmask |= 1 << j;
}
break;
case PIPE_FUNC_LEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] <= bzzzz[j])
+ if (data->qzzzz[j] <= data->bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_GREATER:
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] > bzzzz[j])
+ if (data->qzzzz[j] > data->bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_NOTEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] != bzzzz[j])
+ if (data->qzzzz[j] != data->bzzzz[j])
zmask |= (1 << j);
}
break;
case PIPE_FUNC_GEQUAL:
for (j = 0; j < QUAD_SIZE; j++) {
- if (qzzzz[j] >= bzzzz[j])
+ if (data->qzzzz[j] >= data->bzzzz[j])
zmask |= (1 << j);
}
break;
@@ -193,80 +474,480 @@ sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
}
quad->inout.mask &= zmask;
+ if (quad->inout.mask == 0)
+ return FALSE;
+ /* Update our internal copy only if writemask set. Even if
+ * depth.writemask is FALSE, may still need to write out buffer
+ * data due to stencil changes.
+ */
if (softpipe->depth_stencil->depth.writemask) {
-
- /* This is also efficient with sse / spe instructions:
- */
for (j = 0; j < QUAD_SIZE; j++) {
- if (quad->inout.mask & (1 << j)) {
- bzzzz[j] = qzzzz[j];
- }
+ if (quad->inout.mask & (1 << j)) {
+ data->bzzzz[j] = data->qzzzz[j];
+ }
}
+ }
- /* put updated Z values back into cached tile */
- switch (format) {
- case PIPE_FORMAT_Z16_UNORM:
- 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.depth16[y][x] = (ushort) bzzzz[j];
+ return TRUE;
+}
+
+
+
+/**
+ * Do stencil (and depth) testing. Stenciling depends on the outcome of
+ * depth testing.
+ */
+static void
+depth_stencil_test_quad(struct quad_stage *qs,
+ struct depth_data *data,
+ struct quad_header *quad)
+{
+ struct softpipe_context *softpipe = qs->softpipe;
+ unsigned func, zFailOp, zPassOp, failOp;
+ ubyte ref, wrtMask, valMask;
+ uint face = quad->input.facing;
+
+ if (!softpipe->depth_stencil->stencil[1].enabled) {
+ /* single-sided stencil test, use front (face=0) state */
+ face = 0;
+ }
+
+ /* choose front or back face function, operator, etc */
+ /* XXX we could do these initializations once per primitive */
+ func = softpipe->depth_stencil->stencil[face].func;
+ failOp = softpipe->depth_stencil->stencil[face].fail_op;
+ zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
+ zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
+ ref = softpipe->depth_stencil->stencil[face].ref_value;
+ wrtMask = softpipe->depth_stencil->stencil[face].writemask;
+ valMask = softpipe->depth_stencil->stencil[face].valuemask;
+
+
+ /* do the stencil test first */
+ {
+ unsigned passMask, failMask;
+ passMask = do_stencil_test(data, func, ref, valMask);
+ failMask = quad->inout.mask & ~passMask;
+ quad->inout.mask &= passMask;
+
+ if (failOp != PIPE_STENCIL_OP_KEEP) {
+ apply_stencil_op(data, failMask, failOp, ref, wrtMask);
+ }
+ }
+
+ if (quad->inout.mask) {
+ /* now the pixels that passed the stencil test are depth tested */
+ if (softpipe->depth_stencil->depth.enabled) {
+ const unsigned origMask = quad->inout.mask;
+
+ depth_test_quad(qs, data, quad); /* quad->mask is updated */
+
+ /* update stencil buffer values according to z pass/fail result */
+ if (zFailOp != PIPE_STENCIL_OP_KEEP) {
+ const unsigned zFailMask = origMask & ~quad->inout.mask;
+ apply_stencil_op(data, zFailMask, zFailOp, ref, wrtMask);
}
- break;
- case PIPE_FORMAT_X8Z24_UNORM:
- /* fall-through */
- /* (yes, this falls through to a different case than above) */
- case PIPE_FORMAT_Z32_UNORM:
- 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.depth32[y][x] = bzzzz[j];
+
+ if (zPassOp != PIPE_STENCIL_OP_KEEP) {
+ const unsigned zPassMask = origMask & quad->inout.mask;
+ apply_stencil_op(data, zPassMask, zPassOp, ref, wrtMask);
}
- break;
- case PIPE_FORMAT_S8Z24_UNORM:
- 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);
- uint s8z24 = tile->data.depth32[y][x];
- s8z24 = (s8z24 & 0xff000000) | bzzzz[j];
- tile->data.depth32[y][x] = s8z24;
+ }
+ else {
+ /* no depth test, apply Zpass operator to stencil buffer values */
+ apply_stencil_op(data, quad->inout.mask, zPassOp, ref, wrtMask);
+ }
+ }
+}
+
+
+#define ALPHATEST( FUNC, COMP ) \
+ static int \
+ alpha_test_quads_##FUNC( struct quad_stage *qs, \
+ struct quad_header *quads[], \
+ unsigned nr ) \
+ { \
+ const float ref = qs->softpipe->depth_stencil->alpha.ref_value; \
+ const uint cbuf = 0; /* only output[0].alpha is tested */ \
+ unsigned pass_nr = 0; \
+ unsigned i; \
+ \
+ for (i = 0; i < nr; i++) { \
+ const float *aaaa = quads[i]->output.color[cbuf][3]; \
+ unsigned passMask = 0; \
+ \
+ if (aaaa[0] COMP ref) passMask |= (1 << 0); \
+ if (aaaa[1] COMP ref) passMask |= (1 << 1); \
+ if (aaaa[2] COMP ref) passMask |= (1 << 2); \
+ if (aaaa[3] COMP ref) passMask |= (1 << 3); \
+ \
+ quads[i]->inout.mask &= passMask; \
+ \
+ if (quads[i]->inout.mask) \
+ quads[pass_nr++] = quads[i]; \
+ } \
+ \
+ return pass_nr; \
+ }
+
+
+ALPHATEST( LESS, < )
+ALPHATEST( EQUAL, == )
+ALPHATEST( LEQUAL, <= )
+ALPHATEST( GREATER, > )
+ALPHATEST( NOTEQUAL, != )
+ALPHATEST( GEQUAL, >= )
+
+
+/* XXX: Incorporate into shader using KILP.
+ */
+static int
+alpha_test_quads(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ switch (qs->softpipe->depth_stencil->alpha.func) {
+ case PIPE_FUNC_LESS:
+ return alpha_test_quads_LESS( qs, quads, nr );
+ case PIPE_FUNC_EQUAL:
+ return alpha_test_quads_EQUAL( qs, quads, nr );
+ break;
+ case PIPE_FUNC_LEQUAL:
+ return alpha_test_quads_LEQUAL( qs, quads, nr );
+ case PIPE_FUNC_GREATER:
+ return alpha_test_quads_GREATER( qs, quads, nr );
+ case PIPE_FUNC_NOTEQUAL:
+ return alpha_test_quads_NOTEQUAL( qs, quads, nr );
+ case PIPE_FUNC_GEQUAL:
+ return alpha_test_quads_GEQUAL( qs, quads, nr );
+ case PIPE_FUNC_ALWAYS:
+ return nr;
+ case PIPE_FUNC_NEVER:
+ default:
+ return 0;
+ }
+}
+
+static unsigned mask_count[16] =
+{
+ 0, /* 0x0 */
+ 1, /* 0x1 */
+ 1, /* 0x2 */
+ 2, /* 0x3 */
+ 1, /* 0x4 */
+ 2, /* 0x5 */
+ 2, /* 0x6 */
+ 3, /* 0x7 */
+ 1, /* 0x8 */
+ 2, /* 0x9 */
+ 2, /* 0xa */
+ 3, /* 0xb */
+ 2, /* 0xc */
+ 3, /* 0xd */
+ 3, /* 0xe */
+ 4, /* 0xf */
+};
+
+
+
+static void
+depth_test_quads_fallback(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ unsigned i, pass = 0;
+ const struct sp_fragment_shader *fs = qs->softpipe->fs;
+ boolean interp_depth = !fs->info.writes_z;
+ struct depth_data data;
+
+
+ if (qs->softpipe->depth_stencil->alpha.enabled) {
+ nr = alpha_test_quads(qs, quads, nr);
+ }
+
+ if (qs->softpipe->framebuffer.zsbuf &&
+ (qs->softpipe->depth_stencil->depth.enabled ||
+ qs->softpipe->depth_stencil->stencil[0].enabled)) {
+
+ data.ps = qs->softpipe->framebuffer.zsbuf;
+ data.format = data.ps->format;
+ data.tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache,
+ quads[0]->input.x0,
+ quads[0]->input.y0);
+
+ for (i = 0; i < nr; i++) {
+ get_depth_stencil_values(&data, quads[i]);
+
+ if (qs->softpipe->depth_stencil->depth.enabled) {
+ if (interp_depth)
+ interpolate_quad_depth(quads[i]);
+
+ convert_quad_depth(&data, quads[i]);
}
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- 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);
- uint z24s8 = tile->data.depth32[y][x];
- z24s8 = (z24s8 & 0xff) | (bzzzz[j] << 8);
- tile->data.depth32[y][x] = z24s8;
+
+ if (qs->softpipe->depth_stencil->stencil[0].enabled) {
+ depth_stencil_test_quad(qs, &data, quads[i]);
+ write_depth_stencil_values(&data, quads[i]);
}
- break;
- case PIPE_FORMAT_Z24X8_UNORM:
- 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.depth32[y][x] = bzzzz[j] << 8;
+ else {
+ if (!depth_test_quad(qs, &data, quads[i]))
+ continue;
+
+ if (qs->softpipe->depth_stencil->depth.writemask)
+ write_depth_stencil_values(&data, quads[i]);
}
- break;
- default:
- assert(0);
+
+
+ quads[pass++] = quads[i];
+ }
+
+ nr = pass;
+ }
+
+ if (qs->softpipe->active_query_count) {
+ for (i = 0; i < nr; i++)
+ qs->softpipe->occlusion_count += mask_count[quads[i]->inout.mask];
+ }
+
+ if (nr)
+ qs->next->run(qs->next, quads, nr);
+}
+
+/* XXX: this function assumes setup function actually emits linear
+ * spans of quads. It seems a lot more natural to do (early)
+ * depth-testing on spans rather than quads.
+ */
+static void
+depth_interp_z16_less_write(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ unsigned i, pass = 0;
+ const unsigned ix = quads[0]->input.x0;
+ const unsigned iy = quads[0]->input.y0;
+ const float fx = (float) ix;
+ const float fy = (float) iy;
+ const float dzdx = quads[0]->posCoef->dadx[2];
+ const float dzdy = quads[0]->posCoef->dady[2];
+ const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
+ struct softpipe_cached_tile *tile;
+ ushort (*depth16)[TILE_SIZE];
+ ushort idepth[4], depth_step;
+ const float scale = 65535.0;
+
+ idepth[0] = (ushort)((z0) * scale);
+ idepth[1] = (ushort)((z0 + dzdx) * scale);
+ idepth[2] = (ushort)((z0 + dzdy) * scale);
+ idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
+
+ depth_step = (ushort)(dzdx * 2 * scale);
+
+ tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
+
+ depth16 = (ushort (*)[TILE_SIZE])
+ &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
+
+ for (i = 0; i < nr; i++) {
+ unsigned outmask = quads[i]->inout.mask;
+ unsigned mask = 0;
+
+ if ((outmask & 1) && idepth[0] < depth16[0][0]) {
+ depth16[0][0] = idepth[0];
+ mask |= (1 << 0);
+ }
+
+ if ((outmask & 2) && idepth[1] < depth16[0][1]) {
+ depth16[0][1] = idepth[1];
+ mask |= (1 << 1);
+ }
+
+ if ((outmask & 4) && idepth[2] < depth16[1][0]) {
+ depth16[1][0] = idepth[2];
+ mask |= (1 << 2);
+ }
+
+ if ((outmask & 8) && idepth[3] < depth16[1][1]) {
+ depth16[1][1] = idepth[3];
+ mask |= (1 << 3);
}
+
+ idepth[0] += depth_step;
+ idepth[1] += depth_step;
+ idepth[2] += depth_step;
+ idepth[3] += depth_step;
+
+ depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
+
+ quads[i]->inout.mask = mask;
+ if (quads[i]->inout.mask)
+ quads[pass++] = quads[i];
}
+
+ if (pass)
+ qs->next->run(qs->next, quads, pass);
+
}
static void
-depth_test_quad(struct quad_stage *qs, struct quad_header *quad)
+depth_interp_z16_lequal_write(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
{
- sp_depth_test_quad(qs, quad);
+ unsigned i, pass = 0;
+ const unsigned ix = quads[0]->input.x0;
+ const unsigned iy = quads[0]->input.y0;
+ const float fx = (float) ix;
+ const float fy = (float) iy;
+ const float dzdx = quads[0]->posCoef->dadx[2];
+ const float dzdy = quads[0]->posCoef->dady[2];
+ const float z0 = quads[0]->posCoef->a0[2] + dzdx * fx + dzdy * fy;
+ struct softpipe_cached_tile *tile;
+ ushort (*depth16)[TILE_SIZE];
+ ushort idepth[4], depth_step;
+ const float scale = 65535.0;
+
+ idepth[0] = (ushort)((z0) * scale);
+ idepth[1] = (ushort)((z0 + dzdx) * scale);
+ idepth[2] = (ushort)((z0 + dzdy) * scale);
+ idepth[3] = (ushort)((z0 + dzdx + dzdy) * scale);
+
+ depth_step = (ushort)(dzdx * 2 * scale);
+
+ tile = sp_get_cached_tile(qs->softpipe->zsbuf_cache, ix, iy);
+
+ depth16 = (ushort (*)[TILE_SIZE])
+ &tile->data.depth16[iy % TILE_SIZE][ix % TILE_SIZE];
+
+ for (i = 0; i < nr; i++) {
+ unsigned outmask = quads[i]->inout.mask;
+ unsigned mask = 0;
+
+ if ((outmask & 1) && idepth[0] <= depth16[0][0]) {
+ depth16[0][0] = idepth[0];
+ mask |= (1 << 0);
+ }
+
+ if ((outmask & 2) && idepth[1] <= depth16[0][1]) {
+ depth16[0][1] = idepth[1];
+ mask |= (1 << 1);
+ }
+
+ if ((outmask & 4) && idepth[2] <= depth16[1][0]) {
+ depth16[1][0] = idepth[2];
+ mask |= (1 << 2);
+ }
+
+ if ((outmask & 8) && idepth[3] <= depth16[1][1]) {
+ depth16[1][1] = idepth[3];
+ mask |= (1 << 3);
+ }
+
+ idepth[0] += depth_step;
+ idepth[1] += depth_step;
+ idepth[2] += depth_step;
+ idepth[3] += depth_step;
+
+ depth16 = (ushort (*)[TILE_SIZE]) &depth16[0][2];
+
+ quads[i]->inout.mask = mask;
+ if (quads[i]->inout.mask)
+ quads[pass++] = quads[i];
+ }
+
+ if (pass)
+ qs->next->run(qs->next, quads, pass);
- if (quad->inout.mask)
- qs->next->run(qs->next, quad);
}
+
+
+
+static void
+depth_noop(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ qs->next->run(qs->next, quads, nr);
+}
+
+
+
+static void
+choose_depth_test(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ boolean interp_depth = !qs->softpipe->fs->info.writes_z;
+
+ boolean alpha = qs->softpipe->depth_stencil->alpha.enabled;
+
+ boolean depth = (qs->softpipe->framebuffer.zsbuf &&
+ qs->softpipe->depth_stencil->depth.enabled);
+
+ unsigned depthfunc = qs->softpipe->depth_stencil->depth.func;
+
+ boolean stencil = qs->softpipe->depth_stencil->stencil[0].enabled;
+
+ boolean depthwrite = qs->softpipe->depth_stencil->depth.writemask;
+
+ boolean occlusion = qs->softpipe->active_query_count;
+
+
+ if (!alpha &&
+ !depth &&
+ !stencil) {
+ qs->run = depth_noop;
+ }
+ else if (!alpha &&
+ interp_depth &&
+ depth &&
+ depthwrite &&
+ !occlusion &&
+ !stencil)
+ {
+ switch (depthfunc) {
+ case PIPE_FUNC_LESS:
+ switch (qs->softpipe->framebuffer.zsbuf->format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ qs->run = depth_interp_z16_less_write;
+ break;
+ default:
+ qs->run = depth_test_quads_fallback;
+ break;
+ }
+ break;
+ case PIPE_FUNC_LEQUAL:
+ switch (qs->softpipe->framebuffer.zsbuf->format) {
+ case PIPE_FORMAT_Z16_UNORM:
+ qs->run = depth_interp_z16_lequal_write;
+ break;
+ default:
+ qs->run = depth_test_quads_fallback;
+ break;
+ }
+ break;
+ default:
+ qs->run = depth_test_quads_fallback;
+ }
+ }
+ else {
+ qs->run = depth_test_quads_fallback;
+ }
+
+
+ qs->run( qs, quads, nr );
+}
+
+
+
+
+
static void depth_test_begin(struct quad_stage *qs)
{
+ qs->run = choose_depth_test;
qs->next->begin(qs->next);
}
@@ -283,7 +964,7 @@ struct quad_stage *sp_quad_depth_test_stage( struct softpipe_context *softpipe )
stage->softpipe = softpipe;
stage->begin = depth_test_begin;
- stage->run = depth_test_quad;
+ stage->run = choose_depth_test;
stage->destroy = depth_test_destroy;
return stage;
diff --git a/src/gallium/drivers/softpipe/sp_quad_earlyz.c b/src/gallium/drivers/softpipe/sp_quad_earlyz.c
deleted file mode 100644
index 496fd39ed1a..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_earlyz.c
+++ /dev/null
@@ -1,88 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-/**
- * \brief Quad early-z testing
- */
-
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "sp_quad.h"
-#include "sp_quad_pipe.h"
-
-
-/**
- * All this stage does is compute the quad's Z values (which is normally
- * done by the shading stage).
- * The next stage will do the actual depth test.
- */
-static void
-earlyz_quad(
- struct quad_stage *qs,
- struct quad_header *quad )
-{
- const float fx = (float) quad->input.x0;
- const float fy = (float) quad->input.y0;
- const float dzdx = quad->posCoef->dadx[2];
- const float dzdy = quad->posCoef->dady[2];
- const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
-
- quad->output.depth[0] = z0;
- quad->output.depth[1] = z0 + dzdx;
- quad->output.depth[2] = z0 + dzdy;
- quad->output.depth[3] = z0 + dzdx + dzdy;
-
- qs->next->run( qs->next, quad );
-}
-
-static void
-earlyz_begin(
- struct quad_stage *qs )
-{
- qs->next->begin( qs->next );
-}
-
-static void
-earlyz_destroy(
- struct quad_stage *qs )
-{
- FREE( qs );
-}
-
-struct quad_stage *
-sp_quad_earlyz_stage(
- struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT( quad_stage );
-
- stage->softpipe = softpipe;
- stage->begin = earlyz_begin;
- stage->run = earlyz_quad;
- stage->destroy = earlyz_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_fs.c b/src/gallium/drivers/softpipe/sp_quad_fs.c
index 28f8d1a60ea..1e7533d0f9e 100644
--- a/src/gallium/drivers/softpipe/sp_quad_fs.c
+++ b/src/gallium/drivers/softpipe/sp_quad_fs.c
@@ -68,72 +68,69 @@ quad_shade_stage(struct quad_stage *qs)
/**
* Execute fragment shader for the four fragments in the quad.
*/
-static void
+static INLINE boolean
shade_quad(struct quad_stage *qs, struct quad_header *quad)
{
struct quad_shade_stage *qss = quad_shade_stage( qs );
struct softpipe_context *softpipe = qs->softpipe;
struct tgsi_exec_machine *machine = qss->machine;
- boolean z_written;
-
- /* Consts do not require 16 byte alignment. */
- machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
-
- machine->InterpCoefs = quad->coef;
/* run shader */
- quad->inout.mask &= softpipe->fs->run( softpipe->fs, machine, quad );
-
- /* store outputs */
- z_written = FALSE;
- {
- const ubyte *sem_name = softpipe->fs->info.output_semantic_name;
- const ubyte *sem_index = softpipe->fs->info.output_semantic_index;
- const uint n = qss->stage.softpipe->fs->info.num_outputs;
- uint i;
- for (i = 0; i < n; i++) {
- switch (sem_name[i]) {
- case TGSI_SEMANTIC_COLOR:
- {
- uint cbuf = sem_index[i];
- memcpy(quad->output.color[cbuf],
- &machine->Outputs[i].xyzw[0].f[0],
- sizeof(quad->output.color[0]) );
- }
- break;
- case TGSI_SEMANTIC_POSITION:
- {
- uint j;
- for (j = 0; j < 4; j++) {
- quad->output.depth[j] = machine->Outputs[0].xyzw[2].f[j];
- }
- z_written = TRUE;
- }
- break;
- }
+ return softpipe->fs->run( softpipe->fs, machine, quad );
+}
+
+
+
+static void
+coverage_quad(struct quad_stage *qs, struct quad_header *quad)
+{
+ struct softpipe_context *softpipe = qs->softpipe;
+ uint cbuf;
+
+ /* loop over colorbuffer outputs */
+ for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
+ float (*quadColor)[4] = quad->output.color[cbuf];
+ unsigned j;
+ for (j = 0; j < QUAD_SIZE; j++) {
+ assert(quad->input.coverage[j] >= 0.0);
+ assert(quad->input.coverage[j] <= 1.0);
+ quadColor[3][j] *= quad->input.coverage[j];
}
}
+}
+
- if (!z_written) {
- /* compute Z values now, as in the quad earlyz stage */
- /* XXX we should really only do this if the earlyz stage is not used */
- const float fx = (float) quad->input.x0;
- const float fy = (float) quad->input.y0;
- const float dzdx = quad->posCoef->dadx[2];
- const float dzdy = quad->posCoef->dady[2];
- const float z0 = quad->posCoef->a0[2] + dzdx * fx + dzdy * fy;
-
- quad->output.depth[0] = z0;
- quad->output.depth[1] = z0 + dzdx;
- quad->output.depth[2] = z0 + dzdy;
- quad->output.depth[3] = z0 + dzdx + dzdy;
- }
- /* shader may cull fragments */
- if (quad->inout.mask) {
- qs->next->run( qs->next, quad );
+static void
+shade_quads(struct quad_stage *qs,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ struct quad_shade_stage *qss = quad_shade_stage( qs );
+ struct softpipe_context *softpipe = qs->softpipe;
+ struct tgsi_exec_machine *machine = qss->machine;
+
+ unsigned i, pass = 0;
+
+ machine->Consts = softpipe->mapped_constants[PIPE_SHADER_FRAGMENT];
+ machine->InterpCoefs = quads[0]->coef;
+
+ for (i = 0; i < nr; i++) {
+ if (!shade_quad(qs, quads[i]))
+ continue;
+
+ if (/*do_coverage*/ 0)
+ coverage_quad( qs, quads[i] );
+
+ quads[pass++] = quads[i];
}
+
+ if (pass)
+ qs->next->run(qs->next, quads, pass);
}
+
+
+
/**
@@ -174,7 +171,7 @@ sp_quad_shade_stage( struct softpipe_context *softpipe )
qss->stage.softpipe = softpipe;
qss->stage.begin = shade_begin;
- qss->stage.run = shade_quad;
+ qss->stage.run = shade_quads;
qss->stage.destroy = shade_destroy;
qss->machine = tgsi_exec_machine_create();
diff --git a/src/gallium/drivers/softpipe/sp_quad_occlusion.c b/src/gallium/drivers/softpipe/sp_quad_occlusion.c
deleted file mode 100644
index dfa7ff3b1d1..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_occlusion.c
+++ /dev/null
@@ -1,85 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-
-/**
- * \brief Quad occlusion counter stage
- * \author Brian Paul
- */
-
-
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-
-static unsigned count_bits( unsigned val )
-{
- unsigned i;
-
- for (i = 0; val ; val >>= 1)
- i += (val & 1);
-
- return i;
-}
-
-static void
-occlusion_count_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
-
- softpipe->occlusion_count += count_bits(quad->inout.mask);
-
- qs->next->run(qs->next, quad);
-}
-
-
-static void occlusion_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void occlusion_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_occlusion_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = occlusion_begin;
- stage->run = occlusion_count_quad;
- stage->destroy = occlusion_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_output.c b/src/gallium/drivers/softpipe/sp_quad_output.c
deleted file mode 100644
index 92d5f9f3c1a..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_output.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- **************************************************************************/
-
-#include "util/u_memory.h"
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_quad_pipe.h"
-#include "sp_tile_cache.h"
-
-
-/**
- * Last step of quad processing: write quad colors to the framebuffer,
- * taking mask into account.
- */
-static void
-output_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- /* in-tile pos: */
- const int itx = quad->input.x0 % TILE_SIZE;
- const int ity = quad->input.y0 % TILE_SIZE;
-
- struct softpipe_context *softpipe = qs->softpipe;
- uint cbuf;
-
- /* loop over colorbuffer outputs */
- for (cbuf = 0; cbuf < softpipe->framebuffer.nr_cbufs; cbuf++) {
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe,
- softpipe->cbuf_cache[cbuf],
- quad->input.x0, quad->input.y0);
- float (*quadColor)[4] = quad->output.color[cbuf];
- int i, j;
-
- /* get/swizzle dest colors */
- for (j = 0; j < QUAD_SIZE; j++) {
- if (quad->inout.mask & (1 << j)) {
- int x = itx + (j & 1);
- int y = ity + (j >> 1);
- for (i = 0; i < 4; i++) { /* loop over color chans */
- tile->data.color[y][x][i] = quadColor[i][j];
- }
- if (0) {
- debug_printf("sp write pixel %d,%d: %g, %g, %g\n",
- quad->input.x0 + x,
- quad->input.y0 + y,
- quadColor[0][j],
- quadColor[1][j],
- quadColor[2][j]);
- }
- }
- }
- }
-}
-
-
-static void output_begin(struct quad_stage *qs)
-{
- assert(qs->next == NULL);
-}
-
-
-static void output_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = output_begin;
- stage->run = output_quad;
- stage->destroy = output_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.c b/src/gallium/drivers/softpipe/sp_quad_pipe.c
index b5f69b74264..1b5bab4eca6 100644
--- a/src/gallium/drivers/softpipe/sp_quad_pipe.c
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.c
@@ -31,88 +31,33 @@
#include "pipe/p_shader_tokens.h"
static void
-sp_push_quad_first(
- struct softpipe_context *sp,
- struct quad_stage *quad,
- uint i )
+sp_push_quad_first( struct softpipe_context *sp,
+ struct quad_stage *quad )
{
- quad->next = sp->quad[i].first;
- sp->quad[i].first = quad;
+ quad->next = sp->quad.first;
+ sp->quad.first = quad;
}
-static void
-sp_build_depth_stencil(
- struct softpipe_context *sp,
- uint i )
-{
- if (sp->depth_stencil->stencil[0].enabled ||
- sp->depth_stencil->stencil[1].enabled) {
- sp_push_quad_first( sp, sp->quad[i].stencil_test, i );
- }
- else if (sp->depth_stencil->depth.enabled &&
- sp->framebuffer.zsbuf) {
- sp_push_quad_first( sp, sp->quad[i].depth_test, i );
- }
-}
void
sp_build_quad_pipeline(struct softpipe_context *sp)
{
- uint i;
-
boolean early_depth_test =
- sp->depth_stencil->depth.enabled &&
- sp->framebuffer.zsbuf &&
- !sp->depth_stencil->alpha.enabled &&
- !sp->fs->info.uses_kill &&
- !sp->fs->info.writes_z;
-
- /* build up the pipeline in reverse order... */
- for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
- sp->quad[i].first = sp->quad[i].output;
-
- if (sp->blend->colormask != 0xf) {
- sp_push_quad_first( sp, sp->quad[i].colormask, i );
- }
+ sp->depth_stencil->depth.enabled &&
+ sp->framebuffer.zsbuf &&
+ !sp->depth_stencil->alpha.enabled &&
+ !sp->fs->info.uses_kill &&
+ !sp->fs->info.writes_z;
- if (sp->blend->blend_enable ||
- sp->blend->logicop_enable) {
- sp_push_quad_first( sp, sp->quad[i].blend, i );
- }
+ sp->quad.first = sp->quad.blend;
- if (sp->active_query_count) {
- sp_push_quad_first( sp, sp->quad[i].occlusion, i );
- }
-
- if (sp->rasterizer->poly_smooth ||
- sp->rasterizer->line_smooth ||
- sp->rasterizer->point_smooth) {
- sp_push_quad_first( sp, sp->quad[i].coverage, i );
- }
-
- if (!early_depth_test) {
- sp_build_depth_stencil( sp, i );
- }
-
- if (sp->depth_stencil->alpha.enabled) {
- sp_push_quad_first( sp, sp->quad[i].alpha_test, i );
- }
-
- /* XXX always enable shader? */
- if (1) {
- sp_push_quad_first( sp, sp->quad[i].shade, i );
- }
-
- if (early_depth_test) {
- sp_build_depth_stencil( sp, i );
- sp_push_quad_first( sp, sp->quad[i].earlyz, i );
- }
-
-#if !USE_DRAW_STAGE_PSTIPPLE
- if (sp->rasterizer->poly_stipple_enable) {
- sp_push_quad_first( sp, sp->quad[i].polygon_stipple, i );
- }
-#endif
+ if (early_depth_test) {
+ sp_push_quad_first( sp, sp->quad.shade );
+ sp_push_quad_first( sp, sp->quad.depth_test );
+ }
+ else {
+ sp_push_quad_first( sp, sp->quad.depth_test );
+ sp_push_quad_first( sp, sp->quad.shade );
}
}
diff --git a/src/gallium/drivers/softpipe/sp_quad_pipe.h b/src/gallium/drivers/softpipe/sp_quad_pipe.h
index 0e40586ffc8..c0aa1348319 100644
--- a/src/gallium/drivers/softpipe/sp_quad_pipe.h
+++ b/src/gallium/drivers/softpipe/sp_quad_pipe.h
@@ -49,7 +49,7 @@ struct quad_stage {
void (*begin)(struct quad_stage *qs);
/** the stage action */
- void (*run)(struct quad_stage *qs, struct quad_header *quad);
+ void (*run)(struct quad_stage *qs, struct quad_header *quad[], unsigned nr);
void (*destroy)(struct quad_stage *qs);
};
@@ -69,6 +69,4 @@ struct quad_stage *sp_quad_output_stage( struct softpipe_context *softpipe );
void sp_build_quad_pipeline(struct softpipe_context *sp);
-void sp_depth_test_quad(struct quad_stage *qs, struct quad_header *quad);
-
#endif /* SP_QUAD_PIPE_H */
diff --git a/src/gallium/drivers/softpipe/sp_quad_stencil.c b/src/gallium/drivers/softpipe/sp_quad_stencil.c
deleted file mode 100644
index 5e9d447737d..00000000000
--- a/src/gallium/drivers/softpipe/sp_quad_stencil.c
+++ /dev/null
@@ -1,352 +0,0 @@
-
-/**
- * \brief Quad stencil testing
- */
-
-
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_tile_cache.h"
-#include "sp_quad_pipe.h"
-#include "pipe/p_defines.h"
-#include "util/u_memory.h"
-
-
-/** Only 8-bit stencil supported */
-#define STENCIL_MAX 0xff
-
-
-/**
- * Do the basic stencil test (compare stencil buffer values against the
- * reference value.
- *
- * \param stencilVals the stencil values from the stencil buffer
- * \param func the stencil func (PIPE_FUNC_x)
- * \param ref the stencil reference value
- * \param valMask the stencil value mask indicating which bits of the stencil
- * values and ref value are to be used.
- * \return mask indicating which pixels passed the stencil test
- */
-static unsigned
-do_stencil_test(const ubyte stencilVals[QUAD_SIZE], unsigned func,
- unsigned ref, unsigned valMask)
-{
- unsigned passMask = 0x0;
- unsigned j;
-
- ref &= valMask;
-
- switch (func) {
- case PIPE_FUNC_NEVER:
- /* passMask = 0x0 */
- break;
- case PIPE_FUNC_LESS:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref < (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_EQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref == (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_LEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref <= (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_GREATER:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref > (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_NOTEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref != (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_GEQUAL:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (ref >= (stencilVals[j] & valMask)) {
- passMask |= (1 << j);
- }
- }
- break;
- case PIPE_FUNC_ALWAYS:
- passMask = MASK_ALL;
- break;
- default:
- assert(0);
- }
-
- return passMask;
-}
-
-
-/**
- * Apply the stencil operator to stencil values.
- *
- * \param stencilVals the stencil buffer values (read and written)
- * \param mask indicates which pixels to update
- * \param op the stencil operator (PIPE_STENCIL_OP_x)
- * \param ref the stencil reference value
- * \param wrtMask writemask controlling which bits are changed in the
- * stencil values
- */
-static void
-apply_stencil_op(ubyte stencilVals[QUAD_SIZE],
- unsigned mask, unsigned op, ubyte ref, ubyte wrtMask)
-{
- unsigned j;
- ubyte newstencil[QUAD_SIZE];
-
- for (j = 0; j < QUAD_SIZE; j++) {
- newstencil[j] = stencilVals[j];
- }
-
- switch (op) {
- case PIPE_STENCIL_OP_KEEP:
- /* no-op */
- break;
- case PIPE_STENCIL_OP_ZERO:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- newstencil[j] = 0;
- }
- }
- break;
- case PIPE_STENCIL_OP_REPLACE:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- newstencil[j] = ref;
- }
- }
- break;
- case PIPE_STENCIL_OP_INCR:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- if (stencilVals[j] < STENCIL_MAX) {
- newstencil[j] = stencilVals[j] + 1;
- }
- }
- }
- break;
- case PIPE_STENCIL_OP_DECR:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- if (stencilVals[j] > 0) {
- newstencil[j] = stencilVals[j] - 1;
- }
- }
- }
- break;
- case PIPE_STENCIL_OP_INCR_WRAP:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- newstencil[j] = stencilVals[j] + 1;
- }
- }
- break;
- case PIPE_STENCIL_OP_DECR_WRAP:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- newstencil[j] = stencilVals[j] - 1;
- }
- }
- break;
- case PIPE_STENCIL_OP_INVERT:
- for (j = 0; j < QUAD_SIZE; j++) {
- if (mask & (1 << j)) {
- newstencil[j] = ~stencilVals[j];
- }
- }
- break;
- default:
- assert(0);
- }
-
- /*
- * update the stencil values
- */
- if (wrtMask != STENCIL_MAX) {
- /* apply bit-wise stencil buffer writemask */
- for (j = 0; j < QUAD_SIZE; j++) {
- stencilVals[j] = (wrtMask & newstencil[j]) | (~wrtMask & stencilVals[j]);
- }
- }
- else {
- for (j = 0; j < QUAD_SIZE; j++) {
- stencilVals[j] = newstencil[j];
- }
- }
-}
-
-
-/**
- * Do stencil (and depth) testing. Stenciling depends on the outcome of
- * depth testing.
- */
-static void
-stencil_test_quad(struct quad_stage *qs, struct quad_header *quad)
-{
- struct softpipe_context *softpipe = qs->softpipe;
- struct pipe_surface *ps = softpipe->framebuffer.zsbuf;
- unsigned func, zFailOp, zPassOp, failOp;
- ubyte ref, wrtMask, valMask;
- ubyte stencilVals[QUAD_SIZE];
- struct softpipe_cached_tile *tile
- = sp_get_cached_tile(softpipe, softpipe->zsbuf_cache, quad->input.x0, quad->input.y0);
- uint j;
- uint face = quad->input.facing;
-
- if (!softpipe->depth_stencil->stencil[1].enabled) {
- /* single-sided stencil test, use front (face=0) state */
- face = 0;
- }
-
- /* choose front or back face function, operator, etc */
- /* XXX we could do these initializations once per primitive */
- func = softpipe->depth_stencil->stencil[face].func;
- failOp = softpipe->depth_stencil->stencil[face].fail_op;
- zFailOp = softpipe->depth_stencil->stencil[face].zfail_op;
- zPassOp = softpipe->depth_stencil->stencil[face].zpass_op;
- ref = softpipe->depth_stencil->stencil[face].ref_value;
- wrtMask = softpipe->depth_stencil->stencil[face].writemask;
- valMask = softpipe->depth_stencil->stencil[face].valuemask;
-
- assert(ps); /* shouldn't get here if there's no stencil buffer */
-
- /* get stencil values from cached tile */
- switch (ps->format) {
- case PIPE_FORMAT_S8Z24_UNORM:
- 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);
- stencilVals[j] = tile->data.depth32[y][x] >> 24;
- }
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- 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);
- stencilVals[j] = tile->data.depth32[y][x] & 0xff;
- }
- break;
- case PIPE_FORMAT_S8_UNORM:
- 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);
- stencilVals[j] = tile->data.stencil8[y][x];
- }
- break;
- default:
- assert(0);
- }
-
- /* do the stencil test first */
- {
- unsigned passMask, failMask;
- passMask = do_stencil_test(stencilVals, func, ref, valMask);
- failMask = quad->inout.mask & ~passMask;
- quad->inout.mask &= passMask;
-
- if (failOp != PIPE_STENCIL_OP_KEEP) {
- apply_stencil_op(stencilVals, failMask, failOp, ref, wrtMask);
- }
- }
-
- if (quad->inout.mask) {
- /* now the pixels that passed the stencil test are depth tested */
- if (softpipe->depth_stencil->depth.enabled) {
- const unsigned origMask = quad->inout.mask;
-
- sp_depth_test_quad(qs, quad); /* quad->mask is updated */
-
- /* update stencil buffer values according to z pass/fail result */
- if (zFailOp != PIPE_STENCIL_OP_KEEP) {
- const unsigned failMask = origMask & ~quad->inout.mask;
- apply_stencil_op(stencilVals, failMask, zFailOp, ref, wrtMask);
- }
-
- if (zPassOp != PIPE_STENCIL_OP_KEEP) {
- const unsigned passMask = origMask & quad->inout.mask;
- apply_stencil_op(stencilVals, passMask, zPassOp, ref, wrtMask);
- }
- }
- else {
- /* no depth test, apply Zpass operator to stencil buffer values */
- apply_stencil_op(stencilVals, quad->inout.mask, zPassOp, ref, wrtMask);
- }
-
- }
-
- /* put new stencil values into cached tile */
- switch (ps->format) {
- case PIPE_FORMAT_S8Z24_UNORM:
- 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);
- uint s8z24 = tile->data.depth32[y][x];
- s8z24 = (stencilVals[j] << 24) | (s8z24 & 0xffffff);
- tile->data.depth32[y][x] = s8z24;
- }
- break;
- case PIPE_FORMAT_Z24S8_UNORM:
- 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);
- uint z24s8 = tile->data.depth32[y][x];
- z24s8 = (z24s8 & 0xffffff00) | stencilVals[j];
- tile->data.depth32[y][x] = z24s8;
- }
- break;
- case PIPE_FORMAT_S8_UNORM:
- 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] = stencilVals[j];
- }
- break;
- default:
- assert(0);
- }
-
- if (quad->inout.mask)
- qs->next->run(qs->next, quad);
-}
-
-
-static void stencil_begin(struct quad_stage *qs)
-{
- qs->next->begin(qs->next);
-}
-
-
-static void stencil_destroy(struct quad_stage *qs)
-{
- FREE( qs );
-}
-
-
-struct quad_stage *sp_quad_stencil_test_stage( struct softpipe_context *softpipe )
-{
- struct quad_stage *stage = CALLOC_STRUCT(quad_stage);
-
- stage->softpipe = softpipe;
- stage->begin = stencil_begin;
- stage->run = stencil_test_quad;
- stage->destroy = stencil_destroy;
-
- return stage;
-}
diff --git a/src/gallium/drivers/softpipe/sp_quad_stipple.c b/src/gallium/drivers/softpipe/sp_quad_stipple.c
index 07162db7b6e..a0527a596a6 100644
--- a/src/gallium/drivers/softpipe/sp_quad_stipple.c
+++ b/src/gallium/drivers/softpipe/sp_quad_stipple.c
@@ -14,14 +14,20 @@
* Apply polygon stipple to quads produced by triangle rasterization
*/
static void
-stipple_quad(struct quad_stage *qs, struct quad_header *quad)
+stipple_quad(struct quad_stage *qs, struct quad_header *quads[], unsigned nr)
{
static const uint bit31 = 1 << 31;
static const uint bit30 = 1 << 30;
+ unsigned pass = nr;
+
+ struct softpipe_context *softpipe = qs->softpipe;
+ unsigned q;
+
+ pass = 0;
+
+ for (q = 0; q < nr; q++) {
+ struct quad_header *quad = quads[q];
- if (quad->input.prim == QUAD_PRIM_TRI) {
- struct softpipe_context *softpipe = qs->softpipe;
- /* need to invert Y to index into OpenGL's stipple pattern */
const int col0 = quad->input.x0 % 32;
const int y0 = quad->input.y0;
const int y1 = y0 + 1;
@@ -41,13 +47,11 @@ stipple_quad(struct quad_stage *qs, struct quad_header *quad)
if ((stipple1 & (bit30 >> col0)) == 0)
quad->inout.mask &= ~MASK_BOTTOM_RIGHT;
- if (!quad->inout.mask) {
- /* all fragments failed stipple test, end of quad pipeline */
- return;
- }
+ if (quad->inout.mask)
+ quads[pass++] = quad;
}
- qs->next->run(qs->next, quad);
+ qs->next->run(qs->next, quads, pass);
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6178c4ac7e3..81fb7aa20c6 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -40,7 +40,7 @@
static const char *
softpipe_get_vendor(struct pipe_screen *screen)
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
@@ -65,8 +65,6 @@ softpipe_get_param(struct pipe_screen *screen, int param)
return 1;
case PIPE_CAP_GLSL:
return 1;
- case PIPE_CAP_S3TC:
- return 0;
case PIPE_CAP_ANISOTROPIC_FILTER:
return 0;
case PIPE_CAP_POINT_SPRITE:
@@ -84,7 +82,7 @@ softpipe_get_param(struct pipe_screen *screen, int param)
case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
return 13; /* max 4Kx4K */
case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
- return 8; /* max 128x128x128 */
+ return 9; /* max 256x256x256 */
case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
return 13; /* max 4Kx4K */
case PIPE_CAP_TGSI_CONT_SUPPORTED:
@@ -137,10 +135,14 @@ softpipe_is_format_supported( struct pipe_screen *screen,
target == PIPE_TEXTURE_CUBE);
switch(format) {
+ case PIPE_FORMAT_L16_UNORM:
+ case PIPE_FORMAT_YCBCR_REV:
+ case PIPE_FORMAT_YCBCR:
case PIPE_FORMAT_DXT1_RGB:
case PIPE_FORMAT_DXT1_RGBA:
case PIPE_FORMAT_DXT3_RGBA:
case PIPE_FORMAT_DXT5_RGBA:
+ case PIPE_FORMAT_Z32_FLOAT:
return FALSE;
default:
return TRUE;
diff --git a/src/gallium/drivers/softpipe/sp_setup.c b/src/gallium/drivers/softpipe/sp_setup.c
index de3ae3c3696..ade125662ad 100644
--- a/src/gallium/drivers/softpipe/sp_setup.c
+++ b/src/gallium/drivers/softpipe/sp_setup.c
@@ -33,7 +33,6 @@
*/
#include "sp_context.h"
-#include "sp_prim_setup.h"
#include "sp_quad.h"
#include "sp_quad_pipe.h"
#include "sp_setup.h"
@@ -61,87 +60,9 @@ struct edge {
int lines; /**< number of lines on this edge */
};
-#if SP_NUM_QUAD_THREADS > 1
-/* Set to 1 if you want other threads to be instantly
- * notified of pending jobs.
- */
-#define INSTANT_NOTEMPTY_NOTIFY 0
-
-struct thread_info
-{
- struct setup_context *setup;
- uint id;
- pipe_thread handle;
-};
-
-struct quad_job;
-
-typedef void (* quad_job_routine)( struct setup_context *setup, uint thread, struct quad_job *job );
-
-struct quad_job
-{
- struct quad_header_input input;
- struct quad_header_inout inout;
- quad_job_routine routine;
-};
-
-#define NUM_QUAD_JOBS 64
-
-struct quad_job_que
-{
- struct quad_job jobs[NUM_QUAD_JOBS];
- uint first;
- uint last;
- pipe_mutex que_mutex;
- pipe_condvar que_notfull_condvar;
- pipe_condvar que_notempty_condvar;
- uint jobs_added;
- uint jobs_done;
- pipe_condvar que_done_condvar;
-};
-
-static void
-add_quad_job( struct quad_job_que *que, struct quad_header *quad, quad_job_routine routine )
-{
-#if INSTANT_NOTEMPTY_NOTIFY
- boolean empty;
-#endif
-
- /* Wait for empty slot, see if the que is empty.
- */
- pipe_mutex_lock( que->que_mutex );
- while ((que->last + 1) % NUM_QUAD_JOBS == que->first) {
-#if !INSTANT_NOTEMPTY_NOTIFY
- pipe_condvar_broadcast( que->que_notempty_condvar );
-#endif
- pipe_condvar_wait( que->que_notfull_condvar, que->que_mutex );
- }
-#if INSTANT_NOTEMPTY_NOTIFY
- empty = que->last == que->first;
-#endif
- que->jobs_added++;
- pipe_mutex_unlock( que->que_mutex );
+#define MAX_QUADS 16
- /* Submit new job.
- */
- que->jobs[que->last].input = quad->input;
- que->jobs[que->last].inout = quad->inout;
- que->jobs[que->last].routine = routine;
- que->last = (que->last + 1) % NUM_QUAD_JOBS;
-
-#if INSTANT_NOTEMPTY_NOTIFY
- /* If the que was empty, notify consumers there's a job to be done.
- */
- if (empty) {
- pipe_mutex_lock( que->que_mutex );
- pipe_condvar_broadcast( que->que_notempty_condvar );
- pipe_mutex_unlock( que->que_mutex );
- }
-#endif
-}
-
-#endif
/**
* Triangle setup info (derived from draw_stage).
@@ -164,22 +85,19 @@ struct setup_context {
struct edge emaj;
float oneoverarea;
+ int facing;
+
+ struct quad_header quad[MAX_QUADS];
+ struct quad_header *quad_ptrs[MAX_QUADS];
+ unsigned count;
struct tgsi_interp_coef coef[PIPE_MAX_SHADER_INPUTS];
struct tgsi_interp_coef posCoef; /* For Z, W */
- struct quad_header quad;
-
-#if SP_NUM_QUAD_THREADS > 1
- struct quad_job_que que;
- struct thread_info threads[SP_NUM_QUAD_THREADS];
-#endif
struct {
int left[2]; /**< [0] = row0, [1] = row1 */
int right[2];
int y;
- unsigned y_flags;
- unsigned mask; /**< mask of MASK_BOTTOM/TOP_LEFT/RIGHT bits */
} span;
#if DEBUG_FRAGS
@@ -190,67 +108,6 @@ struct setup_context {
unsigned winding; /* which winding to cull */
};
-#if SP_NUM_QUAD_THREADS > 1
-
-static PIPE_THREAD_ROUTINE( quad_thread, param )
-{
- struct thread_info *info = (struct thread_info *) param;
- struct quad_job_que *que = &info->setup->que;
-
- for (;;) {
- struct quad_job job;
- boolean full;
-
- /* Wait for an available job.
- */
- pipe_mutex_lock( que->que_mutex );
- while (que->last == que->first)
- pipe_condvar_wait( que->que_notempty_condvar, que->que_mutex );
-
- /* See if the que is full.
- */
- full = (que->last + 1) % NUM_QUAD_JOBS == que->first;
-
- /* Take a job and remove it from que.
- */
- job = que->jobs[que->first];
- que->first = (que->first + 1) % NUM_QUAD_JOBS;
-
- /* Notify the producer if the que is not full.
- */
- if (full)
- pipe_condvar_signal( que->que_notfull_condvar );
- pipe_mutex_unlock( que->que_mutex );
-
- job.routine( info->setup, info->id, &job );
-
- /* Notify the producer if that's the last finished job.
- */
- pipe_mutex_lock( que->que_mutex );
- que->jobs_done++;
- if (que->jobs_added == que->jobs_done)
- pipe_condvar_signal( que->que_done_condvar );
- pipe_mutex_unlock( que->que_mutex );
- }
-
- return NULL;
-}
-
-#define WAIT_FOR_COMPLETION(setup) \
- do {\
- pipe_mutex_lock( setup->que.que_mutex );\
- if (!INSTANT_NOTEMPTY_NOTIFY)\
- pipe_condvar_broadcast( setup->que.que_notempty_condvar );\
- while (setup->que.jobs_added != setup->que.jobs_done)\
- pipe_condvar_wait( setup->que.que_done_condvar, setup->que.que_mutex );\
- pipe_mutex_unlock( setup->que.que_mutex );\
- } while (0)
-
-#else
-
-#define WAIT_FOR_COMPLETION(setup) ((void) 0)
-
-#endif
@@ -313,98 +170,18 @@ quad_clip( struct setup_context *setup, struct quad_header *quad )
* Emit a quad (pass to next stage) with clipping.
*/
static INLINE void
-clip_emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread )
+clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
{
quad_clip( setup, quad );
+
if (quad->inout.mask) {
struct softpipe_context *sp = setup->softpipe;
- sp->quad[thread].first->run( sp->quad[thread].first, quad );
+ sp->quad.first->run( sp->quad.first, &quad, 1 );
}
}
-#if SP_NUM_QUAD_THREADS > 1
-
-static void
-clip_emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job )
-{
- struct quad_header quad;
-
- quad.input = job->input;
- quad.inout = job->inout;
- quad.coef = setup->quad.coef;
- quad.posCoef = setup->quad.posCoef;
- quad.nr_attrs = setup->quad.nr_attrs;
- clip_emit_quad( setup, &quad, thread );
-}
-
-#define CLIP_EMIT_QUAD(setup) add_quad_job( &setup->que, &setup->quad, clip_emit_quad_job )
-
-#else
-
-#define CLIP_EMIT_QUAD(setup) clip_emit_quad( setup, &setup->quad, 0 )
-
-#endif
-
-/**
- * Emit a quad (pass to next stage). No clipping is done.
- */
-static INLINE void
-emit_quad( struct setup_context *setup, struct quad_header *quad, uint thread )
-{
- struct softpipe_context *sp = setup->softpipe;
-#if DEBUG_FRAGS
- uint mask = quad->inout.mask;
-#endif
-
-#if DEBUG_FRAGS
- if (mask & 1) setup->numFragsEmitted++;
- if (mask & 2) setup->numFragsEmitted++;
- if (mask & 4) setup->numFragsEmitted++;
- if (mask & 8) setup->numFragsEmitted++;
-#endif
- sp->quad[thread].first->run( sp->quad[thread].first, quad );
-#if DEBUG_FRAGS
- mask = quad->inout.mask;
- if (mask & 1) setup->numFragsWritten++;
- if (mask & 2) setup->numFragsWritten++;
- if (mask & 4) setup->numFragsWritten++;
- if (mask & 8) setup->numFragsWritten++;
-#endif
-}
-
-#if SP_NUM_QUAD_THREADS > 1
-static void
-emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job )
-{
- struct quad_header quad;
-
- quad.input = job->input;
- quad.inout = job->inout;
- quad.coef = setup->quad.coef;
- quad.posCoef = setup->quad.posCoef;
- quad.nr_attrs = setup->quad.nr_attrs;
- emit_quad( setup, &quad, thread );
-}
-
-#define EMIT_QUAD(setup,x,y,mask) do {\
- setup->quad.input.x0 = x;\
- setup->quad.input.y0 = y;\
- setup->quad.inout.mask = mask;\
- add_quad_job( &setup->que, &setup->quad, emit_quad_job );\
- } while (0)
-
-#else
-
-#define EMIT_QUAD(setup,x,y,mask) do {\
- setup->quad.input.x0 = x;\
- setup->quad.input.y0 = y;\
- setup->quad.inout.mask = mask;\
- emit_quad( setup, &setup->quad, 0 );\
- } while (0)
-
-#endif
/**
* Given an X or Y coordinate, return the block/quad coordinate that it
@@ -412,7 +189,12 @@ emit_quad_job( struct setup_context *setup, uint thread, struct quad_job *job )
*/
static INLINE int block( int x )
{
- return x & ~1;
+ return x & ~(2-1);
+}
+
+static INLINE int block_x( int x )
+{
+ return x & ~(16-1);
}
@@ -421,72 +203,63 @@ static INLINE int block( int x )
*/
static void flush_spans( struct setup_context *setup )
{
+ const int step = 16;
const int xleft0 = setup->span.left[0];
const int xleft1 = setup->span.left[1];
const int xright0 = setup->span.right[0];
const int xright1 = setup->span.right[1];
- int minleft, maxright;
+ struct quad_stage *pipe = setup->softpipe->quad.first;
+
+
+ int minleft = block_x(MIN2(xleft0, xleft1));
+ int maxright = MAX2(xright0, xright1);
int x;
- switch (setup->span.y_flags) {
- case 0x3:
- /* both odd and even lines written (both quad rows) */
- minleft = block(MIN2(xleft0, xleft1));
- maxright = block(MAX2(xright0, xright1));
- for (x = minleft; x <= maxright; x += 2) {
- /* determine which of the four pixels is inside the span bounds */
- uint mask = 0x0;
- if (x >= xleft0 && x < xright0)
- mask |= MASK_TOP_LEFT;
- if (x >= xleft1 && x < xright1)
- mask |= MASK_BOTTOM_LEFT;
- if (x+1 >= xleft0 && x+1 < xright0)
- mask |= MASK_TOP_RIGHT;
- if (x+1 >= xleft1 && x+1 < xright1)
- mask |= MASK_BOTTOM_RIGHT;
- if (mask)
- EMIT_QUAD( setup, x, setup->span.y, mask );
- }
- break;
-
- case 0x1:
- /* only even line written (quad top row) */
- minleft = block(xleft0);
- maxright = block(xright0);
- for (x = minleft; x <= maxright; x += 2) {
- uint mask = 0x0;
- if (x >= xleft0 && x < xright0)
- mask |= MASK_TOP_LEFT;
- if (x+1 >= xleft0 && x+1 < xright0)
- mask |= MASK_TOP_RIGHT;
- if (mask)
- EMIT_QUAD( setup, x, setup->span.y, mask );
- }
- break;
-
- case 0x2:
- /* only odd line written (quad bottom row) */
- minleft = block(xleft1);
- maxright = block(xright1);
- for (x = minleft; x <= maxright; x += 2) {
- uint mask = 0x0;
- if (x >= xleft1 && x < xright1)
- mask |= MASK_BOTTOM_LEFT;
- if (x+1 >= xleft1 && x+1 < xright1)
- mask |= MASK_BOTTOM_RIGHT;
- if (mask)
- EMIT_QUAD( setup, x, setup->span.y, mask );
- }
- break;
+ for (x = minleft; x < maxright; x += step) {
+ unsigned skip_left0 = CLAMP(xleft0 - x, 0, step);
+ unsigned skip_left1 = CLAMP(xleft1 - x, 0, step);
+ unsigned skip_right0 = CLAMP(x + step - xright0, 0, step);
+ unsigned skip_right1 = CLAMP(x + step - xright1, 0, step);
+ unsigned lx = x;
+ unsigned q = 0;
- default:
- return;
+ unsigned skipmask_left0 = (1U << skip_left0) - 1U;
+ unsigned skipmask_left1 = (1U << skip_left1) - 1U;
+
+ /* These calculations fail when step == 32 and skip_right == 0.
+ */
+ unsigned skipmask_right0 = ~0U << (unsigned)(step - skip_right0);
+ unsigned skipmask_right1 = ~0U << (unsigned)(step - skip_right1);
+
+ unsigned mask0 = ~skipmask_left0 & ~skipmask_right0;
+ unsigned mask1 = ~skipmask_left1 & ~skipmask_right1;
+
+ if (mask0 | mask1) {
+ do {
+ unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2);
+ if (quadmask) {
+ setup->quad[q].input.x0 = lx;
+ setup->quad[q].input.y0 = setup->span.y;
+ setup->quad[q].input.facing = setup->facing;
+ setup->quad[q].inout.mask = quadmask;
+ setup->quad_ptrs[q] = &setup->quad[q];
+ q++;
+ }
+ mask0 >>= 2;
+ mask1 >>= 2;
+ lx += 2;
+ } while (mask0 | mask1);
+
+ pipe->run( pipe, setup->quad_ptrs, q );
+ }
}
+
setup->span.y = 0;
- setup->span.y_flags = 0;
setup->span.right[0] = 0;
setup->span.right[1] = 0;
+ setup->span.left[0] = 1000000; /* greater than right[0] */
+ setup->span.left[1] = 1000000; /* greater than right[1] */
}
@@ -496,7 +269,7 @@ static void print_vertex(const struct setup_context *setup,
{
int i;
debug_printf(" Vertex: (%p)\n", v);
- for (i = 0; i < setup->quad.nr_attrs; i++) {
+ for (i = 0; i < setup->quad[0].nr_attrs; i++) {
debug_printf(" %d: %f %f %f %f\n", i,
v[i][0], v[i][1], v[i][2], v[i][3]);
if (util_is_inf_or_nan(v[i][0])) {
@@ -601,7 +374,9 @@ static boolean setup_sort_vertices( struct setup_context *setup,
* - the GLSL gl_FrontFacing fragment attribute (bool)
* - two-sided stencil test
*/
- setup->quad.input.facing = (det > 0.0) ^ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW);
+ setup->facing =
+ ((det > 0.0) ^
+ (setup->softpipe->rasterizer->front_winding == PIPE_WINDING_CW));
return TRUE;
}
@@ -788,7 +563,7 @@ static void setup_tri_coefficients( struct setup_context *setup )
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing;
+ setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
@@ -844,11 +619,10 @@ static void subtriangle( struct setup_context *setup,
/* clip top/bottom */
start_y = sy;
- finish_y = sy + lines;
-
if (start_y < miny)
start_y = miny;
+ finish_y = sy + lines;
if (finish_y > maxy)
finish_y = maxy;
@@ -885,7 +659,6 @@ static void subtriangle( struct setup_context *setup,
setup->span.left[_y&1] = left;
setup->span.right[_y&1] = right;
- setup->span.y_flags |= 1<<(_y&1);
}
}
@@ -958,10 +731,9 @@ void setup_tri( struct setup_context *setup,
setup_tri_coefficients( setup );
setup_tri_edges( setup );
- setup->quad.input.prim = QUAD_PRIM_TRI;
+ assert(setup->softpipe->reduced_prim == PIPE_PRIM_TRIANGLES);
setup->span.y = 0;
- setup->span.y_flags = 0;
setup->span.right[0] = 0;
setup->span.right[1] = 0;
/* setup->span.z_mode = tri_z_mode( setup->ctx ); */
@@ -983,8 +755,6 @@ void setup_tri( struct setup_context *setup,
flush_spans( setup );
- WAIT_FOR_COMPLETION(setup);
-
#if DEBUG_FRAGS
printf("Tri: %u frags emitted, %u written\n",
setup->numFragsEmitted,
@@ -1101,7 +871,7 @@ setup_line_coefficients(struct setup_context *setup,
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing;
+ setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
@@ -1122,20 +892,20 @@ plot(struct setup_context *setup, int x, int y)
const int quadY = y - iy;
const int mask = (1 << ix) << (2 * iy);
- if (quadX != setup->quad.input.x0 ||
- quadY != setup->quad.input.y0)
+ if (quadX != setup->quad[0].input.x0 ||
+ quadY != setup->quad[0].input.y0)
{
/* flush prev quad, start new quad */
- if (setup->quad.input.x0 != -1)
- CLIP_EMIT_QUAD(setup);
+ if (setup->quad[0].input.x0 != -1)
+ clip_emit_quad( setup, &setup->quad[0] );
- setup->quad.input.x0 = quadX;
- setup->quad.input.y0 = quadY;
- setup->quad.inout.mask = 0x0;
+ setup->quad[0].input.x0 = quadX;
+ setup->quad[0].input.y0 = quadY;
+ setup->quad[0].inout.mask = 0x0;
}
- setup->quad.inout.mask |= mask;
+ setup->quad[0].inout.mask |= mask;
}
@@ -1195,17 +965,18 @@ setup_line(struct setup_context *setup,
assert(dx >= 0);
assert(dy >= 0);
+ assert(setup->softpipe->reduced_prim == PIPE_PRIM_LINES);
+
+ setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1;
+ setup->quad[0].inout.mask = 0x0;
- setup->quad.input.x0 = setup->quad.input.y0 = -1;
- setup->quad.inout.mask = 0x0;
- setup->quad.input.prim = QUAD_PRIM_LINE;
/* XXX temporary: set coverage to 1.0 so the line appears
* if AA mode happens to be enabled.
*/
- setup->quad.input.coverage[0] =
- setup->quad.input.coverage[1] =
- setup->quad.input.coverage[2] =
- setup->quad.input.coverage[3] = 1.0;
+ setup->quad[0].input.coverage[0] =
+ setup->quad[0].input.coverage[1] =
+ setup->quad[0].input.coverage[2] =
+ setup->quad[0].input.coverage[3] = 1.0;
if (dx > dy) {
/*** X-major line ***/
@@ -1249,11 +1020,9 @@ setup_line(struct setup_context *setup,
}
/* draw final quad */
- if (setup->quad.inout.mask) {
- CLIP_EMIT_QUAD(setup);
+ if (setup->quad[0].inout.mask) {
+ clip_emit_quad( setup, &setup->quad[0] );
}
-
- WAIT_FOR_COMPLETION(setup);
}
@@ -1300,6 +1069,8 @@ setup_point( struct setup_context *setup,
if (softpipe->no_rast)
return;
+ assert(setup->softpipe->reduced_prim == PIPE_PRIM_POINTS);
+
/* For points, all interpolants are constant-valued.
* However, for point sprites, we'll need to setup texcoords appropriately.
* XXX: which coefficients are the texcoords???
@@ -1346,22 +1117,21 @@ setup_point( struct setup_context *setup,
}
if (spfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
- setup->coef[fragSlot].a0[0] = 1.0f - setup->quad.input.facing;
+ setup->coef[fragSlot].a0[0] = 1.0f - setup->facing;
setup->coef[fragSlot].dadx[0] = 0.0;
setup->coef[fragSlot].dady[0] = 0.0;
}
}
- setup->quad.input.prim = QUAD_PRIM_POINT;
if (halfSize <= 0.5 && !round) {
/* special case for 1-pixel points */
const int ix = ((int) x) & 1;
const int iy = ((int) y) & 1;
- setup->quad.input.x0 = (int) x - ix;
- setup->quad.input.y0 = (int) y - iy;
- setup->quad.inout.mask = (1 << ix) << (2 * iy);
- CLIP_EMIT_QUAD(setup);
+ setup->quad[0].input.x0 = (int) x - ix;
+ setup->quad[0].input.y0 = (int) y - iy;
+ setup->quad[0].inout.mask = (1 << ix) << (2 * iy);
+ clip_emit_quad( setup, &setup->quad[0] );
}
else {
if (round) {
@@ -1381,15 +1151,15 @@ setup_point( struct setup_context *setup,
for (ix = ixmin; ix <= ixmax; ix += 2) {
float dx, dy, dist2, cover;
- setup->quad.inout.mask = 0x0;
+ setup->quad[0].inout.mask = 0x0;
dx = (ix + 0.5f) - x;
dy = (iy + 0.5f) - y;
dist2 = dx * dx + dy * dy;
if (dist2 <= rmax2) {
cover = 1.0F - (dist2 - rmin2) * cscale;
- setup->quad.input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f);
- setup->quad.inout.mask |= MASK_TOP_LEFT;
+ setup->quad[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_TOP_LEFT;
}
dx = (ix + 1.5f) - x;
@@ -1397,8 +1167,8 @@ setup_point( struct setup_context *setup,
dist2 = dx * dx + dy * dy;
if (dist2 <= rmax2) {
cover = 1.0F - (dist2 - rmin2) * cscale;
- setup->quad.input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f);
- setup->quad.inout.mask |= MASK_TOP_RIGHT;
+ setup->quad[0].input.coverage[QUAD_TOP_RIGHT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_TOP_RIGHT;
}
dx = (ix + 0.5f) - x;
@@ -1406,8 +1176,8 @@ setup_point( struct setup_context *setup,
dist2 = dx * dx + dy * dy;
if (dist2 <= rmax2) {
cover = 1.0F - (dist2 - rmin2) * cscale;
- setup->quad.input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f);
- setup->quad.inout.mask |= MASK_BOTTOM_LEFT;
+ setup->quad[0].input.coverage[QUAD_BOTTOM_LEFT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_BOTTOM_LEFT;
}
dx = (ix + 1.5f) - x;
@@ -1415,14 +1185,14 @@ setup_point( struct setup_context *setup,
dist2 = dx * dx + dy * dy;
if (dist2 <= rmax2) {
cover = 1.0F - (dist2 - rmin2) * cscale;
- setup->quad.input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f);
- setup->quad.inout.mask |= MASK_BOTTOM_RIGHT;
+ setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT;
}
- if (setup->quad.inout.mask) {
- setup->quad.input.x0 = ix;
- setup->quad.input.y0 = iy;
- CLIP_EMIT_QUAD(setup);
+ if (setup->quad[0].inout.mask) {
+ setup->quad[0].input.x0 = ix;
+ setup->quad[0].input.y0 = iy;
+ clip_emit_quad( setup, &setup->quad[0] );
}
}
}
@@ -1466,33 +1236,25 @@ setup_point( struct setup_context *setup,
mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
}
- setup->quad.inout.mask = mask;
- setup->quad.input.x0 = ix;
- setup->quad.input.y0 = iy;
- CLIP_EMIT_QUAD(setup);
+ setup->quad[0].inout.mask = mask;
+ setup->quad[0].input.x0 = ix;
+ setup->quad[0].input.y0 = iy;
+ clip_emit_quad( setup, &setup->quad[0] );
}
}
}
}
-
- WAIT_FOR_COMPLETION(setup);
}
void setup_prepare( struct setup_context *setup )
{
struct softpipe_context *sp = setup->softpipe;
- unsigned i;
if (sp->dirty) {
softpipe_update_derived(sp);
}
- /* Note: nr_attrs is only used for debugging (vertex printing) */
- setup->quad.nr_attrs = draw_num_vs_outputs(sp->draw);
-
- for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
- sp->quad[i].first->begin( sp->quad[i].first );
- }
+ sp->quad.first->begin( sp->quad.first );
if (sp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
sp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL &&
@@ -1520,30 +1282,17 @@ void setup_destroy_context( struct setup_context *setup )
struct setup_context *setup_create_context( struct softpipe_context *softpipe )
{
struct setup_context *setup = CALLOC_STRUCT(setup_context);
-#if SP_NUM_QUAD_THREADS > 1
- uint i;
-#endif
+ unsigned i;
setup->softpipe = softpipe;
- setup->quad.coef = setup->coef;
- setup->quad.posCoef = &setup->posCoef;
-
-#if SP_NUM_QUAD_THREADS > 1
- setup->que.first = 0;
- setup->que.last = 0;
- pipe_mutex_init( setup->que.que_mutex );
- pipe_condvar_init( setup->que.que_notfull_condvar );
- pipe_condvar_init( setup->que.que_notempty_condvar );
- setup->que.jobs_added = 0;
- setup->que.jobs_done = 0;
- pipe_condvar_init( setup->que.que_done_condvar );
- for (i = 0; i < SP_NUM_QUAD_THREADS; i++) {
- setup->threads[i].setup = setup;
- setup->threads[i].id = i;
- setup->threads[i].handle = pipe_thread_create( quad_thread, &setup->threads[i] );
+ for (i = 0; i < MAX_QUADS; i++) {
+ setup->quad[i].coef = setup->coef;
+ setup->quad[i].posCoef = &setup->posCoef;
}
-#endif
+
+ setup->span.left[0] = 1000000; /* greater than right[0] */
+ setup->span.left[1] = 1000000; /* greater than right[1] */
return setup;
}
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 9776e978e3e..77ee3c1136b 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -87,6 +87,7 @@ struct sp_fragment_shader {
struct sp_vertex_shader {
struct pipe_shader_state shader;
struct draw_vertex_shader *draw_data;
+ int max_sampler; /* -1 if no samplers */
};
diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c
index 384fe559afd..efed082f823 100644
--- a/src/gallium/drivers/softpipe/sp_state_blend.c
+++ b/src/gallium/drivers/softpipe/sp_state_blend.c
@@ -45,7 +45,7 @@ void softpipe_bind_blend_state( struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->blend = (const struct pipe_blend_state *)blend;
+ softpipe->blend = (struct pipe_blend_state *)blend;
softpipe->dirty |= SP_NEW_BLEND;
}
@@ -86,7 +86,7 @@ softpipe_bind_depth_stencil_state(struct pipe_context *pipe,
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
+ softpipe->depth_stencil = (struct pipe_depth_stencil_alpha_state *)depth_stencil;
softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA;
}
diff --git a/src/gallium/drivers/softpipe/sp_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 75551000c9b..1faeca1c2a3 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -32,7 +32,10 @@
#include "draw/draw_vertex.h"
#include "draw/draw_private.h"
#include "sp_context.h"
+#include "sp_screen.h"
#include "sp_state.h"
+#include "sp_texture.h"
+#include "sp_tex_tile_cache.h"
/**
@@ -65,24 +68,19 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
const struct sp_fragment_shader *spfs = softpipe->fs;
const enum interp_mode colorInterp
= softpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
+ struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
+ const uint num = draw_num_vs_outputs(softpipe->draw);
uint i;
- if (softpipe->vbuf) {
- /* if using the post-transform vertex buffer, tell draw_vbuf to
- * simply emit the whole post-xform vertex as-is:
- */
- struct vertex_info *vinfo_vbuf = &softpipe->vertex_info_vbuf;
- const uint num = draw_num_vs_outputs(softpipe->draw);
- uint i;
-
- /* No longer any need to try and emit draw vertex_header info.
- */
- vinfo_vbuf->num_attribs = 0;
- for (i = 0; i < num; i++) {
- draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
- }
- draw_compute_vertex_size(vinfo_vbuf);
+ /* Tell draw_vbuf to simply emit the whole post-xform vertex
+ * as-is. No longer any need to try and emit draw vertex_header
+ * info.
+ */
+ vinfo_vbuf->num_attribs = 0;
+ for (i = 0; i < num; i++) {
+ draw_emit_vertex_attr(vinfo_vbuf, EMIT_4F, INTERP_PERSPECTIVE, i);
}
+ draw_compute_vertex_size(vinfo_vbuf);
/*
* Loop over fragment shader inputs, searching for the matching output
@@ -91,6 +89,23 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
vinfo->num_attribs = 0;
for (i = 0; i < spfs->info.num_inputs; i++) {
int src;
+ enum interp_mode interp;
+
+ switch (spfs->info.input_interpolate[i]) {
+ case TGSI_INTERPOLATE_CONSTANT:
+ interp = INTERP_CONSTANT;
+ break;
+ case TGSI_INTERPOLATE_LINEAR:
+ interp = INTERP_LINEAR;
+ break;
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ interp = INTERP_PERSPECTIVE;
+ break;
+ default:
+ assert(0);
+ interp = INTERP_LINEAR;
+ }
+
switch (spfs->info.input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
src = draw_find_vs_output(softpipe->draw,
@@ -106,7 +121,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
case TGSI_SEMANTIC_FOG:
src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_FOG, 0);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
break;
case TGSI_SEMANTIC_GENERIC:
@@ -114,7 +129,7 @@ softpipe_get_vertex_info(struct softpipe_context *softpipe)
/* this includes texcoords and varying vars */
src = draw_find_vs_output(softpipe->draw, TGSI_SEMANTIC_GENERIC,
spfs->info.input_semantic_index[i]);
- draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_PERSPECTIVE, src);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
break;
default:
@@ -164,11 +179,19 @@ softpipe_get_vbuf_vertex_info(struct softpipe_context *softpipe)
static void
compute_cliprect(struct softpipe_context *sp)
{
+ /* SP_NEW_FRAMEBUFFER
+ */
uint surfWidth = sp->framebuffer.width;
uint surfHeight = sp->framebuffer.height;
+ /* SP_NEW_RASTERIZER
+ */
if (sp->rasterizer->scissor) {
- /* clip to scissor rect */
+
+ /* SP_NEW_SCISSOR
+ *
+ * clip to scissor rect:
+ */
sp->cliprect.minx = MAX2(sp->scissor.minx, 0);
sp->cliprect.miny = MAX2(sp->scissor.miny, 0);
sp->cliprect.maxx = MIN2(sp->scissor.maxx, surfWidth);
@@ -184,27 +207,63 @@ compute_cliprect(struct softpipe_context *sp)
}
+static void
+update_tgsi_samplers( struct softpipe_context *softpipe )
+{
+ unsigned i;
+
+ softpipe_reset_sampler_varients( softpipe );
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ struct softpipe_tex_tile_cache *tc = softpipe->tex_cache[i];
+ if (tc->texture) {
+ struct softpipe_texture *spt = softpipe_texture(tc->texture);
+ if (spt->timestamp != tc->timestamp) {
+ sp_tex_tile_cache_validate_texture( tc );
+ /*
+ _debug_printf("INV %d %d\n", tc->timestamp, spt->timestamp);
+ */
+ tc->timestamp = spt->timestamp;
+ }
+ }
+ }
+}
+
+
/* Hopefully this will remain quite simple, otherwise need to pull in
* something like the state tracker mechanism.
*/
void softpipe_update_derived( struct softpipe_context *softpipe )
{
+ struct softpipe_screen *sp_screen = softpipe_screen(softpipe->pipe.screen);
+
+ /* Check for updated textures.
+ */
+ if (softpipe->tex_timestamp != sp_screen->timestamp) {
+ softpipe->tex_timestamp = sp_screen->timestamp;
+ softpipe->dirty |= SP_NEW_TEXTURE;
+ }
+
+ if (softpipe->dirty & (SP_NEW_SAMPLER |
+ SP_NEW_TEXTURE |
+ SP_NEW_FS |
+ SP_NEW_VS))
+ update_tgsi_samplers( softpipe );
+
if (softpipe->dirty & (SP_NEW_RASTERIZER |
SP_NEW_FS |
SP_NEW_VS))
invalidate_vertex_layout( softpipe );
if (softpipe->dirty & (SP_NEW_SCISSOR |
- SP_NEW_DEPTH_STENCIL_ALPHA |
+ SP_NEW_RASTERIZER |
SP_NEW_FRAMEBUFFER))
compute_cliprect(softpipe);
if (softpipe->dirty & (SP_NEW_BLEND |
SP_NEW_DEPTH_STENCIL_ALPHA |
SP_NEW_FRAMEBUFFER |
- SP_NEW_RASTERIZER |
- SP_NEW_FS |
- SP_NEW_QUERY))
+ SP_NEW_FS))
sp_build_quad_pipeline(softpipe);
softpipe->dirty = 0;
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 4330c203935..256faa94b84 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -31,9 +31,8 @@
#include "pipe/p_defines.h"
#include "util/u_memory.h"
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_shader_tokens.h"
#include "draw/draw_context.h"
+#include "draw/draw_vs.h"
#include "tgsi/tgsi_dump.h"
#include "tgsi/tgsi_scan.h"
#include "tgsi/tgsi_parse.h"
@@ -51,12 +50,9 @@ softpipe_create_fs_state(struct pipe_context *pipe,
tgsi_dump(templ->tokens, 0);
/* codegen */
- state = softpipe_create_fs_llvm( softpipe, templ );
+ state = softpipe_create_fs_sse( softpipe, templ );
if (!state) {
- state = softpipe_create_fs_sse( softpipe, templ );
- if (!state) {
- state = softpipe_create_fs_exec( softpipe, templ );
- }
+ state = softpipe_create_fs_exec( softpipe, templ );
}
assert(state);
@@ -111,6 +107,8 @@ softpipe_create_vs_state(struct pipe_context *pipe,
if (state->draw_data == NULL)
goto fail;
+ state->max_sampler = state->draw_data->info.file_max[TGSI_FILE_SAMPLER];
+
return state;
fail:
@@ -128,7 +126,7 @@ softpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- softpipe->vs = (const struct sp_vertex_shader *)vs;
+ softpipe->vs = (struct sp_vertex_shader *) vs;
draw_bind_vertex_shader(softpipe->draw,
(softpipe->vs ? softpipe->vs->draw_data : NULL));
@@ -142,8 +140,7 @@ softpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct softpipe_context *softpipe = softpipe_context(pipe);
- struct sp_vertex_shader *state =
- (struct sp_vertex_shader *)vs;
+ struct sp_vertex_shader *state = (struct sp_vertex_shader *) vs;
draw_delete_vertex_shader(softpipe->draw, state->draw_data);
FREE( state );
diff --git a/src/gallium/drivers/softpipe/sp_state_sampler.c b/src/gallium/drivers/softpipe/sp_state_sampler.c
index cb517b02e44..db0b8ab76b1 100644
--- a/src/gallium/drivers/softpipe/sp_state_sampler.c
+++ b/src/gallium/drivers/softpipe/sp_state_sampler.c
@@ -32,21 +32,37 @@
#include "util/u_memory.h"
#include "draw/draw_context.h"
+#include "draw/draw_context.h"
#include "sp_context.h"
-#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
-#include "sp_tile_cache.h"
-#include "draw/draw_context.h"
+#include "sp_tex_sample.h"
+#include "sp_tex_tile_cache.h"
+struct sp_sampler {
+ struct pipe_sampler_state base;
+ struct sp_sampler_varient *varients;
+ struct sp_sampler_varient *current;
+};
+
+static struct sp_sampler *sp_sampler( struct pipe_sampler_state *sampler )
+{
+ return (struct sp_sampler *)sampler;
+}
+
void *
softpipe_create_sampler_state(struct pipe_context *pipe,
const struct pipe_sampler_state *sampler)
{
- return mem_dup(sampler, sizeof(*sampler));
+ struct sp_sampler *sp_sampler = CALLOC_STRUCT(sp_sampler);
+
+ sp_sampler->base = *sampler;
+ sp_sampler->varients = NULL;
+
+ return (void *)sp_sampler;
}
@@ -97,7 +113,7 @@ softpipe_set_sampler_textures(struct pipe_context *pipe,
struct pipe_texture *tex = i < num ? texture[i] : NULL;
pipe_texture_reference(&softpipe->texture[i], tex);
- sp_tile_cache_set_texture(pipe, softpipe->tex_cache[i], tex);
+ sp_tex_tile_cache_set_texture(softpipe->tex_cache[i], tex);
}
softpipe->num_textures = num;
@@ -106,10 +122,111 @@ softpipe_set_sampler_textures(struct pipe_context *pipe,
}
+/**
+ * Find/create an sp_sampler_varient object for sampling the given texture,
+ * sampler and tex unit.
+ *
+ * Note that the tex unit is significant. We can't re-use a sampler
+ * varient for multiple texture units because the sampler varient contains
+ * the texture object pointer. If the texture object pointer were stored
+ * somewhere outside the sampler varient, we could re-use samplers for
+ * multiple texture units.
+ */
+static struct sp_sampler_varient *
+get_sampler_varient( unsigned unit,
+ struct sp_sampler *sampler,
+ struct pipe_texture *texture,
+ unsigned processor )
+{
+ struct softpipe_texture *sp_texture = softpipe_texture(texture);
+ struct sp_sampler_varient *v = NULL;
+ union sp_sampler_key key;
+
+ /* if this fails, widen the key.unit field and update this assertion */
+ assert(PIPE_MAX_SAMPLERS <= 16);
+
+ key.bits.target = sp_texture->base.target;
+ key.bits.is_pot = sp_texture->pot;
+ key.bits.processor = processor;
+ key.bits.unit = unit;
+ key.bits.pad = 0;
+
+ if (sampler->current &&
+ key.value == sampler->current->key.value) {
+ v = sampler->current;
+ }
+
+ if (v == NULL) {
+ for (v = sampler->varients; v; v = v->next)
+ if (v->key.value == key.value)
+ break;
+
+ if (v == NULL) {
+ v = sp_create_sampler_varient( &sampler->base, key );
+ v->next = sampler->varients;
+ sampler->varients = v;
+ }
+ }
+
+ sampler->current = v;
+ return v;
+}
+
+
+
+
+void
+softpipe_reset_sampler_varients(struct softpipe_context *softpipe)
+{
+ int i;
+
+ /* It's a bit hard to build these samplers ahead of time -- don't
+ * really know which samplers are going to be used for vertex and
+ * fragment programs.
+ */
+ for (i = 0; i <= softpipe->vs->max_sampler; i++) {
+ if (softpipe->sampler[i]) {
+ softpipe->tgsi.vert_samplers_list[i] =
+ get_sampler_varient( i,
+ sp_sampler(softpipe->sampler[i]),
+ softpipe->texture[i],
+ TGSI_PROCESSOR_VERTEX );
+
+ sp_sampler_varient_bind_texture( softpipe->tgsi.vert_samplers_list[i],
+ softpipe->tex_cache[i],
+ softpipe->texture[i] );
+ }
+ }
+
+ for (i = 0; i <= softpipe->fs->info.file_max[TGSI_FILE_SAMPLER]; i++) {
+ if (softpipe->sampler[i]) {
+ softpipe->tgsi.frag_samplers_list[i] =
+ get_sampler_varient( i,
+ sp_sampler(softpipe->sampler[i]),
+ softpipe->texture[i],
+ TGSI_PROCESSOR_FRAGMENT );
+
+ sp_sampler_varient_bind_texture( softpipe->tgsi.frag_samplers_list[i],
+ softpipe->tex_cache[i],
+ softpipe->texture[i] );
+ }
+ }
+}
+
+
+
void
softpipe_delete_sampler_state(struct pipe_context *pipe,
void *sampler)
{
+ struct sp_sampler *sp_sampler = (struct sp_sampler *)sampler;
+ struct sp_sampler_varient *v, *tmp;
+
+ for (v = sp_sampler->varients; v; v = tmp) {
+ tmp = v->next;
+ sp_sampler_varient_destroy(v);
+ }
+
FREE( sampler );
}
diff --git a/src/gallium/drivers/softpipe/sp_state_surface.c b/src/gallium/drivers/softpipe/sp_state_surface.c
index 7c06d864a75..c8f55c3cec4 100644
--- a/src/gallium/drivers/softpipe/sp_state_surface.c
+++ b/src/gallium/drivers/softpipe/sp_state_surface.c
@@ -53,7 +53,7 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
/* check if changing cbuf */
if (sp->framebuffer.cbufs[i] != fb->cbufs[i]) {
/* flush old */
- sp_flush_tile_cache(sp, sp->cbuf_cache[i]);
+ sp_flush_tile_cache(sp->cbuf_cache[i]);
/* assign new */
sp->framebuffer.cbufs[i] = fb->cbufs[i];
@@ -68,58 +68,28 @@ softpipe_set_framebuffer_state(struct pipe_context *pipe,
/* zbuf changing? */
if (sp->framebuffer.zsbuf != fb->zsbuf) {
/* flush old */
- sp_flush_tile_cache(sp, sp->zsbuf_cache);
+ sp_flush_tile_cache(sp->zsbuf_cache);
/* assign new */
sp->framebuffer.zsbuf = fb->zsbuf;
/* update cache */
sp_tile_cache_set_surface(sp->zsbuf_cache, fb->zsbuf);
- }
-
-#if 0
- /* XXX combined depth/stencil here */
-
- /* sbuf changing? */
- if (sp->framebuffer.sbuf != fb->sbuf) {
- /* flush old */
- sp_flush_tile_cache(sp, sp->sbuf_cache_sep);
-
- /* assign new */
- sp->framebuffer.sbuf = fb->sbuf;
-
- /* update cache */
- if (fb->sbuf != fb->zbuf) {
- /* separate stencil buf */
- sp->sbuf_cache = sp->sbuf_cache_sep;
- sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf);
- }
- else {
- /* combined depth/stencil */
- sp->sbuf_cache = sp->zbuf_cache;
- sp_tile_cache_set_surface(sp->sbuf_cache, fb->sbuf);
- }
- }
-#endif
- /* Tell draw module how deep the Z/depth buffer is */
- {
- int depth_bits;
- double mrd;
+ /* Tell draw module how deep the Z/depth buffer is */
if (sp->framebuffer.zsbuf) {
+ int depth_bits;
+ double mrd;
depth_bits = pf_get_component_bits(sp->framebuffer.zsbuf->format,
PIPE_FORMAT_COMP_Z);
+ if (depth_bits > 16) {
+ mrd = 0.0000001;
+ }
+ else {
+ mrd = 0.00002;
+ }
+ draw_set_mrd(sp->draw, mrd);
}
- else {
- depth_bits = 0;
- }
- if (depth_bits > 16) {
- mrd = 0.0000001;
- }
- else {
- mrd = 0.00002;
- }
- draw_set_mrd(sp->draw, mrd);
}
sp->framebuffer.width = fb->width;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index a1d3bade27a..c22ee86b66c 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -31,29 +31,33 @@
*
* Authors:
* Brian Paul
+ * Keith Whitwell
*/
-#include "sp_context.h"
-#include "sp_quad.h"
-#include "sp_surface.h"
-#include "sp_texture.h"
-#include "sp_tex_sample.h"
-#include "sp_tile_cache.h"
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "sp_quad.h" /* only for #define QUAD_* tokens */
+#include "sp_tex_sample.h"
+#include "sp_tex_tile_cache.h"
/*
- * Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
- * see 1-pixel bands of improperly weighted linear-filtered textures.
+ * Return fractional part of 'f'. Used for computing interpolation weights.
+ * Need to be careful with negative values.
+ * Note, if this function isn't perfect you'll sometimes see 1-pixel bands
+ * of improperly weighted linear-filtered textures.
* The tests/texwrap.c demo is a good test.
- * Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
- * Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
*/
-#define FRAC(f) ((f) - util_ifloor(f))
+static INLINE float
+frac(float f)
+{
+ return f - util_ifloor(f);
+}
+
/**
@@ -100,10 +104,16 @@ lerp_3d(float a, float b, float c,
/**
- * If A is a signed integer, A % B doesn't give the right value for A < 0
- * (in terms of texture repeat). Just casting to unsigned fixes that.
+ * Compute coord % size for repeat wrap modes.
+ * Note that if coord is a signed integer, coord % size doesn't give
+ * the right value for coord < 0 (in terms of texture repeat). Just
+ * casting to unsigned fixes that.
*/
-#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
+static INLINE int
+repeat(int coord, unsigned size)
+{
+ return (int) ((unsigned) coord % size);
+}
/**
@@ -115,133 +125,153 @@ lerp_3d(float a, float b, float c,
* \param icoord returns the integer texcoords
* \return integer texture index
*/
-static INLINE void
-nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
- int icoord[4])
+static void
+wrap_nearest_repeat(const float s[4], unsigned size, int icoord[4])
{
uint ch;
- switch (wrapMode) {
- case PIPE_TEX_WRAP_REPEAT:
- /* s limited to [0,1) */
- /* i limited to [0,size-1] */
- for (ch = 0; ch < 4; ch++) {
- int i = util_ifloor(s[ch] * size);
- icoord[ch] = REMAINDER(i, size);
- }
- return;
- case PIPE_TEX_WRAP_CLAMP:
+ /* s limited to [0,1) */
+ /* i limited to [0,size-1] */
+ for (ch = 0; ch < 4; ch++) {
+ int i = util_ifloor(s[ch] * size);
+ icoord[ch] = repeat(i, size);
+ }
+}
+
+
+static void
+wrap_nearest_clamp(const float s[4], unsigned size, int icoord[4])
+{
+ uint ch;
+ /* s limited to [0,1] */
+ /* i limited to [0,size-1] */
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] <= 0.0F)
+ icoord[ch] = 0;
+ else if (s[ch] >= 1.0F)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
+}
+
+
+static void
+wrap_nearest_clamp_to_edge(const float s[4], unsigned size, int icoord[4])
+{
+ uint ch;
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const float min = 1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] < min)
+ icoord[ch] = 0;
+ else if (s[ch] > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
+}
+
+
+static void
+wrap_nearest_clamp_to_border(const float s[4], unsigned size, int icoord[4])
+{
+ uint ch;
+ /* s limited to [min,max] */
+ /* i limited to [-1, size] */
+ const float min = -1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ for (ch = 0; ch < 4; ch++) {
+ if (s[ch] <= min)
+ icoord[ch] = -1;
+ else if (s[ch] >= max)
+ icoord[ch] = size;
+ else
+ icoord[ch] = util_ifloor(s[ch] * size);
+ }
+}
+
+
+static void
+wrap_nearest_mirror_repeat(const float s[4], unsigned size, int icoord[4])
+{
+ uint ch;
+ const float min = 1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ for (ch = 0; ch < 4; ch++) {
+ const int flr = util_ifloor(s[ch]);
+ float u;
+ if (flr & 1)
+ u = 1.0F - (s[ch] - (float) flr);
+ else
+ u = s[ch] - (float) flr;
+ if (u < min)
+ icoord[ch] = 0;
+ else if (u > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
+}
+
+
+static void
+wrap_nearest_mirror_clamp(const float s[4], unsigned size, int icoord[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
/* s limited to [0,1] */
/* i limited to [0,size-1] */
- for (ch = 0; ch < 4; ch++) {
- if (s[ch] <= 0.0F)
- icoord[ch] = 0;
- else if (s[ch] >= 1.0F)
- icoord[ch] = size - 1;
- else
- icoord[ch] = util_ifloor(s[ch] * size);
- }
- return;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const float min = 1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- if (s[ch] < min)
- icoord[ch] = 0;
- else if (s[ch] > max)
- icoord[ch] = size - 1;
- else
- icoord[ch] = util_ifloor(s[ch] * size);
- }
- }
- return;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- {
- /* s limited to [min,max] */
- /* i limited to [-1, size] */
- const float min = -1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- if (s[ch] <= min)
- icoord[ch] = -1;
- else if (s[ch] >= max)
- icoord[ch] = size;
- else
- icoord[ch] = util_ifloor(s[ch] * size);
- }
- }
- return;
- case PIPE_TEX_WRAP_MIRROR_REPEAT:
- {
- const float min = 1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- const int flr = util_ifloor(s[ch]);
- float u;
- if (flr & 1)
- u = 1.0F - (s[ch] - (float) flr);
- else
- u = s[ch] - (float) flr;
- if (u < min)
- icoord[ch] = 0;
- else if (u > max)
- icoord[ch] = size - 1;
- else
- icoord[ch] = util_ifloor(u * size);
- }
- }
- return;
- case PIPE_TEX_WRAP_MIRROR_CLAMP:
- for (ch = 0; ch < 4; ch++) {
- /* s limited to [0,1] */
- /* i limited to [0,size-1] */
- const float u = fabsf(s[ch]);
- if (u <= 0.0F)
- icoord[ch] = 0;
- else if (u >= 1.0F)
- icoord[ch] = size - 1;
- else
- icoord[ch] = util_ifloor(u * size);
- }
- return;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const float min = 1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- const float u = fabsf(s[ch]);
- if (u < min)
- icoord[ch] = 0;
- else if (u > max)
- icoord[ch] = size - 1;
- else
- icoord[ch] = util_ifloor(u * size);
- }
- }
- return;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- {
- /* s limited to [min,max] */
- /* i limited to [0, size-1] */
- const float min = -1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- const float u = fabsf(s[ch]);
- if (u < min)
- icoord[ch] = -1;
- else if (u > max)
- icoord[ch] = size;
- else
- icoord[ch] = util_ifloor(u * size);
- }
- }
- return;
- default:
- assert(0);
+ const float u = fabsf(s[ch]);
+ if (u <= 0.0F)
+ icoord[ch] = 0;
+ else if (u >= 1.0F)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
+}
+
+
+static void
+wrap_nearest_mirror_clamp_to_edge(const float s[4], unsigned size,
+ int icoord[4])
+{
+ uint ch;
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const float min = 1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ for (ch = 0; ch < 4; ch++) {
+ const float u = fabsf(s[ch]);
+ if (u < min)
+ icoord[ch] = 0;
+ else if (u > max)
+ icoord[ch] = size - 1;
+ else
+ icoord[ch] = util_ifloor(u * size);
+ }
+}
+
+
+static void
+wrap_nearest_mirror_clamp_to_border(const float s[4], unsigned size,
+ int icoord[4])
+{
+ uint ch;
+ /* s limited to [min,max] */
+ /* i limited to [0, size-1] */
+ const float min = -1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ for (ch = 0; ch < 4; ch++) {
+ const float u = fabsf(s[ch]);
+ if (u < min)
+ icoord[ch] = -1;
+ else if (u > max)
+ icoord[ch] = size;
+ else
+ icoord[ch] = util_ifloor(u * size);
}
}
@@ -256,125 +286,156 @@ nearest_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
* \param w returns blend factor/weight between texture indexes
* \param icoord returns the computed integer texture coords
*/
-static INLINE void
-linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
+static void
+wrap_linear_repeat(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = s[ch] * size - 0.5F;
+ icoord0[ch] = repeat(util_ifloor(u), size);
+ icoord1[ch] = repeat(icoord0[ch] + 1, size);
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_clamp(const float s[4], unsigned size,
int icoord0[4], int icoord1[4], float w[4])
{
uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.0F, 1.0F);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = frac(u);
+ }
+}
- switch (wrapMode) {
- case PIPE_TEX_WRAP_REPEAT:
- for (ch = 0; ch < 4; ch++) {
- float u = s[ch] * size - 0.5F;
- icoord0[ch] = REMAINDER(util_ifloor(u), size);
- icoord1[ch] = REMAINDER(icoord0[ch] + 1, size);
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_CLAMP:
- for (ch = 0; ch < 4; ch++) {
- float u = CLAMP(s[ch], 0.0F, 1.0F);
- u = u * size - 0.5f;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- for (ch = 0; ch < 4; ch++) {
- float u = CLAMP(s[ch], 0.0F, 1.0F);
- u = u * size - 0.5f;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- if (icoord0[ch] < 0)
- icoord0[ch] = 0;
- if (icoord1[ch] >= (int) size)
- icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- {
- const float min = -1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- float u = CLAMP(s[ch], min, max);
- u = u * size - 0.5f;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
- }
- }
- break;;
- case PIPE_TEX_WRAP_MIRROR_REPEAT:
- for (ch = 0; ch < 4; ch++) {
- const int flr = util_ifloor(s[ch]);
- float u;
- if (flr & 1)
- u = 1.0F - (s[ch] - (float) flr);
- else
- u = s[ch] - (float) flr;
- u = u * size - 0.5F;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- if (icoord0[ch] < 0)
- icoord0[ch] = 0;
- if (icoord1[ch] >= (int) size)
- icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_MIRROR_CLAMP:
- for (ch = 0; ch < 4; ch++) {
- float u = fabsf(s[ch]);
- if (u >= 1.0F)
- u = (float) size;
- else
- u *= size;
- u -= 0.5F;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
- for (ch = 0; ch < 4; ch++) {
- float u = fabsf(s[ch]);
- if (u >= 1.0F)
- u = (float) size;
- else
- u *= size;
- u -= 0.5F;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- if (icoord0[ch] < 0)
- icoord0[ch] = 0;
- if (icoord1[ch] >= (int) size)
- icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
- }
- break;;
- case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
- {
- const float min = -1.0F / (2.0F * size);
- const float max = 1.0F - min;
- for (ch = 0; ch < 4; ch++) {
- float u = fabsf(s[ch]);
- if (u <= min)
- u = min * size;
- else if (u >= max)
- u = max * size;
- else
- u *= size;
- u -= 0.5F;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
- }
- }
- break;;
- default:
- assert(0);
+
+static void
+wrap_linear_clamp_to_edge(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.0F, 1.0F);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_clamp_to_border(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ const float min = -1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], min, max);
+ u = u * size - 0.5f;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_mirror_repeat(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ const int flr = util_ifloor(s[ch]);
+ float u;
+ if (flr & 1)
+ u = 1.0F - (s[ch] - (float) flr);
+ else
+ u = s[ch] - (float) flr;
+ u = u * size - 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_mirror_clamp(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u >= 1.0F)
+ u = (float) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_mirror_clamp_to_edge(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u >= 1.0F)
+ u = (float) size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord0[ch] < 0)
+ icoord0[ch] = 0;
+ if (icoord1[ch] >= (int) size)
+ icoord1[ch] = size - 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+static void
+wrap_linear_mirror_clamp_to_border(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ const float min = -1.0F / (2.0F * size);
+ const float max = 1.0F - min;
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = fabsf(s[ch]);
+ if (u <= min)
+ u = min * size;
+ else if (u >= max)
+ u = max * size;
+ else
+ u *= size;
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = frac(u);
}
}
@@ -383,27 +444,27 @@ linear_texcoord_4(unsigned wrapMode, const float s[4], unsigned size,
* For RECT textures / unnormalized texcoords
* Only a subset of wrap modes supported.
*/
-static INLINE void
-nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
- int icoord[4])
+static void
+wrap_nearest_unorm_clamp(const float s[4], unsigned size, int icoord[4])
{
uint ch;
- switch (wrapMode) {
- case PIPE_TEX_WRAP_CLAMP:
- for (ch = 0; ch < 4; ch++) {
- int i = util_ifloor(s[ch]);
- icoord[ch]= CLAMP(i, 0, (int) size-1);
- }
- return;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- /* fall-through */
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- for (ch = 0; ch < 4; ch++) {
- icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
- }
- return;
- default:
- assert(0);
+ for (ch = 0; ch < 4; ch++) {
+ int i = util_ifloor(s[ch]);
+ icoord[ch]= CLAMP(i, 0, (int) size-1);
+ }
+}
+
+
+/**
+ * Handles clamp_to_edge and clamp_to_border:
+ */
+static void
+wrap_nearest_unorm_clamp_to_border(const float s[4], unsigned size,
+ int icoord[4])
+{
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ icoord[ch]= util_ifloor( CLAMP(s[ch], 0.5F, (float) size - 0.5F) );
}
}
@@ -412,358 +473,971 @@ nearest_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
* For RECT textures / unnormalized texcoords.
* Only a subset of wrap modes supported.
*/
-static INLINE void
-linear_texcoord_unnorm_4(unsigned wrapMode, const float s[4], unsigned size,
- int icoord0[4], int icoord1[4], float w[4])
+static void
+wrap_linear_unorm_clamp(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
{
uint ch;
- switch (wrapMode) {
- case PIPE_TEX_WRAP_CLAMP:
- for (ch = 0; ch < 4; ch++) {
- /* Not exactly what the spec says, but it matches NVIDIA output */
- float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- w[ch] = FRAC(u);
- }
- return;
- case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
- /* fall-through */
- case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
- for (ch = 0; ch < 4; ch++) {
- float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
- u -= 0.5F;
- icoord0[ch] = util_ifloor(u);
- icoord1[ch] = icoord0[ch] + 1;
- if (icoord1[ch] > (int) size - 1)
- icoord1[ch] = size - 1;
- w[ch] = FRAC(u);
- }
- break;
- default:
- assert(0);
+ for (ch = 0; ch < 4; ch++) {
+ /* Not exactly what the spec says, but it matches NVIDIA output */
+ float u = CLAMP(s[ch] - 0.5F, 0.0f, (float) size - 1.0f);
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ w[ch] = frac(u);
}
}
-static unsigned
-choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
+static void
+wrap_linear_unorm_clamp_to_border(const float s[4], unsigned size,
+ int icoord0[4], int icoord1[4], float w[4])
{
- /*
- major axis
- direction target sc tc ma
- ---------- ------------------------------- --- --- ---
- +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
- -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
- +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
- -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
- +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
- -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
- */
- const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
- unsigned face;
- float sc, tc, ma;
-
- if (arx > ary && arx > arz) {
- if (rx >= 0.0F) {
- face = PIPE_TEX_FACE_POS_X;
- sc = -rz;
- tc = -ry;
- ma = arx;
+ uint ch;
+ for (ch = 0; ch < 4; ch++) {
+ float u = CLAMP(s[ch], 0.5F, (float) size - 0.5F);
+ u -= 0.5F;
+ icoord0[ch] = util_ifloor(u);
+ icoord1[ch] = icoord0[ch] + 1;
+ if (icoord1[ch] > (int) size - 1)
+ icoord1[ch] = size - 1;
+ w[ch] = frac(u);
+ }
+}
+
+
+
+/**
+ * Examine the quad's texture coordinates to compute the partial
+ * derivatives w.r.t X and Y, then compute lambda (level of detail).
+ */
+static float
+compute_lambda_1d(const struct sp_sampler_varient *samp,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias)
+{
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
+ float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
+ float rho = MAX2(dsdx, dsdy) * texture->width[0];
+ float lambda;
+
+ lambda = util_fast_log2(rho);
+ lambda += lodbias + sampler->lod_bias;
+ lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
+
+ return lambda;
+}
+
+
+static float
+compute_lambda_2d(const struct sp_sampler_varient *samp,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias)
+{
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
+ float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
+ float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
+ float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]);
+ float maxx = MAX2(dsdx, dsdy) * texture->width[0];
+ float maxy = MAX2(dtdx, dtdy) * texture->height[0];
+ float rho = MAX2(maxx, maxy);
+ float lambda;
+
+ lambda = util_fast_log2(rho);
+ lambda += lodbias + sampler->lod_bias;
+ lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
+
+ return lambda;
+}
+
+
+static float
+compute_lambda_3d(const struct sp_sampler_varient *samp,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias)
+{
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ float dsdx = fabsf(s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT]);
+ float dsdy = fabsf(s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT]);
+ float dtdx = fabsf(t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT]);
+ float dtdy = fabsf(t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT]);
+ float dpdx = fabsf(p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT]);
+ float dpdy = fabsf(p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT]);
+ float maxx = MAX2(dsdx, dsdy) * texture->width[0];
+ float maxy = MAX2(dtdx, dtdy) * texture->height[0];
+ float maxz = MAX2(dpdx, dpdy) * texture->depth[0];
+ float rho, lambda;
+
+ rho = MAX2(maxx, maxy);
+ rho = MAX2(rho, maxz);
+
+ lambda = util_fast_log2(rho);
+ lambda += lodbias + sampler->lod_bias;
+ lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
+
+ return lambda;
+}
+
+
+/**
+ * Compute lambda for a vertex texture sampler.
+ * Since there aren't derivatives to use, just return the LOD bias.
+ */
+static float
+compute_lambda_vert(const struct sp_sampler_varient *samp,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias)
+{
+ return lodbias;
+}
+
+
+
+/**
+ * Get a texel from a texture, using the texture tile cache.
+ *
+ * \param addr the template tex address containing cube, z, face info.
+ * \param x the x coord of texel within 2D image
+ * \param y the y coord of texel within 2D image
+ * \param rgba the quad to put the texel/color into
+ *
+ * XXX maybe move this into sp_tex_tile_cache.c and merge with the
+ * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...
+ */
+
+
+
+
+static INLINE const float *
+get_texel_2d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y)
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+ y %= TILE_SIZE;
+ x %= TILE_SIZE;
+
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ return &tile->data.color[y][x][0];
+}
+
+
+static INLINE const float *
+get_texel_2d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y)
+{
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level = addr.bits.level;
+
+ if (x < 0 || x >= (int) texture->width[level] ||
+ y < 0 || y >= (int) texture->height[level]) {
+ return samp->sampler->border_color;
+ }
+ else {
+ return get_texel_2d_no_border( samp, addr, x, y );
+ }
+}
+
+
+/* Gather a quad of adjacent texels within a tile:
+ */
+static INLINE void
+get_texel_quad_2d_no_border_single_tile(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ unsigned x, unsigned y,
+ const float *out[4])
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+ y %= TILE_SIZE;
+ x %= TILE_SIZE;
+
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ out[0] = &tile->data.color[y ][x ][0];
+ out[1] = &tile->data.color[y ][x+1][0];
+ out[2] = &tile->data.color[y+1][x ][0];
+ out[3] = &tile->data.color[y+1][x+1][0];
+}
+
+
+/* Gather a quad of potentially non-adjacent texels:
+ */
+static INLINE void
+get_texel_quad_2d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ int x0, int y0,
+ int x1, int y1,
+ const float *out[4])
+{
+ out[0] = get_texel_2d_no_border( samp, addr, x0, y0 );
+ out[1] = get_texel_2d_no_border( samp, addr, x1, y0 );
+ out[2] = get_texel_2d_no_border( samp, addr, x0, y1 );
+ out[3] = get_texel_2d_no_border( samp, addr, x1, y1 );
+}
+
+/* Can involve a lot of unnecessary checks for border color:
+ */
+static INLINE void
+get_texel_quad_2d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr,
+ int x0, int y0,
+ int x1, int y1,
+ const float *out[4])
+{
+ out[0] = get_texel_2d( samp, addr, x0, y0 );
+ out[1] = get_texel_2d( samp, addr, x1, y0 );
+ out[3] = get_texel_2d( samp, addr, x1, y1 );
+ out[2] = get_texel_2d( samp, addr, x0, y1 );
+}
+
+
+
+/* 3d varients:
+ */
+static INLINE const float *
+get_texel_3d_no_border(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y, int z)
+{
+ const struct softpipe_tex_cached_tile *tile;
+
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+ addr.bits.z = z;
+ y %= TILE_SIZE;
+ x %= TILE_SIZE;
+
+ tile = sp_get_cached_tile_tex(samp->cache, addr);
+
+ return &tile->data.color[y][x][0];
+}
+
+
+static INLINE const float *
+get_texel_3d(const struct sp_sampler_varient *samp,
+ union tex_tile_address addr, int x, int y, int z)
+{
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level = addr.bits.level;
+
+ if (x < 0 || x >= (int) texture->width[level] ||
+ y < 0 || y >= (int) texture->height[level] ||
+ z < 0 || z >= (int) texture->depth[level]) {
+ return samp->sampler->border_color;
+ }
+ else {
+ return get_texel_3d_no_border( samp, addr, x, y, z );
+ }
+}
+
+
+/**
+ * Given the logbase2 of a mipmap's base level size and a mipmap level,
+ * return the size (in texels) of that mipmap level.
+ * For example, if level[0].width = 256 then base_pot will be 8.
+ * If level = 2, then we'll return 64 (the width at level=2).
+ * Return 1 if level > base_pot.
+ */
+static INLINE unsigned
+pot_level_size(unsigned base_pot, unsigned level)
+{
+ return (base_pot >= level) ? (1 << (base_pot - level)) : 1;
+}
+
+
+/* Some image-filter fastpaths:
+ */
+static INLINE void
+img_filter_2d_linear_repeat_POT(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
+ unsigned xmax = (xpot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, xpot) - 1; */
+ unsigned ymax = (ypot - 1) & (TILE_SIZE - 1); /* MIN2(TILE_SIZE, ypot) - 1; */
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+
+ float u = s[j] * xpot - 0.5F;
+ float v = t[j] * ypot - 0.5F;
+
+ int uflr = util_ifloor(u);
+ int vflr = util_ifloor(v);
+
+ float xw = u - (float)uflr;
+ float yw = v - (float)vflr;
+
+ int x0 = uflr & (xpot - 1);
+ int y0 = vflr & (ypot - 1);
+
+ const float *tx[4];
+
+ /* Can we fetch all four at once:
+ */
+ if (x0 < xmax && y0 < ymax) {
+ get_texel_quad_2d_no_border_single_tile(samp, addr, x0, y0, tx);
}
else {
- face = PIPE_TEX_FACE_NEG_X;
- sc = rz;
- tc = -ry;
- ma = arx;
+ unsigned x1 = (x0 + 1) & (xpot - 1);
+ unsigned y1 = (y0 + 1) & (ypot - 1);
+ get_texel_quad_2d_no_border(samp, addr, x0, y0, x1, y1, tx);
+ }
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw, yw,
+ tx[0][c], tx[1][c],
+ tx[2][c], tx[3][c]);
}
}
- else if (ary > arx && ary > arz) {
- if (ry >= 0.0F) {
- face = PIPE_TEX_FACE_POS_Y;
- sc = rx;
- tc = rz;
- ma = ary;
+}
+
+
+static INLINE void
+img_filter_2d_nearest_repeat_POT(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+
+ float u = s[j] * xpot;
+ float v = t[j] * ypot;
+
+ int uflr = util_ifloor(u);
+ int vflr = util_ifloor(v);
+
+ int x0 = uflr & (xpot - 1);
+ int y0 = vflr & (ypot - 1);
+
+ const float *out = get_texel_2d_no_border(samp, addr, x0, y0);
+
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
}
- else {
- face = PIPE_TEX_FACE_NEG_Y;
- sc = rx;
- tc = -rz;
- ma = ary;
+ }
+}
+
+
+static INLINE void
+img_filter_2d_nearest_clamp_POT(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = pot_level_size(samp->xpot, level);
+ unsigned ypot = pot_level_size(samp->ypot, level);
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+
+ float u = s[j] * xpot;
+ float v = t[j] * ypot;
+
+ int x0, y0;
+ const float *out;
+
+ x0 = util_ifloor(u);
+ if (x0 < 0)
+ x0 = 0;
+ else if (x0 > xpot - 1)
+ x0 = xpot - 1;
+
+ y0 = util_ifloor(v);
+ if (y0 < 0)
+ y0 = 0;
+ else if (y0 > ypot - 1)
+ y0 = ypot - 1;
+
+ out = get_texel_2d_no_border(samp, addr, x0, y0);
+
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
}
}
- else {
- if (rz > 0.0F) {
- face = PIPE_TEX_FACE_POS_Z;
- sc = rx;
- tc = -ry;
- ma = arz;
+}
+
+
+static void
+img_filter_1d_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width;
+ int x[4];
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+
+ assert(width > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->nearest_texcoord_s(s, width, x);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *out = get_texel_2d(samp, addr, x[j], 0);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
}
- else {
- face = PIPE_TEX_FACE_NEG_Z;
- sc = -rx;
- tc = -ry;
- ma = arz;
+ }
+}
+
+
+static void
+img_filter_2d_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width, height;
+ int x[4], y[4];
+ union tex_tile_address addr;
+
+
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
+
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->nearest_texcoord_s(s, width, x);
+ samp->nearest_texcoord_t(t, height, y);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *out = get_texel_2d(samp, addr, x[j], y[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
}
}
+}
- *newS = ( sc / ma + 1.0F ) * 0.5F;
- *newT = ( tc / ma + 1.0F ) * 0.5F;
- return face;
+static INLINE union tex_tile_address
+face(union tex_tile_address addr, unsigned face )
+{
+ addr.bits.face = face;
+ return addr;
}
-/**
- * Examine the quad's texture coordinates to compute the partial
- * derivatives w.r.t X and Y, then compute lambda (level of detail).
- *
- * This is only done for fragment shaders, not vertex shaders.
- */
-static float
-compute_lambda(const struct pipe_texture *tex,
- const struct pipe_sampler_state *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias)
+static void
+img_filter_cube_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- float rho, lambda;
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const unsigned *faces = samp->faces; /* zero when not cube-mapping */
+ unsigned level0, j;
+ int width, height;
+ int x[4], y[4];
+ union tex_tile_address addr;
- assert(sampler->normalized_coords);
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
- assert(s);
- {
- float dsdx = s[QUAD_BOTTOM_RIGHT] - s[QUAD_BOTTOM_LEFT];
- float dsdy = s[QUAD_TOP_LEFT] - s[QUAD_BOTTOM_LEFT];
- dsdx = fabsf(dsdx);
- dsdy = fabsf(dsdy);
- rho = MAX2(dsdx, dsdy) * tex->width[0];
- }
- if (t) {
- float dtdx = t[QUAD_BOTTOM_RIGHT] - t[QUAD_BOTTOM_LEFT];
- float dtdy = t[QUAD_TOP_LEFT] - t[QUAD_BOTTOM_LEFT];
- float max;
- dtdx = fabsf(dtdx);
- dtdy = fabsf(dtdy);
- max = MAX2(dtdx, dtdy) * tex->height[0];
- rho = MAX2(rho, max);
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->nearest_texcoord_s(s, width, x);
+ samp->nearest_texcoord_t(t, height, y);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *out = get_texel_2d(samp, face(addr, faces[j]), x[j], y[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
}
- if (p) {
- float dpdx = p[QUAD_BOTTOM_RIGHT] - p[QUAD_BOTTOM_LEFT];
- float dpdy = p[QUAD_TOP_LEFT] - p[QUAD_BOTTOM_LEFT];
- float max;
- dpdx = fabsf(dpdx);
- dpdy = fabsf(dpdy);
- max = MAX2(dpdx, dpdy) * tex->depth[0];
- rho = MAX2(rho, max);
+}
+
+
+static void
+img_filter_3d_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width, height, depth;
+ int x[4], y[4], z[4];
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
+ depth = texture->depth[level0];
+
+ assert(width > 0);
+ assert(height > 0);
+ assert(depth > 0);
+
+ samp->nearest_texcoord_s(s, width, x);
+ samp->nearest_texcoord_t(t, height, y);
+ samp->nearest_texcoord_p(p, depth, z);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *out = get_texel_3d(samp, addr, x[j], y[j], z[j]);
+ int c;
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = out[c];
+ }
}
+}
- lambda = util_fast_log2(rho);
- lambda += lodbias + sampler->lod_bias;
- lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
- return lambda;
+static void
+img_filter_1d_linear(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width;
+ int x0[4], x1[4];
+ float xw[4]; /* weights */
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+
+ assert(width > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *tx0 = get_texel_2d(samp, addr, x0[j], 0);
+ const float *tx1 = get_texel_2d(samp, addr, x1[j], 0);
+ int c;
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp(xw[j], tx0[c], tx1[c]);
+ }
+ }
}
-/**
- * Do several things here:
- * 1. Compute lambda from the texcoords, if needed
- * 2. Determine if we're minifying or magnifying
- * 3. If minifying, choose mipmap levels
- * 4. Return image filter to use within mipmap images
- * \param level0 Returns first mipmap level to sample from
- * \param level1 Returns second mipmap level to sample from
- * \param levelBlend Returns blend factor between levels, in [0,1]
- * \param imgFilter Returns either the min or mag filter, depending on lambda
- */
static void
-choose_mipmap_levels(const struct pipe_texture *texture,
- const struct pipe_sampler_state *sampler,
+img_filter_2d_linear(struct tgsi_sampler *tgsi_sampler,
const float s[QUAD_SIZE],
const float t[QUAD_SIZE],
const float p[QUAD_SIZE],
- boolean computeLambda,
float lodbias,
- unsigned *level0, unsigned *level1, float *levelBlend,
- unsigned *imgFilter)
-{
- if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
- /* no mipmap selection needed */
- *level0 = *level1 = CLAMP((int) sampler->min_lod,
- 0, (int) texture->last_level);
-
- if (sampler->min_img_filter != sampler->mag_img_filter) {
- /* non-mipmapped texture, but still need to determine if doing
- * minification or magnification.
- */
- float lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
- if (lambda <= 0.0) {
- *imgFilter = sampler->mag_img_filter;
- }
- else {
- *imgFilter = sampler->min_img_filter;
- }
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width, height;
+ int x0[4], y0[4], x1[4], y1[4];
+ float xw[4], yw[4]; /* weights */
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
+
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
+ samp->linear_texcoord_t(t, height, y0, y1, yw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ const float *tx0 = get_texel_2d(samp, addr, x0[j], y0[j]);
+ const float *tx1 = get_texel_2d(samp, addr, x1[j], y0[j]);
+ const float *tx2 = get_texel_2d(samp, addr, x0[j], y1[j]);
+ const float *tx3 = get_texel_2d(samp, addr, x1[j], y1[j]);
+ int c;
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw[j], yw[j],
+ tx0[c], tx1[c],
+ tx2[c], tx3[c]);
}
- else {
- *imgFilter = sampler->mag_img_filter;
+ }
+}
+
+
+static void
+img_filter_cube_linear(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const unsigned *faces = samp->faces; /* zero when not cube-mapping */
+ unsigned level0, j;
+ int width, height;
+ int x0[4], y0[4], x1[4], y1[4];
+ float xw[4], yw[4]; /* weights */
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
+
+ assert(width > 0);
+ assert(height > 0);
+
+ addr.value = 0;
+ addr.bits.level = samp->level;
+
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
+ samp->linear_texcoord_t(t, height, y0, y1, yw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ union tex_tile_address addrj = face(addr, faces[j]);
+ const float *tx0 = get_texel_2d(samp, addrj, x0[j], y0[j]);
+ const float *tx1 = get_texel_2d(samp, addrj, x1[j], y0[j]);
+ const float *tx2 = get_texel_2d(samp, addrj, x0[j], y1[j]);
+ const float *tx3 = get_texel_2d(samp, addrj, x1[j], y1[j]);
+ int c;
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw[j], yw[j],
+ tx0[c], tx1[c],
+ tx2[c], tx3[c]);
}
}
- else {
- float lambda;
+}
- if (computeLambda)
- /* fragment shader */
- lambda = compute_lambda(texture, sampler, s, t, p, lodbias);
- else
- /* vertex shader */
- lambda = lodbias; /* not really a bias, but absolute LOD */
- if (lambda <= 0.0) { /* XXX threshold depends on the filter */
- /* magnifying */
- *imgFilter = sampler->mag_img_filter;
- *level0 = *level1 = 0;
+static void
+img_filter_3d_linear(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ const struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ unsigned level0, j;
+ int width, height, depth;
+ int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
+ float xw[4], yw[4], zw[4]; /* interpolation weights */
+ union tex_tile_address addr;
+
+ level0 = samp->level;
+ width = texture->width[level0];
+ height = texture->height[level0];
+ depth = texture->depth[level0];
+
+ addr.value = 0;
+ addr.bits.level = level0;
+
+ assert(width > 0);
+ assert(height > 0);
+ assert(depth > 0);
+
+ samp->linear_texcoord_s(s, width, x0, x1, xw);
+ samp->linear_texcoord_t(t, height, y0, y1, yw);
+ samp->linear_texcoord_p(p, depth, z0, z1, zw);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+
+ const float *tx00 = get_texel_3d(samp, addr, x0[j], y0[j], z0[j]);
+ const float *tx01 = get_texel_3d(samp, addr, x1[j], y0[j], z0[j]);
+ const float *tx02 = get_texel_3d(samp, addr, x0[j], y1[j], z0[j]);
+ const float *tx03 = get_texel_3d(samp, addr, x1[j], y1[j], z0[j]);
+
+ const float *tx10 = get_texel_3d(samp, addr, x0[j], y0[j], z1[j]);
+ const float *tx11 = get_texel_3d(samp, addr, x1[j], y0[j], z1[j]);
+ const float *tx12 = get_texel_3d(samp, addr, x0[j], y1[j], z1[j]);
+ const float *tx13 = get_texel_3d(samp, addr, x1[j], y1[j], z1[j]);
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
+ tx00[c], tx01[c],
+ tx02[c], tx03[c],
+ tx10[c], tx11[c],
+ tx12[c], tx13[c]);
}
- else {
- /* minifying */
- *imgFilter = sampler->min_img_filter;
-
- /* choose mipmap level(s) and compute the blend factor between them */
- if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NEAREST) {
- /* Nearest mipmap level */
- const int lvl = (int) (lambda + 0.5);
- *level0 =
- *level1 = CLAMP(lvl, 0, (int) texture->last_level);
- }
- else {
- /* Linear interpolation between mipmap levels */
- const int lvl = (int) lambda;
- *level0 = CLAMP(lvl, 0, (int) texture->last_level);
- *level1 = CLAMP(lvl + 1, 0, (int) texture->last_level);
- *levelBlend = FRAC(lambda); /* blending weight between levels */
+ }
+}
+
+
+static void
+mip_filter_linear(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ int level0;
+ float lambda;
+
+ lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+ level0 = (int)lambda;
+
+ if (lambda < 0.0) {
+ samp->level = 0;
+ samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ }
+ else if (level0 >= texture->last_level) {
+ samp->level = texture->last_level;
+ samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ }
+ else {
+ float levelBlend = lambda - level0;
+ float rgba0[4][4];
+ float rgba1[4][4];
+ int c,j;
+
+ samp->level = level0;
+ samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba0 );
+
+ samp->level = level0+1;
+ samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba1 );
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]);
}
}
}
}
-/**
- * Get a texel from a texture, using the texture tile cache.
- *
- * \param face the cube face in 0..5
- * \param level the mipmap level
- * \param x the x coord of texel within 2D image
- * \param y the y coord of texel within 2D image
- * \param z which slice of a 3D texture
- * \param rgba the quad to put the texel/color into
- * \param j which element of the rgba quad to write to
- *
- * XXX maybe move this into sp_tile_cache.c and merge with the
- * sp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...
- */
static void
-get_texel(const struct tgsi_sampler *tgsi_sampler,
- unsigned face, unsigned level, int x, int y, int z,
- float rgba[NUM_CHANNELS][QUAD_SIZE], unsigned j)
+mip_filter_nearest(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- struct softpipe_context *sp = samp->sp;
- const uint unit = samp->unit;
- const struct pipe_texture *texture = sp->texture[unit];
- const struct pipe_sampler_state *sampler = sp->sampler[unit];
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ float lambda;
- if (x < 0 || x >= (int) texture->width[level] ||
- y < 0 || y >= (int) texture->height[level] ||
- z < 0 || z >= (int) texture->depth[level]) {
- rgba[0][j] = sampler->border_color[0];
- rgba[1][j] = sampler->border_color[1];
- rgba[2][j] = sampler->border_color[2];
- rgba[3][j] = sampler->border_color[3];
+ lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+
+ if (lambda < 0.0) {
+ samp->level = 0;
+ samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
}
else {
- const int tx = x % TILE_SIZE;
- const int ty = y % TILE_SIZE;
- const struct softpipe_cached_tile *tile
- = sp_get_cached_tile_tex(sp, samp->cache,
- x, y, z, face, level);
- rgba[0][j] = tile->data.color[ty][tx][0];
- rgba[1][j] = tile->data.color[ty][tx][1];
- rgba[2][j] = tile->data.color[ty][tx][2];
- rgba[3][j] = tile->data.color[ty][tx][3];
- if (0)
- {
- debug_printf("Get texel %f %f %f %f from %s\n",
- rgba[0][j], rgba[1][j], rgba[2][j], rgba[3][j],
- pf_name(texture->format));
- }
+ samp->level = (int)(lambda + 0.5) ;
+ samp->level = MIN2(samp->level, (int)texture->last_level);
+ samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ }
+
+#if 0
+ printf("RGBA %g %g %g %g, %g %g %g %g, %g %g %g %g, %g %g %g %g\n",
+ rgba[0][0], rgba[1][0], rgba[2][0], rgba[3][0],
+ rgba[0][1], rgba[1][1], rgba[2][1], rgba[3][1],
+ rgba[0][2], rgba[1][2], rgba[2][2], rgba[3][2],
+ rgba[0][3], rgba[1][3], rgba[2][3], rgba[3][3]);
+#endif
+}
+
+
+static void
+mip_filter_none(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ float lambda = samp->compute_lambda(samp, s, t, p, lodbias);
+
+ if (lambda < 0.0) {
+ samp->mag_img_filter( tgsi_sampler, s, t, p, 0, rgba );
+ }
+ else {
+ samp->min_img_filter( tgsi_sampler, s, t, p, 0, rgba );
}
}
+
/**
- * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
- * When we sampled the depth texture, the depth value was put into all
- * RGBA channels. We look at the red channel here.
- * \param rgba quad of (depth) texel values
- * \param p texture 'P' components for four pixels in quad
- * \param j which pixel in the quad to test [0..3]
+ * Specialized version of mip_filter_linear with hard-wired calls to
+ * 2d lambda calculation and 2d_linear_repeat_POT img filters.
*/
-static INLINE void
-shadow_compare(const struct pipe_sampler_state *sampler,
- float rgba[NUM_CHANNELS][QUAD_SIZE],
- const float p[QUAD_SIZE],
- uint j)
+static void
+mip_filter_linear_2d_linear_repeat_POT(
+ struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
- int k;
- switch (sampler->compare_func) {
- case PIPE_FUNC_LESS:
- k = p[j] < rgba[0][j];
- break;
- case PIPE_FUNC_LEQUAL:
- k = p[j] <= rgba[0][j];
- break;
- case PIPE_FUNC_GREATER:
- k = p[j] > rgba[0][j];
- break;
- case PIPE_FUNC_GEQUAL:
- k = p[j] >= rgba[0][j];
- break;
- case PIPE_FUNC_EQUAL:
- k = p[j] == rgba[0][j];
- break;
- case PIPE_FUNC_NOTEQUAL:
- k = p[j] != rgba[0][j];
- break;
- case PIPE_FUNC_ALWAYS:
- k = 1;
- break;
- case PIPE_FUNC_NEVER:
- k = 0;
- break;
- default:
- k = 0;
- assert(0);
- break;
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ int level0;
+ float lambda;
+
+ lambda = compute_lambda_2d(samp, s, t, p, lodbias);
+ level0 = (int)lambda;
+
+ /* Catches both negative and large values of level0:
+ */
+ if ((unsigned)level0 >= texture->last_level) {
+ if (level0 < 0)
+ samp->level = 0;
+ else
+ samp->level = texture->last_level;
+
+ img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba );
}
+ else {
+ float levelBlend = lambda - level0;
+ float rgba0[4][4];
+ float rgba1[4][4];
+ int c,j;
- /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
- rgba[0][j] = rgba[1][j] = rgba[2][j] = (float) k;
- rgba[3][j] = 1.0F;
+ samp->level = level0;
+ img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba0 );
+
+ samp->level = level0+1;
+ img_filter_2d_linear_repeat_POT( tgsi_sampler, s, t, p, 0, rgba1 );
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp(levelBlend, rgba0[c][j], rgba1[c][j]);
+ }
+ }
+ }
}
+
/**
- * As above, but do four z/texture comparisons.
+ * Do shadow/depth comparisons.
*/
-static INLINE void
-shadow_compare4(const struct pipe_sampler_state *sampler,
- float rgba[NUM_CHANNELS][QUAD_SIZE],
- const float p[QUAD_SIZE])
+static void
+sample_compare(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
{
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ const struct pipe_sampler_state *sampler = samp->sampler;
int j, k0, k1, k2, k3;
float val;
+ samp->mip_filter( tgsi_sampler, s, t, p, lodbias, rgba );
+
+ /**
+ * Compare texcoord 'p' (aka R) against texture value 'rgba[0]'
+ * When we sampled the depth texture, the depth value was put into all
+ * RGBA channels. We look at the red channel here.
+ */
+
/* compare four texcoords vs. four texture samples */
switch (sampler->compare_func) {
case PIPE_FUNC_LESS:
@@ -826,470 +1500,392 @@ shadow_compare4(const struct pipe_sampler_state *sampler,
/**
- * Common code for sampling 1D/2D/cube textures.
- * Could probably extend for 3D...
+ * Compute which cube face is referenced by each texcoord and put that
+ * info into the sampler faces[] array. Then sample the cube faces
*/
static void
-sp_get_samples_2d_common(const struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE],
- const unsigned faces[4])
-{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- const struct softpipe_context *sp = samp->sp;
- const uint unit = samp->unit;
- const struct pipe_texture *texture = sp->texture[unit];
- const struct pipe_sampler_state *sampler = sp->sampler[unit];
- unsigned level0, level1, j, imgFilter;
- int width, height;
- float levelBlend;
-
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
- &level0, &level1, &levelBlend, &imgFilter);
-
- assert(sampler->normalized_coords);
-
- width = texture->width[level0];
- height = texture->height[level0];
-
- assert(width > 0);
-
- switch (imgFilter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- int x[4], y[4];
- nearest_texcoord_4(sampler->wrap_s, s, width, x);
- nearest_texcoord_4(sampler->wrap_t, t, height, y);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, faces[j], level0, x[j], y[j], 0, rgba, j);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(sampler, rgba, p, j);
- }
+sample_cube(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler);
+ unsigned j;
+ float ssss[4], tttt[4];
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x[j] /= 2;
- y[j] /= 2;
- get_texel(tgsi_sampler, faces[j], level1, x[j], y[j], 0,
- rgba2, j);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
- shadow_compare(sampler, rgba2, p, j);
- }
-
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
+ /*
+ major axis
+ direction target sc tc ma
+ ---------- ------------------------------- --- --- ---
+ +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
+ -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
+ -ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
+ +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
+ -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
+ */
+ for (j = 0; j < QUAD_SIZE; j++) {
+ float rx = s[j];
+ float ry = t[j];
+ float rz = p[j];
+ const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz);
+ unsigned face;
+ float sc, tc, ma;
+
+ if (arx >= ary && arx >= arz) {
+ if (rx >= 0.0F) {
+ face = PIPE_TEX_FACE_POS_X;
+ sc = -rz;
+ tc = -ry;
+ ma = arx;
+ }
+ else {
+ face = PIPE_TEX_FACE_NEG_X;
+ sc = rz;
+ tc = -ry;
+ ma = arx;
}
}
- break;
- case PIPE_TEX_FILTER_LINEAR:
- case PIPE_TEX_FILTER_ANISO:
+ else if (ary >= arx && ary >= arz) {
+ if (ry >= 0.0F) {
+ face = PIPE_TEX_FACE_POS_Y;
+ sc = rx;
+ tc = rz;
+ ma = ary;
+ }
+ else {
+ face = PIPE_TEX_FACE_NEG_Y;
+ sc = rx;
+ tc = -rz;
+ ma = ary;
+ }
+ }
+ else {
+ if (rz > 0.0F) {
+ face = PIPE_TEX_FACE_POS_Z;
+ sc = rx;
+ tc = -ry;
+ ma = arz;
+ }
+ else {
+ face = PIPE_TEX_FACE_NEG_Z;
+ sc = -rx;
+ tc = -ry;
+ ma = arz;
+ }
+ }
+
{
- int x0[4], y0[4], x1[4], y1[4];
- float xw[4], yw[4]; /* weights */
-
- linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
- linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4]; /* texels */
- int c;
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, faces[j], level0, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, faces[j], level0, x1[j], y1[j], 0, tx, 3);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare4(sampler, tx, p);
- }
+ const float ima = 1.0 / ma;
+ ssss[j] = ( sc * ima + 1.0F ) * 0.5F;
+ tttt[j] = ( tc * ima + 1.0F ) * 0.5F;
+ samp->faces[j] = face;
+ }
+ }
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1],
- tx[c][2], tx[c][3]);
- }
+ /* In our little pipeline, the compare stage is next. If compare
+ * is not active, this will point somewhere deeper into the
+ * pipeline, eg. to mip_filter or even img_filter.
+ */
+ samp->compare(tgsi_sampler, ssss, tttt, NULL, lodbias, rgba);
+}
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- x0[j] /= 2;
- y0[j] /= 2;
- x1[j] /= 2;
- y1[j] /= 2;
- get_texel(tgsi_sampler, faces[j], level1, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, faces[j], level1, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, faces[j], level1, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, faces[j], level1, x1[j], y1[j], 0, tx, 3);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE){
- shadow_compare4(sampler, tx, p);
- }
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba2[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
- }
-
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
- }
- }
- break;
+
+
+static wrap_nearest_func
+get_nearest_unorm_wrap(unsigned mode)
+{
+ switch (mode) {
+ case PIPE_TEX_WRAP_CLAMP:
+ return wrap_nearest_unorm_clamp;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return wrap_nearest_unorm_clamp_to_border;
default:
assert(0);
+ return wrap_nearest_unorm_clamp;
}
}
-static INLINE void
-sp_get_samples_1d(const struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+static wrap_nearest_func
+get_nearest_wrap(unsigned mode)
{
- static const unsigned faces[4] = {0, 0, 0, 0};
- static const float tzero[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, tzero, NULL,
- computeLambda, lodbias, rgba, faces);
+ switch (mode) {
+ case PIPE_TEX_WRAP_REPEAT:
+ return wrap_nearest_repeat;
+ case PIPE_TEX_WRAP_CLAMP:
+ return wrap_nearest_clamp;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ return wrap_nearest_clamp_to_edge;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return wrap_nearest_clamp_to_border;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ return wrap_nearest_mirror_repeat;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ return wrap_nearest_mirror_clamp;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ return wrap_nearest_mirror_clamp_to_edge;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ return wrap_nearest_mirror_clamp_to_border;
+ default:
+ assert(0);
+ return wrap_nearest_repeat;
+ }
}
-static INLINE void
-sp_get_samples_2d(const struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+static wrap_linear_func
+get_linear_unorm_wrap(unsigned mode)
{
- static const unsigned faces[4] = {0, 0, 0, 0};
- sp_get_samples_2d_common(sampler, s, t, p,
- computeLambda, lodbias, rgba, faces);
+ switch (mode) {
+ case PIPE_TEX_WRAP_CLAMP:
+ return wrap_linear_unorm_clamp;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return wrap_linear_unorm_clamp_to_border;
+ default:
+ assert(0);
+ return wrap_linear_unorm_clamp;
+ }
}
-static INLINE void
-sp_get_samples_3d(const struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+static wrap_linear_func
+get_linear_wrap(unsigned mode)
{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- const struct softpipe_context *sp = samp->sp;
- const uint unit = samp->unit;
- const struct pipe_texture *texture = sp->texture[unit];
- const struct pipe_sampler_state *sampler = sp->sampler[unit];
- /* get/map pipe_surfaces corresponding to 3D tex slices */
- unsigned level0, level1, j, imgFilter;
- int width, height, depth;
- float levelBlend;
- const uint face = 0;
-
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
- &level0, &level1, &levelBlend, &imgFilter);
-
- assert(sampler->normalized_coords);
-
- width = texture->width[level0];
- height = texture->height[level0];
- depth = texture->depth[level0];
-
- assert(width > 0);
- assert(height > 0);
- assert(depth > 0);
-
- switch (imgFilter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- int x[4], y[4], z[4];
- nearest_texcoord_4(sampler->wrap_s, s, width, x);
- nearest_texcoord_4(sampler->wrap_t, t, height, y);
- nearest_texcoord_4(sampler->wrap_r, p, depth, z);
- for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, face, level0, x[j], y[j], z[j], rgba, j);
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- unsigned c;
- x[j] /= 2;
- y[j] /= 2;
- z[j] /= 2;
- get_texel(tgsi_sampler, face, level1, x[j], y[j], z[j], rgba2, j);
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba2[c][j], rgba[c][j]);
- }
- }
- }
- }
- break;
- case PIPE_TEX_FILTER_LINEAR:
- case PIPE_TEX_FILTER_ANISO:
- {
- int x0[4], x1[4], y0[4], y1[4], z0[4], z1[4];
- float xw[4], yw[4], zw[4]; /* interpolation weights */
- linear_texcoord_4(sampler->wrap_s, s, width, x0, x1, xw);
- linear_texcoord_4(sampler->wrap_t, t, height, y0, y1, yw);
- linear_texcoord_4(sampler->wrap_r, p, depth, z0, z1, zw);
-
- for (j = 0; j < QUAD_SIZE; j++) {
- int c;
- float tx0[4][4], tx1[4][4];
- get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z0[j], tx0, 0);
- get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z0[j], tx0, 1);
- get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z0[j], tx0, 2);
- get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z0[j], tx0, 3);
- get_texel(tgsi_sampler, face, level0, x0[j], y0[j], z1[j], tx1, 0);
- get_texel(tgsi_sampler, face, level0, x1[j], y0[j], z1[j], tx1, 1);
- get_texel(tgsi_sampler, face, level0, x0[j], y1[j], z1[j], tx1, 2);
- get_texel(tgsi_sampler, face, level0, x1[j], y1[j], z1[j], tx1, 3);
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_3d(xw[j], yw[j], zw[j],
- tx0[c][0], tx0[c][1],
- tx0[c][2], tx0[c][3],
- tx1[c][0], tx1[c][1],
- tx1[c][2], tx1[c][3]);
- }
-
- if (level0 != level1) {
- /* get texels from second mipmap level and blend */
- float rgba2[4][4];
- x0[j] /= 2;
- y0[j] /= 2;
- z0[j] /= 2;
- x1[j] /= 2;
- y1[j] /= 2;
- z1[j] /= 2;
- get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z0[j], tx0, 0);
- get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z0[j], tx0, 1);
- get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z0[j], tx0, 2);
- get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z0[j], tx0, 3);
- get_texel(tgsi_sampler, face, level1, x0[j], y0[j], z1[j], tx1, 0);
- get_texel(tgsi_sampler, face, level1, x1[j], y0[j], z1[j], tx1, 1);
- get_texel(tgsi_sampler, face, level1, x0[j], y1[j], z1[j], tx1, 2);
- get_texel(tgsi_sampler, face, level1, x1[j], y1[j], z1[j], tx1, 3);
-
- /* interpolate R, G, B, A */
- for (c = 0; c < 4; c++) {
- rgba2[c][j] = lerp_3d(xw[j], yw[j], zw[j],
- tx0[c][0], tx0[c][1],
- tx0[c][2], tx0[c][3],
- tx1[c][0], tx1[c][1],
- tx1[c][2], tx1[c][3]);
- }
-
- /* blend mipmap levels */
- for (c = 0; c < NUM_CHANNELS; c++) {
- rgba[c][j] = lerp(levelBlend, rgba[c][j], rgba2[c][j]);
- }
- }
- }
- }
- break;
+ switch (mode) {
+ case PIPE_TEX_WRAP_REPEAT:
+ return wrap_linear_repeat;
+ case PIPE_TEX_WRAP_CLAMP:
+ return wrap_linear_clamp;
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ return wrap_linear_clamp_to_edge;
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ return wrap_linear_clamp_to_border;
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ return wrap_linear_mirror_repeat;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP:
+ return wrap_linear_mirror_clamp;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE:
+ return wrap_linear_mirror_clamp_to_edge;
+ case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER:
+ return wrap_linear_mirror_clamp_to_border;
default:
assert(0);
+ return wrap_linear_repeat;
}
}
-static void
-sp_get_samples_cube(const struct tgsi_sampler *sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+static compute_lambda_func
+get_lambda_func(const union sp_sampler_key key)
{
- unsigned faces[QUAD_SIZE], j;
- float ssss[4], tttt[4];
- for (j = 0; j < QUAD_SIZE; j++) {
- faces[j] = choose_cube_face(s[j], t[j], p[j], ssss + j, tttt + j);
+ if (key.bits.processor == TGSI_PROCESSOR_VERTEX)
+ return compute_lambda_vert;
+
+ switch (key.bits.target) {
+ case PIPE_TEXTURE_1D:
+ return compute_lambda_1d;
+ case PIPE_TEXTURE_2D:
+ case PIPE_TEXTURE_CUBE:
+ return compute_lambda_2d;
+ case PIPE_TEXTURE_3D:
+ return compute_lambda_3d;
+ default:
+ assert(0);
+ return compute_lambda_1d;
}
- sp_get_samples_2d_common(sampler, ssss, tttt, NULL,
- computeLambda, lodbias, rgba, faces);
}
-static void
-sp_get_samples_rect(const struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
-{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- const struct softpipe_context *sp = samp->sp;
- const uint unit = samp->unit;
- const struct pipe_texture *texture = sp->texture[unit];
- const struct pipe_sampler_state *sampler = sp->sampler[unit];
- const uint face = 0;
- unsigned level0, level1, j, imgFilter;
- int width, height;
- float levelBlend;
-
- choose_mipmap_levels(texture, sampler, s, t, p, computeLambda, lodbias,
- &level0, &level1, &levelBlend, &imgFilter);
-
- /* texture RECTS cannot be mipmapped */
- assert(level0 == level1);
-
- width = texture->width[level0];
- height = texture->height[level0];
-
- assert(width > 0);
-
- switch (imgFilter) {
- case PIPE_TEX_FILTER_NEAREST:
- {
- int x[4], y[4];
- nearest_texcoord_unnorm_4(sampler->wrap_s, s, width, x);
- nearest_texcoord_unnorm_4(sampler->wrap_t, t, height, y);
- for (j = 0; j < QUAD_SIZE; j++) {
- get_texel(tgsi_sampler, face, level0, x[j], y[j], 0, rgba, j);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare(sampler, rgba, p, j);
- }
- }
- }
+static filter_func
+get_img_filter(const union sp_sampler_key key,
+ unsigned filter,
+ const struct pipe_sampler_state *sampler)
+{
+ switch (key.bits.target) {
+ case PIPE_TEXTURE_1D:
+ if (filter == PIPE_TEX_FILTER_NEAREST)
+ return img_filter_1d_nearest;
+ else
+ return img_filter_1d_linear;
break;
- case PIPE_TEX_FILTER_LINEAR:
- case PIPE_TEX_FILTER_ANISO:
+ case PIPE_TEXTURE_2D:
+ /* Try for fast path:
+ */
+ if (key.bits.is_pot &&
+ sampler->wrap_s == sampler->wrap_t &&
+ sampler->normalized_coords)
{
- int x0[4], y0[4], x1[4], y1[4];
- float xw[4], yw[4]; /* weights */
- linear_texcoord_unnorm_4(sampler->wrap_s, s, width, x0, x1, xw);
- linear_texcoord_unnorm_4(sampler->wrap_t, t, height, y0, y1, yw);
- for (j = 0; j < QUAD_SIZE; j++) {
- float tx[4][4]; /* texels */
- int c;
- get_texel(tgsi_sampler, face, level0, x0[j], y0[j], 0, tx, 0);
- get_texel(tgsi_sampler, face, level0, x1[j], y0[j], 0, tx, 1);
- get_texel(tgsi_sampler, face, level0, x0[j], y1[j], 0, tx, 2);
- get_texel(tgsi_sampler, face, level0, x1[j], y1[j], 0, tx, 3);
- if (sampler->compare_mode == PIPE_TEX_COMPARE_R_TO_TEXTURE) {
- shadow_compare4(sampler, tx, p);
+ switch (sampler->wrap_s) {
+ case PIPE_TEX_WRAP_REPEAT:
+ switch (filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ return img_filter_2d_nearest_repeat_POT;
+ case PIPE_TEX_FILTER_LINEAR:
+ return img_filter_2d_linear_repeat_POT;
+ default:
+ break;
}
- for (c = 0; c < 4; c++) {
- rgba[c][j] = lerp_2d(xw[j], yw[j],
- tx[c][0], tx[c][1], tx[c][2], tx[c][3]);
+ break;
+ case PIPE_TEX_WRAP_CLAMP:
+ switch (filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ return img_filter_2d_nearest_clamp_POT;
+ default:
+ break;
}
}
}
+ /* Otherwise use default versions:
+ */
+ if (filter == PIPE_TEX_FILTER_NEAREST)
+ return img_filter_2d_nearest;
+ else
+ return img_filter_2d_linear;
+ break;
+ case PIPE_TEXTURE_CUBE:
+ if (filter == PIPE_TEX_FILTER_NEAREST)
+ return img_filter_cube_nearest;
+ else
+ return img_filter_cube_linear;
+ break;
+ case PIPE_TEXTURE_3D:
+ if (filter == PIPE_TEX_FILTER_NEAREST)
+ return img_filter_3d_nearest;
+ else
+ return img_filter_3d_linear;
break;
default:
assert(0);
+ return img_filter_1d_nearest;
}
}
/**
- * Common code for vertex/fragment program texture sampling.
+ * Bind the given texture object and texture cache to the sampler varient.
*/
-static INLINE void
-sp_get_samples(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- boolean computeLambda,
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+void
+sp_sampler_varient_bind_texture( struct sp_sampler_varient *samp,
+ struct softpipe_tex_tile_cache *tex_cache,
+ const struct pipe_texture *texture )
{
- const struct sp_shader_sampler *samp = sp_shader_sampler(tgsi_sampler);
- const struct softpipe_context *sp = samp->sp;
- const uint unit = samp->unit;
- const struct pipe_texture *texture = sp->texture[unit];
- const struct pipe_sampler_state *sampler = sp->sampler[unit];
-
- if (!texture)
- return;
+ const struct pipe_sampler_state *sampler = samp->sampler;
- switch (texture->target) {
- case PIPE_TEXTURE_1D:
- assert(sampler->normalized_coords);
- sp_get_samples_1d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- break;
- case PIPE_TEXTURE_2D:
- if (sampler->normalized_coords)
- sp_get_samples_2d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- else
- sp_get_samples_rect(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- break;
- case PIPE_TEXTURE_3D:
- assert(sampler->normalized_coords);
- sp_get_samples_3d(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- break;
- case PIPE_TEXTURE_CUBE:
- assert(sampler->normalized_coords);
- sp_get_samples_cube(tgsi_sampler, s, t, p, computeLambda, lodbias, rgba);
- break;
- default:
- assert(0);
- }
-
-#if 0 /* DEBUG */
- {
- int i;
- printf("Sampled at %f, %f, %f:\n", s[0], t[0], p[0]);
- for (i = 0; i < 4; i++) {
- printf("Frag %d: %f %f %f %f\n", i,
- rgba[0][i],
- rgba[1][i],
- rgba[2][i],
- rgba[3][i]);
- }
- }
-#endif
+ samp->texture = texture;
+ samp->cache = tex_cache;
+ samp->xpot = util_unsigned_logbase2( texture->width[0] );
+ samp->ypot = util_unsigned_logbase2( texture->height[0] );
+ samp->level = CLAMP((int) sampler->min_lod, 0, (int) texture->last_level);
}
-/**
- * Called via tgsi_sampler::get_samples() when running a fragment shader.
- * Get four filtered RGBA values from the sampler's texture.
- */
void
-sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+sp_sampler_varient_destroy( struct sp_sampler_varient *samp )
{
- sp_get_samples(tgsi_sampler, s, t, p, TRUE, lodbias, rgba);
+ FREE(samp);
}
/**
- * Called via tgsi_sampler::get_samples() when running a vertex shader.
- * Get four filtered RGBA values from the sampler's texture.
+ * Create a sampler varient for a given set of non-orthogonal state.
*/
-void
-sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE])
+struct sp_sampler_varient *
+sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
+ const union sp_sampler_key key )
{
- sp_get_samples(tgsi_sampler, s, t, p, FALSE, lodbias, rgba);
+ struct sp_sampler_varient *samp = CALLOC_STRUCT(sp_sampler_varient);
+ if (!samp)
+ return NULL;
+
+ samp->sampler = sampler;
+ samp->key = key;
+
+ /* Note that (for instance) linear_texcoord_s and
+ * nearest_texcoord_s may be active at the same time, if the
+ * sampler min_img_filter differs from its mag_img_filter.
+ */
+ if (sampler->normalized_coords) {
+ samp->linear_texcoord_s = get_linear_wrap( sampler->wrap_s );
+ samp->linear_texcoord_t = get_linear_wrap( sampler->wrap_t );
+ samp->linear_texcoord_p = get_linear_wrap( sampler->wrap_r );
+
+ samp->nearest_texcoord_s = get_nearest_wrap( sampler->wrap_s );
+ samp->nearest_texcoord_t = get_nearest_wrap( sampler->wrap_t );
+ samp->nearest_texcoord_p = get_nearest_wrap( sampler->wrap_r );
+ }
+ else {
+ samp->linear_texcoord_s = get_linear_unorm_wrap( sampler->wrap_s );
+ samp->linear_texcoord_t = get_linear_unorm_wrap( sampler->wrap_t );
+ samp->linear_texcoord_p = get_linear_unorm_wrap( sampler->wrap_r );
+
+ samp->nearest_texcoord_s = get_nearest_unorm_wrap( sampler->wrap_s );
+ samp->nearest_texcoord_t = get_nearest_unorm_wrap( sampler->wrap_t );
+ samp->nearest_texcoord_p = get_nearest_unorm_wrap( sampler->wrap_r );
+ }
+
+ samp->compute_lambda = get_lambda_func( key );
+
+ samp->min_img_filter = get_img_filter(key, sampler->min_img_filter, sampler);
+ samp->mag_img_filter = get_img_filter(key, sampler->mag_img_filter, sampler);
+
+ switch (sampler->min_mip_filter) {
+ case PIPE_TEX_MIPFILTER_NONE:
+ if (sampler->min_img_filter == sampler->mag_img_filter)
+ samp->mip_filter = samp->min_img_filter;
+ else
+ samp->mip_filter = mip_filter_none;
+ break;
+
+ case PIPE_TEX_MIPFILTER_NEAREST:
+ samp->mip_filter = mip_filter_nearest;
+ break;
+
+ case PIPE_TEX_MIPFILTER_LINEAR:
+ if (key.bits.is_pot &&
+ sampler->min_img_filter == sampler->mag_img_filter &&
+ sampler->normalized_coords &&
+ sampler->wrap_s == PIPE_TEX_WRAP_REPEAT &&
+ sampler->wrap_t == PIPE_TEX_WRAP_REPEAT &&
+ sampler->min_img_filter == PIPE_TEX_FILTER_LINEAR)
+ {
+ samp->mip_filter = mip_filter_linear_2d_linear_repeat_POT;
+ }
+ else
+ {
+ samp->mip_filter = mip_filter_linear;
+ }
+ break;
+ }
+
+ if (sampler->compare_mode != FALSE) {
+ samp->compare = sample_compare;
+ }
+ else {
+ /* Skip compare operation by promoting the mip_filter function
+ * pointer:
+ */
+ samp->compare = samp->mip_filter;
+ }
+
+ if (key.bits.target == PIPE_TEXTURE_CUBE) {
+ samp->base.get_samples = sample_cube;
+ }
+ else {
+ samp->faces[0] = 0;
+ samp->faces[1] = 0;
+ samp->faces[2] = 0;
+ samp->faces[3] = 0;
+
+ /* Skip cube face determination by promoting the compare
+ * function pointer:
+ */
+ samp->base.get_samples = samp->compare;
+ }
+
+ return samp;
}
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.h b/src/gallium/drivers/softpipe/sp_tex_sample.h
index 40d8eb2c2a8..b0797711d37 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.h
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.h
@@ -31,43 +31,122 @@
#include "tgsi/tgsi_exec.h"
+struct sp_sampler_varient;
+
+typedef void (*wrap_nearest_func)(const float s[4],
+ unsigned size,
+ int icoord[4]);
+
+typedef void (*wrap_linear_func)(const float s[4],
+ unsigned size,
+ int icoord0[4],
+ int icoord1[4],
+ float w[4]);
+
+typedef float (*compute_lambda_func)(const struct sp_sampler_varient *sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias);
+
+typedef void (*filter_func)(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
+
+
+union sp_sampler_key {
+ struct {
+ unsigned target:3;
+ unsigned is_pot:1;
+ unsigned processor:2;
+ unsigned unit:4;
+ unsigned pad:22;
+ } bits;
+ unsigned value;
+};
/**
* Subclass of tgsi_sampler
*/
-struct sp_shader_sampler
+struct sp_sampler_varient
{
struct tgsi_sampler base; /**< base class */
- uint unit;
- struct softpipe_context *sp;
- struct softpipe_tile_cache *cache;
+ union sp_sampler_key key;
+
+ /* The owner of this struct:
+ */
+ const struct pipe_sampler_state *sampler;
+
+
+ /* Currently bound texture:
+ */
+ const struct pipe_texture *texture;
+ struct softpipe_tex_tile_cache *cache;
+
+ unsigned processor;
+
+ /* For sp_get_samples_2d_linear_POT:
+ */
+ unsigned xpot;
+ unsigned ypot;
+ unsigned level;
+
+ unsigned faces[4];
+
+ wrap_nearest_func nearest_texcoord_s;
+ wrap_nearest_func nearest_texcoord_t;
+ wrap_nearest_func nearest_texcoord_p;
+
+ wrap_linear_func linear_texcoord_s;
+ wrap_linear_func linear_texcoord_t;
+ wrap_linear_func linear_texcoord_p;
+
+ filter_func min_img_filter;
+ filter_func mag_img_filter;
+
+ compute_lambda_func compute_lambda;
+
+ filter_func mip_filter;
+ filter_func compare;
+
+ /* Linked list:
+ */
+ struct sp_sampler_varient *next;
};
+struct sp_sampler;
+/* Create a sampler varient for a given set of non-orthogonal state. Currently the
+ */
+struct sp_sampler_varient *
+sp_create_sampler_varient( const struct pipe_sampler_state *sampler,
+ const union sp_sampler_key key );
-static INLINE const struct sp_shader_sampler *
-sp_shader_sampler(const struct tgsi_sampler *sampler)
-{
- return (const struct sp_shader_sampler *) sampler;
-}
+void sp_sampler_varient_bind_texture( struct sp_sampler_varient *varient,
+ struct softpipe_tex_tile_cache *tex_cache,
+ const struct pipe_texture *tex );
+void sp_sampler_varient_destroy( struct sp_sampler_varient * );
-extern void
-sp_get_samples_fragment(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE]);
+
+
+static INLINE struct sp_sampler_varient *
+sp_sampler_varient(const struct tgsi_sampler *sampler)
+{
+ return (struct sp_sampler_varient *) sampler;
+}
extern void
-sp_get_samples_vertex(struct tgsi_sampler *tgsi_sampler,
- const float s[QUAD_SIZE],
- const float t[QUAD_SIZE],
- const float p[QUAD_SIZE],
- float lodbias,
- float rgba[NUM_CHANNELS][QUAD_SIZE]);
+sp_get_samples(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE]);
#endif /* SP_TEX_SAMPLE_H */
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.c b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
new file mode 100644
index 00000000000..407a22a9f4b
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.c
@@ -0,0 +1,273 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * Texture tile caching.
+ *
+ * Author:
+ * Brian Paul
+ */
+
+#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
+#include "util/u_tile.h"
+#include "sp_context.h"
+#include "sp_surface.h"
+#include "sp_texture.h"
+#include "sp_tex_tile_cache.h"
+
+
+
+struct softpipe_tex_tile_cache *
+sp_create_tex_tile_cache( struct pipe_screen *screen )
+{
+ struct softpipe_tex_tile_cache *tc;
+ uint pos;
+
+ tc = CALLOC_STRUCT( softpipe_tex_tile_cache );
+ if (tc) {
+ tc->screen = screen;
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ tc->entries[pos].addr.bits.invalid = 1;
+ }
+ tc->last_tile = &tc->entries[0]; /* any tile */
+ }
+ return tc;
+}
+
+
+void
+sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
+{
+ struct pipe_screen *screen;
+ uint pos;
+
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ /*assert(tc->entries[pos].x < 0);*/
+ }
+ if (tc->transfer) {
+ screen = tc->transfer->texture->screen;
+ screen->tex_transfer_destroy(tc->transfer);
+ }
+ if (tc->tex_trans) {
+ screen = tc->tex_trans->texture->screen;
+ screen->tex_transfer_destroy(tc->tex_trans);
+ }
+
+ FREE( tc );
+}
+
+
+
+
+void
+sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc)
+{
+ if (tc->tex_trans && !tc->tex_trans_map)
+ tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
+}
+
+
+void
+sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc)
+{
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
+ }
+}
+
+/**
+ * Invalidate all cached tiles for the cached texture.
+ * Should be called when the texture is modified.
+ */
+void
+sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc)
+{
+ unsigned i;
+
+ assert(tc);
+ assert(tc->texture);
+
+ for (i = 0; i < NUM_ENTRIES; i++) {
+ tc->entries[i].addr.bits.invalid = 1;
+ }
+}
+
+/**
+ * Specify the texture to cache.
+ */
+void
+sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
+ struct pipe_texture *texture)
+{
+ uint i;
+
+ assert(!tc->transfer);
+
+ if (tc->texture != texture) {
+ pipe_texture_reference(&tc->texture, texture);
+
+ if (tc->tex_trans) {
+ struct pipe_screen *screen = tc->tex_trans->texture->screen;
+
+ if (tc->tex_trans_map) {
+ screen->transfer_unmap(screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
+ }
+
+ screen->tex_transfer_destroy(tc->tex_trans);
+ tc->tex_trans = NULL;
+ }
+
+ /* mark as entries as invalid/empty */
+ /* XXX we should try to avoid this when the teximage hasn't changed */
+ for (i = 0; i < NUM_ENTRIES; i++) {
+ tc->entries[i].addr.bits.invalid = 1;
+ }
+
+ tc->tex_face = -1; /* any invalid value here */
+ }
+}
+
+
+
+
+/**
+ * Flush the tile cache: write all dirty tiles back to the transfer.
+ * any tiles "flagged" as cleared will be "really" cleared.
+ */
+void
+sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc)
+{
+ int pos;
+
+ if (tc->texture) {
+ /* caching a texture, mark all entries as empty */
+ for (pos = 0; pos < NUM_ENTRIES; pos++) {
+ tc->entries[pos].addr.bits.invalid = 1;
+ }
+ tc->tex_face = -1;
+ }
+
+}
+
+
+/**
+ * Given the texture face, level, zslice, x and y values, compute
+ * the cache entry position/index where we'd hope to find the
+ * cached texture tile.
+ * This is basically a direct-map cache.
+ * XXX There's probably lots of ways in which we can improve this.
+ */
+static INLINE uint
+tex_cache_pos( union tex_tile_address addr )
+{
+ uint entry = (addr.bits.x +
+ addr.bits.y * 9 +
+ addr.bits.z * 3 +
+ addr.bits.face +
+ addr.bits.level * 7);
+
+ return entry % NUM_ENTRIES;
+}
+
+/**
+ * Similar to sp_get_cached_tile() but for textures.
+ * Tiles are read-only and indexed with more params.
+ */
+const struct softpipe_tex_cached_tile *
+sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
+ union tex_tile_address addr )
+{
+ struct pipe_screen *screen = tc->screen;
+ struct softpipe_tex_cached_tile *tile;
+
+ tile = tc->entries + tex_cache_pos( addr );
+
+ if (addr.value != tile->addr.value) {
+
+ /* cache miss. Most misses are because we've invaldiated the
+ * texture cache previously -- most commonly on binding a new
+ * texture. Currently we effectively flush the cache on texture
+ * bind.
+ */
+#if 0
+ _debug_printf("miss at %u: x=%d y=%d z=%d face=%d level=%d\n"
+ " tile %u: x=%d y=%d z=%d face=%d level=%d\n",
+ pos, x/TILE_SIZE, y/TILE_SIZE, z, face, level,
+ pos, tile->addr.bits.x, tile->addr.bits.y, tile->z, tile->face, tile->level);
+#endif
+
+ /* check if we need to get a new transfer */
+ if (!tc->tex_trans ||
+ tc->tex_face != addr.bits.face ||
+ tc->tex_level != addr.bits.level ||
+ tc->tex_z != addr.bits.z) {
+ /* get new transfer (view into texture) */
+
+ if (tc->tex_trans) {
+ if (tc->tex_trans_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
+ tc->tex_trans_map = NULL;
+ }
+
+ screen->tex_transfer_destroy(tc->tex_trans);
+ tc->tex_trans = NULL;
+ }
+
+ tc->tex_trans =
+ screen->get_tex_transfer(screen, tc->texture,
+ addr.bits.face,
+ addr.bits.level,
+ addr.bits.z,
+ PIPE_TRANSFER_READ, 0, 0,
+ tc->texture->width[addr.bits.level],
+ tc->texture->height[addr.bits.level]);
+
+ tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
+
+ tc->tex_face = addr.bits.face;
+ tc->tex_level = addr.bits.level;
+ tc->tex_z = addr.bits.z;
+ }
+
+ /* get tile from the transfer (view into texture) */
+ pipe_get_tile_rgba(tc->tex_trans,
+ addr.bits.x * TILE_SIZE,
+ addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
+ (float *) tile->data.color);
+ tile->addr = addr;
+ }
+
+ tc->last_tile = tile;
+ return tile;
+}
+
+
+
diff --git a/src/gallium/drivers/softpipe/sp_tex_tile_cache.h b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
new file mode 100644
index 00000000000..ac6886a3df1
--- /dev/null
+++ b/src/gallium/drivers/softpipe/sp_tex_tile_cache.h
@@ -0,0 +1,155 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef SP_TEX_TILE_CACHE_H
+#define SP_TEX_TILE_CACHE_H
+
+
+#include "pipe/p_compiler.h"
+
+
+struct softpipe_context;
+struct softpipe_tex_tile_cache;
+
+
+/**
+ * Cache tile size (width and height). This needs to be a power of two.
+ */
+#define TILE_SIZE 64
+
+
+/* If we need to support > 4096, just expand this to be a 64 bit
+ * union, or consider tiling in Z as well.
+ */
+union tex_tile_address {
+ struct {
+ unsigned x:6; /* 4096 / TILE_SIZE */
+ unsigned y:6; /* 4096 / TILE_SIZE */
+ unsigned z:12; /* 4096 -- z not tiled */
+ unsigned face:3;
+ unsigned level:4;
+ unsigned invalid:1;
+ } bits;
+ unsigned value;
+};
+
+
+struct softpipe_tex_cached_tile
+{
+ union tex_tile_address addr;
+ union {
+ float color[TILE_SIZE][TILE_SIZE][4];
+ } data;
+};
+
+#define NUM_ENTRIES 50
+
+struct softpipe_tex_tile_cache
+{
+ struct pipe_screen *screen;
+ struct pipe_transfer *transfer;
+ void *transfer_map;
+
+ struct pipe_texture *texture; /**< if caching a texture */
+ unsigned timestamp;
+
+ struct softpipe_tex_cached_tile entries[NUM_ENTRIES];
+
+ struct pipe_transfer *tex_trans;
+ void *tex_trans_map;
+ int tex_face, tex_level, tex_z;
+
+ struct softpipe_tex_cached_tile *last_tile; /**< most recently retrieved tile */
+};
+
+
+extern struct softpipe_tex_tile_cache *
+sp_create_tex_tile_cache( struct pipe_screen *screen );
+
+extern void
+sp_destroy_tex_tile_cache(struct softpipe_tex_tile_cache *tc);
+
+
+extern void
+sp_tex_tile_cache_map_transfers(struct softpipe_tex_tile_cache *tc);
+
+extern void
+sp_tex_tile_cache_unmap_transfers(struct softpipe_tex_tile_cache *tc);
+
+extern void
+sp_tex_tile_cache_set_texture(struct softpipe_tex_tile_cache *tc,
+ struct pipe_texture *texture);
+
+void
+sp_tex_tile_cache_validate_texture(struct softpipe_tex_tile_cache *tc);
+
+extern void
+sp_flush_tex_tile_cache(struct softpipe_tex_tile_cache *tc);
+
+
+
+extern const struct softpipe_tex_cached_tile *
+sp_find_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
+ union tex_tile_address addr );
+
+static INLINE union tex_tile_address
+tex_tile_address( unsigned x,
+ unsigned y,
+ unsigned z,
+ unsigned face,
+ unsigned level )
+{
+ union tex_tile_address addr;
+
+ addr.value = 0;
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+ addr.bits.z = z;
+ addr.bits.face = face;
+ addr.bits.level = level;
+
+ return addr;
+}
+
+/* Quickly retrieve tile if it matches last lookup.
+ */
+static INLINE const struct softpipe_tex_cached_tile *
+sp_get_cached_tile_tex(struct softpipe_tex_tile_cache *tc,
+ union tex_tile_address addr )
+{
+ if (tc->last_tile->addr.value == addr.value)
+ return tc->last_tile;
+
+ return sp_find_cached_tile_tex( tc, addr );
+}
+
+
+
+
+
+#endif /* SP_TEX_TILE_CACHE_H */
+
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 70f09324311..49b51afda7e 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -30,26 +30,21 @@
* Michel Dänzer <[email protected]>
*/
-#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h"
#include "util/u_memory.h"
#include "sp_context.h"
#include "sp_state.h"
#include "sp_texture.h"
-#include "sp_tile_cache.h"
#include "sp_screen.h"
#include "sp_winsys.h"
-/* Simple, maximally packed layout.
- */
-
-
-/* Conventional allocation path for non-display textures:
+/**
+ * Conventional allocation path for non-display textures:
+ * Use a simple, maximally packed layout.
*/
static boolean
softpipe_texture_layout(struct pipe_screen *screen,
@@ -89,6 +84,10 @@ softpipe_texture_layout(struct pipe_screen *screen,
return spt->buffer != NULL;
}
+
+/**
+ * Texture layout for simple color buffers.
+ */
static boolean
softpipe_displaytarget_layout(struct pipe_screen *screen,
struct softpipe_texture * spt)
@@ -112,21 +111,22 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
}
-
-
-
static struct pipe_texture *
softpipe_texture_create(struct pipe_screen *screen,
- const struct pipe_texture *templat)
+ const struct pipe_texture *template)
{
struct softpipe_texture *spt = CALLOC_STRUCT(softpipe_texture);
if (!spt)
return NULL;
- spt->base = *templat;
+ spt->base = *template;
pipe_reference_init(&spt->base.reference, 1);
spt->base.screen = screen;
+ spt->pot = (util_is_power_of_two(template->width[0]) &&
+ util_is_power_of_two(template->height[0]) &&
+ util_is_power_of_two(template->depth[0]));
+
if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
PIPE_TEXTURE_USAGE_PRIMARY)) {
if (!softpipe_displaytarget_layout(screen, spt))
@@ -222,6 +222,13 @@ softpipe_get_tex_surface(struct pipe_screen *screen,
if (ps->usage & PIPE_BUFFER_USAGE_GPU_READ)
ps->usage |= PIPE_BUFFER_USAGE_CPU_READ;
+ if (ps->usage & (PIPE_BUFFER_USAGE_CPU_WRITE |
+ PIPE_BUFFER_USAGE_GPU_WRITE)) {
+ /* Mark the surface as dirty. The tile cache will look for this. */
+ spt->timestamp++;
+ softpipe_screen(screen)->timestamp++;
+ }
+
ps->face = face;
ps->level = level;
ps->zslice = zslice;
@@ -342,14 +349,13 @@ softpipe_transfer_map( struct pipe_screen *screen,
/* May want to different things here depending on read/write nature
* of the map:
*/
- if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
- {
+ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ) {
/* Do something to notify sharing contexts of a texture change.
* In softpipe, that would mean flushing the texture cache.
*/
softpipe_screen(screen)->timestamp++;
}
-
+
xfer_map = map + softpipe_transfer(transfer)->offset +
transfer->y / transfer->block.height * transfer->stride +
transfer->x / transfer->block.width * transfer->block.size;
@@ -360,7 +366,7 @@ softpipe_transfer_map( struct pipe_screen *screen,
static void
softpipe_transfer_unmap(struct pipe_screen *screen,
- struct pipe_transfer *transfer)
+ struct pipe_transfer *transfer)
{
struct softpipe_texture *spt;
@@ -371,18 +377,12 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
if (transfer->usage != PIPE_TRANSFER_READ) {
/* Mark the texture as dirty to expire the tile caches. */
- spt->modified = TRUE;
+ spt->timestamp++;
}
}
void
-softpipe_init_texture_funcs(struct softpipe_context *sp)
-{
-}
-
-
-void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen)
{
screen->texture_create = softpipe_texture_create;
@@ -404,7 +404,7 @@ softpipe_get_texture_buffer( struct pipe_texture *texture,
struct pipe_buffer **buf,
unsigned *stride )
{
- struct softpipe_texture *tex = (struct softpipe_texture *)texture;
+ struct softpipe_texture *tex = (struct softpipe_texture *) texture;
if (!tex)
return FALSE;
diff --git a/src/gallium/drivers/softpipe/sp_texture.h b/src/gallium/drivers/softpipe/sp_texture.h
index 893aa7d11d8..2537ab6a40d 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -48,7 +48,11 @@ struct softpipe_texture
*/
struct pipe_buffer *buffer;
- boolean modified;
+ /* True if texture images are power-of-two in all dimensions:
+ */
+ boolean pot;
+
+ unsigned timestamp;
};
struct softpipe_transfer
@@ -74,9 +78,6 @@ softpipe_transfer(struct pipe_transfer *pt)
extern void
-softpipe_init_texture_funcs( struct softpipe_context *softpipe );
-
-extern void
softpipe_init_screen_texture_funcs(struct pipe_screen *screen);
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.c b/src/gallium/drivers/softpipe/sp_tile_cache.c
index 1f9b8f1f4fb..de479709858 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.c
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.c
@@ -26,7 +26,7 @@
**************************************************************************/
/**
- * Texture tile caching.
+ * Render target tile caching.
*
* Author:
* Brian Paul
@@ -35,38 +35,8 @@
#include "pipe/p_inlines.h"
#include "util/u_memory.h"
#include "util/u_tile.h"
-#include "sp_context.h"
-#include "sp_surface.h"
-#include "sp_texture.h"
#include "sp_tile_cache.h"
-#define NUM_ENTRIES 50
-
-
-/** XXX move these */
-#define MAX_WIDTH 2048
-#define MAX_HEIGHT 2048
-
-
-struct softpipe_tile_cache
-{
- struct pipe_screen *screen;
- struct pipe_surface *surface; /**< the surface we're caching */
- struct pipe_transfer *transfer;
- void *transfer_map;
- struct pipe_texture *texture; /**< if caching a texture */
- struct softpipe_cached_tile entries[NUM_ENTRIES];
- uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
- float clear_color[4]; /**< for color bufs */
- uint clear_val; /**< for z+stencil, or packed color clear value */
- boolean depth_stencil; /**< Is the surface a depth/stencil format? */
-
- struct pipe_transfer *tex_trans;
- void *tex_trans_map;
- int tex_face, tex_level, tex_z;
-
- struct softpipe_cached_tile tile; /**< scratch tile for clears */
-};
/**
@@ -76,7 +46,7 @@ struct softpipe_tile_cache
* a LRU replacement policy.
*/
#define CACHE_POS(x, y) \
- (((x) / TILE_SIZE + ((y) / TILE_SIZE) * 5) % NUM_ENTRIES)
+ (((x) + (y) * 5) % NUM_ENTRIES)
@@ -84,12 +54,10 @@ struct softpipe_tile_cache
* Is the tile at (x,y) in cleared state?
*/
static INLINE uint
-is_clear_flag_set(const uint *bitvec, int x, int y)
+is_clear_flag_set(const uint *bitvec, union tile_address addr)
{
int pos, bit;
- x /= TILE_SIZE;
- y /= TILE_SIZE;
- pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+ pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
bit = bitvec[pos / 32] & (1 << (pos & 31));
return bit;
@@ -100,12 +68,10 @@ is_clear_flag_set(const uint *bitvec, int x, int y)
* Mark the tile at (x,y) as not cleared.
*/
static INLINE void
-clear_clear_flag(uint *bitvec, int x, int y)
+clear_clear_flag(uint *bitvec, union tile_address addr)
{
int pos;
- x /= TILE_SIZE;
- y /= TILE_SIZE;
- pos = y * (MAX_WIDTH / TILE_SIZE) + x;
+ pos = addr.bits.y * (MAX_WIDTH / TILE_SIZE) + addr.bits.x;
assert(pos / 32 < (MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32);
bitvec[pos / 32] &= ~(1 << (pos & 31));
}
@@ -116,14 +82,20 @@ sp_create_tile_cache( struct pipe_screen *screen )
{
struct softpipe_tile_cache *tc;
uint pos;
+ int maxLevels, maxTexSize;
+
+ /* sanity checking: max sure MAX_WIDTH/HEIGHT >= largest texture image */
+ maxLevels = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS);
+ maxTexSize = 1 << (maxLevels - 1);
+ assert(MAX_WIDTH >= maxTexSize);
tc = CALLOC_STRUCT( softpipe_tile_cache );
if (tc) {
tc->screen = screen;
for (pos = 0; pos < NUM_ENTRIES; pos++) {
- tc->entries[pos].x =
- tc->entries[pos].y = -1;
+ tc->entries[pos].addr.bits.invalid = 1;
}
+ tc->last_tile = &tc->entries[0]; /* any tile */
}
return tc;
}
@@ -142,10 +114,6 @@ sp_destroy_tile_cache(struct softpipe_tile_cache *tc)
screen = tc->transfer->texture->screen;
screen->tex_transfer_destroy(tc->transfer);
}
- if (tc->tex_trans) {
- screen = tc->tex_trans->texture->screen;
- screen->tex_transfer_destroy(tc->tex_trans);
- }
FREE( tc );
}
@@ -158,8 +126,6 @@ void
sp_tile_cache_set_surface(struct softpipe_tile_cache *tc,
struct pipe_surface *ps)
{
- assert(!tc->texture);
-
if (tc->transfer) {
struct pipe_screen *screen = tc->transfer->texture->screen;
@@ -211,9 +177,6 @@ sp_tile_cache_map_transfers(struct softpipe_tile_cache *tc)
{
if (tc->transfer && !tc->transfer_map)
tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
-
- if (tc->tex_trans && !tc->tex_trans_map)
- tc->tex_trans_map = tc->screen->transfer_map(tc->screen, tc->tex_trans);
}
@@ -224,47 +187,6 @@ sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc)
tc->screen->transfer_unmap(tc->screen, tc->transfer);
tc->transfer_map = NULL;
}
-
- if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
- tc->tex_trans_map = NULL;
- }
-}
-
-
-/**
- * Specify the texture to cache.
- */
-void
-sp_tile_cache_set_texture(struct pipe_context *pipe,
- struct softpipe_tile_cache *tc,
- struct pipe_texture *texture)
-{
- uint i;
-
- assert(!tc->transfer);
-
- pipe_texture_reference(&tc->texture, texture);
-
- if (tc->tex_trans) {
- struct pipe_screen *screen = tc->tex_trans->texture->screen;
-
- if (tc->tex_trans_map) {
- screen->transfer_unmap(screen, tc->tex_trans);
- tc->tex_trans_map = NULL;
- }
-
- screen->tex_transfer_destroy(tc->tex_trans);
- tc->tex_trans = NULL;
- }
-
- /* mark as entries as invalid/empty */
- /* XXX we should try to avoid this when the teximage hasn't changed */
- for (i = 0; i < NUM_ENTRIES; i++) {
- tc->entries[i].x = -1;
- }
-
- tc->tex_face = -1; /* any invalid value here */
}
@@ -308,7 +230,7 @@ clear_tile(struct softpipe_cached_tile *tile,
switch (pf_get_size(format)) {
case 1:
- memset(tile->data.any, 0, TILE_SIZE * TILE_SIZE);
+ memset(tile->data.any, clear_value, TILE_SIZE * TILE_SIZE);
break;
case 2:
if (clear_value == 0) {
@@ -344,8 +266,7 @@ clear_tile(struct softpipe_cached_tile *tile,
* Actually clear the tiles which were flagged as being in a clear state.
*/
static void
-sp_tile_cache_flush_clear(struct pipe_context *pipe,
- struct softpipe_tile_cache *tc)
+sp_tile_cache_flush_clear(struct softpipe_tile_cache *tc)
{
struct pipe_transfer *pt = tc->transfer;
const uint w = tc->transfer->width;
@@ -359,13 +280,15 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
/* push the tile to all positions marked as clear */
for (y = 0; y < h; y += TILE_SIZE) {
for (x = 0; x < w; x += TILE_SIZE) {
- if (is_clear_flag_set(tc->clear_flags, x, y)) {
+ union tile_address addr = tile_address(x, y);
+
+ if (is_clear_flag_set(tc->clear_flags, addr)) {
pipe_put_tile_raw(pt,
x, y, TILE_SIZE, TILE_SIZE,
tc->tile.data.color32, 0/*STRIDE*/);
/* do this? */
- clear_clear_flag(tc->clear_flags, x, y);
+ clear_clear_flag(tc->clear_flags, addr);
numCleared++;
}
@@ -382,8 +305,7 @@ sp_tile_cache_flush_clear(struct pipe_context *pipe,
* any tiles "flagged" as cleared will be "really" cleared.
*/
void
-sp_flush_tile_cache(struct softpipe_context *softpipe,
- struct softpipe_tile_cache *tc)
+sp_flush_tile_cache(struct softpipe_tile_cache *tc)
{
struct pipe_transfer *pt = tc->transfer;
int inuse = 0, pos;
@@ -392,33 +314,30 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
/* caching a drawing transfer */
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
- if (tile->x >= 0) {
+ if (!tile->addr.bits.invalid) {
if (tc->depth_stencil) {
pipe_put_tile_raw(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe_put_tile_rgba(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
- tile->x = tile->y = -1; /* mark as empty */
+ tile->addr.bits.invalid = 1; /* mark as empty */
inuse++;
}
}
#if TILE_CLEAR_OPTIMIZATION
- sp_tile_cache_flush_clear(&softpipe->pipe, tc);
+ sp_tile_cache_flush_clear(tc);
#endif
}
- else if (tc->texture) {
- /* caching a texture, mark all entries as empty */
- for (pos = 0; pos < NUM_ENTRIES; pos++) {
- tc->entries[pos].x = -1;
- }
- tc->tex_face = -1;
- }
#if 0
debug_printf("flushed tiles in use: %d\n", inuse);
@@ -431,40 +350,39 @@ sp_flush_tile_cache(struct softpipe_context *softpipe,
* \param x, y position of tile, in pixels
*/
struct softpipe_cached_tile *
-sp_get_cached_tile(struct softpipe_context *softpipe,
- struct softpipe_tile_cache *tc, int x, int y)
+sp_find_cached_tile(struct softpipe_tile_cache *tc,
+ union tile_address addr )
{
struct pipe_transfer *pt = tc->transfer;
-
- /* tile pos in framebuffer: */
- const int tile_x = x & ~(TILE_SIZE - 1);
- const int tile_y = y & ~(TILE_SIZE - 1);
-
+
/* cache pos/entry: */
- const int pos = CACHE_POS(x, y);
+ const int pos = CACHE_POS(addr.bits.x,
+ addr.bits.y);
struct softpipe_cached_tile *tile = tc->entries + pos;
- if (tile_x != tile->x ||
- tile_y != tile->y) {
+ if (addr.value != tile->addr.value) {
- if (tile->x != -1) {
+ if (tile->addr.bits.invalid == 0) {
/* put dirty tile back in framebuffer */
if (tc->depth_stencil) {
pipe_put_tile_raw(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe_put_tile_rgba(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
- tile->x = tile_x;
- tile->y = tile_y;
+ tile->addr = addr;
- if (is_clear_flag_set(tc->clear_flags, x, y)) {
+ if (is_clear_flag_set(tc->clear_flags, addr)) {
/* don't get tile from framebuffer, just clear it */
if (tc->depth_stencil) {
clear_tile(tile, pt->format, tc->clear_val);
@@ -472,125 +390,33 @@ sp_get_cached_tile(struct softpipe_context *softpipe,
else {
clear_tile_rgba(tile, pt->format, tc->clear_color);
}
- clear_clear_flag(tc->clear_flags, x, y);
+ clear_clear_flag(tc->clear_flags, addr);
}
else {
/* get new tile data from transfer */
if (tc->depth_stencil) {
pipe_get_tile_raw(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
tile->data.depth32, 0/*STRIDE*/);
}
else {
pipe_get_tile_rgba(pt,
- tile->x, tile->y, TILE_SIZE, TILE_SIZE,
+ tile->addr.bits.x * TILE_SIZE,
+ tile->addr.bits.y * TILE_SIZE,
+ TILE_SIZE, TILE_SIZE,
(float *) tile->data.color);
}
}
}
+ tc->last_tile = tile;
return tile;
}
-/**
- * Given the texture face, level, zslice, x and y values, compute
- * the cache entry position/index where we'd hope to find the
- * cached texture tile.
- * This is basically a direct-map cache.
- * XXX There's probably lots of ways in which we can improve this.
- */
-static INLINE uint
-tex_cache_pos(int x, int y, int z, int face, int level)
-{
- uint entry = x + y * 9 + z * 3 + face + level * 7;
- return entry % NUM_ENTRIES;
-}
-
-
-/**
- * Similar to sp_get_cached_tile() but for textures.
- * Tiles are read-only and indexed with more params.
- */
-const struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct softpipe_context *sp,
- struct softpipe_tile_cache *tc, int x, int y, int z,
- int face, int level)
-{
- struct pipe_screen *screen = sp->pipe.screen;
- /* tile pos in framebuffer: */
- const int tile_x = x & ~(TILE_SIZE - 1);
- const int tile_y = y & ~(TILE_SIZE - 1);
- /* cache pos/entry: */
- const uint pos = tex_cache_pos(x / TILE_SIZE, y / TILE_SIZE, z,
- face, level);
- struct softpipe_cached_tile *tile = tc->entries + pos;
-
- if (tc->texture) {
- struct softpipe_texture *spt = softpipe_texture(tc->texture);
- if (spt->modified) {
- /* texture was modified, invalidate all cached tiles */
- uint p;
- for (p = 0; p < NUM_ENTRIES; p++) {
- tile = tc->entries + p;
- tile->x = -1;
- }
- spt->modified = FALSE;
- }
- }
-
- if (tile_x != tile->x ||
- tile_y != tile->y ||
- z != tile->z ||
- face != tile->face ||
- level != tile->level) {
- /* cache miss */
-#if 0
- printf("miss at %u x=%d y=%d z=%d face=%d level=%d\n", pos,
- x/TILE_SIZE, y/TILE_SIZE, z, face, level);
-#endif
- /* check if we need to get a new transfer */
- if (!tc->tex_trans ||
- tc->tex_face != face ||
- tc->tex_level != level ||
- tc->tex_z != z) {
- /* get new transfer (view into texture) */
-
- if (tc->tex_trans) {
- if (tc->tex_trans_map) {
- tc->screen->transfer_unmap(tc->screen, tc->tex_trans);
- tc->tex_trans_map = NULL;
- }
-
- screen->tex_transfer_destroy(tc->tex_trans);
- tc->tex_trans = NULL;
- }
-
- tc->tex_trans = screen->get_tex_transfer(screen, tc->texture, face, level, z,
- PIPE_TRANSFER_READ, 0, 0,
- tc->texture->width[level],
- tc->texture->height[level]);
- tc->tex_trans_map = screen->transfer_map(screen, tc->tex_trans);
-
- tc->tex_face = face;
- tc->tex_level = level;
- tc->tex_z = z;
- }
-
- /* get tile from the transfer (view into texture) */
- pipe_get_tile_rgba(tc->tex_trans,
- tile_x, tile_y, TILE_SIZE, TILE_SIZE,
- (float *) tile->data.color);
- tile->x = tile_x;
- tile->y = tile_y;
- tile->z = z;
- tile->face = face;
- tile->level = level;
- }
-
- return tile;
-}
/**
@@ -621,6 +447,6 @@ sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba,
for (pos = 0; pos < NUM_ENTRIES; pos++) {
struct softpipe_cached_tile *tile = tc->entries + pos;
- tile->x = tile->y = -1;
+ tile->addr.bits.invalid = 1;
}
}
diff --git a/src/gallium/drivers/softpipe/sp_tile_cache.h b/src/gallium/drivers/softpipe/sp_tile_cache.h
index 8f247d0e580..a12092702a6 100644
--- a/src/gallium/drivers/softpipe/sp_tile_cache.h
+++ b/src/gallium/drivers/softpipe/sp_tile_cache.h
@@ -34,7 +34,6 @@
#include "pipe/p_compiler.h"
-struct softpipe_context;
struct softpipe_tile_cache;
@@ -44,11 +43,23 @@ struct softpipe_tile_cache;
#define TILE_SIZE 64
+/* If we need to support > 4096, just expand this to be a 64 bit
+ * union, or consider tiling in Z as well.
+ */
+union tile_address {
+ struct {
+ unsigned x:6; /* 4096 / TILE_SIZE */
+ unsigned y:6; /* 4096 / TILE_SIZE */
+ unsigned invalid:1;
+ unsigned pad:19;
+ } bits;
+ unsigned value;
+};
+
struct softpipe_cached_tile
{
- int x, y; /**< pos of tile in window coords */
- int z, face, level; /**< Extra texture indexes */
+ union tile_address addr;
union {
float color[TILE_SIZE][TILE_SIZE][4];
uint color32[TILE_SIZE][TILE_SIZE];
@@ -59,6 +70,32 @@ struct softpipe_cached_tile
} data;
};
+#define NUM_ENTRIES 50
+
+
+/** XXX move these */
+#define MAX_WIDTH 4096
+#define MAX_HEIGHT 4096
+
+
+struct softpipe_tile_cache
+{
+ struct pipe_screen *screen;
+ struct pipe_surface *surface; /**< the surface we're caching */
+ struct pipe_transfer *transfer;
+ void *transfer_map;
+
+ struct softpipe_cached_tile entries[NUM_ENTRIES];
+ uint clear_flags[(MAX_WIDTH / TILE_SIZE) * (MAX_HEIGHT / TILE_SIZE) / 32];
+ float clear_color[4]; /**< for color bufs */
+ uint clear_val; /**< for z+stencil, or packed color clear value */
+ boolean depth_stencil; /**< Is the surface a depth/stencil format? */
+
+ struct softpipe_cached_tile tile; /**< scratch tile for clears */
+
+ struct softpipe_cached_tile *last_tile; /**< most recently retrieved tile */
+};
+
extern struct softpipe_tile_cache *
sp_create_tile_cache( struct pipe_screen *screen );
@@ -80,26 +117,45 @@ extern void
sp_tile_cache_unmap_transfers(struct softpipe_tile_cache *tc);
extern void
-sp_tile_cache_set_texture(struct pipe_context *pipe,
- struct softpipe_tile_cache *tc,
- struct pipe_texture *texture);
-
-extern void
-sp_flush_tile_cache(struct softpipe_context *softpipe,
- struct softpipe_tile_cache *tc);
+sp_flush_tile_cache(struct softpipe_tile_cache *tc);
extern void
sp_tile_cache_clear(struct softpipe_tile_cache *tc, const float *rgba,
uint clearValue);
extern struct softpipe_cached_tile *
-sp_get_cached_tile(struct softpipe_context *softpipe,
- struct softpipe_tile_cache *tc, int x, int y);
+sp_find_cached_tile(struct softpipe_tile_cache *tc,
+ union tile_address addr );
+
+
+static INLINE union tile_address
+tile_address( unsigned x,
+ unsigned y )
+{
+ union tile_address addr;
+
+ addr.value = 0;
+ addr.bits.x = x / TILE_SIZE;
+ addr.bits.y = y / TILE_SIZE;
+
+ return addr;
+}
+
+/* Quickly retrieve tile if it matches last lookup.
+ */
+static INLINE struct softpipe_cached_tile *
+sp_get_cached_tile(struct softpipe_tile_cache *tc,
+ int x, int y )
+{
+ union tile_address addr = tile_address( x, y );
+
+ if (tc->last_tile->addr.value == addr.value)
+ return tc->last_tile;
+
+ return sp_find_cached_tile( tc, addr );
+}
+
-extern const struct softpipe_cached_tile *
-sp_get_cached_tile_tex(struct softpipe_context *softpipe,
- struct softpipe_tile_cache *tc, int x, int y, int z,
- int face, int level);
#endif /* SP_TILE_CACHE_H */
diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index ae0af4d0557..bf470b46ae1 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -125,11 +125,11 @@ trace_context_draw_block(struct trace_context *tr_ctx, int flag)
} else if ((tr_ctx->draw_rule.blocker & flag) &&
(tr_ctx->draw_blocker & 4)) {
boolean block = FALSE;
- debug_printf("%s (%lu %lu) (%lu %lu) (%lu %u) (%lu %u)\n", __FUNCTION__,
- tr_ctx->draw_rule.fs, tr_ctx->curr.fs,
- tr_ctx->draw_rule.vs, tr_ctx->curr.vs,
- tr_ctx->draw_rule.surf, 0,
- tr_ctx->draw_rule.tex, 0);
+ debug_printf("%s (%p %p) (%p %p) (%p %u) (%p %u)\n", __FUNCTION__,
+ (void *) tr_ctx->draw_rule.fs, (void *) tr_ctx->curr.fs,
+ (void *) tr_ctx->draw_rule.vs, (void *) tr_ctx->curr.vs,
+ (void *) tr_ctx->draw_rule.surf, 0,
+ (void *) tr_ctx->draw_rule.tex, 0);
if (tr_ctx->draw_rule.fs &&
tr_ctx->draw_rule.fs == tr_ctx->curr.fs)
block = TRUE;
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index b01ab6d137c..f252d6df00d 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -281,7 +281,7 @@ enum pipe_transfer_usage {
#define PIPE_CAP_NPOT_TEXTURES 2
#define PIPE_CAP_TWO_SIDED_STENCIL 3
#define PIPE_CAP_GLSL 4 /* XXX need something better */
-#define PIPE_CAP_S3TC 5
+#define PIPE_CAP_S3TC 5 /* XXX: deprecated; cap determined via supported sampler formats */
#define PIPE_CAP_ANISOTROPIC_FILTER 6
#define PIPE_CAP_POINT_SPRITE 7
#define PIPE_CAP_MAX_RENDER_TARGETS 8
diff --git a/src/gallium/include/pipe/p_inlines.h b/src/gallium/include/pipe/p_inlines.h
index a5c1e8270a3..30a4aaf4093 100644
--- a/src/gallium/include/pipe/p_inlines.h
+++ b/src/gallium/include/pipe/p_inlines.h
@@ -118,7 +118,7 @@ pipe_buffer_write(struct pipe_screen *screen,
unsigned offset, unsigned size,
const void *data)
{
- uint8_t *map;
+ void *map;
assert(offset < buf->size);
assert(offset + size <= buf->size);
@@ -129,7 +129,7 @@ pipe_buffer_write(struct pipe_screen *screen,
PIPE_BUFFER_USAGE_FLUSH_EXPLICIT);
assert(map);
if(map) {
- memcpy(map + offset, data, size);
+ memcpy((uint8_t *)map + offset, data, size);
pipe_buffer_flush_mapped_range(screen, buf, offset, size);
pipe_buffer_unmap(screen, buf);
}
@@ -141,7 +141,7 @@ pipe_buffer_read(struct pipe_screen *screen,
unsigned offset, unsigned size,
void *data)
{
- uint8_t *map;
+ void *map;
assert(offset < buf->size);
assert(offset + size <= buf->size);
@@ -150,11 +150,31 @@ pipe_buffer_read(struct pipe_screen *screen,
map = pipe_buffer_map_range(screen, buf, offset, size, PIPE_BUFFER_USAGE_CPU_READ);
assert(map);
if(map) {
- memcpy(data, map + offset, size);
+ memcpy(data, (const uint8_t *)map + offset, size);
pipe_buffer_unmap(screen, buf);
}
}
+static INLINE void *
+pipe_transfer_map( struct pipe_transfer *transf )
+{
+ struct pipe_screen *screen = transf->texture->screen;
+ return screen->transfer_map(screen, transf);
+}
+
+static INLINE void
+pipe_transfer_unmap( struct pipe_transfer *transf )
+{
+ struct pipe_screen *screen = transf->texture->screen;
+ screen->transfer_unmap(screen, transf);
+}
+
+static INLINE void
+pipe_transfer_destroy( struct pipe_transfer *transf )
+{
+ struct pipe_screen *screen = transf->texture->screen;
+ screen->tex_transfer_destroy(transf);
+}
#ifdef __cplusplus
}
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 626bedb35a8..b59d6b7ae32 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -114,11 +114,29 @@ struct pipe_rasterizer_state
* the vertex shader, clipping and viewport processing. Note that
* a vertex shader is still needed though, to indicate the mapping
* from vertex elements to fragment shader input semantics.
+ *
+ * XXX: considered for removal.
*/
unsigned bypass_vs_clip_and_viewport:1;
- unsigned flatshade_first:1; /**< take color attribute from the first vertex of a primitive */
- unsigned gl_rasterization_rules:1; /**< enable tweaks for GL rasterization? */
+ /**
+ * Use the first vertex of a primitive as the provoking vertex for
+ * flat shading.
+ */
+ unsigned flatshade_first:1;
+
+ /**
+ * When true, triangle rasterization uses (0.5, 0.5) pixel centers
+ * for determining pixel ownership.
+ *
+ * When false, triangle rasterization uses (0,0) pixel centers for
+ * determining pixel ownership.
+ *
+ * Triangle rasterization always uses a 'top,left' rule for pixel
+ * ownership, this just alters which point we consider the pixel
+ * center for that test.
+ */
+ unsigned gl_rasterization_rules:1;
float line_width;
float point_size; /**< used when no per-vertex size */
@@ -307,7 +325,7 @@ struct pipe_transfer
unsigned nblocksx; /**< allocated width in blocks */
unsigned nblocksy; /**< allocated height in blocks */
unsigned stride; /**< stride in bytes between rows of blocks */
- unsigned usage; /**< PIPE_TRANSFER_* */
+ enum pipe_transfer_usage usage; /**< PIPE_TRANSFER_* */
struct pipe_texture *texture; /**< texture to transfer to/from */
unsigned face;
diff --git a/src/gallium/include/pipe/p_thread.h b/src/gallium/include/pipe/p_thread.h
index b1606dc6526..25e41482325 100644
--- a/src/gallium/include/pipe/p_thread.h
+++ b/src/gallium/include/pipe/p_thread.h
@@ -39,7 +39,7 @@
#include "util/u_debug.h" /* for assert */
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
#include <pthread.h> /* POSIX threads headers */
#include <stdio.h> /* for perror() */
@@ -213,7 +213,7 @@ typedef unsigned pipe_condvar;
*/
typedef struct {
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
pthread_key_t key;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
DWORD key;
@@ -228,7 +228,7 @@ typedef struct {
static INLINE void
pipe_tsd_init(pipe_tsd *tsd)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
if (pthread_key_create(&tsd->key, NULL/*free*/) != 0) {
perror("pthread_key_create(): failed to allocate key for thread specific data");
exit(-1);
@@ -245,7 +245,7 @@ pipe_tsd_get(pipe_tsd *tsd)
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
pipe_tsd_init(tsd);
}
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
return pthread_getspecific(tsd->key);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
assert(0);
@@ -262,7 +262,7 @@ pipe_tsd_set(pipe_tsd *tsd, void *value)
if (tsd->initMagic != (int) PIPE_TSD_INIT_MAGIC) {
pipe_tsd_init(tsd);
}
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
if (pthread_setspecific(tsd->key, value) != 0) {
perror("pthread_set_specific() failed");
exit(-1);
diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
index 20d682de3fb..b1683b891be 100644
--- a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
+++ b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
@@ -51,6 +51,7 @@ static int vlResizeFrameBuffer
struct vlBasicCSC *basic_csc;
struct pipe_context *pipe;
struct pipe_texture template;
+ float clear_color[4];
assert(csc);
@@ -68,7 +69,12 @@ static int vlResizeFrameBuffer
basic_csc->viewport.translate[1] = 0;
basic_csc->viewport.translate[2] = 0;
basic_csc->viewport.translate[3] = 0;
-
+
+ clear_color[0] = 0.0f;
+ clear_color[1] = 0.0f;
+ clear_color[2] = 0.0f;
+ clear_color[3] = 0.0f;
+
if (basic_csc->framebuffer_tex)
{
pipe_surface_reference(&basic_csc->framebuffer.cbufs[0], NULL);
@@ -98,7 +104,7 @@ static int vlResizeFrameBuffer
/* Clear to black, in case video doesn't fill the entire window */
pipe->set_framebuffer_state(pipe, &basic_csc->framebuffer);
- pipe->clear(pipe, PIPE_CLEAR_COLOR, 0, 0.0f, 0);
+ pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0.0f, 0);
return 0;
}
@@ -425,7 +431,7 @@ static int vlCreateVertexShader
*/
for (i = 0; i < 2; ++i)
{
- inst = vl_inst4(TGSI_OPCODE_MADD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1);
+ inst = vl_inst4(TGSI_OPCODE_MAD, TGSI_FILE_OUTPUT, i, TGSI_FILE_INPUT, i, TGSI_FILE_CONSTANT, i * 2, TGSI_FILE_CONSTANT, i * 2 + 1);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
}
diff --git a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf_shaders.inc b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf_shaders.inc
index ef4a4b2add9..34d93e1df0a 100644
--- a/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf_shaders.inc
+++ b/src/gallium/state_trackers/g3dvl/vl_r16snorm_mc_buf_shaders.inc
@@ -615,7 +615,7 @@ static int vlCreateFragmentShaderFieldPMB
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* floor t3, t3 ; Get rid of fractional part */
- inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
+ inst = vl_inst2(TGSI_OPCODE_FLR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* mul t3, t3, c1.y ; Multiply by 2 */
@@ -632,7 +632,7 @@ static int vlCreateFragmentShaderFieldPMB
/* TODO: Move to conditional tex fetch on t3 instead of lerp */
/* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
+ inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* add o0, t0, t1 ; Add ref and differential to form final output */
@@ -969,7 +969,7 @@ static int vlCreateFragmentShaderFrameBMB
}
/* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
+ inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
@@ -1116,7 +1116,7 @@ static int vlCreateFragmentShaderFieldBMB
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* floor t3, t3 ; Get rid of fractional part */
- inst = vl_inst2(TGSI_OPCODE_FLOOR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
+ inst = vl_inst2(TGSI_OPCODE_FLR, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 3);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* mul t3, t3, c1.y ; Multiply by 2 */
@@ -1143,7 +1143,7 @@ static int vlCreateFragmentShaderFieldBMB
/* TODO: Move to conditional tex fetch on t3 instead of lerp */
/* lerp t1, t3, t1, t2 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
+ inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/*
@@ -1158,11 +1158,11 @@ static int vlCreateFragmentShaderFieldBMB
/* TODO: Move to conditional tex fetch on t3 instead of lerp */
/* lerp t2, t3, t4, t5 ; Choose between top and bottom fields based on Y % 2 */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5);
+ inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 2, TGSI_FILE_TEMPORARY, 3, TGSI_FILE_TEMPORARY, 4, TGSI_FILE_TEMPORARY, 5);
ti += tgsi_build_full_instruction(&inst, &tokens[ti], header, max_tokens - ti);
/* lerp t1, c1.x, t1, t2 ; Blend past and future texels */
- inst = vl_inst4(TGSI_OPCODE_LERP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
+ inst = vl_inst4(TGSI_OPCODE_LRP, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_CONSTANT, 1, TGSI_FILE_TEMPORARY, 1, TGSI_FILE_TEMPORARY, 2);
inst.FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
inst.FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_X;
inst.FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_X;
diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index 69b88618ecb..b05944a33b3 100644
--- a/src/gallium/state_trackers/wgl/SConscript
+++ b/src/gallium/state_trackers/wgl/SConscript
@@ -18,20 +18,17 @@ if env['platform'] in ['windows']:
])
sources = [
- 'icd/stw_icd.c',
-
- 'wgl/stw_wgl.c',
-
- 'shared/stw_context.c',
- 'shared/stw_device.c',
- 'shared/stw_framebuffer.c',
- 'shared/stw_pixelformat.c',
- 'shared/stw_extensionsstring.c',
- 'shared/stw_extswapinterval.c',
- 'shared/stw_getprocaddress.c',
- 'shared/stw_extgallium.c',
- 'shared/stw_arbpixelformat.c',
- 'shared/stw_tls.c',
+ 'stw_context.c',
+ 'stw_device.c',
+ 'stw_ext_extensionsstring.c',
+ 'stw_ext_gallium.c',
+ 'stw_ext_pixelformat.c',
+ 'stw_ext_swapinterval.c',
+ 'stw_framebuffer.c',
+ 'stw_getprocaddress.c',
+ 'stw_pixelformat.c',
+ 'stw_tls.c',
+ 'stw_wgl.c',
]
wgl = env.ConvenienceLibrary(
diff --git a/src/gallium/state_trackers/wgl/opengl32.def b/src/gallium/state_trackers/wgl/opengl32.def
index 596417ed844..5daa6ddd413 100644
--- a/src/gallium/state_trackers/wgl/opengl32.def
+++ b/src/gallium/state_trackers/wgl/opengl32.def
@@ -376,6 +376,7 @@ EXPORTS
DrvDescribePixelFormat
DrvGetLayerPaletteEntries
DrvGetProcAddress
+ DrvPresentBuffers
DrvRealizeLayerPalette
DrvReleaseContext
DrvSetCallbackProcs
diff --git a/src/gallium/state_trackers/wgl/opengl32.mingw.def b/src/gallium/state_trackers/wgl/opengl32.mingw.def
index 1f03ea3b375..6ebb31a6f1b 100644
--- a/src/gallium/state_trackers/wgl/opengl32.mingw.def
+++ b/src/gallium/state_trackers/wgl/opengl32.mingw.def
@@ -375,6 +375,7 @@ EXPORTS
DrvDescribePixelFormat = DrvDescribePixelFormat@16
DrvGetLayerPaletteEntries = DrvGetLayerPaletteEntries@20
DrvGetProcAddress = DrvGetProcAddress@4
+ DrvPresentBuffers = DrvPresentBuffers@8
DrvRealizeLayerPalette = DrvRealizeLayerPalette@12
DrvReleaseContext = DrvReleaseContext@4
DrvSetCallbackProcs = DrvSetCallbackProcs@8
diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c
deleted file mode 100644
index 4968ecc692d..00000000000
--- a/src/gallium/state_trackers/wgl/shared/stw_context.c
+++ /dev/null
@@ -1,382 +0,0 @@
-/**************************************************************************
- *
- * Copyright 2008 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 <windows.h>
-
-#include "main/mtypes.h"
-#include "main/context.h"
-#include "pipe/p_compiler.h"
-#include "pipe/p_context.h"
-#include "state_tracker/st_context.h"
-#include "state_tracker/st_public.h"
-
-#ifdef DEBUG
-#include "trace/tr_screen.h"
-#include "trace/tr_context.h"
-#endif
-
-#include "shared/stw_device.h"
-#include "shared/stw_winsys.h"
-#include "shared/stw_framebuffer.h"
-#include "shared/stw_pixelformat.h"
-#include "stw_public.h"
-#include "stw_context.h"
-#include "stw_tls.h"
-
-
-static INLINE struct stw_context *
-stw_context(GLcontext *glctx)
-{
- if(!glctx)
- return NULL;
- assert(glctx->DriverCtx);
- return (struct stw_context *)glctx->DriverCtx;
-}
-
-static INLINE struct stw_context *
-stw_current_context(void)
-{
- /* We must check if multiple threads are being used or GET_CURRENT_CONTEXT
- * might return the current context of the thread first seen. */
- _glapi_check_multithread();
-
- {
- GET_CURRENT_CONTEXT( glctx );
- return stw_context(glctx);
- }
-}
-
-BOOL
-stw_copy_context(
- UINT_PTR hglrcSrc,
- UINT_PTR hglrcDst,
- UINT mask )
-{
- struct stw_context *src;
- struct stw_context *dst;
- BOOL ret = FALSE;
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
-
- src = stw_lookup_context_locked( hglrcSrc );
- dst = stw_lookup_context_locked( hglrcDst );
-
- if (src && dst) {
- /* FIXME */
- assert(0);
- (void) src;
- (void) dst;
- (void) mask;
- }
-
- pipe_mutex_unlock( stw_dev->ctx_mutex );
-
- return ret;
-}
-
-BOOL
-stw_share_lists(
- UINT_PTR hglrc1,
- UINT_PTR hglrc2 )
-{
- struct stw_context *ctx1;
- struct stw_context *ctx2;
- BOOL ret = FALSE;
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
-
- ctx1 = stw_lookup_context_locked( hglrc1 );
- ctx2 = stw_lookup_context_locked( hglrc2 );
-
- if (ctx1 && ctx2 &&
- ctx1->iPixelFormat == ctx2->iPixelFormat) {
- ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
- }
-
- pipe_mutex_unlock( stw_dev->ctx_mutex );
-
- return ret;
-}
-
-static void
-stw_viewport(GLcontext * glctx, GLint x, GLint y,
- GLsizei width, GLsizei height)
-{
- struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx;
- struct stw_framebuffer *fb;
-
- fb = stw_framebuffer_from_hdc( ctx->hdc );
- if(fb) {
- stw_framebuffer_update(fb);
- stw_framebuffer_release(fb);
- }
-}
-
-UINT_PTR
-stw_create_layer_context(
- HDC hdc,
- int iLayerPlane )
-{
- int iPixelFormat;
- const struct stw_pixelformat_info *pfi;
- GLvisual visual;
- struct stw_context *ctx = NULL;
- struct pipe_screen *screen = NULL;
- struct pipe_context *pipe = NULL;
-
- if(!stw_dev)
- return 0;
-
- if (iLayerPlane != 0)
- return 0;
-
- iPixelFormat = GetPixelFormat(hdc);
- if(!iPixelFormat)
- return 0;
-
- pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
- stw_pixelformat_visual(&visual, pfi);
-
- ctx = CALLOC_STRUCT( stw_context );
- if (ctx == NULL)
- goto no_ctx;
-
- ctx->hdc = hdc;
- ctx->iPixelFormat = iPixelFormat;
-
- screen = stw_dev->screen;
-
-#ifdef DEBUG
- /* Unwrap screen */
- if(stw_dev->trace_running)
- screen = trace_screen(screen)->screen;
-#endif
-
- pipe = stw_dev->stw_winsys->create_context( screen );
- if (pipe == NULL)
- goto no_pipe;
-
-#ifdef DEBUG
- /* Wrap context */
- if(stw_dev->trace_running)
- pipe = trace_context_create(stw_dev->screen, pipe);
-#endif
-
- /* pass to stw_flush_frontbuffer as context_private */
- assert(!pipe->priv);
- pipe->priv = hdc;
-
- ctx->st = st_create_context( pipe, &visual, NULL );
- if (ctx->st == NULL)
- goto no_st_ctx;
-
- ctx->st->ctx->DriverCtx = ctx;
- ctx->st->ctx->Driver.Viewport = stw_viewport;
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
- ctx->hglrc = handle_table_add(stw_dev->ctx_table, ctx);
- pipe_mutex_unlock( stw_dev->ctx_mutex );
- if (!ctx->hglrc)
- goto no_hglrc;
-
- return ctx->hglrc;
-
-no_hglrc:
- st_destroy_context(ctx->st);
- goto no_pipe; /* st_context_destroy already destroys pipe */
-no_st_ctx:
- pipe->destroy( pipe );
-no_pipe:
- FREE(ctx);
-no_ctx:
- return 0;
-}
-
-BOOL
-stw_delete_context(
- UINT_PTR hglrc )
-{
- struct stw_context *ctx ;
- BOOL ret = FALSE;
-
- if (!stw_dev)
- return FALSE;
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
- ctx = stw_lookup_context_locked(hglrc);
- handle_table_remove(stw_dev->ctx_table, hglrc);
- pipe_mutex_unlock( stw_dev->ctx_mutex );
-
- if (ctx) {
- struct stw_context *curctx = stw_current_context();
-
- /* Unbind current if deleting current context. */
- if (curctx == ctx)
- st_make_current( NULL, NULL, NULL );
-
- st_destroy_context(ctx->st);
- FREE(ctx);
-
- ret = TRUE;
- }
-
- return ret;
-}
-
-BOOL
-stw_release_context(
- UINT_PTR hglrc )
-{
- struct stw_context *ctx;
-
- if (!stw_dev)
- return FALSE;
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
- ctx = stw_lookup_context_locked( hglrc );
- pipe_mutex_unlock( stw_dev->ctx_mutex );
-
- if (!ctx)
- return FALSE;
-
- /* The expectation is that ctx is the same context which is
- * current for this thread. We should check that and return False
- * if not the case.
- */
- if (ctx != stw_current_context())
- return FALSE;
-
- if (stw_make_current( NULL, 0 ) == FALSE)
- return FALSE;
-
- return TRUE;
-}
-
-
-UINT_PTR
-stw_get_current_context( void )
-{
- struct stw_context *ctx;
-
- ctx = stw_current_context();
- if(!ctx)
- return 0;
-
- return ctx->hglrc;
-}
-
-HDC
-stw_get_current_dc( void )
-{
- struct stw_context *ctx;
-
- ctx = stw_current_context();
- if(!ctx)
- return NULL;
-
- return ctx->hdc;
-}
-
-BOOL
-stw_make_current(
- HDC hdc,
- UINT_PTR hglrc )
-{
- struct stw_context *curctx = NULL;
- struct stw_context *ctx = NULL;
- struct stw_framebuffer *fb = NULL;
-
- if (!stw_dev)
- goto fail;
-
- curctx = stw_current_context();
- if (curctx != NULL) {
- if (curctx->hglrc != hglrc)
- st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
-
- /* Return if already current. */
- if (curctx->hglrc == hglrc && curctx->hdc == hdc) {
- ctx = curctx;
- fb = stw_framebuffer_from_hdc( hdc );
- goto success;
- }
- }
-
- if (hdc == NULL || hglrc == 0) {
- return st_make_current( NULL, NULL, NULL );
- }
-
- pipe_mutex_lock( stw_dev->ctx_mutex );
- ctx = stw_lookup_context_locked( hglrc );
- pipe_mutex_unlock( stw_dev->ctx_mutex );
- if(!ctx)
- goto fail;
-
- fb = stw_framebuffer_from_hdc( hdc );
- if(!fb) {
- /* Applications should call SetPixelFormat before creating a context,
- * but not all do, and the opengl32 runtime seems to use a default pixel
- * format in some cases, so we must create a framebuffer for those here
- */
- int iPixelFormat = GetPixelFormat(hdc);
- if(iPixelFormat)
- fb = stw_framebuffer_create( hdc, iPixelFormat );
- if(!fb)
- goto fail;
- }
-
- if(fb->iPixelFormat != ctx->iPixelFormat)
- goto fail;
-
- /* Lazy allocation of the frame buffer */
- if(!stw_framebuffer_allocate(fb))
- goto fail;
-
- /* Bind the new framebuffer */
- ctx->hdc = hdc;
-
- /* pass to stw_flush_frontbuffer as context_private */
- ctx->st->pipe->priv = hdc;
-
- if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
- goto fail;
-
-success:
- assert(fb);
- if(fb) {
- stw_framebuffer_update(fb);
- stw_framebuffer_release(fb);
- }
-
- return TRUE;
-
-fail:
- if(fb)
- stw_framebuffer_release(fb);
- st_make_current( NULL, NULL, NULL );
- return FALSE;
-}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_public.h b/src/gallium/state_trackers/wgl/shared/stw_public.h
deleted file mode 100644
index 7fe9cfb3561..00000000000
--- a/src/gallium/state_trackers/wgl/shared/stw_public.h
+++ /dev/null
@@ -1,73 +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 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 STW_PUBLIC_H
-#define STW_PUBLIC_H
-
-#include <windows.h>
-
-BOOL stw_copy_context( UINT_PTR hglrcSrc,
- UINT_PTR hglrcDst,
- UINT mask );
-
-UINT_PTR stw_create_layer_context( HDC hdc,
- int iLayerPlane );
-
-BOOL stw_share_lists( UINT_PTR hglrc1, UINT_PTR hglrc2 );
-
-BOOL stw_delete_context( UINT_PTR hglrc );
-
-BOOL
-stw_release_context( UINT_PTR dhglrc );
-
-UINT_PTR stw_get_current_context( void );
-
-HDC stw_get_current_dc( void );
-
-BOOL stw_make_current( HDC hdc, UINT_PTR hglrc );
-
-BOOL stw_swap_buffers( HDC hdc );
-
-BOOL
-stw_swap_layer_buffers( HDC hdc, UINT fuPlanes );
-
-PROC stw_get_proc_address( LPCSTR lpszProc );
-
-int stw_pixelformat_describe( HDC hdc,
- int iPixelFormat,
- UINT nBytes,
- LPPIXELFORMATDESCRIPTOR ppfd );
-
-int stw_pixelformat_get( HDC hdc );
-
-BOOL stw_pixelformat_set( HDC hdc,
- int iPixelFormat );
-
-int stw_pixelformat_choose( HDC hdc,
- CONST PIXELFORMATDESCRIPTOR *ppfd );
-
-#endif
diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.c b/src/gallium/state_trackers/wgl/stw_context.c
index 347f40aa06b..f2f0264844a 100644
--- a/src/gallium/state_trackers/wgl/icd/stw_icd.c
+++ b/src/gallium/state_trackers/wgl/stw_context.c
@@ -26,18 +26,49 @@
**************************************************************************/
#include <windows.h>
-#include <stdio.h>
-#include "GL/gl.h"
-
-#include "util/u_debug.h"
-#include "pipe/p_thread.h"
-
-#include "shared/stw_public.h"
-#include "icd/stw_icd.h"
+#include "main/mtypes.h"
+#include "main/context.h"
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+#include "state_tracker/st_context.h"
+#include "state_tracker/st_public.h"
+
+#ifdef DEBUG
+#include "trace/tr_screen.h"
+#include "trace/tr_context.h"
+#endif
+
+#include "stw_icd.h"
+#include "stw_device.h"
+#include "stw_winsys.h"
+#include "stw_framebuffer.h"
+#include "stw_pixelformat.h"
+#include "stw_context.h"
+#include "stw_tls.h"
+
+
+static INLINE struct stw_context *
+stw_context(GLcontext *glctx)
+{
+ if(!glctx)
+ return NULL;
+ assert(glctx->DriverCtx);
+ return (struct stw_context *)glctx->DriverCtx;
+}
-#define DBG 0
+static INLINE struct stw_context *
+stw_current_context(void)
+{
+ /* We must check if multiple threads are being used or GET_CURRENT_CONTEXT
+ * might return the current context of the thread first seen. */
+ _glapi_check_multithread();
+ {
+ GET_CURRENT_CONTEXT( glctx );
+ return stw_context(glctx);
+ }
+}
BOOL APIENTRY
DrvCopyContext(
@@ -45,24 +76,64 @@ DrvCopyContext(
DHGLRC dhrcDest,
UINT fuMask )
{
- return stw_copy_context(dhrcSource, dhrcDest, fuMask);
-}
+ struct stw_context *src;
+ struct stw_context *dst;
+ BOOL ret = FALSE;
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+
+ src = stw_lookup_context_locked( dhrcSource );
+ dst = stw_lookup_context_locked( dhrcDest );
+
+ if (src && dst) {
+ /* FIXME */
+ assert(0);
+ (void) src;
+ (void) dst;
+ (void) fuMask;
+ }
-DHGLRC APIENTRY
-DrvCreateLayerContext(
- HDC hdc,
- INT iLayerPlane )
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
+
+ return ret;
+}
+
+BOOL APIENTRY
+DrvShareLists(
+ DHGLRC dhglrc1,
+ DHGLRC dhglrc2 )
{
- DHGLRC r;
+ struct stw_context *ctx1;
+ struct stw_context *ctx2;
+ BOOL ret = FALSE;
+
+ pipe_mutex_lock( stw_dev->ctx_mutex );
- r = stw_create_layer_context( hdc, iLayerPlane );
+ ctx1 = stw_lookup_context_locked( dhglrc1 );
+ ctx2 = stw_lookup_context_locked( dhglrc2 );
+
+ if (ctx1 && ctx2 &&
+ ctx1->iPixelFormat == ctx2->iPixelFormat) {
+ ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx);
+ }
+
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
- if (DBG)
- debug_printf( "%s( %p, %i ) = %u\n",
- __FUNCTION__, hdc, iLayerPlane, r );
+ return ret;
+}
+
+static void
+stw_viewport(GLcontext * glctx, GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ struct stw_context *ctx = (struct stw_context *)glctx->DriverCtx;
+ struct stw_framebuffer *fb;
- return r;
+ fb = stw_framebuffer_from_hdc( ctx->hdc );
+ if(fb) {
+ stw_framebuffer_update(fb);
+ stw_framebuffer_release(fb);
+ }
}
DHGLRC APIENTRY
@@ -72,114 +143,253 @@ DrvCreateContext(
return DrvCreateLayerContext( hdc, 0 );
}
-BOOL APIENTRY
-DrvDeleteContext(
- DHGLRC dhglrc )
+DHGLRC APIENTRY
+DrvCreateLayerContext(
+ HDC hdc,
+ INT iLayerPlane )
{
- BOOL r;
+ int iPixelFormat;
+ const struct stw_pixelformat_info *pfi;
+ GLvisual visual;
+ struct stw_context *ctx = NULL;
+ struct pipe_screen *screen = NULL;
+ struct pipe_context *pipe = NULL;
- r = stw_delete_context( dhglrc );
+ if(!stw_dev)
+ return 0;
- if (DBG)
- debug_printf( "%s( %u ) = %u\n",
- __FUNCTION__, dhglrc, r );
+ if (iLayerPlane != 0)
+ return 0;
+
+ iPixelFormat = GetPixelFormat(hdc);
+ if(!iPixelFormat)
+ return 0;
- return r;
+ pfi = stw_pixelformat_get_info( iPixelFormat - 1 );
+ stw_pixelformat_visual(&visual, pfi);
+
+ ctx = CALLOC_STRUCT( stw_context );
+ if (ctx == NULL)
+ goto no_ctx;
+
+ ctx->hdc = hdc;
+ ctx->iPixelFormat = iPixelFormat;
+
+ screen = stw_dev->screen;
+
+#ifdef DEBUG
+ /* Unwrap screen */
+ if(stw_dev->trace_running)
+ screen = trace_screen(screen)->screen;
+#endif
+
+ pipe = stw_dev->stw_winsys->create_context( screen );
+ if (pipe == NULL)
+ goto no_pipe;
+
+#ifdef DEBUG
+ /* Wrap context */
+ if(stw_dev->trace_running)
+ pipe = trace_context_create(stw_dev->screen, pipe);
+#endif
+
+ /* pass to stw_flush_frontbuffer as context_private */
+ assert(!pipe->priv);
+ pipe->priv = hdc;
+
+ ctx->st = st_create_context( pipe, &visual, NULL );
+ if (ctx->st == NULL)
+ goto no_st_ctx;
+
+ ctx->st->ctx->DriverCtx = ctx;
+ ctx->st->ctx->Driver.Viewport = stw_viewport;
+
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+ ctx->dhglrc = handle_table_add(stw_dev->ctx_table, ctx);
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
+ if (!ctx->dhglrc)
+ goto no_hglrc;
+
+ return ctx->dhglrc;
+
+no_hglrc:
+ st_destroy_context(ctx->st);
+ goto no_pipe; /* st_context_destroy already destroys pipe */
+no_st_ctx:
+ pipe->destroy( pipe );
+no_pipe:
+ FREE(ctx);
+no_ctx:
+ return 0;
}
BOOL APIENTRY
-DrvDescribeLayerPlane(
- HDC hdc,
- INT iPixelFormat,
- INT iLayerPlane,
- UINT nBytes,
- LPLAYERPLANEDESCRIPTOR plpd )
+DrvDeleteContext(
+ DHGLRC dhglrc )
{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
+ struct stw_context *ctx ;
+ BOOL ret = FALSE;
+
+ if (!stw_dev)
+ return FALSE;
- return FALSE;
-}
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+ ctx = stw_lookup_context_locked(dhglrc);
+ handle_table_remove(stw_dev->ctx_table, dhglrc);
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
-LONG APIENTRY
-DrvDescribePixelFormat(
- HDC hdc,
- INT iPixelFormat,
- ULONG cjpfd,
- PIXELFORMATDESCRIPTOR *ppfd )
-{
- LONG r;
+ if (ctx) {
+ struct stw_context *curctx = stw_current_context();
+
+ /* Unbind current if deleting current context. */
+ if (curctx == ctx)
+ st_make_current( NULL, NULL, NULL );
- r = stw_pixelformat_describe( hdc, iPixelFormat, cjpfd, ppfd );
+ st_destroy_context(ctx->st);
+ FREE(ctx);
- if (DBG)
- debug_printf( "%s( %p, %d, %u, %p ) = %d\n",
- __FUNCTION__, hdc, iPixelFormat, cjpfd, ppfd, r );
+ ret = TRUE;
+ }
- return r;
+ return ret;
}
-int APIENTRY
-DrvGetLayerPaletteEntries(
- HDC hdc,
- INT iLayerPlane,
- INT iStart,
- INT cEntries,
- COLORREF *pcr )
+BOOL APIENTRY
+DrvReleaseContext(
+ DHGLRC dhglrc )
{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
+ struct stw_context *ctx;
- return 0;
-}
+ if (!stw_dev)
+ return FALSE;
-PROC APIENTRY
-DrvGetProcAddress(
- LPCSTR lpszProc )
-{
- PROC r;
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+ ctx = stw_lookup_context_locked( dhglrc );
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
- r = stw_get_proc_address( lpszProc );
+ if (!ctx)
+ return FALSE;
+
+ /* The expectation is that ctx is the same context which is
+ * current for this thread. We should check that and return False
+ * if not the case.
+ */
+ if (ctx != stw_current_context())
+ return FALSE;
- if (DBG)
- debug_printf( "%s( \"%s\" ) = %p\n", __FUNCTION__, lpszProc, r );
+ if (stw_make_current( NULL, 0 ) == FALSE)
+ return FALSE;
- return r;
+ return TRUE;
}
-BOOL APIENTRY
-DrvRealizeLayerPalette(
- HDC hdc,
- INT iLayerPlane,
- BOOL bRealize )
+
+DHGLRC
+stw_get_current_context( void )
{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
+ struct stw_context *ctx;
- return FALSE;
+ ctx = stw_current_context();
+ if(!ctx)
+ return 0;
+
+ return ctx->dhglrc;
}
-BOOL APIENTRY
-DrvReleaseContext(
- DHGLRC dhglrc )
+HDC
+stw_get_current_dc( void )
{
- return stw_release_context(dhglrc);
+ struct stw_context *ctx;
+
+ ctx = stw_current_context();
+ if(!ctx)
+ return NULL;
+
+ return ctx->hdc;
}
-void APIENTRY
-DrvSetCallbackProcs(
- INT nProcs,
- PROC *pProcs )
+BOOL
+stw_make_current(
+ HDC hdc,
+ DHGLRC dhglrc )
{
- if (DBG)
- debug_printf( "%s( %d, %p )\n", __FUNCTION__, nProcs, pProcs );
+ struct stw_context *curctx = NULL;
+ struct stw_context *ctx = NULL;
+ struct stw_framebuffer *fb = NULL;
- return;
-}
+ if (!stw_dev)
+ goto fail;
+
+ curctx = stw_current_context();
+ if (curctx != NULL) {
+ if (curctx->dhglrc != dhglrc)
+ st_flush(curctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ /* Return if already current. */
+ if (curctx->dhglrc == dhglrc && curctx->hdc == hdc) {
+ ctx = curctx;
+ fb = stw_framebuffer_from_hdc( hdc );
+ goto success;
+ }
+ }
+
+ if (hdc == NULL || dhglrc == 0) {
+ return st_make_current( NULL, NULL, NULL );
+ }
+
+ pipe_mutex_lock( stw_dev->ctx_mutex );
+ ctx = stw_lookup_context_locked( dhglrc );
+ pipe_mutex_unlock( stw_dev->ctx_mutex );
+ if(!ctx)
+ goto fail;
+
+ fb = stw_framebuffer_from_hdc( hdc );
+ if(!fb) {
+ /* Applications should call SetPixelFormat before creating a context,
+ * but not all do, and the opengl32 runtime seems to use a default pixel
+ * format in some cases, so we must create a framebuffer for those here
+ */
+ int iPixelFormat = GetPixelFormat(hdc);
+ if(iPixelFormat)
+ fb = stw_framebuffer_create( hdc, iPixelFormat );
+ if(!fb)
+ goto fail;
+ }
+
+ if(fb->iPixelFormat != ctx->iPixelFormat)
+ goto fail;
+
+ /* Lazy allocation of the frame buffer */
+ if(!stw_framebuffer_allocate(fb))
+ goto fail;
+
+ /* Bind the new framebuffer */
+ ctx->hdc = hdc;
+
+ /* pass to stw_flush_frontbuffer as context_private */
+ ctx->st->pipe->priv = hdc;
+
+ if(!st_make_current( ctx->st, fb->stfb, fb->stfb ))
+ goto fail;
+
+success:
+ assert(fb);
+ if(fb) {
+ stw_framebuffer_update(fb);
+ stw_framebuffer_release(fb);
+ }
+
+ return TRUE;
+fail:
+ if(fb)
+ stw_framebuffer_release(fb);
+ st_make_current( NULL, NULL, NULL );
+ return FALSE;
+}
/**
- * Although WGL allows different dispatch entrypoints per context
+ * Although WGL allows different dispatch entrypoints per context
*/
static const GLCLTPROCTABLE cpt =
{
@@ -524,7 +734,6 @@ static const GLCLTPROCTABLE cpt =
}
};
-
PGLCLTPROCTABLE APIENTRY
DrvSetContext(
HDC hdc,
@@ -532,86 +741,9 @@ DrvSetContext(
PFN_SETPROCTABLE pfnSetProcTable )
{
PGLCLTPROCTABLE r = (PGLCLTPROCTABLE)&cpt;
-
+
if (!stw_make_current( hdc, dhglrc ))
r = NULL;
-
- if (DBG)
- debug_printf( "%s( 0x%p, %u, 0x%p ) = %p\n",
- __FUNCTION__, hdc, dhglrc, pfnSetProcTable, r );
-
- return r;
-}
-
-int APIENTRY
-DrvSetLayerPaletteEntries(
- HDC hdc,
- INT iLayerPlane,
- INT iStart,
- INT cEntries,
- CONST COLORREF *pcr )
-{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
-
- return 0;
-}
-
-BOOL APIENTRY
-DrvSetPixelFormat(
- HDC hdc,
- LONG iPixelFormat )
-{
- BOOL r;
-
- r = stw_pixelformat_set( hdc, iPixelFormat );
-
- if (DBG)
- debug_printf( "%s( %p, %d ) = %s\n", __FUNCTION__, hdc, iPixelFormat, r ? "TRUE" : "FALSE" );
return r;
}
-
-BOOL APIENTRY
-DrvShareLists(
- DHGLRC dhglrc1,
- DHGLRC dhglrc2 )
-{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
-
- return stw_share_lists(dhglrc1, dhglrc2);
-}
-
-BOOL APIENTRY
-DrvSwapBuffers(
- HDC hdc )
-{
- if (DBG)
- debug_printf( "%s( %p )\n", __FUNCTION__, hdc );
-
- return stw_swap_buffers( hdc );
-}
-
-BOOL APIENTRY
-DrvSwapLayerBuffers(
- HDC hdc,
- UINT fuPlanes )
-{
- if (DBG)
- debug_printf( "%s\n", __FUNCTION__ );
-
- return stw_swap_layer_buffers( hdc, fuPlanes );
-}
-
-BOOL APIENTRY
-DrvValidateVersion(
- ULONG ulVersion )
-{
- if (DBG)
- debug_printf( "%s( %u )\n", __FUNCTION__, ulVersion );
-
- /* TODO: get the expected version from the winsys */
-
- return ulVersion == 1;
-}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_context.h b/src/gallium/state_trackers/wgl/stw_context.h
index 166471de5eb..256c27e21ef 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_context.h
+++ b/src/gallium/state_trackers/wgl/stw_context.h
@@ -35,9 +35,15 @@ struct st_context;
struct stw_context
{
struct st_context *st;
- UINT_PTR hglrc;
+ DHGLRC dhglrc;
int iPixelFormat;
HDC hdc;
};
+DHGLRC stw_get_current_context( void );
+
+HDC stw_get_current_dc( void );
+
+BOOL stw_make_current( HDC hdc, DHGLRC dhglrc );
+
#endif /* STW_CONTEXT_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c
index 0b6954915a6..985b8f0456a 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -29,6 +29,7 @@
#include "glapi/glthread.h"
#include "util/u_debug.h"
+#include "util/u_math.h"
#include "pipe/p_screen.h"
#include "state_tracker/st_public.h"
@@ -37,12 +38,12 @@
#include "trace/tr_texture.h"
#endif
-#include "shared/stw_device.h"
-#include "shared/stw_winsys.h"
-#include "shared/stw_pixelformat.h"
-#include "shared/stw_public.h"
-#include "shared/stw_tls.h"
-#include "shared/stw_framebuffer.h"
+#include "stw_device.h"
+#include "stw_winsys.h"
+#include "stw_pixelformat.h"
+#include "stw_icd.h"
+#include "stw_tls.h"
+#include "stw_framebuffer.h"
#ifdef WIN32_THREADS
extern _glthread_Mutex OneTimeLock;
@@ -62,38 +63,28 @@ stw_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surface,
void *context_private )
{
- const struct stw_winsys *stw_winsys = stw_dev->stw_winsys;
HDC hdc = (HDC)context_private;
struct stw_framebuffer *fb;
fb = stw_framebuffer_from_hdc( hdc );
- /* fb can be NULL if window was destroyed already */
- if (fb) {
+ if (!fb) {
+ /* fb can be NULL if window was destroyed already */
+ return;
+ }
+
#if DEBUG
- {
- struct pipe_surface *surface2;
-
- if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 ))
- assert(0);
- else
- assert(surface2 == surface);
- }
-#endif
+ {
+ /* ensure that a random surface was not passed to us */
+ struct pipe_surface *surface2;
-#ifdef DEBUG
- if(stw_dev->trace_running) {
- screen = trace_screen(screen)->screen;
- surface = trace_surface(surface)->surface;
- }
-#endif
- }
-
- stw_winsys->flush_frontbuffer(screen, surface, hdc);
-
- if(fb) {
- stw_framebuffer_update(fb);
- stw_framebuffer_release(fb);
+ if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_FRONT_LEFT, &surface2 ))
+ assert(0);
+ else
+ assert(surface2 == surface);
}
+#endif
+
+ stw_framebuffer_present_locked(hdc, fb, ST_SURFACE_FRONT_LEFT);
}
@@ -126,6 +117,9 @@ stw_init(const struct stw_winsys *stw_winsys)
if(!screen)
goto error1;
+ if(stw_winsys->get_adapter_luid)
+ stw_winsys->get_adapter_luid(screen, &stw_dev->AdapterLuid);
+
#ifdef DEBUG
stw_dev->screen = trace_screen_create(screen);
stw_dev->trace_running = stw_dev->screen != screen ? TRUE : FALSE;
@@ -182,7 +176,7 @@ stw_cleanup(void)
/* Ensure all contexts are destroyed */
i = handle_table_get_first_handle(stw_dev->ctx_table);
while (i) {
- stw_delete_context(i);
+ DrvDeleteContext(i);
i = handle_table_get_next_handle(stw_dev->ctx_table, i);
}
handle_table_destroy(stw_dev->ctx_table);
@@ -212,7 +206,7 @@ stw_cleanup(void)
struct stw_context *
-stw_lookup_context_locked( UINT_PTR dhglrc )
+stw_lookup_context_locked( DHGLRC dhglrc )
{
if (dhglrc == 0)
return NULL;
@@ -223,3 +217,28 @@ stw_lookup_context_locked( UINT_PTR dhglrc )
return (struct stw_context *) handle_table_get(stw_dev->ctx_table, dhglrc);
}
+
+void APIENTRY
+DrvSetCallbackProcs(
+ INT nProcs,
+ PROC *pProcs )
+{
+ size_t size;
+
+ if (stw_dev == NULL)
+ return;
+
+ size = MIN2(nProcs * sizeof *pProcs, sizeof stw_dev->callbacks);
+ memcpy(&stw_dev->callbacks, pProcs, size);
+
+ return;
+}
+
+
+BOOL APIENTRY
+DrvValidateVersion(
+ ULONG ulVersion )
+{
+ /* TODO: get the expected version from the winsys */
+ return ulVersion == 1;
+}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_device.h b/src/gallium/state_trackers/wgl/stw_device.h
index e1bb9518dd1..0bf3b0da825 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.h
+++ b/src/gallium/state_trackers/wgl/stw_device.h
@@ -29,11 +29,10 @@
#define STW_DEVICE_H_
-#include <windows.h>
-
#include "pipe/p_compiler.h"
#include "pipe/p_thread.h"
#include "util/u_handle_table.h"
+#include "stw_icd.h"
#include "stw_pixelformat.h"
@@ -53,10 +52,14 @@ struct stw_device
boolean trace_running;
#endif
+ LUID AdapterLuid;
+
struct stw_pixelformat_info pixelformats[STW_MAX_PIXELFORMATS];
unsigned pixelformat_count;
unsigned pixelformat_extended_count;
+ GLCALLBACKTABLE callbacks;
+
pipe_mutex ctx_mutex;
struct handle_table *ctx_table;
@@ -69,7 +72,7 @@ struct stw_device
};
struct stw_context *
-stw_lookup_context_locked( UINT_PTR hglrc );
+stw_lookup_context_locked( DHGLRC hglrc );
extern struct stw_device *stw_dev;
diff --git a/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
index 62c859e1f92..62c859e1f92 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_extensionsstring.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_extensionsstring.c
diff --git a/src/gallium/state_trackers/wgl/shared/stw_extgallium.c b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
index fc22737d7e3..fb30ec5dba9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_extgallium.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.c
@@ -27,9 +27,9 @@
#include "pipe/p_screen.h"
-#include "stw_public.h"
#include "stw_device.h"
#include "stw_winsys.h"
+#include "stw_ext_gallium.h"
#ifdef DEBUG
#include "trace/tr_screen.h"
diff --git a/src/gallium/state_trackers/wgl/shared/stw_extgallium.h b/src/gallium/state_trackers/wgl/stw_ext_gallium.h
index cc35f2bb7fe..cc35f2bb7fe 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_extgallium.h
+++ b/src/gallium/state_trackers/wgl/stw_ext_gallium.h
diff --git a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
index 0e2d4076993..8a9995aba8e 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_arbpixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_pixelformat.c
@@ -43,7 +43,6 @@
#include "pipe/p_compiler.h"
#include "util/u_memory.h"
-#include "stw_public.h"
#include "stw_pixelformat.h"
diff --git a/src/gallium/state_trackers/wgl/shared/stw_extswapinterval.c b/src/gallium/state_trackers/wgl/stw_ext_swapinterval.c
index 9eac6a1d09d..9eac6a1d09d 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_extswapinterval.c
+++ b/src/gallium/state_trackers/wgl/stw_ext_swapinterval.c
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c
index b8956bb5509..8a3e11b6b40 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -1,8 +1,8 @@
/**************************************************************************
- *
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ *
+ * Copyright 2008-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
@@ -10,19 +10,19 @@
* 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
+ * 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 <windows.h>
@@ -38,9 +38,9 @@
#include "trace/tr_texture.h"
#endif
+#include "stw_icd.h"
#include "stw_framebuffer.h"
#include "stw_device.h"
-#include "stw_public.h"
#include "stw_winsys.h"
#include "stw_tls.h"
@@ -83,6 +83,9 @@ stw_framebuffer_destroy_locked(
*link = fb->next;
fb->next = NULL;
+ if(fb->shared_surface)
+ stw_dev->stw_winsys->shared_surface_close(stw_dev->screen, fb->shared_surface);
+
st_unreference_framebuffer(fb->stfb);
pipe_mutex_unlock( fb->mutex );
@@ -106,13 +109,18 @@ static INLINE void
stw_framebuffer_get_size( struct stw_framebuffer *fb )
{
unsigned width, height;
- RECT rect;
+ RECT client_rect;
+ RECT window_rect;
+ POINT client_pos;
assert(fb->hWnd);
- GetClientRect( fb->hWnd, &rect );
- width = rect.right - rect.left;
- height = rect.bottom - rect.top;
+ /* Get the client area size. */
+ GetClientRect( fb->hWnd, &client_rect );
+ assert(client_rect.left == 0);
+ assert(client_rect.top == 0);
+ width = client_rect.right - client_rect.left;
+ height = client_rect.bottom - client_rect.top;
if(width < 1)
width = 1;
@@ -124,6 +132,31 @@ stw_framebuffer_get_size( struct stw_framebuffer *fb )
fb->width = width;
fb->height = height;
}
+
+ client_pos.x = 0;
+ client_pos.y = 0;
+ ClientToScreen(fb->hWnd, &client_pos);
+
+ GetWindowRect(fb->hWnd, &window_rect);
+
+ fb->client_rect.left = client_pos.x - window_rect.left;
+ fb->client_rect.top = client_pos.y - window_rect.top;
+ fb->client_rect.right = fb->client_rect.left + fb->width;
+ fb->client_rect.bottom = fb->client_rect.top + fb->height;
+
+#if 0
+ debug_printf("\n");
+ debug_printf("%s: client_position = (%i, %i)\n",
+ __FUNCTION__, client_pos.x, client_pos.y);
+ debug_printf("%s: window_rect = (%i, %i) - (%i, %i)\n",
+ __FUNCTION__,
+ window_rect.left, window_rect.top,
+ window_rect.right, window_rect.bottom);
+ debug_printf("%s: client_rect = (%i, %i) - (%i, %i)\n",
+ __FUNCTION__,
+ fb->client_rect.left, fb->client_rect.top,
+ fb->client_rect.right, fb->client_rect.bottom);
+#endif
}
@@ -155,6 +188,7 @@ stw_call_window_proc(
* can be masked out by the application. */
LPWINDOWPOS lpWindowPos = (LPWINDOWPOS)pParams->lParam;
if((lpWindowPos->flags & SWP_SHOWWINDOW) ||
+ !(lpWindowPos->flags & SWP_NOMOVE) ||
!(lpWindowPos->flags & SWP_NOSIZE)) {
fb = stw_framebuffer_from_hwnd( pParams->hwnd );
if(fb) {
@@ -379,10 +413,10 @@ stw_framebuffer_from_hwnd(
}
-BOOL
-stw_pixelformat_set(
+BOOL APIENTRY
+DrvSetPixelFormat(
HDC hdc,
- int iPixelFormat )
+ LONG iPixelFormat )
{
uint count;
uint index;
@@ -435,35 +469,24 @@ stw_pixelformat_get(
}
-BOOL
-stw_swap_buffers(
- HDC hdc )
+BOOL APIENTRY
+DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data)
{
struct stw_framebuffer *fb;
struct pipe_screen *screen;
struct pipe_surface *surface;
+ unsigned surface_index;
+ BOOL ret = FALSE;
fb = stw_framebuffer_from_hdc( hdc );
if (fb == NULL)
return FALSE;
- if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) {
- stw_framebuffer_release(fb);
- return TRUE;
- }
-
- /* If we're swapping the buffer associated with the current context
- * we have to flush any pending rendering commands first.
- */
- st_notify_swapbuffers( fb->stfb );
-
screen = stw_dev->screen;
-
- if(!st_get_framebuffer_surface( fb->stfb, ST_SURFACE_BACK_LEFT, &surface )) {
- /* FIXME: this shouldn't happen, but does on glean */
- stw_framebuffer_release(fb);
- return FALSE;
- }
+
+ surface_index = (unsigned)(uintptr_t)data->pPrivateData;
+ if(!st_get_framebuffer_surface( fb->stfb, surface_index, &surface ))
+ goto fail;
#ifdef DEBUG
if(stw_dev->trace_running) {
@@ -472,22 +495,127 @@ stw_swap_buffers(
}
#endif
- stw_dev->stw_winsys->flush_frontbuffer( screen, surface, hdc );
-
+ if(data->hSharedSurface != fb->hSharedSurface) {
+ if(fb->shared_surface) {
+ stw_dev->stw_winsys->shared_surface_close(screen, fb->shared_surface);
+ fb->shared_surface = NULL;
+ }
+
+ fb->hSharedSurface = data->hSharedSurface;
+
+ if(data->hSharedSurface &&
+ stw_dev->stw_winsys->shared_surface_open) {
+ fb->shared_surface = stw_dev->stw_winsys->shared_surface_open(screen, fb->hSharedSurface);
+ }
+ }
+
+ if(fb->shared_surface) {
+ stw_dev->stw_winsys->compose(screen,
+ surface,
+ fb->shared_surface,
+ &fb->client_rect,
+ data->PresentHistoryToken);
+ }
+ else {
+ stw_dev->stw_winsys->present( screen, surface, hdc );
+ }
+
+ ret = TRUE;
+
+fail:
+
stw_framebuffer_update(fb);
+
stw_framebuffer_release(fb);
-
- return TRUE;
+
+ return ret;
}
+/**
+ * Queue a composition.
+ *
+ * It will drop the lock on success.
+ */
BOOL
-stw_swap_layer_buffers(
+stw_framebuffer_present_locked(HDC hdc,
+ struct stw_framebuffer *fb,
+ unsigned surface_index)
+{
+ if(stw_dev->callbacks.wglCbPresentBuffers &&
+ stw_dev->stw_winsys->compose) {
+ GLCBPRESENTBUFFERSDATA data;
+
+ memset(&data, 0, sizeof data);
+ data.magic1 = 2;
+ data.magic2 = 0;
+ data.AdapterLuid = stw_dev->AdapterLuid;
+ data.rect = fb->client_rect;
+ data.pPrivateData = (void *)(uintptr_t)surface_index;
+
+ stw_framebuffer_release(fb);
+
+ return stw_dev->callbacks.wglCbPresentBuffers(hdc, &data);
+ }
+ else {
+ struct pipe_screen *screen = stw_dev->screen;
+ struct pipe_surface *surface;
+
+ if(!st_get_framebuffer_surface( fb->stfb, surface_index, &surface )) {
+ /* FIXME: this shouldn't happen, but does on glean */
+ stw_framebuffer_release(fb);
+ return FALSE;
+ }
+
+#ifdef DEBUG
+ if(stw_dev->trace_running) {
+ screen = trace_screen(screen)->screen;
+ surface = trace_surface(surface)->surface;
+ }
+#endif
+
+ stw_dev->stw_winsys->present( screen, surface, hdc );
+
+ stw_framebuffer_update(fb);
+
+ stw_framebuffer_release(fb);
+
+ return TRUE;
+ }
+}
+
+
+BOOL APIENTRY
+DrvSwapBuffers(
+ HDC hdc )
+{
+ struct stw_framebuffer *fb;
+
+ fb = stw_framebuffer_from_hdc( hdc );
+ if (fb == NULL)
+ return FALSE;
+
+ if (!(fb->pfi->pfd.dwFlags & PFD_DOUBLEBUFFER)) {
+ stw_framebuffer_release(fb);
+ return TRUE;
+ }
+
+ /* If we're swapping the buffer associated with the current context
+ * we have to flush any pending rendering commands first.
+ */
+ st_notify_swapbuffers( fb->stfb );
+
+ return stw_framebuffer_present_locked(hdc, fb, ST_SURFACE_BACK_LEFT);
+}
+
+
+BOOL APIENTRY
+DrvSwapLayerBuffers(
HDC hdc,
UINT fuPlanes )
{
if(fuPlanes & WGL_SWAP_MAIN_PLANE)
- return stw_swap_buffers(hdc);
+ return DrvSwapBuffers(hdc);
return FALSE;
}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h b/src/gallium/state_trackers/wgl/stw_framebuffer.h
index 13d29f37e48..5afbe749086 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
@@ -73,9 +73,20 @@ struct stw_framebuffer
/* FIXME: Make this work for multiple contexts bound to the same framebuffer */
boolean must_resize;
+
unsigned width;
unsigned height;
+ /**
+ * Client area rectangle, relative to the window upper-left corner.
+ *
+ * @sa GLCBPRESENTBUFFERSDATA::rect.
+ */
+ RECT client_rect;
+
+ HANDLE hSharedSurface;
+ struct stw_shared_surface *shared_surface;
+
/**
* This is protected by stw_device::fb_mutex, not the mutex above.
*
@@ -126,6 +137,11 @@ BOOL
stw_framebuffer_allocate(
struct stw_framebuffer *fb );
+BOOL
+stw_framebuffer_present_locked(HDC hdc,
+ struct stw_framebuffer *fb,
+ unsigned surface_index);
+
void
stw_framebuffer_update(
struct stw_framebuffer *fb);
diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 879ced925a5..8875dc22f3d 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c
+++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
@@ -33,8 +33,7 @@
#include <GL/wglext.h>
#include "glapi/glapi.h"
-#include "stw_public.h"
-#include "stw_extgallium.h"
+#include "stw_ext_gallium.h"
struct stw_extension_entry
{
@@ -68,8 +67,8 @@ static const struct stw_extension_entry stw_extension_entries[] = {
{ NULL, NULL }
};
-PROC
-stw_get_proc_address(
+PROC APIENTRY
+DrvGetProcAddress(
LPCSTR lpszProc )
{
const struct stw_extension_entry *entry;
diff --git a/src/gallium/state_trackers/wgl/icd/stw_icd.h b/src/gallium/state_trackers/wgl/stw_icd.h
index cbc1a665481..02eb543fef0 100644
--- a/src/gallium/state_trackers/wgl/icd/stw_icd.h
+++ b/src/gallium/state_trackers/wgl/stw_icd.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008-2009 Vmware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
* THE SOFTWARE IS PROVIDED "AS 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
+ * 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.
@@ -388,6 +388,113 @@ typedef struct _GLCLTPROCTABLE
typedef VOID (APIENTRY * PFN_SETPROCTABLE)(PGLCLTPROCTABLE);
+/**
+ * Presentation data passed to opengl32!wglCbPresentBuffers.
+ *
+ * Pure software drivers don't need to worry about this -- if they stick to the
+ * GDI API then will integrate with the Desktop Window Manager (DWM) without
+ * problems. Hardware drivers, however, cannot present directly to the primary
+ * surface while the DWM is active, as DWM gets exclusive access to the primary
+ * surface.
+ *
+ * Proper DWM integration requires:
+ * - advertise the PFD_SUPPORT_COMPOSITION flag
+ * - redirect glFlush/glfinish/wglSwapBuffers into a surface shared with the
+ * DWM process.
+ *
+ * @sa http://www.opengl.org/pipeline/article/vol003_7/
+ * @sa http://blogs.msdn.com/greg_schechter/archive/2006/05/02/588934.aspx
+ */
+typedef struct _GLCBPRESENTBUFFERSDATA
+{
+ /**
+ * wglCbPresentBuffers enforces this to be 2.
+ */
+ DWORD magic1;
+
+ /**
+ * wglCbPresentBuffers enforces to be 0 or 1, but it is most commonly
+ * set to 0.
+ */
+ DWORD magic2;
+
+ /**
+ * Locally unique identifier (LUID) of the graphics adapter.
+ *
+ * This should contain the value returned by D3DKMTOpenAdapterFromHdc. It
+ * is passed to dwmapi!DwmpDxGetWindowSharedSurface in order to obtain
+ * the shared surface handle for the bound drawable (window).
+ *
+ * @sa http://msdn.microsoft.com/en-us/library/ms799177.aspx
+ */
+ LUID AdapterLuid;
+
+ /**
+ * This is passed unmodified to DrvPresentBuffers
+ */
+ LPVOID pPrivateData;
+
+ /**
+ * Client area rectangle to update, relative to the window upper-left corner.
+ */
+ RECT rect;
+} GLCBPRESENTBUFFERSDATA, *PGLCBPRESENTBUFFERSDATA;
+
+/**
+ * Callbacks supplied to DrvSetCallbackProcs by the OpenGL runtime.
+ *
+ * Pointers to several callback functions in opengl32.dll.
+ */
+typedef struct _GLCALLBACKTABLE
+{
+ /** Unused */
+ PROC wglCbSetCurrentValue;
+
+ /** Unused */
+ PROC wglCbGetCurrentValue;
+
+ /** Unused */
+ PROC wglCbGetDhglrc;
+
+ /** Unused */
+ PROC wglCbGetDdHandle;
+
+ /**
+ * Queue a present composition.
+ *
+ * Makes the runtime call DrvPresentBuffers with the composition information.
+ */
+ BOOL (APIENTRY *wglCbPresentBuffers)(HDC hdc, PGLCBPRESENTBUFFERSDATA data);
+
+} GLCALLBACKTABLE;
+
+typedef struct _GLPRESENTBUFFERSDATA
+{
+ /**
+ * The shared surface handle.
+ *
+ * Return by dwmapi!DwmpDxGetWindowSharedSurface.
+ *
+ * @sa http://channel9.msdn.com/forums/TechOff/251261-Help-Getting-the-shared-window-texture-out-of-DWM-/
+ */
+ HANDLE hSharedSurface;
+
+ LUID AdapterLuid;
+
+ /**
+ * Present history token.
+ *
+ * This is returned by dwmapi!DwmpDxGetWindowSharedSurface and
+ * should be passed to D3DKMTRender in D3DKMT_RENDER::PresentHistoryToken.
+ *
+ * @sa http://msdn.microsoft.com/en-us/library/ms799176.aspx
+ */
+ ULONGLONG PresentHistoryToken;
+
+ /** Same as GLCBPRESENTBUFFERSDATA::pPrivateData */
+ LPVOID pPrivateData;
+} GLPRESENTBUFFERSDATA, *PGLPRESENTBUFFERSDATA;
+
BOOL APIENTRY
DrvCopyContext(
DHGLRC dhrcSource,
@@ -435,6 +542,9 @@ DrvGetProcAddress(
LPCSTR lpszProc );
BOOL APIENTRY
+DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data);
+
+BOOL APIENTRY
DrvRealizeLayerPalette(
HDC hdc,
INT iLayerPlane,
diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index c296744838b..7abe5d9f7fa 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c
@@ -34,9 +34,9 @@
#include "util/u_debug.h"
+#include "stw_icd.h"
#include "stw_device.h"
#include "stw_pixelformat.h"
-#include "stw_public.h"
#include "stw_tls.h"
@@ -154,8 +154,11 @@ stw_pixelformat_add(
pfi->pfd.dwFlags = PFD_SUPPORT_OPENGL;
/* TODO: also support non-native pixel formats */
- pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW ;
-
+ pfi->pfd.dwFlags |= PFD_DRAW_TO_WINDOW;
+
+ /* See http://www.opengl.org/pipeline/article/vol003_7/ */
+ pfi->pfd.dwFlags |= PFD_SUPPORT_COMPOSITION;
+
if (doublebuffer)
pfi->pfd.dwFlags |= PFD_DOUBLEBUFFER | PFD_SWAP_COPY;
@@ -288,12 +291,12 @@ stw_pixelformat_visual(GLvisual *visual,
}
-int
-stw_pixelformat_describe(
+LONG APIENTRY
+DrvDescribePixelFormat(
HDC hdc,
- int iPixelFormat,
- UINT nBytes,
- LPPIXELFORMATDESCRIPTOR ppfd )
+ INT iPixelFormat,
+ ULONG cjpfd,
+ PIXELFORMATDESCRIPTOR *ppfd )
{
uint count;
uint index;
@@ -306,7 +309,7 @@ stw_pixelformat_describe(
if (ppfd == NULL)
return count;
- if (index >= count || nBytes != sizeof( PIXELFORMATDESCRIPTOR ))
+ if (index >= count || cjpfd != sizeof( PIXELFORMATDESCRIPTOR ))
return 0;
pfi = stw_pixelformat_get_info( index );
@@ -316,6 +319,52 @@ stw_pixelformat_describe(
return count;
}
+BOOL APIENTRY
+DrvDescribeLayerPlane(
+ HDC hdc,
+ INT iPixelFormat,
+ INT iLayerPlane,
+ UINT nBytes,
+ LPLAYERPLANEDESCRIPTOR plpd )
+{
+ assert(0);
+ return FALSE;
+}
+
+int APIENTRY
+DrvGetLayerPaletteEntries(
+ HDC hdc,
+ INT iLayerPlane,
+ INT iStart,
+ INT cEntries,
+ COLORREF *pcr )
+{
+ assert(0);
+ return 0;
+}
+
+int APIENTRY
+DrvSetLayerPaletteEntries(
+ HDC hdc,
+ INT iLayerPlane,
+ INT iStart,
+ INT cEntries,
+ CONST COLORREF *pcr )
+{
+ assert(0);
+ return 0;
+}
+
+BOOL APIENTRY
+DrvRealizeLayerPalette(
+ HDC hdc,
+ INT iLayerPlane,
+ BOOL bRealize )
+{
+ assert(0);
+ return FALSE;
+}
+
/* Only used by the wgl code, but have it here to avoid exporting the
* pixelformat.h functionality.
*/
diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h b/src/gallium/state_trackers/wgl/stw_pixelformat.h
index bec429231b2..3a690b35bad 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -30,6 +30,10 @@
#include <windows.h>
+#ifndef PFD_SUPPORT_COMPOSITION
+#define PFD_SUPPORT_COMPOSITION 0x00008000
+#endif
+
#include "main/mtypes.h"
#include "pipe/p_compiler.h"
@@ -62,4 +66,11 @@ void
stw_pixelformat_visual(GLvisual *visual,
const struct stw_pixelformat_info *pfi );
+int
+stw_pixelformat_choose( HDC hdc,
+ CONST PIXELFORMATDESCRIPTOR *ppfd );
+
+int
+stw_pixelformat_get(HDC hdc);
+
#endif /* STW_PIXELFORMAT_H */
diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.c b/src/gallium/state_trackers/wgl/stw_tls.c
index 4bd6a9289c9..4bd6a9289c9 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_tls.c
+++ b/src/gallium/state_trackers/wgl/stw_tls.c
diff --git a/src/gallium/state_trackers/wgl/shared/stw_tls.h b/src/gallium/state_trackers/wgl/stw_tls.h
index fbf8b1cbee4..fbf8b1cbee4 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_tls.h
+++ b/src/gallium/state_trackers/wgl/stw_tls.h
diff --git a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/stw_wgl.c
index a131292f7ae..bb199fdd252 100644
--- a/src/gallium/state_trackers/wgl/wgl/stw_wgl.c
+++ b/src/gallium/state_trackers/wgl/stw_wgl.c
@@ -28,7 +28,9 @@
#include <windows.h>
#include "util/u_debug.h"
-#include "shared/stw_public.h"
+#include "stw_icd.h"
+#include "stw_context.h"
+#include "stw_pixelformat.h"
#include "stw_wgl.h"
@@ -38,16 +40,16 @@ wglCopyContext(
HGLRC hglrcDst,
UINT mask )
{
- return stw_copy_context( (UINT_PTR)hglrcSrc,
- (UINT_PTR)hglrcDst,
- mask );
+ return DrvCopyContext( (DHGLRC)(UINT_PTR)hglrcSrc,
+ (DHGLRC)(UINT_PTR)hglrcDst,
+ mask );
}
WINGDIAPI HGLRC APIENTRY
wglCreateContext(
HDC hdc )
{
- return wglCreateLayerContext(hdc, 0);
+ return (HGLRC) DrvCreateContext(hdc);
}
WINGDIAPI HGLRC APIENTRY
@@ -55,21 +57,21 @@ wglCreateLayerContext(
HDC hdc,
int iLayerPlane )
{
- return (HGLRC) stw_create_layer_context( hdc, iLayerPlane );
+ return (HGLRC) DrvCreateLayerContext( hdc, iLayerPlane );
}
WINGDIAPI BOOL APIENTRY
wglDeleteContext(
HGLRC hglrc )
{
- return stw_delete_context( (UINT_PTR)hglrc );
+ return DrvDeleteContext((DHGLRC)(UINT_PTR)hglrc );
}
WINGDIAPI HGLRC APIENTRY
wglGetCurrentContext( VOID )
{
- return (HGLRC)stw_get_current_context();
+ return (HGLRC)(UINT_PTR)stw_get_current_context();
}
WINGDIAPI HDC APIENTRY
@@ -83,7 +85,7 @@ wglMakeCurrent(
HDC hdc,
HGLRC hglrc )
{
- return stw_make_current( hdc, (UINT_PTR)hglrc );
+ return DrvSetContext( hdc, (DHGLRC)(UINT_PTR)hglrc, NULL ) ? TRUE : FALSE;
}
@@ -91,7 +93,7 @@ WINGDIAPI BOOL APIENTRY
wglSwapBuffers(
HDC hdc )
{
- return stw_swap_buffers( hdc );
+ return DrvSwapBuffers( hdc );
}
@@ -100,14 +102,14 @@ wglSwapLayerBuffers(
HDC hdc,
UINT fuPlanes )
{
- return stw_swap_layer_buffers( hdc, fuPlanes );
+ return DrvSwapLayerBuffers( hdc, fuPlanes );
}
WINGDIAPI PROC APIENTRY
wglGetProcAddress(
LPCSTR lpszProc )
{
- return stw_get_proc_address( lpszProc );
+ return DrvGetProcAddress( lpszProc );
}
@@ -141,7 +143,7 @@ wglDescribePixelFormat(
UINT nBytes,
LPPIXELFORMATDESCRIPTOR ppfd )
{
- return stw_pixelformat_describe( hdc, iPixelFormat, nBytes, ppfd );
+ return DrvDescribePixelFormat( hdc, iPixelFormat, nBytes, ppfd );
}
WINGDIAPI int APIENTRY
@@ -160,7 +162,7 @@ wglSetPixelFormat(
if (ppfd->nSize != sizeof( PIXELFORMATDESCRIPTOR ))
return FALSE;
- return stw_pixelformat_set( hdc, iPixelFormat );
+ return DrvSetPixelFormat( hdc, iPixelFormat );
}
@@ -186,7 +188,8 @@ wglShareLists(
HGLRC hglrc1,
HGLRC hglrc2 )
{
- return stw_share_lists( (UINT_PTR)hglrc1, (UINT_PTR)hglrc2);;
+ return DrvShareLists((DHGLRC)(UINT_PTR)hglrc1,
+ (DHGLRC)(UINT_PTR)hglrc2);
}
WINGDIAPI BOOL APIENTRY
@@ -264,15 +267,7 @@ wglDescribeLayerPlane(
UINT nBytes,
LPLAYERPLANEDESCRIPTOR plpd )
{
- (void) hdc;
- (void) iPixelFormat;
- (void) iLayerPlane;
- (void) nBytes;
- (void) plpd;
-
- assert( 0 );
-
- return FALSE;
+ return DrvDescribeLayerPlane(hdc, iPixelFormat, iLayerPlane, nBytes, plpd);
}
WINGDIAPI int APIENTRY
@@ -283,15 +278,7 @@ wglSetLayerPaletteEntries(
int cEntries,
CONST COLORREF *pcr )
{
- (void) hdc;
- (void) iLayerPlane;
- (void) iStart;
- (void) cEntries;
- (void) pcr;
-
- assert( 0 );
-
- return 0;
+ return DrvSetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
}
WINGDIAPI int APIENTRY
@@ -302,15 +289,7 @@ wglGetLayerPaletteEntries(
int cEntries,
COLORREF *pcr )
{
- (void) hdc;
- (void) iLayerPlane;
- (void) iStart;
- (void) cEntries;
- (void) pcr;
-
- assert( 0 );
-
- return 0;
+ return DrvGetLayerPaletteEntries(hdc, iLayerPlane, iStart, cEntries, pcr);
}
WINGDIAPI BOOL APIENTRY
diff --git a/src/gallium/state_trackers/wgl/wgl/stw_wgl.h b/src/gallium/state_trackers/wgl/stw_wgl.h
index a98179944aa..a98179944aa 100644
--- a/src/gallium/state_trackers/wgl/wgl/stw_wgl.h
+++ b/src/gallium/state_trackers/wgl/stw_wgl.h
diff --git a/src/gallium/state_trackers/wgl/shared/stw_winsys.h b/src/gallium/state_trackers/wgl/stw_winsys.h
index c0bf82c9ed7..1ead47d6e63 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/stw_winsys.h
@@ -1,6 +1,6 @@
/**************************************************************************
*
- * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * Copyright 2008-2009 Vmware, Inc.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -18,7 +18,7 @@
* THE SOFTWARE IS PROVIDED "AS 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
+ * 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.
@@ -36,6 +36,8 @@ struct pipe_screen;
struct pipe_context;
struct pipe_surface;
+struct stw_shared_surface;
+
struct stw_winsys
{
struct pipe_screen *
@@ -44,10 +46,52 @@ struct stw_winsys
struct pipe_context *
(*create_context)( struct pipe_screen *screen );
+ /**
+ * Present the color buffer to the window associated with the device context.
+ */
+ void
+ (*present)( struct pipe_screen *screen,
+ struct pipe_surface *surf,
+ HDC hDC );
+
+ /**
+ * Locally unique identifier (LUID) of the graphics adapter.
+ *
+ * @sa GLCBPRESENTBUFFERSDATA::AdapterLuid;
+ */
+ boolean
+ (*get_adapter_luid)( struct pipe_screen *screen,
+ LUID *pAdapterLuid );
+
+ /**
+ * Open a shared surface (optional).
+ *
+ * @sa GLCBPRESENTBUFFERSDATA::hSharedSurface;
+ */
+ struct stw_shared_surface *
+ (*shared_surface_open)(struct pipe_screen *screen,
+ HANDLE hSharedSurface);
+
+ /**
+ * Open a shared surface (optional).
+ */
+ void
+ (*shared_surface_close)(struct pipe_screen *screen,
+ struct stw_shared_surface *surface);
+
+ /**
+ * Compose into a shared (optional).
+ *
+ * Blit the color buffer into a shared surface.
+ *
+ * @sa GLPRESENTBUFFERSDATA::PresentHistoryToken.
+ */
void
- (*flush_frontbuffer)( struct pipe_screen *screen,
- struct pipe_surface *surf,
- HDC hDC );
+ (*compose)( struct pipe_screen *screen,
+ struct pipe_surface *src,
+ struct stw_shared_surface *dest,
+ LPCRECT pRect,
+ ULONGLONG PresentHistoryToken );
};
boolean
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 15c955450d0..9d15a615f15 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -12,9 +12,9 @@ struct xorg_composite_blend {
int op:8;
unsigned rgb_src_factor:5; /**< PIPE_BLENDFACTOR_x */
- unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
-
unsigned alpha_src_factor:5; /**< PIPE_BLENDFACTOR_x */
+
+ unsigned rgb_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
unsigned alpha_dst_factor:5; /**< PIPE_BLENDFACTOR_x */
};
@@ -57,24 +57,6 @@ pixel_to_float4(Pixel pixel, float *color)
color[3] = ((float)a) / 255.;
}
-static INLINE void
-render_pixel_to_float4(PictFormatPtr format,
- CARD32 pixel, float *color)
-{
- CARD32 r, g, b, a;
-
- debug_assert(format->type == PictTypeDirect);
-
- r = (pixel >> format->direct.red) & format->direct.redMask;
- g = (pixel >> format->direct.green) & format->direct.greenMask;
- b = (pixel >> format->direct.blue) & format->direct.blueMask;
- a = (pixel >> format->direct.alpha) & format->direct.alphaMask;
- color[0] = ((float)r) / ((float)format->direct.redMask);
- color[1] = ((float)g) / ((float)format->direct.greenMask);
- color[2] = ((float)b) / ((float)format->direct.blueMask);
- color[3] = ((float)a) / ((float)format->direct.alphaMask);
-}
-
struct acceleration_info {
int op : 16;
int with_mask : 1;
@@ -150,24 +132,22 @@ setup_vertex_data0(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
- float vertices[4][2][4];
-
/* 1st vertex */
- setup_vertex0(vertices[0], dstX, dstY,
+ setup_vertex0(ctx->vertices2[0], dstX, dstY,
ctx->solid_color);
/* 2nd vertex */
- setup_vertex0(vertices[1], dstX + width, dstY,
+ setup_vertex0(ctx->vertices2[1], dstX + width, dstY,
ctx->solid_color);
/* 3rd vertex */
- setup_vertex0(vertices[2], dstX + width, dstY + height,
+ setup_vertex0(ctx->vertices2[2], dstX + width, dstY + height,
ctx->solid_color);
/* 4th vertex */
- setup_vertex0(vertices[3], dstX, dstY + height,
+ setup_vertex0(ctx->vertices2[3], dstX, dstY + height,
ctx->solid_color);
return pipe_user_buffer_create(ctx->pipe->screen,
- vertices,
- sizeof(vertices));
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
}
static INLINE void
@@ -189,7 +169,6 @@ setup_vertex_data1(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
- float vertices[4][2][4];
float s0, t0, s1, t1;
struct pipe_texture *src = ctx->bound_textures[0];
@@ -199,21 +178,21 @@ setup_vertex_data1(struct exa_context *ctx,
t1 = srcY + height / src->height[0];
/* 1st vertex */
- setup_vertex1(vertices[0], dstX, dstY,
+ setup_vertex1(ctx->vertices2[0], dstX, dstY,
s0, t0);
/* 2nd vertex */
- setup_vertex1(vertices[1], dstX + width, dstY,
+ setup_vertex1(ctx->vertices2[1], dstX + width, dstY,
s1, t0);
/* 3rd vertex */
- setup_vertex1(vertices[2], dstX + width, dstY + height,
+ setup_vertex1(ctx->vertices2[2], dstX + width, dstY + height,
s1, t1);
/* 4th vertex */
- setup_vertex1(vertices[3], dstX, dstY + height,
+ setup_vertex1(ctx->vertices2[3], dstX, dstY + height,
s0, t1);
return pipe_user_buffer_create(ctx->pipe->screen,
- vertices,
- sizeof(vertices));
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
}
static struct pipe_buffer *
@@ -222,24 +201,22 @@ setup_vertex_data_tex(struct exa_context *ctx,
float s0, float t0, float s1, float t1,
float z)
{
- float vertices[4][2][4];
-
/* 1st vertex */
- setup_vertex1(vertices[0], x0, y0,
+ setup_vertex1(ctx->vertices2[0], x0, y0,
s0, t0);
/* 2nd vertex */
- setup_vertex1(vertices[1], x1, y0,
+ setup_vertex1(ctx->vertices2[1], x1, y0,
s1, t0);
/* 3rd vertex */
- setup_vertex1(vertices[2], x1, y1,
+ setup_vertex1(ctx->vertices2[2], x1, y1,
s1, t1);
/* 4th vertex */
- setup_vertex1(vertices[3], x0, y1,
+ setup_vertex1(ctx->vertices2[3], x0, y1,
s0, t1);
return pipe_user_buffer_create(ctx->pipe->screen,
- vertices,
- sizeof(vertices));
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
}
@@ -269,7 +246,6 @@ setup_vertex_data2(struct exa_context *ctx,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
- float vertices[4][3][4];
float st0[4], st1[4];
struct pipe_texture *src = ctx->bound_textures[0];
struct pipe_texture *mask = ctx->bound_textures[0];
@@ -285,21 +261,21 @@ setup_vertex_data2(struct exa_context *ctx,
st1[3] = maskY + height / mask->height[0];
/* 1st vertex */
- setup_vertex2(vertices[0], dstX, dstY,
+ setup_vertex2(ctx->vertices3[0], dstX, dstY,
st0[0], st0[1], st1[0], st1[1]);
/* 2nd vertex */
- setup_vertex2(vertices[1], dstX + width, dstY,
+ setup_vertex2(ctx->vertices3[1], dstX + width, dstY,
st0[2], st0[1], st1[2], st1[1]);
/* 3rd vertex */
- setup_vertex2(vertices[2], dstX + width, dstY + height,
+ setup_vertex2(ctx->vertices3[2], dstX + width, dstY + height,
st0[2], st0[3], st1[2], st1[3]);
/* 4th vertex */
- setup_vertex2(vertices[3], dstX, dstY + height,
+ setup_vertex2(ctx->vertices3[3], dstX, dstY + height,
st0[0], st0[3], st1[0], st1[3]);
return pipe_user_buffer_create(ctx->pipe->screen,
- vertices,
- sizeof(vertices));
+ ctx->vertices3,
+ sizeof(ctx->vertices3));
}
boolean xorg_composite_accelerated(int op,
@@ -311,22 +287,25 @@ boolean xorg_composite_accelerated(int op,
unsigned accel_ops_count =
sizeof(accelerated_ops)/sizeof(struct acceleration_info);
-
- /*FIXME: currently accel is disabled */
- return FALSE;
-
- if (pSrcPicture) {
- /* component alpha not supported */
- if (pSrcPicture->componentAlpha)
+ if (pSrcPicture->pSourcePict) {
+ /* Gradients not yet supported */
+ if (pSrcPicture->pSourcePict->type != SourcePictTypeSolidFill)
return FALSE;
- /* fills not supported */
- if (pSrcPicture->pSourcePict)
+
+ /* Solid source with mask not yet handled properly */
+ if (pMaskPicture)
return FALSE;
}
for (i = 0; i < accel_ops_count; ++i) {
if (op == accelerated_ops[i].op) {
- if (pMaskPicture && !accelerated_ops[i].with_mask)
+ /* Check for unsupported component alpha */
+ if ((pSrcPicture->componentAlpha &&
+ !accelerated_ops[i].component_alpha) ||
+ (pMaskPicture &&
+ (!accelerated_ops[i].with_mask ||
+ (pMaskPicture->componentAlpha &&
+ !accelerated_ops[i].component_alpha))))
return FALSE;
return TRUE;
}
@@ -359,6 +338,9 @@ bind_framebuffer_state(struct exa_context *exa, struct exa_pixmap_priv *pDst)
state.zsbuf = 0;
cso_set_framebuffer(exa->cso, &state);
+
+ /* we do fire and forget for the framebuffer, this is the forget part */
+ pipe_surface_reference(&surface, NULL);
}
enum AxisOrientation {
@@ -391,7 +373,7 @@ bind_viewport_state(struct exa_context *exa, struct exa_pixmap_priv *pDst)
int width = pDst->tex->width[0];
int height = pDst->tex->height[0];
- debug_printf("Bind viewport (%d, %d)\n", width, height);
+ /*debug_printf("Bind viewport (%d, %d)\n", width, height);*/
set_viewport(exa, width, height, Y0_TOP);
}
@@ -400,14 +382,9 @@ static void
bind_blend_state(struct exa_context *exa, int op,
PicturePtr pSrcPicture, PicturePtr pMaskPicture)
{
- boolean component_alpha = (pSrcPicture) ?
- pSrcPicture->componentAlpha : FALSE;
struct xorg_composite_blend blend_opt;
struct pipe_blend_state blend;
- if (component_alpha) {
- op = PictOpOver;
- }
blend_opt = blend_for_op(op);
memset(&blend, 0, sizeof(struct pipe_blend_state));
@@ -448,9 +425,9 @@ bind_shaders(struct exa_context *exa, int op,
if (pSrcPicture->pSourcePict->type == SourcePictTypeSolidFill) {
fs_traits |= FS_SOLID_FILL;
vs_traits |= VS_SOLID_FILL;
- render_pixel_to_float4(pSrcPicture->pFormat,
- pSrcPicture->pSourcePict->solidFill.color,
- exa->solid_color);
+ debug_assert(pSrcPicture->format == PICT_a8r8g8b8);
+ pixel_to_float4(pSrcPicture->pSourcePict->solidFill.color,
+ exa->solid_color);
exa->has_solid_color = TRUE;
} else {
debug_assert("!gradients not supported");
@@ -488,6 +465,12 @@ bind_samplers(struct exa_context *exa, int op,
memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
+ if ((pSrc && exa->pipe->is_texture_referenced(exa->pipe, pSrc->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE) ||
+ (pMask && exa->pipe->is_texture_referenced(exa->pipe, pMask->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE))
+ exa->pipe->flush(exa->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
if (pSrcPicture && pSrc) {
unsigned src_wrap = render_repeat_to_gallium(
pSrcPicture->repeatType);
@@ -653,17 +636,12 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
exa->solid_color[3] = 1.f;
+#if 0
debug_printf("Color Pixel=(%d, %d, %d, %d), RGBA=(%f, %f, %f, %f)\n",
(fg >> 24) & 0xff, (fg >> 16) & 0xff,
(fg >> 8) & 0xff, (fg >> 0) & 0xff,
exa->solid_color[0], exa->solid_color[1],
exa->solid_color[2], exa->solid_color[3]);
-
-#if 0
- exa->solid_color[0] = 1.f;
- exa->solid_color[1] = 0.f;
- exa->solid_color[2] = 0.f;
- exa->solid_color[3] = 1.f;
#endif
vs_traits = VS_SOLID_FILL;
@@ -680,7 +658,7 @@ boolean xorg_solid_bind_state(struct exa_context *exa,
cso_set_vertex_shader_handle(exa->cso, shader.vs);
cso_set_fragment_shader_handle(exa->cso, shader.fs);
- return FALSE;
+ return TRUE;
}
void xorg_solid(struct exa_context *exa,
@@ -689,31 +667,26 @@ void xorg_solid(struct exa_context *exa,
{
struct pipe_context *pipe = exa->pipe;
struct pipe_buffer *buf = 0;
- float vertices[4][2][4];
-
- x0 = 10; y0 = 10;
- x1 = 300; y1 = 300;
/* 1st vertex */
- setup_vertex0(vertices[0], x0, y0,
+ setup_vertex0(exa->vertices2[0], x0, y0,
exa->solid_color);
/* 2nd vertex */
- setup_vertex0(vertices[1], x1, y0,
+ setup_vertex0(exa->vertices2[1], x1, y0,
exa->solid_color);
/* 3rd vertex */
- setup_vertex0(vertices[2], x1, y1,
+ setup_vertex0(exa->vertices2[2], x1, y1,
exa->solid_color);
/* 4th vertex */
- setup_vertex0(vertices[3], x0, y1,
+ setup_vertex0(exa->vertices2[3], x0, y1,
exa->solid_color);
buf = pipe_user_buffer_create(exa->pipe->screen,
- vertices,
- sizeof(vertices));
+ exa->vertices2,
+ sizeof(exa->vertices2));
if (buf) {
- debug_printf("Drawing buf is %p\n", buf);
util_draw_vertex_buffer(pipe, buf, 0,
PIPE_PRIM_TRIANGLE_FAN,
4, /* verts */
@@ -844,11 +817,6 @@ static void renderer_copy_texture(struct exa_context *exa,
assert(dst->width[0] != 0);
assert(dst->height[0] != 0);
-#if 0
- debug_printf("copy texture [%f, %f, %f, %f], [%f, %f, %f, %f]\n",
- sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2);
-#endif
-
#if 1
s0 = sx1 / src->width[0];
s1 = sx2 / src->width[0];
@@ -861,8 +829,16 @@ static void renderer_copy_texture(struct exa_context *exa,
t1 = 1;
#endif
- assert(screen->is_format_supported(screen, dst_surf->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
+#if 1
+ debug_printf("copy texture src=[%f, %f, %f, %f], dst=[%f, %f, %f, %f], tex=[%f, %f, %f, %f]\n",
+ sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2,
+ s0, t0, s1, t1);
+#endif
+
+ assert(screen->is_format_supported(screen, dst_surf->format,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET,
+ 0));
/* save state (restored below) */
cso_save_blend(exa->cso);
@@ -907,6 +883,8 @@ static void renderer_copy_texture(struct exa_context *exa,
/* texture */
cso_set_sampler_textures(exa->cso, 1, &src);
+ bind_rasterizer_state(exa);
+
/* shaders */
shader = xorg_shaders_get(exa->shaders,
VS_COMPOSITE,
@@ -926,6 +904,8 @@ static void renderer_copy_texture(struct exa_context *exa,
fb.cbufs[i] = 0;
}
cso_set_framebuffer(exa->cso, &fb);
+ setup_vs_constant_buffer(exa, fb.width, fb.height);
+ setup_fs_constant_buffer(exa);
/* draw quad */
buf = setup_vertex_data_tex(exa,
@@ -955,6 +935,61 @@ static void renderer_copy_texture(struct exa_context *exa,
pipe_surface_reference(&dst_surf, NULL);
}
+
+static struct pipe_texture *
+create_sampler_texture(struct exa_context *ctx,
+ struct pipe_texture *src)
+{
+ enum pipe_format format;
+ struct pipe_context *pipe = ctx->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_texture *pt;
+ struct pipe_texture templ;
+
+ pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+ /* the coming in texture should already have that invariance */
+ debug_assert(screen->is_format_supported(screen, src->format,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
+
+ format = src->format;
+
+ memset(&templ, 0, sizeof(templ));
+ templ.target = PIPE_TEXTURE_2D;
+ templ.format = format;
+ templ.last_level = 0;
+ templ.width[0] = src->width[0];
+ templ.height[0] = src->height[0];
+ templ.depth[0] = 1;
+ pf_get_block(format, &templ.block);
+ templ.tex_usage = PIPE_TEXTURE_USAGE_SAMPLER;
+
+ pt = screen->texture_create(screen, &templ);
+
+ debug_assert(!pt || pipe_is_referenced(&pt->reference));
+
+ if (!pt)
+ return NULL;
+
+ {
+ /* copy source framebuffer surface into texture */
+ struct pipe_surface *ps_read = screen->get_tex_surface(
+ screen, src, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_READ);
+ struct pipe_surface *ps_tex = screen->get_tex_surface(
+ screen, pt, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE );
+ pipe->surface_copy(pipe,
+ ps_tex, /* dest */
+ 0, 0, /* destx/y */
+ ps_read,
+ 0, 0, src->width[0], src->height[0]);
+ pipe_surface_reference(&ps_read, NULL);
+ pipe_surface_reference(&ps_tex, NULL);
+ }
+
+ return pt;
+}
+
void xorg_copy_pixmap(struct exa_context *ctx,
struct exa_pixmap_priv *dst_priv, int dx, int dy,
struct exa_pixmap_priv *src_priv, int sx, int sy,
@@ -966,6 +1001,10 @@ void xorg_copy_pixmap(struct exa_context *ctx,
struct pipe_texture *dst = dst_priv->tex;
struct pipe_texture *src = src_priv->tex;
+ if (ctx->pipe->is_texture_referenced(ctx->pipe, src, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)
+ ctx->pipe->flush(ctx->pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+
dst_loc[0] = dx;
dst_loc[1] = dy;
dst_loc[2] = width;
@@ -1003,17 +1042,25 @@ void xorg_copy_pixmap(struct exa_context *ctx,
if (src_loc[2] >= 0 && src_loc[3] >= 0 &&
dst_loc[2] >= 0 && dst_loc[3] >= 0) {
+ struct pipe_texture *temp_src = src;
+
+ if (src == dst)
+ temp_src = create_sampler_texture(ctx, src);
+
renderer_copy_texture(ctx,
- src,
+ temp_src,
src_loc[0],
- src_loc[1] + src_loc[3],
- src_loc[0] + src_loc[2],
src_loc[1],
+ src_loc[0] + src_loc[2],
+ src_loc[1] + src_loc[3],
dst,
dst_loc[0],
- dst_loc[1] + dst_loc[3],
+ dst_loc[1],
dst_loc[0] + dst_loc[2],
- dst_loc[1]);
+ dst_loc[1] + dst_loc[3]);
+
+ if (src == dst)
+ pipe_texture_reference(&temp_src, NULL);
}
}
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index fe08bde9efc..67fe29a69da 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -42,8 +42,12 @@
#include "xorg_tracker.h"
#include "xf86Modes.h"
+#ifdef HAVE_XEXTPROTO_71
+#include <X11/extensions/dpmsconst.h>
+#else
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
+#endif
#include "pipe/p_inlines.h"
#include "util/u_rect.h"
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 312dab1544c..3f48ab98ac5 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -47,6 +47,9 @@
#include "util/u_rect.h"
+#define DEBUG_SOLID 0
+#define DISABLE_ACCEL 0
+
/*
* Helper functions
*/
@@ -72,6 +75,9 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
assert(*bbp == 16);
break;
case 8:
+ *format = PIPE_FORMAT_I8_UNORM;
+ assert(*bbp == 8);
+ break;
case 4:
case 1:
*format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
@@ -253,7 +259,7 @@ ExaDone(PixmapPtr pPixmap)
#if 1
xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
#else
- xorg_finish(exa);
+ xorg_exa_finish(exa);
#endif
xorg_exa_common_done(exa);
}
@@ -276,24 +282,36 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_context *exa = ms->exa;
- debug_printf("ExaPrepareSolid - test\n");
- if (pPixmap->drawable.depth < 15)
- return FALSE;
-
+#if 1
+ debug_printf("ExaPrepareSolid(0x%x)\n", fg);
+#endif
if (!EXA_PM_IS_SOLID(&pPixmap->drawable, planeMask))
return FALSE;
if (!priv || !priv->tex)
return FALSE;
+ if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+ priv->tex->target,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ return FALSE;
+
if (alu != GXcopy)
return FALSE;
if (!exa->pipe)
return FALSE;
- debug_printf(" ExaPrepareSolid(0x%x)\n", fg);
+
+#if DEBUG_SOLID
+ fg = 0xffff0000;
+#endif
+
+#if DISABLE_ACCEL
+ return FALSE;
+#else
return xorg_solid_bind_state(exa, priv, fg);
+#endif
}
static void
@@ -310,11 +328,42 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
if (x0 == 0 && y0 == 0 &&
x1 == priv->tex->width[0] &&
y1 == priv->tex->height[0]) {
- exa->ctx->clear(exa->ctx, PIPE_CLEAR_COLOR | PIPE_CLEAR_DEPTHSTENCIL,
+ exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
exa->solid_color, 1., 0);
} else
#endif
- xorg_solid(exa, priv, x0, y0, x1, y1) ;
+
+#if DEBUG_SOLID
+ exa->solid_color[0] = 0.f;
+ exa->solid_color[1] = 1.f;
+ exa->solid_color[2] = 0.f;
+ exa->solid_color[3] = 1.f;
+ xorg_solid(exa, priv, 0, 0, 1024, 768);
+ exa->solid_color[0] = 1.f;
+ exa->solid_color[1] = 0.f;
+ exa->solid_color[2] = 0.f;
+ exa->solid_color[3] = 1.f;
+ xorg_solid(exa, priv, 0, 0, 300, 300);
+ xorg_solid(exa, priv, 300, 300, 350, 350);
+ xorg_solid(exa, priv, 350, 350, 500, 500);
+
+ xorg_solid(exa, priv,
+ priv->tex->width[0] - 10,
+ priv->tex->height[0] - 10,
+ priv->tex->width[0],
+ priv->tex->height[0]);
+
+ exa->solid_color[0] = 0.f;
+ exa->solid_color[1] = 0.f;
+ exa->solid_color[2] = 1.f;
+ exa->solid_color[3] = 1.f;
+
+ exa->has_solid_color = FALSE;
+ ExaPrepareCopy(pPixmap, pPixmap, 0, 0, GXcopy, 0xffffffff);
+ ExaCopy(pPixmap, 0, 0, 50, 50, 500, 500);
+#else
+ xorg_solid(exa, priv, x0, y0, x1, y1) ;
+#endif
}
static Bool
@@ -332,15 +381,20 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
if (alu != GXcopy)
return FALSE;
- if (pSrcPixmap->drawable.depth < 15 || pDstPixmap->drawable.depth < 15)
- return FALSE;
-
if (!EXA_PM_IS_SOLID(&pSrcPixmap->drawable, planeMask))
return FALSE;
if (!priv || !src_priv)
return FALSE;
+ if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+ priv->tex->target,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0) ||
+ !exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format,
+ src_priv->tex->target,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0))
+ return FALSE;
+
if (!priv->tex || !src_priv->tex)
return FALSE;
@@ -350,8 +404,11 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
exa->copy.src = src_priv;
exa->copy.dst = priv;
- /*XXX disabled until some issues with syncing are fixed */
+#if DISABLE_ACCEL
return FALSE;
+#else
+ return TRUE;
+#endif
}
static void
@@ -381,14 +438,45 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
ScrnInfoPtr pScrn = xf86Screens[pDst->drawable.pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
+ struct exa_pixmap_priv *priv;
debug_printf("ExaPrepareComposite\n");
+ priv = exaGetPixmapDriverPrivate(pDst);
+ if (!priv || !priv->tex ||
+ !exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+ priv->tex->target,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
+ return FALSE;
+
+ if (pSrc) {
+ priv = exaGetPixmapDriverPrivate(pSrc);
+ if (!priv || !priv->tex ||
+ !exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+ priv->tex->target,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0))
+ return FALSE;
+ }
+
+ if (pMask) {
+ priv = exaGetPixmapDriverPrivate(pMask);
+ if (!priv || !priv->tex ||
+ !exa->scrn->is_format_supported(exa->scrn, priv->tex->format,
+ priv->tex->target,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0))
+ return FALSE;
+ }
+
+#if DISABLE_ACCEL
+ (void) exa;
+ return FALSE;
+#else
return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
pDstPicture,
- exaGetPixmapDriverPrivate(pSrc),
- exaGetPixmapDriverPrivate(pMask),
+ pSrc ? exaGetPixmapDriverPrivate(pSrc) : NULL,
+ pMask ? exaGetPixmapDriverPrivate(pMask) : NULL,
exaGetPixmapDriverPrivate(pDst));
+#endif
}
static void
@@ -411,10 +499,13 @@ ExaCheckComposite(int op,
PicturePtr pSrcPicture, PicturePtr pMaskPicture,
PicturePtr pDstPicture)
{
- return xorg_composite_accelerated(op,
- pSrcPicture,
- pMaskPicture,
- pDstPicture);
+ boolean accelerated = xorg_composite_accelerated(op,
+ pSrcPicture,
+ pMaskPicture,
+ pDstPicture);
+ debug_printf("ExaCheckComposite(%d, %p, %p, %p) = %d\n",
+ op, pSrcPicture, pMaskPicture, pDstPicture, accelerated);
+ return accelerated;
}
static void *
@@ -433,14 +524,11 @@ static void
ExaDestroyPixmap(ScreenPtr pScreen, void *dPriv)
{
struct exa_pixmap_priv *priv = (struct exa_pixmap_priv *)dPriv;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
if (!priv)
return;
- if (priv->tex)
- ms->screen->texture_destroy(priv->tex);
+ pipe_texture_reference(&priv->tex, NULL);
xfree(priv);
}
@@ -583,8 +671,8 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
struct pipe_surface *dst_surf;
struct pipe_surface *src_surf;
- dst_surf = exa->scrn->get_tex_surface(exa->scrn, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
+ dst_surf = exa->scrn->get_tex_surface(
+ exa->scrn, texture, 0, 0, 0, PIPE_BUFFER_USAGE_GPU_WRITE);
src_surf = exa_gpu_surface(exa, priv);
exa->pipe->surface_copy(exa->pipe, dst_surf, 0, 0, src_surf,
0, 0, min(width, texture->width[0]),
@@ -621,6 +709,8 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
#endif
pipe_texture_reference(&priv->tex, texture);
+ /* the texture we create has one reference */
+ pipe_texture_reference(&texture, NULL);
}
return TRUE;
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 43949b04a44..fe1f1cd103c 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -32,8 +32,11 @@ struct exa_context
struct exa_pixmap_priv *src;
struct exa_pixmap_priv *dst;
} copy;
-};
+ /* we should combine these two */
+ float vertices2[4][2][4];
+ float vertices3[4][3][4];
+};
struct exa_pixmap_priv
{
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
index 694eded09a2..bb5a42af37e 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -52,8 +52,7 @@ struct xorg_shaders {
static const char over_op[] =
"SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n"
- "MUL TEMP[3], TEMP[0], TEMP[3]\n"
- "ADD TEMP[0], TEMP[3], TEMP[0]\n";
+ "MAD TEMP[3], TEMP[0], TEMP[3], TEMP[0]\n";
static INLINE void
@@ -79,8 +78,7 @@ vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
{
struct ureg_dst tmp = ureg_DECL_temporary(ureg);
struct ureg_src ret;
- ureg_MUL(ureg, tmp, coords, const0);
- ureg_ADD(ureg, tmp, ureg_src(tmp), const1);
+ ureg_MAD(ureg, tmp, coords, const0, const1);
ret = ureg_src(tmp);
ureg_release_temporary(ureg, tmp);
return ret;
@@ -241,42 +239,39 @@ create_vs(struct pipe_context *pipe,
boolean is_fill = vs_traits & VS_FILL;
boolean is_composite = vs_traits & VS_COMPOSITE;
boolean has_mask = vs_traits & VS_MASK;
+ unsigned input_slot = 0;
ureg = ureg_create(TGSI_PROCESSOR_VERTEX);
if (ureg == NULL)
return 0;
- const0 = ureg_DECL_constant(ureg);
- const1 = ureg_DECL_constant(ureg);
+ const0 = ureg_DECL_constant(ureg, 0);
+ const1 = ureg_DECL_constant(ureg, 1);
/* it has to be either a fill or a composite op */
debug_assert(is_fill ^ is_composite);
- src = ureg_DECL_vs_input(ureg,
- TGSI_SEMANTIC_POSITION, 0);
+ src = ureg_DECL_vs_input(ureg, input_slot++);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 0);
src = vs_normalize_coords(ureg, src,
const0, const1);
ureg_MOV(ureg, dst, src);
-
if (is_composite) {
- src = ureg_DECL_vs_input(ureg,
- TGSI_SEMANTIC_GENERIC, 1);
- dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 1);
+ src = ureg_DECL_vs_input(ureg, input_slot++);
+ dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 0);
ureg_MOV(ureg, dst, src);
}
+
if (is_fill) {
- src = ureg_DECL_vs_input(ureg,
- TGSI_SEMANTIC_COLOR, 0);
+ src = ureg_DECL_vs_input(ureg, input_slot++);
dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_COLOR, 0);
ureg_MOV(ureg, dst, src);
}
if (has_mask) {
- src = ureg_DECL_vs_input(ureg,
- TGSI_SEMANTIC_GENERIC, 2);
- dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2);
+ src = ureg_DECL_vs_input(ureg, input_slot++);
+ dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_GENERIC, 2);
ureg_MOV(ureg, dst, src);
}
@@ -315,7 +310,7 @@ create_fs(struct pipe_context *pipe,
if (is_composite) {
src_sampler = ureg_DECL_sampler(ureg, 0);
src_input = ureg_DECL_fs_input(ureg,
- TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC,
0,
TGSI_INTERPOLATE_PERSPECTIVE);
} else {
@@ -335,7 +330,7 @@ create_fs(struct pipe_context *pipe,
if (has_mask) {
mask_sampler = ureg_DECL_sampler(ureg, 1);
mask_pos = ureg_DECL_fs_input(ureg,
- TGSI_SEMANTIC_POSITION,
+ TGSI_SEMANTIC_GENERIC,
1,
TGSI_INTERPOLATE_PERSPECTIVE);
}
@@ -370,11 +365,11 @@ create_fs(struct pipe_context *pipe,
else
src = out;
- coords = ureg_DECL_constant(ureg);
- const0124 = ureg_DECL_constant(ureg);
- matrow0 = ureg_DECL_constant(ureg);
- matrow1 = ureg_DECL_constant(ureg);
- matrow2 = ureg_DECL_constant(ureg);
+ coords = ureg_DECL_constant(ureg, 0);
+ const0124 = ureg_DECL_constant(ureg, 1);
+ matrow0 = ureg_DECL_constant(ureg, 2);
+ matrow1 = ureg_DECL_constant(ureg, 3);
+ matrow2 = ureg_DECL_constant(ureg, 4);
if (is_lingrad) {
linear_gradient(ureg, src,
@@ -470,7 +465,7 @@ struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc,
unsigned vs_traits,
unsigned fs_traits)
{
- struct xorg_shader shader = {0};
+ struct xorg_shader shader = { NULL, NULL };
void *vs, *fs;
vs = shader_from_cache(sc->exa->pipe, PIPE_SHADER_VERTEX,
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 950af942f5b..26f45f8d645 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -42,8 +42,12 @@
#include <sys/stat.h>
#include <sys/types.h>
+#ifdef HAVE_XEXTPROTO_71
+#include <X11/extensions/dpmsconst.h>
+#else
#define DPMS_SERVER
#include <X11/extensions/dpms.h>
+#endif
#include "X11/Xatom.h"
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index b1ab783a15a..2f7050bcb74 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -151,5 +151,11 @@ crtc_cursor_destroy(xf86CrtcPtr crtc);
void
output_init(ScrnInfoPtr pScrn);
+/***********************************************************************
+ * xorg_xv.c
+ */
+void
+xorg_init_video(ScreenPtr pScreen);
+
#endif /* _XORG_TRACKER_H_ */
diff --git a/src/gallium/state_trackers/xorg/xorg_xv.c b/src/gallium/state_trackers/xorg/xorg_xv.c
new file mode 100644
index 00000000000..88955d47fd3
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xorg_xv.c
@@ -0,0 +1,212 @@
+#include "xorg_tracker.h"
+
+#include <xf86xv.h>
+#include <X11/extensions/Xv.h>
+#include <fourcc.h>
+
+/*XXX get these from pipe's texture limits */
+#define IMAGE_MAX_WIDTH 2048
+#define IMAGE_MAX_HEIGHT 2048
+
+#define MAKE_ATOM(a) MakeAtom(a, sizeof(a) - 1, TRUE)
+
+static Atom xvBrightness, xvContrast;
+
+#define NUM_TEXTURED_ATTRIBUTES 2
+static XF86AttributeRec TexturedAttributes[NUM_TEXTURED_ATTRIBUTES] = {
+ {XvSettable | XvGettable, -128, 127, "XV_BRIGHTNESS"},
+ {XvSettable | XvGettable, 0, 255, "XV_CONTRAST"}
+};
+
+#define NUM_FORMATS 3
+static XF86VideoFormatRec Formats[NUM_FORMATS] = {
+ {15, TrueColor}, {16, TrueColor}, {24, TrueColor}
+};
+
+static XF86VideoEncodingRec DummyEncoding[1] = {
+ {
+ 0,
+ "XV_IMAGE",
+ IMAGE_MAX_WIDTH, IMAGE_MAX_HEIGHT,
+ {1, 1}
+ }
+};
+
+#define NUM_IMAGES 2
+static XF86ImageRec Images[NUM_IMAGES] = {
+ XVIMAGE_UYVY,
+ XVIMAGE_YUY2,
+};
+
+struct xorg_xv_port_priv {
+ RegionRec clip;
+};
+
+
+static void
+stop_video(ScrnInfoPtr pScrn, pointer data, Bool shutdown)
+{
+}
+
+static int
+set_port_attribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 value, pointer data)
+{
+ return 0;
+}
+
+static int
+get_port_attribute(ScrnInfoPtr pScrn,
+ Atom attribute, INT32 * value, pointer data)
+{
+ return 0;
+}
+
+static void
+query_best_size(ScrnInfoPtr pScrn,
+ Bool motion,
+ short vid_w, short vid_h,
+ short drw_w, short drw_h,
+ unsigned int *p_w, unsigned int *p_h, pointer data)
+{
+}
+
+static int
+put_image(ScrnInfoPtr pScrn,
+ short src_x, short src_y,
+ short drw_x, short drw_y,
+ short src_w, short src_h,
+ short drw_w, short drw_h,
+ int id, unsigned char *buf,
+ short width, short height,
+ Bool sync, RegionPtr clipBoxes, pointer data,
+ DrawablePtr pDraw)
+{
+ return 0;
+}
+
+static int
+query_image_attributes(ScrnInfoPtr pScrn,
+ int id,
+ unsigned short *w, unsigned short *h,
+ int *pitches, int *offsets)
+{
+ return 0;
+}
+
+static struct xorg_xv_port_priv *
+port_priv_create(ScreenPtr pScreen)
+{
+ /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
+ /*modesettingPtr ms = modesettingPTR(pScrn);*/
+ struct xorg_xv_port_priv *priv = NULL;
+
+ priv = calloc(1, sizeof(struct xorg_xv_port_priv));
+
+ if (!priv)
+ return NULL;
+
+ REGION_NULL(pScreen, &priv->clip);
+
+ return priv;
+}
+
+static XF86VideoAdaptorPtr
+xorg_setup_textured_adapter(ScreenPtr pScreen)
+{
+ /*ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];*/
+ /*modesettingPtr ms = modesettingPTR(pScrn);*/
+ XF86VideoAdaptorPtr adapt;
+ XF86AttributePtr attrs;
+ DevUnion *dev_unions;
+ int nports = 16, i;
+ int nattributes;
+
+ nattributes = NUM_TEXTURED_ATTRIBUTES;
+
+ adapt = calloc(1, sizeof(XF86VideoAdaptorRec));
+ dev_unions = calloc(nports, sizeof(DevUnion));
+ attrs = calloc(nattributes, sizeof(XF86AttributeRec));
+ if (adapt == NULL || dev_unions == NULL || attrs == NULL) {
+ free(adapt);
+ free(dev_unions);
+ free(attrs);
+ return NULL;
+ }
+
+ adapt->type = XvWindowMask | XvInputMask | XvImageMask;
+ adapt->flags = 0;
+ adapt->name = "Gallium3D Textured Video";
+ adapt->nEncodings = 1;
+ adapt->pEncodings = DummyEncoding;
+ adapt->nFormats = NUM_FORMATS;
+ adapt->pFormats = Formats;
+ adapt->nPorts = 0;
+ adapt->pPortPrivates = dev_unions;
+ adapt->nAttributes = nattributes;
+ adapt->pAttributes = attrs;
+ memcpy(attrs, TexturedAttributes, nattributes * sizeof(XF86AttributeRec));
+ adapt->nImages = NUM_IMAGES;
+ adapt->pImages = Images;
+ adapt->PutVideo = NULL;
+ adapt->PutStill = NULL;
+ adapt->GetVideo = NULL;
+ adapt->GetStill = NULL;
+ adapt->StopVideo = stop_video;
+ adapt->SetPortAttribute = set_port_attribute;
+ adapt->GetPortAttribute = get_port_attribute;
+ adapt->QueryBestSize = query_best_size;
+ adapt->PutImage = put_image;
+ adapt->QueryImageAttributes = query_image_attributes;
+
+ for (i = 0; i < nports; i++) {
+ struct xorg_xv_port_priv *priv =
+ port_priv_create(pScreen);
+
+ adapt->pPortPrivates[i].ptr = (pointer) (priv);
+ adapt->nPorts++;
+ }
+
+ return adapt;
+}
+
+void
+xorg_init_video(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ /*modesettingPtr ms = modesettingPTR(pScrn);*/
+ XF86VideoAdaptorPtr *adaptors, *new_adaptors = NULL;
+ XF86VideoAdaptorPtr textured_adapter;
+ int num_adaptors;
+
+ num_adaptors = xf86XVListGenericAdaptors(pScrn, &adaptors);
+ new_adaptors = malloc((num_adaptors + 1) * sizeof(XF86VideoAdaptorPtr *));
+ if (new_adaptors == NULL)
+ return;
+
+ memcpy(new_adaptors, adaptors, num_adaptors * sizeof(XF86VideoAdaptorPtr));
+ adaptors = new_adaptors;
+
+ /* Add the adaptors supported by our hardware. First, set up the atoms
+ * that will be used by both output adaptors.
+ */
+ xvBrightness = MAKE_ATOM("XV_BRIGHTNESS");
+ xvContrast = MAKE_ATOM("XV_CONTRAST");
+
+ textured_adapter = xorg_setup_textured_adapter(pScreen);
+
+ debug_assert(textured_adapter);
+
+ if (textured_adapter) {
+ adaptors[num_adaptors++] = textured_adapter;
+ }
+
+ if (num_adaptors) {
+ xf86XVScreenInit(pScreen, adaptors, num_adaptors);
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "Disabling Xv because no adaptors could be initialized.\n");
+ }
+
+ free(adaptors);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
index 4c5a1d2ea89..0fd5cdd9697 100644
--- a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -7,6 +7,7 @@
#include "i915simple/i915_context.h"
#include "i915simple/i915_screen.h"
+#include "trace/tr_drm.h"
/*
* Helper functions
@@ -198,5 +199,5 @@ struct drm_api intel_drm_api =
struct drm_api *
drm_api_create()
{
- return &intel_drm_api;
+ return trace_drm_create(&intel_drm_api);
}
diff --git a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
index 091cbbcfed1..117ca6059bb 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -112,7 +112,7 @@ nouveau_drm_create_screen(struct drm_api *api, int fd,
return NULL;
}
- if (arg->mode == DRM_CREATE_DRI1) {
+ if (arg && arg->mode == DRM_CREATE_DRI1) {
struct nouveau_dri *nvdri = dri1->ddx_info;
enum pipe_format format;
diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile
new file mode 100644
index 00000000000..f0d3b337e83
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/xorg/Makefile
@@ -0,0 +1,61 @@
+TARGET = modesetting_drv.so
+CFILES = $(wildcard ./*.c)
+OBJECTS = $(patsubst ./%.c,./%.o,$(CFILES))
+TOP = ../../../../../..
+
+include $(TOP)/configs/current
+
+INCLUDES = \
+ $(shell pkg-config --cflags-only-I pixman-1 xorg-server libdrm xproto) \
+ -I../gem \
+ -I$(TOP)/src/gallium/include \
+ -I$(TOP)/src/gallium/drivers \
+ -I$(TOP)/src/gallium/auxiliary \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/include \
+ -I$(TOP)/src/egl/main
+
+LIBS = \
+ $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
+ $(TOP)/src/gallium/winsys/drm/nouveau/drm/libnouveaudrm.a \
+ $(TOP)/src/gallium/drivers/nv04/libnv04.a \
+ $(TOP)/src/gallium/drivers/nv10/libnv10.a \
+ $(TOP)/src/gallium/drivers/nv20/libnv20.a \
+ $(TOP)/src/gallium/drivers/nv30/libnv30.a \
+ $(TOP)/src/gallium/drivers/nv40/libnv40.a \
+ $(TOP)/src/gallium/drivers/nv50/libnv50.a \
+ $(TOP)/src/gallium/drivers/nouveau/libnouveau.a \
+ $(GALLIUM_AUXILIARIES)
+
+DRIVER_DEFINES = \
+ -DHAVE_CONFIG_H
+
+
+#############################################
+
+
+
+all default: $(TARGET)
+
+$(TARGET): $(OBJECTS) Makefile $(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a $(LIBS)
+ $(TOP)/bin/mklib -noprefix -o $@ \
+ $(OBJECTS) $(LIBS) $(shell pkg-config --libs libdrm) -ldrm_nouveau
+
+clean:
+ rm -rf $(OBJECTS) $(TARGET)
+
+install:
+ $(INSTALL) -d $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+ $(MINSTALL) -m 755 $(TARGET) $(DESTDIR)/$(XORG_DRIVER_INSTALL_DIR)
+
+
+##############################################
+
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCLUDES) $(DRIVER_DEFINES) $< -o $@
+
+
+##############################################
+
+.PHONY = all clean install
diff --git a/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
new file mode 100644
index 00000000000..a669b3080aa
--- /dev/null
+++ b/src/gallium/winsys/drm/nouveau/xorg/nouveau_xorg.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Author: Alan Hourihane <[email protected]>
+ * Author: Jakob Bornecrantz <[email protected]>
+ *
+ */
+
+#include "../../../../state_trackers/xorg/xorg_winsys.h"
+
+static void nouveau_xorg_identify(int flags);
+static Bool nouveau_xorg_pci_probe(DriverPtr driver, int entity_num,
+ struct pci_device *device,
+ intptr_t match_data);
+
+static const struct pci_id_match nouveau_xorg_device_match[] = {
+ { 0x10de, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ 0x00030000, 0x00ffffff, 0 },
+ { 0x12d2, PCI_MATCH_ANY, PCI_MATCH_ANY, PCI_MATCH_ANY,
+ 0x00030000, 0x00ffffff, 0 },
+ {0, 0, 0},
+};
+
+static SymTabRec nouveau_xorg_chipsets[] = {
+ {PCI_MATCH_ANY, "NVIDIA Graphics Device"},
+ {-1, NULL}
+};
+
+static PciChipsets nouveau_xorg_pci_devices[] = {
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
+};
+
+static XF86ModuleVersionInfo nouveau_xorg_version = {
+ "modesetting",
+ MODULEVENDORSTRING,
+ MODINFOSTRING1,
+ MODINFOSTRING2,
+ XORG_VERSION_CURRENT,
+ 0, 1, 0, /* major, minor, patch */
+ ABI_CLASS_VIDEODRV,
+ ABI_VIDEODRV_VERSION,
+ MOD_CLASS_VIDEODRV,
+ {0, 0, 0, 0}
+};
+
+/*
+ * Xorg driver exported structures
+ */
+
+_X_EXPORT DriverRec modesetting = {
+ 1,
+ "modesetting",
+ nouveau_xorg_identify,
+ NULL,
+ xorg_tracker_available_options,
+ NULL,
+ 0,
+ NULL,
+ nouveau_xorg_device_match,
+ nouveau_xorg_pci_probe
+};
+
+static MODULESETUPPROTO(nouveau_xorg_setup);
+
+_X_EXPORT XF86ModuleData modesettingModuleData = {
+ &nouveau_xorg_version,
+ nouveau_xorg_setup,
+ NULL
+};
+
+/*
+ * Xorg driver functions
+ */
+
+static pointer
+nouveau_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
+{
+ static Bool setupDone = 0;
+
+ /* This module should be loaded only once, but check to be sure.
+ */
+ if (!setupDone) {
+ setupDone = 1;
+ xf86AddDriver(&modesetting, module, HaveDriverFuncs);
+
+ /*
+ * The return value must be non-NULL on success even though there
+ * is no TearDownProc.
+ */
+ return (pointer) 1;
+ } else {
+ if (errmaj)
+ *errmaj = LDR_ONCEONLY;
+ return NULL;
+ }
+}
+
+static void
+nouveau_xorg_identify(int flags)
+{
+ xf86PrintChipsets("modesetting", "Driver for Modesetting Kernel Drivers",
+ nouveau_xorg_chipsets);
+}
+
+static Bool
+nouveau_xorg_pci_probe(DriverPtr driver,
+ int entity_num, struct pci_device *device, intptr_t match_data)
+{
+ ScrnInfoPtr scrn = NULL;
+ EntityInfoPtr entity;
+
+ scrn = xf86ConfigPciEntity(scrn, 0, entity_num, nouveau_xorg_pci_devices,
+ NULL, NULL, NULL, NULL, NULL);
+ if (scrn != NULL) {
+ scrn->driverVersion = 1;
+ scrn->driverName = "i915";
+ scrn->name = "modesetting";
+ scrn->Probe = NULL;
+
+ entity = xf86GetEntityInfo(entity_num);
+
+ /* Use all the functions from the xorg tracker */
+ xorg_tracker_set_functions(scrn);
+ }
+ return scrn != NULL;
+}
diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c
index 698c2856a4f..37d60ce5406 100644
--- a/src/gallium/winsys/g3dvl/xsp_winsys.c
+++ b/src/gallium/winsys/g3dvl/xsp_winsys.c
@@ -105,6 +105,7 @@ static struct pipe_buffer* xsp_surface_buffer_create
unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride
)
{
diff --git a/src/gallium/winsys/gdi/SConscript b/src/gallium/winsys/gdi/SConscript
index 86eb9ef55ed..f5e6d36d89c 100644
--- a/src/gallium/winsys/gdi/SConscript
+++ b/src/gallium/winsys/gdi/SConscript
@@ -5,35 +5,39 @@ Import('*')
if env['platform'] == 'windows':
- env = env.Clone()
+ env = env.Clone()
- env.Append(CPPPATH = [
- '#src/gallium/state_trackers/wgl',
- ])
+ env.Append(CPPPATH = [
+ '#src/gallium/state_trackers/wgl',
+ ])
- env.Append(LIBS = [
- 'gdi32',
- 'user32',
- 'kernel32',
- 'ws2_32',
- ])
+ env.Append(LIBS = [
+ 'gdi32',
+ 'user32',
+ 'kernel32',
+ 'ws2_32',
+ ])
- sources = [
- 'gdi_softpipe_winsys.c',
- ]
-
- if env['gcc']:
- sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
- else:
- sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
-
- drivers = [
- trace,
- softpipe,
- ]
+ if 'llvmpipe' in env['drivers']:
+ sources = ['gdi_llvmpipe_winsys.c']
+ drivers = [llvmpipe]
+ env.Tool('llvm')
+ elif 'softpipe' in env['drivers']:
+ sources = ['gdi_softpipe_winsys.c']
+ drivers = [softpipe]
+ else:
+ print 'warning: softpipe or llvmpipe not selected, gdi winsys disabled'
+ Return()
+
+ if env['gcc']:
+ sources += ['#src/gallium/state_trackers/wgl/opengl32.mingw.def']
+ else:
+ sources += ['#src/gallium/state_trackers/wgl/opengl32.def']
+
+ drivers += [trace]
- env.SharedLibrary(
- target ='opengl32',
- source = sources,
- LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'],
- )
+ env.SharedLibrary(
+ target ='opengl32',
+ source = sources,
+ LIBS = wgl + glapi + mesa + drivers + auxiliaries + env['LIBS'],
+ )
diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
new file mode 100644
index 00000000000..e8bc0f55ac4
--- /dev/null
+++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
@@ -0,0 +1,288 @@
+/**************************************************************************
+ *
+ * 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 SOFTWARE IS PROVIDED "AS 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
+ * LLVMpipe support.
+ *
+ * @author Jose Fonseca <[email protected]>
+ */
+
+
+#include <windows.h>
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_inlines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "llvmpipe/lp_winsys.h"
+#include "llvmpipe/lp_texture.h"
+#include "stw_winsys.h"
+
+
+struct gdi_llvmpipe_displaytarget
+{
+ enum pipe_format format;
+ struct pipe_format_block block;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ unsigned size;
+
+ void *data;
+
+ BITMAPINFO bmi;
+};
+
+
+/** Cast wrapper */
+static INLINE struct gdi_llvmpipe_displaytarget *
+gdi_llvmpipe_displaytarget( struct llvmpipe_displaytarget *buf )
+{
+ return (struct gdi_llvmpipe_displaytarget *)buf;
+}
+
+
+static boolean
+gdi_llvmpipe_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+ enum pipe_format format )
+{
+ switch(format) {
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ return TRUE;
+
+ /* TODO: Support other formats possible with BMPs, as described in
+ * http://msdn.microsoft.com/en-us/library/dd183376(VS.85).aspx */
+
+ default:
+ return FALSE;
+ }
+}
+
+
+static void *
+gdi_llvmpipe_displaytarget_map(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt,
+ unsigned flags )
+{
+ struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+
+ return gdt->data;
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_unmap(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt )
+{
+
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_destroy(struct llvmpipe_winsys *winsys,
+ struct llvmpipe_displaytarget *dt)
+{
+ struct gdi_llvmpipe_displaytarget *gdt = gdi_llvmpipe_displaytarget(dt);
+
+ align_free(gdt->data);
+ FREE(gdt);
+}
+
+
+/**
+ * Round n up to next multiple.
+ */
+static INLINE unsigned
+round_up(unsigned n, unsigned multiple)
+{
+ return (n + multiple - 1) & ~(multiple - 1);
+}
+
+
+static struct llvmpipe_displaytarget *
+gdi_llvmpipe_displaytarget_create(struct llvmpipe_winsys *winsys,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct gdi_llvmpipe_displaytarget *gdt;
+ unsigned cpp;
+ unsigned bpp;
+
+ gdt = CALLOC_STRUCT(gdi_llvmpipe_displaytarget);
+ if(!gdt)
+ goto no_gdt;
+
+ gdt->format = format;
+ gdt->width = width;
+ gdt->height = height;
+
+ bpp = pf_get_bits(format);
+ cpp = pf_get_size(format);
+
+ gdt->stride = round_up(width * cpp, alignment);
+ gdt->size = gdt->stride * height;
+
+ gdt->data = align_malloc(gdt->size, alignment);
+ if(!gdt->data)
+ goto no_data;
+
+ gdt->bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
+ gdt->bmi.bmiHeader.biWidth = gdt->stride / cpp;
+ gdt->bmi.bmiHeader.biHeight= -(long)height;
+ gdt->bmi.bmiHeader.biPlanes = 1;
+ gdt->bmi.bmiHeader.biBitCount = bpp;
+ gdt->bmi.bmiHeader.biCompression = BI_RGB;
+ gdt->bmi.bmiHeader.biSizeImage = 0;
+ gdt->bmi.bmiHeader.biXPelsPerMeter = 0;
+ gdt->bmi.bmiHeader.biYPelsPerMeter = 0;
+ gdt->bmi.bmiHeader.biClrUsed = 0;
+ gdt->bmi.bmiHeader.biClrImportant = 0;
+
+ *stride = gdt->stride;
+ return (struct llvmpipe_displaytarget *)gdt;
+
+no_data:
+ FREE(gdt);
+no_gdt:
+ return NULL;
+}
+
+
+static void
+gdi_llvmpipe_displaytarget_display(struct llvmpipe_winsys *winsys,
+ struct llvmpipe_displaytarget *dt,
+ void *context_private)
+{
+ assert(0);
+}
+
+
+static void
+gdi_llvmpipe_destroy(struct llvmpipe_winsys *winsys)
+{
+ FREE(winsys);
+}
+
+
+static struct pipe_screen *
+gdi_llvmpipe_screen_create(void)
+{
+ static struct llvmpipe_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = CALLOC_STRUCT(llvmpipe_winsys);
+ if(!winsys)
+ goto no_winsys;
+
+ winsys->destroy = gdi_llvmpipe_destroy;
+ winsys->is_displaytarget_format_supported = gdi_llvmpipe_is_displaytarget_format_supported;
+ winsys->displaytarget_create = gdi_llvmpipe_displaytarget_create;
+ winsys->displaytarget_map = gdi_llvmpipe_displaytarget_map;
+ winsys->displaytarget_unmap = gdi_llvmpipe_displaytarget_unmap;
+ winsys->displaytarget_display = gdi_llvmpipe_displaytarget_display;
+ winsys->displaytarget_destroy = gdi_llvmpipe_displaytarget_destroy;
+
+ screen = llvmpipe_create_screen(winsys);
+ if(!screen)
+ goto no_screen;
+
+ return screen;
+
+no_screen:
+ FREE(winsys);
+no_winsys:
+ return NULL;
+}
+
+
+static struct pipe_context *
+gdi_llvmpipe_context_create(struct pipe_screen *screen)
+{
+ return llvmpipe_create(screen);
+}
+
+
+static void
+gdi_llvmpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
+{
+ struct llvmpipe_texture *texture;
+ struct gdi_llvmpipe_displaytarget *gdt;
+
+ texture = llvmpipe_texture(surface->texture);
+ gdt = gdi_llvmpipe_displaytarget(texture->dt);
+
+ StretchDIBits(hDC,
+ 0, 0, gdt->width, gdt->height,
+ 0, 0, gdt->width, gdt->height,
+ gdt->data, &gdt->bmi, 0, SRCCOPY);
+}
+
+
+static const struct stw_winsys stw_winsys = {
+ &gdi_llvmpipe_screen_create,
+ &gdi_llvmpipe_context_create,
+ &gdi_llvmpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
+};
+
+
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+ switch (fdwReason) {
+ case DLL_PROCESS_ATTACH:
+ if (!stw_init(&stw_winsys)) {
+ return FALSE;
+ }
+ return stw_init_thread();
+
+ case DLL_THREAD_ATTACH:
+ return stw_init_thread();
+
+ case DLL_THREAD_DETACH:
+ stw_cleanup_thread();
+ break;
+
+ case DLL_PROCESS_DETACH:
+ stw_cleanup_thread();
+ stw_cleanup();
+ break;
+ }
+ return TRUE;
+}
diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
index 66120a6a983..5e0ccf32f48 100644
--- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
+++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c
@@ -46,7 +46,7 @@
#include "util/u_memory.h"
#include "softpipe/sp_winsys.h"
#include "softpipe/sp_texture.h"
-#include "shared/stw_winsys.h"
+#include "stw_winsys.h"
struct gdi_softpipe_buffer
@@ -269,9 +269,9 @@ gdi_softpipe_context_create(struct pipe_screen *screen)
static void
-gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen,
- struct pipe_surface *surface,
- HDC hDC)
+gdi_softpipe_present(struct pipe_screen *screen,
+ struct pipe_surface *surface,
+ HDC hDC)
{
struct softpipe_texture *texture;
struct gdi_softpipe_buffer *buffer;
@@ -304,7 +304,11 @@ gdi_softpipe_flush_frontbuffer(struct pipe_screen *screen,
static const struct stw_winsys stw_winsys = {
&gdi_softpipe_screen_create,
&gdi_softpipe_context_create,
- &gdi_softpipe_flush_frontbuffer
+ &gdi_softpipe_present,
+ NULL, /* get_adapter_luid */
+ NULL, /* shared_surface_open */
+ NULL, /* shared_surface_close */
+ NULL /* compose */
};
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 522f6dc5aee..3a1945d92c5 100644
--- a/src/gallium/winsys/xlib/Makefile
+++ b/src/gallium/winsys/xlib/Makefile
@@ -34,6 +34,7 @@ XLIB_WINSYS_SOURCES = \
xlib_brw_aub.c \
xlib_brw_context.c \
xlib_brw_screen.c \
+ xlib_llvmpipe.c \
xlib_softpipe.c \
xlib_trace.c
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c
index bc876591c0d..3dd15e099b0 100644
--- a/src/gallium/winsys/xlib/xlib_llvmpipe.c
+++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c
@@ -33,6 +33,8 @@
*/
+#if defined(GALLIUM_LLVMPIPE)
+
#include "xm_api.h"
#undef ASSERT
@@ -459,3 +461,4 @@ struct xm_driver xlib_llvmpipe_driver =
+#endif /* GALLIUM_LLVMPIPE */
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 67fea023a3b..260b39e2a0f 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -75,9 +75,6 @@ struct xmesa_pipe_winsys
{
struct pipe_winsys base;
/* struct xmesa_visual *xm_visual; */
-#ifdef USE_XSHM
- int shm;
-#endif
};
@@ -93,11 +90,6 @@ xm_buffer( struct pipe_buffer *buf )
/**
* X Shared Memory Image extension code
*/
-#ifdef USE_XSHM
-#define XSHM_ENABLED(b) ((b)->shm)
-#else
-#define XSHM_ENABLED(b) 0
-#endif
#ifdef USE_XSHM
@@ -116,23 +108,23 @@ mesaHandleXError(Display *dpy, XErrorEvent *event)
}
-static GLboolean alloc_shm(struct xm_buffer *buf, unsigned size)
+static char *alloc_shm(struct xm_buffer *buf, unsigned size)
{
XShmSegmentInfo *const shminfo = & buf->shminfo;
shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
if (shminfo->shmid < 0) {
- return GL_FALSE;
+ return NULL;
}
shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
if (shminfo->shmaddr == (char *) -1) {
shmctl(shminfo->shmid, IPC_RMID, 0);
- return GL_FALSE;
+ return NULL;
}
shminfo->readOnly = False;
- return GL_TRUE;
+ return shminfo->shmaddr;
}
@@ -258,25 +250,30 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
return;
#ifdef USE_XSHM
- if (XSHM_ENABLED(xm_buf) && (xm_buf->tempImage == NULL)) {
- assert(surf->texture->block.width == 1);
- assert(surf->texture->block.height == 1);
- alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
- surf->texture->block.size, surf->height);
- }
-#endif
+ if (xm_buf->shm)
+ {
+ if (xm_buf->tempImage == NULL)
+ {
+ assert(surf->texture->block.width == 1);
+ assert(surf->texture->block.height == 1);
+ alloc_shm_ximage(xm_buf, b, spt->stride[surf->level] /
+ surf->texture->block.size, surf->height);
+ }
- ximage = (XSHM_ENABLED(xm_buf)) ? xm_buf->tempImage : b->tempImage;
- ximage->data = xm_buf->data;
+ ximage = xm_buf->tempImage;
+ ximage->data = xm_buf->data;
- /* display image in Window */
-#ifdef USE_XSHM
- if (XSHM_ENABLED(xm_buf)) {
+ /* _debug_printf("XSHM\n"); */
XShmPutImage(b->xm_visual->display, b->drawable, b->gc,
ximage, 0, 0, 0, 0, surf->width, surf->height, False);
- } else
+ }
+ else
#endif
{
+ /* display image in Window */
+ ximage = b->tempImage;
+ ximage->data = xm_buf->data;
+
/* check that the XImage has been previously initialized */
assert(ximage->format);
assert(ximage->bitmap_unit);
@@ -286,6 +283,7 @@ xlib_softpipe_display_surface(struct xmesa_buffer *b,
ximage->height = surf->height;
ximage->bytes_per_line = spt->stride[surf->level];
+ /* _debug_printf("XPUT\n"); */
XPutImage(b->xm_visual->display, b->drawable, b->gc,
ximage, 0, 0, 0, 0, surf->width, surf->height);
}
@@ -322,21 +320,6 @@ xm_buffer_create(struct pipe_winsys *pws,
unsigned size)
{
struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
-#ifdef USE_XSHM
- struct xmesa_pipe_winsys *xpws = (struct xmesa_pipe_winsys *) pws;
-
- buffer->shminfo.shmid = -1;
- buffer->shminfo.shmaddr = (char *) -1;
-
- if (xpws->shm && (usage & PIPE_BUFFER_USAGE_PIXEL) != 0) {
- buffer->shm = xpws->shm;
-
- if (alloc_shm(buffer, size)) {
- buffer->data = buffer->shminfo.shmaddr;
- buffer->shm = 1;
- }
- }
-#endif
pipe_reference_init(&buffer->base.reference, 1);
buffer->base.alignment = alignment;
@@ -363,9 +346,6 @@ xm_user_buffer_create(struct pipe_winsys *pws, void *ptr, unsigned bytes)
buffer->base.size = bytes;
buffer->userBuffer = TRUE;
buffer->data = ptr;
-#ifdef USE_XSHM
- buffer->shm = 0;
-#endif
return &buffer->base;
}
@@ -381,16 +361,44 @@ xm_surface_buffer_create(struct pipe_winsys *winsys,
{
const unsigned alignment = 64;
struct pipe_format_block block;
- unsigned nblocksx, nblocksy;
+ unsigned nblocksx, nblocksy, size;
pf_get_block(format, &block);
nblocksx = pf_get_nblocksx(&block, width);
nblocksy = pf_get_nblocksy(&block, height);
*stride = align(nblocksx * block.size, alignment);
+ size = *stride * nblocksy;
+
+#ifdef USE_XSHM
+ if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
+ {
+ struct xm_buffer *buffer = CALLOC_STRUCT(xm_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.alignment = alignment;
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+ buffer->userBuffer = FALSE;
+ buffer->shminfo.shmid = -1;
+ buffer->shminfo.shmaddr = (char *) -1;
+ buffer->shm = TRUE;
+
+ buffer->data = alloc_shm(buffer, size);
+ if (!buffer->data)
+ goto out;
+
+ return &buffer->base;
+
+ out:
+ if (buffer)
+ FREE(buffer);
+ }
+#endif
+
return winsys->buffer_create(winsys, alignment,
usage,
- *stride * nblocksy);
+ size);
}
diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c
index 88a17df6f8d..501500afc3d 100644
--- a/src/glx/x11/glx_pbuffer.c
+++ b/src/glx/x11/glx_pbuffer.c
@@ -39,6 +39,30 @@
#include "glxextensions.h"
#include "glcontextmodes.h"
+#define WARN_ONCE_GLX_1_3(a, b) { \
+ static int warned=1; \
+ if(warned) { \
+ warn_GLX_1_3((a), b ); \
+ warned=0; \
+ } \
+ }
+
+/**
+ * Emit a warning when clients use GLX 1.3 functions on pre-1.3 systems.
+ */
+static void
+warn_GLX_1_3(Display *dpy, const char *function_name)
+{
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+
+ if (priv->minorVersion < 3) {
+ fprintf(stderr,
+ "WARNING: Application calling GLX 1.3 function \"%s\" "
+ "when GLX 1.3 is not supported! This is an application bug!\n",
+ function_name);
+ }
+}
+
/**
* Change a drawable's attribute.
@@ -559,6 +583,8 @@ glXCreatePbuffer(Display * dpy, GLXFBConfig config, const int *attrib_list)
width = 0;
height = 0;
+ WARN_ONCE_GLX_1_3(dpy, __func__);
+
for (i = 0; attrib_list[i * 2]; i++) {
switch (attrib_list[i * 2]) {
case GLX_PBUFFER_WIDTH:
@@ -592,6 +618,7 @@ PUBLIC void
glXQueryDrawable(Display * dpy, GLXDrawable drawable,
int attribute, unsigned int *value)
{
+ WARN_ONCE_GLX_1_3(dpy, __func__);
GetDrawableAttribute(dpy, drawable, attribute, value);
}
@@ -645,6 +672,8 @@ PUBLIC GLXPixmap
glXCreatePixmap(Display * dpy, GLXFBConfig config, Pixmap pixmap,
const int *attrib_list)
{
+ WARN_ONCE_GLX_1_3(dpy, __func__);
+
return CreateDrawable(dpy, (__GLcontextModes *) config,
(Drawable) pixmap, attrib_list, X_GLXCreatePixmap);
}
@@ -654,6 +683,8 @@ PUBLIC GLXWindow
glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
const int *attrib_list)
{
+ WARN_ONCE_GLX_1_3(dpy, __func__);
+
return CreateDrawable(dpy, (__GLcontextModes *) config,
(Drawable) win, attrib_list, X_GLXCreateWindow);
}
@@ -662,6 +693,8 @@ glXCreateWindow(Display * dpy, GLXFBConfig config, Window win,
PUBLIC void
glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
{
+ WARN_ONCE_GLX_1_3(dpy, __func__);
+
DestroyDrawable(dpy, (GLXDrawable) pixmap, X_GLXDestroyPixmap);
}
@@ -669,6 +702,8 @@ glXDestroyPixmap(Display * dpy, GLXPixmap pixmap)
PUBLIC void
glXDestroyWindow(Display * dpy, GLXWindow win)
{
+ WARN_ONCE_GLX_1_3(dpy, __func__);
+
DestroyDrawable(dpy, (GLXDrawable) win, X_GLXDestroyWindow);
}
@@ -688,3 +723,4 @@ GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long *mask), (dpy, drawable, mask),
glXGetSelectedEvent)
+
diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c
index 74cd4f344df..6f2c51d39dd 100644
--- a/src/glx/x11/glxhash.c
+++ b/src/glx/x11/glxhash.c
@@ -77,6 +77,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#define HASH_MAGIC 0xdeadbeef
#define HASH_DEBUG 0
@@ -87,9 +88,13 @@
#define HASH_ALLOC malloc
#define HASH_FREE free
-#define HASH_RANDOM_DECL
-#define HASH_RANDOM_INIT(seed) srandom(seed)
-#define HASH_RANDOM random()
+#define HASH_RANDOM_DECL struct random_data rd; int32_t rv; char rs[256]
+#define HASH_RANDOM_INIT(seed) \
+ do { \
+ (void) memset(&rd, 0, sizeof(rd)); \
+ (void) initstate_r(seed, rs, sizeof(rs), &rd); \
+ } while(0)
+#define HASH_RANDOM ((void) random_r(&rd, &rv), rv)
#define HASH_RANDOM_DESTROY
typedef struct __glxHashBucket
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index a9f3c8e7271..f09106b77c3 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -56,6 +56,7 @@
#include "swrast/swrast.h"
#include "driverfuncs.h"
+#include "meta.h"
@@ -100,11 +101,11 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->TexSubImage2D = _mesa_store_texsubimage2d;
driver->TexSubImage3D = _mesa_store_texsubimage3d;
driver->GetTexImage = _mesa_get_teximage;
- driver->CopyTexImage1D = _swrast_copy_teximage1d;
- driver->CopyTexImage2D = _swrast_copy_teximage2d;
- driver->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- driver->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- driver->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+ driver->CopyTexImage1D = _mesa_meta_CopyTexImage1D;
+ driver->CopyTexImage2D = _mesa_meta_CopyTexImage2D;
+ driver->CopyTexSubImage1D = _mesa_meta_CopyTexSubImage1D;
+ driver->CopyTexSubImage2D = _mesa_meta_CopyTexSubImage2D;
+ driver->CopyTexSubImage3D = _mesa_meta_CopyTexSubImage3D;
driver->GenerateMipmap = _mesa_generate_mipmap;
driver->TestProxyTexImage = _mesa_test_proxy_teximage;
driver->CompressedTexImage1D = _mesa_store_compressed_teximage1d;
@@ -129,10 +130,10 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->UpdateTexturePalette = NULL;
/* imaging */
- driver->CopyColorTable = _swrast_CopyColorTable;
- driver->CopyColorSubTable = _swrast_CopyColorSubTable;
- driver->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
- driver->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+ driver->CopyColorTable = _mesa_meta_CopyColorTable;
+ driver->CopyColorSubTable = _mesa_meta_CopyColorSubTable;
+ driver->CopyConvolutionFilter1D = _mesa_meta_CopyConvolutionFilter1D;
+ driver->CopyConvolutionFilter2D = _mesa_meta_CopyConvolutionFilter2D;
/* Vertex/fragment programs */
driver->BindProgram = NULL;
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
index 0b9781027e7..b445323aabe 100644
--- a/src/mesa/drivers/common/meta.c
+++ b/src/mesa/drivers/common/meta.c
@@ -38,6 +38,8 @@
#include "main/blend.h"
#include "main/bufferobj.h"
#include "main/buffers.h"
+#include "main/colortab.h"
+#include "main/convolve.h"
#include "main/depth.h"
#include "main/enable.h"
#include "main/fbobject.h"
@@ -49,6 +51,7 @@
#include "main/readpix.h"
#include "main/scissor.h"
#include "main/shaders.h"
+#include "main/state.h"
#include "main/stencil.h"
#include "main/texobj.h"
#include "main/texenv.h"
@@ -63,6 +66,33 @@
#include "drivers/common/meta.h"
+/** Return offset in bytes of the field within a vertex struct */
+#define OFFSET(FIELD) ((void *) offsetof(struct vertex, FIELD))
+
+
+/**
+ * Flags passed to _mesa_meta_begin().
+ */
+/*@{*/
+#define META_ALL ~0x0
+#define META_ALPHA_TEST 0x1
+#define META_BLEND 0x2 /**< includes logicop */
+#define META_COLOR_MASK 0x4
+#define META_DEPTH_TEST 0x8
+#define META_FOG 0x10
+#define META_PIXEL_STORE 0x20
+#define META_PIXEL_TRANSFER 0x40
+#define META_RASTERIZATION 0x80
+#define META_SCISSOR 0x100
+#define META_SHADER 0x200
+#define META_STENCIL_TEST 0x400
+#define META_TRANSFORM 0x800 /**< modelview, projection, clip planes */
+#define META_TEXTURE 0x1000
+#define META_VERTEX 0x2000
+#define META_VIEWPORT 0x4000
+/*@}*/
+
+
/**
* State which we may save/restore across meta ops.
* XXX this may be incomplete...
@@ -90,6 +120,17 @@ struct save_state
/** META_PIXEL_STORE */
struct gl_pixelstore_attrib Pack, Unpack;
+ /** META_PIXEL_TRANSFER */
+ GLfloat RedBias, RedScale;
+ GLfloat GreenBias, GreenScale;
+ GLfloat BlueBias, BlueScale;
+ GLfloat AlphaBias, AlphaScale;
+ GLfloat DepthBias, DepthScale;
+ GLboolean MapColorFlag;
+ GLboolean Convolution1DEnabled;
+ GLboolean Convolution2DEnabled;
+ GLboolean Separable2DEnabled;
+
/** META_RASTERIZATION */
GLenum FrontPolygonMode, BackPolygonMode;
GLboolean PolygonOffset;
@@ -195,7 +236,6 @@ struct copypix_state
struct drawpix_state
{
GLuint ArrayObj;
- GLuint VBO;
GLuint StencilFP; /**< Fragment program for drawing stencil images */
GLuint DepthFP; /**< Fragment program for drawing depth images */
@@ -233,12 +273,12 @@ struct gl_meta_state
struct temp_texture TempTex;
- struct blit_state Blit; /**< For _mesa_meta_blit_framebuffer() */
- struct clear_state Clear; /**< For _mesa_meta_clear() */
- struct copypix_state CopyPix; /**< For _mesa_meta_copy_pixels() */
- struct drawpix_state DrawPix; /**< For _mesa_meta_draw_pixels() */
- struct bitmap_state Bitmap; /**< For _mesa_meta_bitmap() */
- struct gen_mipmap_state Mipmap; /**< For _mesa_meta_generate_mipmap() */
+ struct blit_state Blit; /**< For _mesa_meta_BlitFramebuffer() */
+ struct clear_state Clear; /**< For _mesa_meta_Clear() */
+ struct copypix_state CopyPix; /**< For _mesa_meta_CopyPixels() */
+ struct drawpix_state DrawPix; /**< For _mesa_meta_DrawPixels() */
+ struct bitmap_state Bitmap; /**< For _mesa_meta_Bitmap() */
+ struct gen_mipmap_state Mipmap; /**< For _mesa_meta_GenerateMipmap() */
};
@@ -286,7 +326,6 @@ _mesa_meta_free(GLcontext *ctx)
_mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
/* glDrawPixels */
- _mesa_DeleteBuffersARB(1, & meta->DrawPix.VBO);
_mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
_mesa_DeletePrograms(1, &meta->DrawPix.DepthFP);
_mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);
@@ -359,6 +398,35 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
ctx->Unpack = ctx->DefaultPacking;
}
+ if (state & META_PIXEL_TRANSFER) {
+ save->RedScale = ctx->Pixel.RedScale;
+ save->RedBias = ctx->Pixel.RedBias;
+ save->GreenScale = ctx->Pixel.GreenScale;
+ save->GreenBias = ctx->Pixel.GreenBias;
+ save->BlueScale = ctx->Pixel.BlueScale;
+ save->BlueBias = ctx->Pixel.BlueBias;
+ save->AlphaScale = ctx->Pixel.AlphaScale;
+ save->AlphaBias = ctx->Pixel.AlphaBias;
+ save->MapColorFlag = ctx->Pixel.MapColorFlag;
+ save->Convolution1DEnabled = ctx->Pixel.Convolution1DEnabled;
+ save->Convolution2DEnabled = ctx->Pixel.Convolution2DEnabled;
+ save->Separable2DEnabled = ctx->Pixel.Separable2DEnabled;
+ ctx->Pixel.RedScale = 1.0F;
+ ctx->Pixel.RedBias = 0.0F;
+ ctx->Pixel.GreenScale = 1.0F;
+ ctx->Pixel.GreenBias = 0.0F;
+ ctx->Pixel.BlueScale = 1.0F;
+ ctx->Pixel.BlueBias = 0.0F;
+ ctx->Pixel.AlphaScale = 1.0F;
+ ctx->Pixel.AlphaBias = 0.0F;
+ ctx->Pixel.MapColorFlag = GL_FALSE;
+ ctx->Pixel.Convolution1DEnabled = GL_FALSE;
+ ctx->Pixel.Convolution2DEnabled = GL_FALSE;
+ ctx->Pixel.Separable2DEnabled = GL_FALSE;
+ /* XXX more state */
+ ctx->NewState |=_NEW_PIXEL;
+ }
+
if (state & META_RASTERIZATION) {
save->FrontPolygonMode = ctx->Polygon.FrontMode;
save->BackPolygonMode = ctx->Polygon.BackMode;
@@ -411,11 +479,6 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
save->ClientActiveUnit = ctx->Array.ActiveTexture;
save->EnvMode = ctx->Texture.Unit[0].EnvMode;
- if (ctx->Texture._EnabledUnits |
- ctx->Texture._EnabledCoordUnits |
- ctx->Texture._TexGenEnabled |
- ctx->Texture._TexMatEnabled) {
-
/* Disable all texture units */
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
@@ -434,7 +497,6 @@ _mesa_meta_begin(GLcontext *ctx, GLbitfield state)
_mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_FALSE);
}
}
- }
/* save current texture objects for unit[0] only */
for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
@@ -560,6 +622,23 @@ _mesa_meta_end(GLcontext *ctx)
ctx->Unpack = save->Unpack;
}
+ if (state & META_PIXEL_TRANSFER) {
+ ctx->Pixel.RedScale = save->RedScale;
+ ctx->Pixel.RedBias = save->RedBias;
+ ctx->Pixel.GreenScale = save->GreenScale;
+ ctx->Pixel.GreenBias = save->GreenBias;
+ ctx->Pixel.BlueScale = save->BlueScale;
+ ctx->Pixel.BlueBias = save->BlueBias;
+ ctx->Pixel.AlphaScale = save->AlphaScale;
+ ctx->Pixel.AlphaBias = save->AlphaBias;
+ ctx->Pixel.MapColorFlag = save->MapColorFlag;
+ ctx->Pixel.Convolution1DEnabled = save->Convolution1DEnabled;
+ ctx->Pixel.Convolution2DEnabled = save->Convolution2DEnabled;
+ ctx->Pixel.Separable2DEnabled = save->Separable2DEnabled;
+ /* XXX more state */
+ ctx->NewState |=_NEW_PIXEL;
+ }
+
if (state & META_RASTERIZATION) {
_mesa_PolygonMode(GL_FRONT, save->FrontPolygonMode);
_mesa_PolygonMode(GL_BACK, save->BackPolygonMode);
@@ -691,7 +770,6 @@ _mesa_meta_end(GLcontext *ctx)
_mesa_MatrixMode(save->MatrixMode);
- save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
if (save->ClipPlanesEnabled) {
GLuint i;
for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
@@ -727,9 +805,6 @@ _mesa_meta_end(GLcontext *ctx)
if (save->Lighting) {
_mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
}
- if (save->Fog) {
- _mesa_set_enable(ctx, GL_FOG, GL_TRUE);
- }
}
@@ -974,10 +1049,10 @@ init_blit_depth_pixels(GLcontext *ctx)
* of texture mapping and polygon rendering.
*/
void
-_mesa_meta_blit_framebuffer(GLcontext *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
+_mesa_meta_BlitFramebuffer(GLcontext *ctx,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter)
{
struct blit_state *blit = &ctx->Meta->Blit;
struct temp_texture *tex = get_temp_texture(ctx);
@@ -988,7 +1063,10 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,
const GLint srcH = abs(srcY1 - srcY0);
const GLboolean srcFlipX = srcX1 < srcX0;
const GLboolean srcFlipY = srcY1 < srcY0;
- GLfloat verts[4][4]; /* four verts of X,Y,S,T */
+ struct vertex {
+ GLfloat x, y, s, t;
+ };
+ struct vertex verts[4];
GLboolean newTex;
if (srcW > maxTexSize || srcH > maxTexSize) {
@@ -1027,10 +1105,8 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (2 * sizeof(GLfloat)));
+ _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -1043,23 +1119,23 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,
/* vertex positions/texcoords (after texture allocation!) */
{
- verts[0][0] = (GLfloat) dstX0;
- verts[0][1] = (GLfloat) dstY0;
- verts[1][0] = (GLfloat) dstX1;
- verts[1][1] = (GLfloat) dstY0;
- verts[2][0] = (GLfloat) dstX1;
- verts[2][1] = (GLfloat) dstY1;
- verts[3][0] = (GLfloat) dstX0;
- verts[3][1] = (GLfloat) dstY1;
-
- verts[0][2] = 0.0F;
- verts[0][3] = 0.0F;
- verts[1][2] = tex->Sright;
- verts[1][3] = 0.0F;
- verts[2][2] = tex->Sright;
- verts[2][3] = tex->Ttop;
- verts[3][2] = 0.0F;
- verts[3][3] = tex->Ttop;
+ verts[0].x = (GLfloat) dstX0;
+ verts[0].y = (GLfloat) dstY0;
+ verts[1].x = (GLfloat) dstX1;
+ verts[1].y = (GLfloat) dstY0;
+ verts[2].x = (GLfloat) dstX1;
+ verts[2].y = (GLfloat) dstY1;
+ verts[3].x = (GLfloat) dstX0;
+ verts[3].y = (GLfloat) dstY1;
+
+ verts[0].s = 0.0F;
+ verts[0].t = 0.0F;
+ verts[1].s = tex->Sright;
+ verts[1].t = 0.0F;
+ verts[2].s = tex->Sright;
+ verts[2].t = tex->Ttop;
+ verts[3].s = 0.0F;
+ verts[3].t = tex->Ttop;
/* upload new vertex data */
_mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
@@ -1122,10 +1198,13 @@ _mesa_meta_blit_framebuffer(GLcontext *ctx,
* Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
*/
void
-_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
+_mesa_meta_Clear(GLcontext *ctx, GLbitfield buffers)
{
struct clear_state *clear = &ctx->Meta->Clear;
- GLfloat verts[4][7]; /* four verts of X,Y,Z,R,G,B,A */
+ struct vertex {
+ GLfloat x, y, z, r, g, b, a;
+ };
+ struct vertex verts[4];
/* save all state but scissor, pixel pack/unpack */
GLbitfield metaSave = META_ALL - META_SCISSOR - META_PIXEL_STORE;
@@ -1150,10 +1229,8 @@ _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_ColorPointer(4, GL_FLOAT, sizeof(verts[0]),
- (void *) (3 * sizeof(GLfloat)));
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_COLOR_ARRAY);
}
@@ -1203,22 +1280,25 @@ _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
GLuint i;
- verts[0][0] = x0;
- verts[0][1] = y0;
- verts[0][2] = z;
- verts[1][0] = x1;
- verts[1][1] = y0;
- verts[1][2] = z;
- verts[2][0] = x1;
- verts[2][1] = y1;
- verts[2][2] = z;
- verts[3][0] = x0;
- verts[3][1] = y1;
- verts[3][2] = z;
+ verts[0].x = x0;
+ verts[0].y = y0;
+ verts[0].z = z;
+ verts[1].x = x1;
+ verts[1].y = y0;
+ verts[1].z = z;
+ verts[2].x = x1;
+ verts[2].y = y1;
+ verts[2].z = z;
+ verts[3].x = x0;
+ verts[3].y = y1;
+ verts[3].z = z;
/* vertex colors */
for (i = 0; i < 4; i++) {
- COPY_4FV(&verts[i][3], ctx->Color.ClearColor);
+ verts[i].r = ctx->Color.ClearColor[0];
+ verts[i].g = ctx->Color.ClearColor[1];
+ verts[i].b = ctx->Color.ClearColor[2];
+ verts[i].a = ctx->Color.ClearColor[3];
}
/* upload new vertex data */
@@ -1237,13 +1317,16 @@ _mesa_meta_clear(GLcontext *ctx, GLbitfield buffers)
* of texture mapping and polygon rendering.
*/
void
-_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
- GLsizei width, GLsizei height,
- GLint dstX, GLint dstY, GLenum type)
+_mesa_meta_CopyPixels(GLcontext *ctx, GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height,
+ GLint dstX, GLint dstY, GLenum type)
{
struct copypix_state *copypix = &ctx->Meta->CopyPix;
struct temp_texture *tex = get_temp_texture(ctx);
- GLfloat verts[4][5]; /* four verts of X,Y,Z,S,T */
+ struct vertex {
+ GLfloat x, y, z, s, t;
+ };
+ struct vertex verts[4];
GLboolean newTex;
GLenum intFormat = GL_RGBA;
@@ -1281,10 +1364,8 @@ _mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (3 * sizeof(GLfloat)));
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -1303,26 +1384,26 @@ _mesa_meta_copy_pixels(GLcontext *ctx, GLint srcX, GLint srcY,
const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
const GLfloat z = ctx->Current.RasterPos[2];
- verts[0][0] = dstX0;
- verts[0][1] = dstY0;
- verts[0][2] = z;
- verts[0][3] = 0.0F;
- verts[0][4] = 0.0F;
- verts[1][0] = dstX1;
- verts[1][1] = dstY0;
- verts[1][2] = z;
- verts[1][3] = tex->Sright;
- verts[1][4] = 0.0F;
- verts[2][0] = dstX1;
- verts[2][1] = dstY1;
- verts[2][2] = z;
- verts[2][3] = tex->Sright;
- verts[2][4] = tex->Ttop;
- verts[3][0] = dstX0;
- verts[3][1] = dstY1;
- verts[3][2] = z;
- verts[3][3] = 0.0F;
- verts[3][4] = tex->Ttop;
+ verts[0].x = dstX0;
+ verts[0].y = dstY0;
+ verts[0].z = z;
+ verts[0].s = 0.0F;
+ verts[0].t = 0.0F;
+ verts[1].x = dstX1;
+ verts[1].y = dstY0;
+ verts[1].z = z;
+ verts[1].s = tex->Sright;
+ verts[1].t = 0.0F;
+ verts[2].x = dstX1;
+ verts[2].y = dstY1;
+ verts[2].z = z;
+ verts[2].s = tex->Sright;
+ verts[2].t = tex->Ttop;
+ verts[3].x = dstX0;
+ verts[3].y = dstY1;
+ verts[3].z = z;
+ verts[3].s = 0.0F;
+ verts[3].t = tex->Ttop;
/* upload new vertex data */
_mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
@@ -1375,9 +1456,8 @@ tiled_draw_pixels(GLcontext *ctx,
tileUnpack.SkipRows = unpack->SkipRows + j;
- _mesa_meta_draw_pixels(ctx, tileX, tileY,
- tileWidth, tileHeight,
- format, type, &tileUnpack, pixels);
+ _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
+ format, type, &tileUnpack, pixels);
}
}
}
@@ -1486,20 +1566,24 @@ init_draw_depth_pixels(GLcontext *ctx)
* of texture mapping and polygon rendering.
*/
void
-_mesa_meta_draw_pixels(GLcontext *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
+_mesa_meta_DrawPixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
{
struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
struct temp_texture *tex = get_temp_texture(ctx);
const struct gl_pixelstore_attrib unpackSave = ctx->Unpack;
const GLuint origStencilMask = ctx->Stencil.WriteMask[0];
- GLfloat verts[4][5]; /* four verts of X,Y,Z,S,T */
+ struct vertex {
+ GLfloat x, y, z, s, t;
+ };
+ struct vertex verts[4];
GLenum texIntFormat;
GLboolean fallback, newTex;
GLbitfield metaExtraSave = 0x0;
+ GLuint vbo;
/*
* Determine if we can do the glDrawPixels with texture mapping.
@@ -1579,32 +1663,6 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
META_VIEWPORT |
metaExtraSave));
- if (drawpix->ArrayObj == 0) {
- /* one-time setup */
-
- /* create vertex array object */
- _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
- _mesa_BindVertexArray(drawpix->ArrayObj);
-
- /* create vertex array buffer */
- _mesa_GenBuffersARB(1, &drawpix->VBO);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
- _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
- NULL, GL_DYNAMIC_DRAW_ARB);
-
- /* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (3 * sizeof(GLfloat)));
- _mesa_EnableClientState(GL_VERTEX_ARRAY);
- _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
- }
- else {
- _mesa_BindVertexArray(drawpix->ArrayObj);
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, drawpix->VBO);
- }
-
newTex = alloc_texture(tex, width, height, texIntFormat);
/* vertex positions, texcoords (after texture allocation!) */
@@ -1615,30 +1673,45 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
const GLfloat z = ctx->Current.RasterPos[2];
- verts[0][0] = x0;
- verts[0][1] = y0;
- verts[0][2] = z;
- verts[0][3] = 0.0F;
- verts[0][4] = 0.0F;
- verts[1][0] = x1;
- verts[1][1] = y0;
- verts[1][2] = z;
- verts[1][3] = tex->Sright;
- verts[1][4] = 0.0F;
- verts[2][0] = x1;
- verts[2][1] = y1;
- verts[2][2] = z;
- verts[2][3] = tex->Sright;
- verts[2][4] = tex->Ttop;
- verts[3][0] = x0;
- verts[3][1] = y1;
- verts[3][2] = z;
- verts[3][3] = 0.0F;
- verts[3][4] = tex->Ttop;
+ verts[0].x = x0;
+ verts[0].y = y0;
+ verts[0].z = z;
+ verts[0].s = 0.0F;
+ verts[0].t = 0.0F;
+ verts[1].x = x1;
+ verts[1].y = y0;
+ verts[1].z = z;
+ verts[1].s = tex->Sright;
+ verts[1].t = 0.0F;
+ verts[2].x = x1;
+ verts[2].y = y1;
+ verts[2].z = z;
+ verts[2].s = tex->Sright;
+ verts[2].t = tex->Ttop;
+ verts[3].x = x0;
+ verts[3].y = y1;
+ verts[3].z = z;
+ verts[3].s = 0.0F;
+ verts[3].t = tex->Ttop;
+ }
- /* upload new vertex data */
- _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ if (drawpix->ArrayObj == 0) {
+ /* one-time setup: create vertex array object */
+ _mesa_GenVertexArrays(1, &drawpix->ArrayObj);
}
+ _mesa_BindVertexArray(drawpix->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &vbo);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, vbo);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ verts, GL_DYNAMIC_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
+ _mesa_EnableClientState(GL_VERTEX_ARRAY);
+ _mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
/* set given unpack params */
ctx->Unpack = *unpack;
@@ -1709,6 +1782,8 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
_mesa_set_enable(ctx, tex->Target, GL_FALSE);
+ _mesa_DeleteBuffersARB(1, &vbo);
+
/* restore unpack params */
ctx->Unpack = unpackSave;
@@ -1724,7 +1799,7 @@ _mesa_meta_draw_pixels(GLcontext *ctx,
* improve performance a lot.
*/
void
-_mesa_meta_bitmap(GLcontext *ctx,
+_mesa_meta_Bitmap(GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap1)
@@ -1733,7 +1808,10 @@ _mesa_meta_bitmap(GLcontext *ctx,
struct temp_texture *tex = get_bitmap_temp_texture(ctx);
const GLenum texIntFormat = GL_ALPHA;
const struct gl_pixelstore_attrib unpackSave = *unpack;
- GLfloat verts[4][9]; /* four verts of X,Y,Z,S,T,R,G,B,A */
+ struct vertex {
+ GLfloat x, y, z, s, t, r, g, b, a;
+ };
+ struct vertex verts[4];
GLboolean newTex;
GLubyte *bitmap8;
@@ -1776,13 +1854,9 @@ _mesa_meta_bitmap(GLcontext *ctx,
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(3, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (3 * sizeof(GLfloat)));
- _mesa_ColorPointer(4, GL_FLOAT, sizeof(verts[0]),
- (void *) (5 * sizeof(GLfloat)));
-
+ _mesa_VertexPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_TexCoordPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
+ _mesa_ColorPointer(4, GL_FLOAT, sizeof(struct vertex), OFFSET(r));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
_mesa_EnableClientState(GL_COLOR_ARRAY);
@@ -1803,32 +1877,32 @@ _mesa_meta_bitmap(GLcontext *ctx,
const GLfloat z = ctx->Current.RasterPos[2];
GLuint i;
- verts[0][0] = x0;
- verts[0][1] = y0;
- verts[0][2] = z;
- verts[0][3] = 0.0F;
- verts[0][4] = 0.0F;
- verts[1][0] = x1;
- verts[1][1] = y0;
- verts[1][2] = z;
- verts[1][3] = tex->Sright;
- verts[1][4] = 0.0F;
- verts[2][0] = x1;
- verts[2][1] = y1;
- verts[2][2] = z;
- verts[2][3] = tex->Sright;
- verts[2][4] = tex->Ttop;
- verts[3][0] = x0;
- verts[3][1] = y1;
- verts[3][2] = z;
- verts[3][3] = 0.0F;
- verts[3][4] = tex->Ttop;
+ verts[0].x = x0;
+ verts[0].y = y0;
+ verts[0].z = z;
+ verts[0].s = 0.0F;
+ verts[0].t = 0.0F;
+ verts[1].x = x1;
+ verts[1].y = y0;
+ verts[1].z = z;
+ verts[1].s = tex->Sright;
+ verts[1].t = 0.0F;
+ verts[2].x = x1;
+ verts[2].y = y1;
+ verts[2].z = z;
+ verts[2].s = tex->Sright;
+ verts[2].t = tex->Ttop;
+ verts[3].x = x0;
+ verts[3].y = y1;
+ verts[3].z = z;
+ verts[3].s = 0.0F;
+ verts[3].t = tex->Ttop;
for (i = 0; i < 4; i++) {
- verts[i][5] = ctx->Current.RasterColor[0];
- verts[i][6] = ctx->Current.RasterColor[1];
- verts[i][7] = ctx->Current.RasterColor[2];
- verts[i][8] = ctx->Current.RasterColor[3];
+ verts[i].r = ctx->Current.RasterColor[0];
+ verts[i].g = ctx->Current.RasterColor[1];
+ verts[i].b = ctx->Current.RasterColor[2];
+ verts[i].a = ctx->Current.RasterColor[3];
}
/* upload new vertex data */
@@ -1865,23 +1939,37 @@ _mesa_meta_bitmap(GLcontext *ctx,
}
+/**
+ * Called via ctx->Driver.GenerateMipmap()
+ * Note: texture borders and 3D texture support not yet complete.
+ */
void
-_mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
- struct gl_texture_object *texObj)
+_mesa_meta_GenerateMipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj)
{
struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
- struct { GLfloat x, y, s, t, r; } verts[4];
+ struct vertex {
+ GLfloat x, y, s, t, r;
+ };
+ struct vertex verts[4];
const GLuint baseLevel = texObj->BaseLevel;
const GLuint maxLevel = texObj->MaxLevel;
const GLenum minFilterSave = texObj->MinFilter;
const GLenum magFilterSave = texObj->MagFilter;
+ const GLint baseLevelSave = texObj->BaseLevel;
+ const GLint maxLevelSave = texObj->MaxLevel;
+ const GLboolean genMipmapSave = texObj->GenerateMipmap;
+ const GLenum wrapSSave = texObj->WrapS;
+ const GLenum wrapTSave = texObj->WrapT;
+ const GLenum wrapRSave = texObj->WrapR;
const GLuint fboSave = ctx->DrawBuffer->Name;
GLenum faceTarget;
- GLuint level;
+ GLuint dstLevel;
GLuint border = 0;
/* check for fallbacks */
- if (!ctx->Extensions.EXT_framebuffer_object) {
+ if (!ctx->Extensions.EXT_framebuffer_object ||
+ target == GL_TEXTURE_3D) {
_mesa_generate_mipmap(ctx, target, texObj);
return;
}
@@ -1911,11 +1999,8 @@ _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
NULL, GL_DYNAMIC_DRAW_ARB);
/* setup vertex arrays */
- _mesa_VertexPointer(2, GL_FLOAT, sizeof(verts[0]),
- (void *) (0 * sizeof(GLfloat)));
- _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(verts[0]),
- (void *) (2 * sizeof(GLfloat)));
-
+ _mesa_VertexPointer(2, GL_FLOAT, sizeof(struct vertex), OFFSET(x));
+ _mesa_TexCoordPointer(3, GL_FLOAT, sizeof(struct vertex), OFFSET(s));
_mesa_EnableClientState(GL_VERTEX_ARRAY);
_mesa_EnableClientState(GL_TEXTURE_COORD_ARRAY);
}
@@ -1933,12 +2018,16 @@ _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
_mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
_mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, GL_FALSE);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
+
_mesa_set_enable(ctx, target, GL_TRUE);
/* setup texcoords once (XXX what about border?) */
switch (faceTarget) {
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- break;
+ case GL_TEXTURE_1D:
case GL_TEXTURE_2D:
verts[0].s = 0.0F;
verts[0].t = 0.0F;
@@ -1953,63 +2042,180 @@ _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
verts[3].t = 1.0F;
verts[3].r = 0.0F;
break;
+ case GL_TEXTURE_3D:
+ abort();
+ break;
+ default:
+ /* cube face */
+ {
+ static const GLfloat st[4][2] = {
+ {0.0f, 0.0f}, {1.0f, 0.0f}, {1.0f, 1.0f}, {0.0f, 1.0f}
+ };
+ GLuint i;
+
+ /* loop over quad verts */
+ for (i = 0; i < 4; i++) {
+ /* Compute sc = +/-scale and tc = +/-scale.
+ * Not +/-1 to avoid cube face selection ambiguity near the edges,
+ * though that can still sometimes happen with this scale factor...
+ */
+ const GLfloat scale = 0.9999f;
+ const GLfloat sc = (2.0f * st[i][0] - 1.0f) * scale;
+ const GLfloat tc = (2.0f * st[i][1] - 1.0f) * scale;
+
+ switch (faceTarget) {
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+ verts[i].s = 1.0f;
+ verts[i].t = -tc;
+ verts[i].r = -sc;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+ verts[i].s = -1.0f;
+ verts[i].t = -tc;
+ verts[i].r = sc;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+ verts[i].s = sc;
+ verts[i].t = 1.0f;
+ verts[i].r = tc;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+ verts[i].s = sc;
+ verts[i].t = -1.0f;
+ verts[i].r = -tc;
+ break;
+ case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+ verts[i].s = sc;
+ verts[i].t = -tc;
+ verts[i].r = 1.0f;
+ break;
+ case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+ verts[i].s = -sc;
+ verts[i].t = -tc;
+ verts[i].r = -1.0f;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
}
+ _mesa_set_enable(ctx, target, GL_TRUE);
+
+ /* texture is already locked, unlock now */
+ _mesa_unlock_texture(ctx, texObj);
- for (level = baseLevel + 1; level <= maxLevel; level++) {
+ for (dstLevel = baseLevel + 1; dstLevel <= maxLevel; dstLevel++) {
const struct gl_texture_image *srcImage;
- const GLuint srcLevel = level - 1;
- GLsizei srcWidth, srcHeight;
- GLsizei newWidth, newHeight;
+ const GLuint srcLevel = dstLevel - 1;
+ GLsizei srcWidth, srcHeight, srcDepth;
+ GLsizei dstWidth, dstHeight, dstDepth;
GLenum status;
- srcImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
+ srcImage = _mesa_select_tex_image(ctx, texObj, faceTarget, srcLevel);
assert(srcImage->Border == 0); /* XXX we can fix this */
+ /* src size w/out border */
srcWidth = srcImage->Width - 2 * border;
srcHeight = srcImage->Height - 2 * border;
+ srcDepth = srcImage->Depth - 2 * border;
- newWidth = MAX2(1, srcWidth / 2) + 2 * border;
- newHeight = MAX2(1, srcHeight / 2) + 2 * border;
+ /* new dst size w/ border */
+ dstWidth = MAX2(1, srcWidth / 2) + 2 * border;
+ dstHeight = MAX2(1, srcHeight / 2) + 2 * border;
+ dstDepth = MAX2(1, srcDepth / 2) + 2 * border;
- if (newWidth == srcImage->Width && newHeight == srcImage->Height) {
- break;
+ if (dstWidth == srcImage->Width &&
+ dstHeight == srcImage->Height &&
+ dstDepth == srcImage->Depth) {
+ /* all done */
+ break;
}
- /* Create empty image */
- _mesa_TexImage2D(GL_TEXTURE_2D, level, srcImage->InternalFormat,
- newWidth, newHeight, border,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ /* Create empty dest image */
+ if (target == GL_TEXTURE_1D) {
+ _mesa_TexImage1D(target, dstLevel, srcImage->InternalFormat,
+ dstWidth, border,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ else if (target == GL_TEXTURE_3D) {
+ _mesa_TexImage3D(target, dstLevel, srcImage->InternalFormat,
+ dstWidth, dstHeight, dstDepth, border,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ else {
+ /* 2D or cube */
+ _mesa_TexImage2D(faceTarget, dstLevel, srcImage->InternalFormat,
+ dstWidth, dstHeight, border,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ if (target == GL_TEXTURE_CUBE_MAP) {
+ /* If texturing from a cube, we need to make sure all src faces
+ * have been defined (even if we're not sampling from them.)
+ * Otherwise the texture object will be 'incomplete' and
+ * texturing from it will not be allowed.
+ */
+ GLuint face;
+ for (face = 0; face < 6; face++) {
+ if (!texObj->Image[face][srcLevel] ||
+ texObj->Image[face][srcLevel]->Width != srcWidth) {
+ _mesa_TexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face,
+ srcLevel, srcImage->InternalFormat,
+ srcWidth, srcHeight, border,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+ }
+ }
+ }
+ }
- /* vertex positions */
+ /* setup vertex positions */
{
verts[0].x = 0.0F;
verts[0].y = 0.0F;
- verts[1].x = (GLfloat) newWidth;
+ verts[1].x = (GLfloat) dstWidth;
verts[1].y = 0.0F;
- verts[2].x = (GLfloat) newWidth;
- verts[2].y = (GLfloat) newHeight;
+ verts[2].x = (GLfloat) dstWidth;
+ verts[2].y = (GLfloat) dstHeight;
verts[3].x = 0.0F;
- verts[3].y = (GLfloat) newHeight;
+ verts[3].y = (GLfloat) dstHeight;
/* upload new vertex data */
_mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
}
/* limit sampling to src level */
- _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, srcLevel);
- _mesa_TexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, srcLevel);
-
- /* Set to draw into the current level */
- _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
- GL_COLOR_ATTACHMENT0_EXT,
- target,
- texObj->Name,
- level);
+ _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, srcLevel);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, srcLevel);
+
+ /* Set to draw into the current dstLevel */
+ if (target == GL_TEXTURE_1D) {
+ _mesa_FramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target,
+ texObj->Name,
+ dstLevel);
+ }
+ else if (target == GL_TEXTURE_3D) {
+ GLint zoffset = 0; /* XXX unfinished */
+ _mesa_FramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ target,
+ texObj->Name,
+ dstLevel, zoffset);
+ }
+ else {
+ /* 2D / cube */
+ _mesa_FramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0_EXT,
+ faceTarget,
+ texObj->Name,
+ dstLevel);
+ }
- /* Choose to render to the color attachment. */
_mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+ /* sanity check */
status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
abort();
@@ -2019,11 +2225,386 @@ _mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
_mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
+ _mesa_lock_texture(ctx, texObj); /* relock */
+
_mesa_meta_end(ctx);
_mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
_mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, baseLevelSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, maxLevelSave);
+ _mesa_TexParameteri(target, GL_GENERATE_MIPMAP, genMipmapSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_S, wrapSSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_T, wrapTSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_WRAP_R, wrapRSave);
- /* restore (XXX add to meta_begin/end()? */
_mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, fboSave);
}
+
+
+/**
+ * Determine the GL data type to use for the temporary image read with
+ * ReadPixels() and passed to Tex[Sub]Image().
+ */
+static GLenum
+get_temp_image_type(GLcontext *ctx, GLenum baseFormat)
+{
+ switch (baseFormat) {
+ case GL_RGBA:
+ case GL_RGB:
+ case GL_ALPHA:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE_ALPHA:
+ case GL_INTENSITY:
+ if (ctx->DrawBuffer->Visual.redBits <= 8)
+ return GL_UNSIGNED_BYTE;
+ else if (ctx->DrawBuffer->Visual.redBits <= 8)
+ return GL_UNSIGNED_SHORT;
+ else
+ return GL_FLOAT;
+ case GL_DEPTH_COMPONENT:
+ return GL_UNSIGNED_INT;
+ case GL_DEPTH_STENCIL:
+ return GL_UNSIGNED_INT_24_8;
+ default:
+ _mesa_problem(ctx, "Unexpected format in get_temp_image_type()");
+ return 0;
+ }
+}
+
+
+/**
+ * Helper for _mesa_meta_CopyTexImage1/2D() functions.
+ * Have to be careful with locking and meta state for pixel transfer.
+ */
+static void
+copy_tex_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLsizei postConvWidth = width, postConvHeight = height;
+ GLenum format, type;
+ GLint bpp;
+ void *buf;
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+
+ format = _mesa_base_tex_format(ctx, internalFormat);
+ type = get_temp_image_type(ctx, format);
+ bpp = _mesa_bytes_per_pixel(format, type);
+ if (bpp <= 0) {
+ _mesa_problem(ctx, "Bad bpp in meta copy_tex_image()");
+ return;
+ }
+
+ /*
+ * Alloc image buffer (XXX could use a PBO)
+ */
+ buf = _mesa_malloc(width * height * bpp);
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD", dims);
+ return;
+ }
+
+ _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ ctx->Driver.ReadPixels(ctx, x, y, width, height,
+ format, type, &ctx->Pack, buf);
+ _mesa_meta_end(ctx);
+
+ /*
+ * Prepare for new texture image size/data
+ */
+#if FEATURE_convolve
+ if (_mesa_is_color_format(internalFormat)) {
+ _mesa_adjust_image_for_convolution(ctx, 2,
+ &postConvWidth, &postConvHeight);
+ }
+#endif
+
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData(ctx, texImage);
+ }
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ /*
+ * Store texture data (with pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE);
+
+ _mesa_update_state(ctx); /* to update pixel transfer state */
+
+ if (target == GL_TEXTURE_1D) {
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border, format, type,
+ buf, &ctx->Unpack, texObj, texImage);
+ }
+ else {
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border, format, type,
+ buf, &ctx->Unpack, texObj, texImage);
+ }
+ _mesa_meta_end(ctx);
+
+ _mesa_lock_texture(ctx, texObj); /* re-lock */
+
+ _mesa_free(buf);
+}
+
+
+void
+_mesa_meta_CopyTexImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLint border)
+{
+ copy_tex_image(ctx, 1, target, level, internalFormat, x, y,
+ width, 1, border);
+}
+
+
+void
+_mesa_meta_CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border)
+{
+ copy_tex_image(ctx, 2, target, level, internalFormat, x, y,
+ width, height, border);
+}
+
+
+
+/**
+ * Helper for _mesa_meta_CopyTexSubImage1/2/3D() functions.
+ * Have to be careful with locking and meta state for pixel transfer.
+ */
+static void
+copy_tex_sub_image(GLcontext *ctx, GLuint dims, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLenum format, type;
+ GLint bpp;
+ void *buf;
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+
+ format = texImage->TexFormat->BaseFormat;
+ type = get_temp_image_type(ctx, format);
+ bpp = _mesa_bytes_per_pixel(format, type);
+ if (bpp <= 0) {
+ _mesa_problem(ctx, "Bad bpp in meta copy_tex_sub_image()");
+ return;
+ }
+
+ /*
+ * Alloc image buffer (XXX could use a PBO)
+ */
+ buf = _mesa_malloc(width * height * bpp);
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage%uD", dims);
+ return;
+ }
+
+ _mesa_unlock_texture(ctx, texObj); /* need to unlock first */
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ ctx->Driver.ReadPixels(ctx, x, y, width, height,
+ format, type, &ctx->Pack, buf);
+ _mesa_meta_end(ctx);
+
+ _mesa_update_state(ctx); /* to update pixel transfer state */
+
+ /*
+ * Store texture data (with pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE);
+ if (target == GL_TEXTURE_1D) {
+ ctx->Driver.TexSubImage1D(ctx, target, level, xoffset,
+ width, format, type, buf,
+ &ctx->Unpack, texObj, texImage);
+ }
+ else if (target == GL_TEXTURE_3D) {
+ ctx->Driver.TexSubImage3D(ctx, target, level, xoffset, yoffset, zoffset,
+ width, height, 1, format, type, buf,
+ &ctx->Unpack, texObj, texImage);
+ }
+ else {
+ ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
+ width, height, format, type, buf,
+ &ctx->Unpack, texObj, texImage);
+ }
+ _mesa_meta_end(ctx);
+
+ _mesa_lock_texture(ctx, texObj); /* re-lock */
+
+ _mesa_free(buf);
+}
+
+
+void
+_mesa_meta_CopyTexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset,
+ GLint x, GLint y, GLsizei width)
+{
+ copy_tex_sub_image(ctx, 1, target, level, xoffset, 0, 0,
+ x, y, width, 1);
+}
+
+
+void
+_mesa_meta_CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ copy_tex_sub_image(ctx, 2, target, level, xoffset, yoffset, 0,
+ x, y, width, height);
+}
+
+
+void
+_mesa_meta_CopyTexSubImage3D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ copy_tex_sub_image(ctx, 3, target, level, xoffset, yoffset, zoffset,
+ x, y, width, height);
+}
+
+
+void
+_mesa_meta_CopyColorTable(GLcontext *ctx,
+ GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width)
+{
+ GLfloat *buf;
+
+ buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorTable");
+ return;
+ }
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ ctx->Driver.ReadPixels(ctx, x, y, width, 1,
+ GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
+
+ _mesa_ColorTable(target, internalformat, width, GL_RGBA, GL_FLOAT, buf);
+
+ _mesa_meta_end(ctx);
+
+ _mesa_free(buf);
+}
+
+
+void
+_mesa_meta_CopyColorSubTable(GLcontext *ctx,GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width)
+{
+ GLfloat *buf;
+
+ buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyColorSubTable");
+ return;
+ }
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ ctx->Driver.ReadPixels(ctx, x, y, width, 1,
+ GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
+
+ _mesa_ColorSubTable(target, start, width, GL_RGBA, GL_FLOAT, buf);
+
+ _mesa_meta_end(ctx);
+
+ _mesa_free(buf);
+}
+
+
+void
+_mesa_meta_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width)
+{
+ GLfloat *buf;
+
+ buf = (GLfloat *) _mesa_malloc(width * 4 * sizeof(GLfloat));
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyConvolutionFilter2D");
+ return;
+ }
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ _mesa_update_state(ctx);
+ ctx->Driver.ReadPixels(ctx, x, y, width, 1,
+ GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
+
+ _mesa_ConvolutionFilter1D(target, internalFormat, width,
+ GL_RGBA, GL_FLOAT, buf);
+
+ _mesa_meta_end(ctx);
+
+ _mesa_free(buf);
+}
+
+
+void
+_mesa_meta_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height)
+{
+ GLfloat *buf;
+
+ buf = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat));
+ if (!buf) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyConvolutionFilter2D");
+ return;
+ }
+
+ /*
+ * Read image from framebuffer (disable pixel transfer ops)
+ */
+ _mesa_meta_begin(ctx, META_PIXEL_STORE | META_PIXEL_TRANSFER);
+ _mesa_update_state(ctx);
+
+ ctx->Driver.ReadPixels(ctx, x, y, width, height,
+ GL_RGBA, GL_FLOAT, &ctx->Pack, buf);
+
+ _mesa_ConvolutionFilter2D(target, internalFormat, width, height,
+ GL_RGBA, GL_FLOAT, buf);
+
+ _mesa_meta_end(ctx);
+
+ _mesa_free(buf);
+}
diff --git a/src/mesa/drivers/common/meta.h b/src/mesa/drivers/common/meta.h
index 171ad27f265..7f659528dc0 100644
--- a/src/mesa/drivers/common/meta.h
+++ b/src/mesa/drivers/common/meta.h
@@ -27,29 +27,6 @@
#define META_H
-/**
- * Flags passed to _mesa_meta_begin().
- * XXX these flags may evolve...
- */
-/*@{*/
-#define META_ALPHA_TEST 0x1
-#define META_BLEND 0x2 /**< includes logicop */
-#define META_COLOR_MASK 0x4
-#define META_DEPTH_TEST 0x8
-#define META_FOG 0x10
-#define META_RASTERIZATION 0x20
-#define META_SCISSOR 0x40
-#define META_SHADER 0x80
-#define META_STENCIL_TEST 0x100
-#define META_TRANSFORM 0x200 /**< modelview, projection */
-#define META_TEXTURE 0x400
-#define META_VERTEX 0x800
-#define META_VIEWPORT 0x1000
-#define META_PIXEL_STORE 0x2000
-#define META_ALL ~0x0
-/*@}*/
-
-
extern void
_mesa_meta_init(GLcontext *ctx);
@@ -57,35 +34,81 @@ extern void
_mesa_meta_free(GLcontext *ctx);
extern void
-_mesa_meta_blit_framebuffer(GLcontext *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter);
+_mesa_meta_BlitFramebuffer(GLcontext *ctx,
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
extern void
-_mesa_meta_clear(GLcontext *ctx, GLbitfield buffers);
+_mesa_meta_Clear(GLcontext *ctx, GLbitfield buffers);
extern void
-_mesa_meta_copy_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
- GLsizei width, GLsizei height,
- GLint dstx, GLint dsty, GLenum type);
+_mesa_meta_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type);
extern void
-_mesa_meta_draw_pixels(GLcontext *ctx,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels);
+_mesa_meta_DrawPixels(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels);
extern void
-_mesa_meta_bitmap(GLcontext *ctx,
+_mesa_meta_Bitmap(GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap);
extern void
-_mesa_meta_generate_mipmap(GLcontext *ctx, GLenum target,
- struct gl_texture_object *texObj);
+_mesa_meta_GenerateMipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj);
+
+extern void
+_mesa_meta_CopyTexImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLint border);
+
+extern void
+_mesa_meta_CopyTexImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border);
+
+extern void
+_mesa_meta_CopyTexSubImage1D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset,
+ GLint x, GLint y, GLsizei width);
+
+extern void
+_mesa_meta_CopyTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height);
+
+extern void
+_mesa_meta_CopyTexSubImage3D(GLcontext *ctx, GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y,
+ GLsizei width, GLsizei height);
+
+extern void
+_mesa_meta_CopyColorTable(GLcontext *ctx,
+ GLenum target, GLenum internalformat,
+ GLint x, GLint y, GLsizei width);
+
+extern void
+_mesa_meta_CopyColorSubTable(GLcontext *ctx,GLenum target, GLsizei start,
+ GLint x, GLint y, GLsizei width);
+
+extern void
+_mesa_meta_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
+ GLenum internalFormat,
+ GLint x, GLint y, GLsizei width);
+
+extern void
+_mesa_meta_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
+ GLenum internalFormat, GLint x, GLint y,
+ GLsizei width, GLsizei height);
#endif /* META_H */
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index 2c89a9f58a9..5e86324eece 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -4417,10 +4417,11 @@ static const char SpriteParameterivSGIX_names[] =
"";
#endif
-#if defined(need_GL_EXT_provoking_vertex)
+#if defined(need_GL_EXT_provoking_vertex) || defined(need_GL_ARB_provoking_vertex)
static const char ProvokingVertexEXT_names[] =
"i\0" /* Parameter signature */
"glProvokingVertexEXT\0"
+ "glProvokingVertex\0"
"";
#endif
@@ -5194,6 +5195,13 @@ static const struct dri_extension_function GL_ARB_point_parameters_functions[] =
};
#endif
+#if defined(need_GL_ARB_provoking_vertex)
+static const struct dri_extension_function GL_ARB_provoking_vertex_functions[] = {
+ { ProvokingVertexEXT_names, ProvokingVertexEXT_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_shader_objects)
static const struct dri_extension_function GL_ARB_shader_objects_functions[] = {
{ UniformMatrix3fvARB_names, UniformMatrix3fvARB_remap_index, -1 },
diff --git a/src/mesa/drivers/dri/ffb/ffb_tex.c b/src/mesa/drivers/dri/ffb/ffb_tex.c
index 69d30aedbaf..95058e9069f 100644
--- a/src/mesa/drivers/dri/ffb/ffb_tex.c
+++ b/src/mesa/drivers/dri/ffb/ffb_tex.c
@@ -30,24 +30,6 @@
#include "ffb_tex.h"
/* No texture unit, all software. */
-/* XXX this function isn't needed since _mesa_init_driver_functions()
- * will make all these assignments.
- */
void ffbDDInitTexFuncs(GLcontext *ctx)
{
- /*
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- ctx->Driver.TexImage2D = _mesa_store_teximage2d;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
- ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
- */
}
diff --git a/src/mesa/drivers/dri/glcore/Makefile b/src/mesa/drivers/dri/glcore/Makefile
deleted file mode 100644
index ac7e1de9285..00000000000
--- a/src/mesa/drivers/dri/glcore/Makefile
+++ /dev/null
@@ -1,84 +0,0 @@
-# src/mesa/drivers/dri/glcore/Makefile
-
-TOP = ../../../../..
-include $(TOP)/configs/current
-
-LIBNAME = glcore_dri.so
-
-DRIVER_SOURCES = glcore_driver.c \
- $(TOP)/src/mesa/drivers/common/driverfuncs.c \
- ../common/dri_util.c
-
-C_SOURCES = \
- $(DRIVER_SOURCES) \
- $(DRI_SOURCES)
-
-
-# Include directories
-INCLUDE_DIRS = \
- -I. \
- -I../common \
- -I../dri_client \
- -I../dri_client/imports \
- -Iserver \
- -I$(TOP)/include \
- -I$(DRM_SOURCE_PATH)/shared-core \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main \
- -I$(TOP)/src/mesa/glapi \
- -I$(TOP)/src/mesa/math \
- -I$(TOP)/src/mesa/transform \
- -I$(TOP)/src/mesa/shader \
- -I$(TOP)/src/mesa/swrast \
- -I$(TOP)/src/mesa/swrast_setup
-
-# Core Mesa objects
-MESA_MODULES = $(TOP)/src/mesa/libmesa.a
-
-# Libraries that the driver shared lib depends on
-LIB_DEPS = -lm -lpthread -lc
-# LIB_DEPS = -lGL -lm -lpthread -lc
-
-
-ASM_SOURCES =
-
-OBJECTS = $(C_SOURCES:.c=.o) \
- $(ASM_SOURCES:.S=.o)
-
-
-##### RULES #####
-
-.c.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@
-
-.S.o:
- $(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $(DEFINES) $< -o $@
-
-
-##### TARGETS #####
-
-default: depend $(TOP)/$(LIB_DIR)/$(LIBNAME)
-
-
-$(TOP)/$(LIB_DIR)/$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile
- CC="$(CC)" CXX="$(CXX)" $(TOP)/bin/mklib -o $(LIBNAME) -noprefix -install $(TOP)/$(LIB_DIR) \
- $(OBJECTS) $(WINLIB) $(LIB_DEPS) $(WINOBJ) $(MESA_MODULES)
-
-
-depend: $(C_SOURCES) $(ASM_SOURCES)
- rm -f depend
- touch depend
- $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDE_DIRS) $(C_SOURCES) $(ASM_SOURCES) \
- > /dev/null
-
-
-# Emacs tags
-tags:
- etags `find . -name \*.[ch]` `find ../include`
-
-
-clean:
- -rm -f *.o server/*.o
-
-
-include depend
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 3c5b8483197..c300c33adce 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -125,6 +125,7 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
/* We want the GLSL compiler to emit code that uses condition codes */
ctx->Shader.EmitCondCodes = GL_TRUE;
+ ctx->Shader.EmitNVTempInitialization = GL_TRUE;
ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
ctx->Const.VertexProgram.MaxAluInstructions = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index 0b0e6931a06..4be6c77aa1e 100644
--- a/src/mesa/drivers/dri/i965/brw_curbe.c
+++ b/src/mesa/drivers/dri/i965/brw_curbe.c
@@ -248,6 +248,9 @@ static void prepare_constant_buffer(struct brw_context *brw)
GLuint offset = brw->curbe.vs_start * 16;
GLuint nr = brw->vs.prog_data->nr_params / 4;
+ if (brw->vertex_program->IsNVProgram)
+ _mesa_load_tracked_matrices(ctx);
+
/* Updates the ParamaterValues[i] pointers for all parameters of the
* basic type of PROGRAM_STATE_VAR.
*/
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index 78572356a3d..5335eac8951 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -86,9 +86,6 @@ const struct brw_tracked_state brw_psp_urb_cbs;
const struct brw_tracked_state brw_pipe_control;
-const struct brw_tracked_state brw_clear_surface_cache;
-const struct brw_tracked_state brw_clear_batch_cache;
-
const struct brw_tracked_state brw_drawing_rect;
const struct brw_tracked_state brw_indices;
const struct brw_tracked_state brw_vertices;
@@ -165,7 +162,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
const void *data,
GLuint sz );
void brw_destroy_batch_cache( struct brw_context *brw );
-void brw_clear_batch_cache_flush( struct brw_context *brw );
+void brw_clear_batch_cache( struct brw_context *brw );
/* brw_wm_surface_state.c */
dri_bo *
diff --git a/src/mesa/drivers/dri/i965/brw_state_batch.c b/src/mesa/drivers/dri/i965/brw_state_batch.c
index 811940edc05..7821898cf9b 100644
--- a/src/mesa/drivers/dri/i965/brw_state_batch.c
+++ b/src/mesa/drivers/dri/i965/brw_state_batch.c
@@ -79,7 +79,7 @@ GLboolean brw_cached_batch_struct( struct brw_context *brw,
return GL_TRUE;
}
-static void clear_batch_cache( struct brw_context *brw )
+void brw_clear_batch_cache( struct brw_context *brw )
{
struct brw_cached_batch_item *item = brw->cached_batch_items;
@@ -93,18 +93,7 @@ static void clear_batch_cache( struct brw_context *brw )
brw->cached_batch_items = NULL;
}
-void brw_clear_batch_cache_flush( struct brw_context *brw )
-{
- clear_batch_cache(brw);
-
- brw->state.dirty.mesa |= ~0;
- brw->state.dirty.brw |= ~0;
- brw->state.dirty.cache |= ~0;
-}
-
-
-
void brw_destroy_batch_cache( struct brw_context *brw )
{
- clear_batch_cache(brw);
+ brw_clear_batch_cache(brw);
}
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 414620d0b39..b817b741e77 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -287,6 +287,7 @@ void brw_validate_state( struct brw_context *brw )
if (brw->emit_state_always) {
state->mesa |= ~0;
state->brw |= ~0;
+ state->cache |= ~0;
}
if (brw->fragment_program != ctx->FragmentProgram._Current) {
@@ -305,7 +306,7 @@ void brw_validate_state( struct brw_context *brw )
return;
if (brw->state.dirty.brw & BRW_NEW_CONTEXT)
- brw_clear_batch_cache_flush(brw);
+ brw_clear_batch_cache(brw);
brw->intel.Fallback = 0;
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index e3111c66800..f0c79efbd96 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -90,8 +90,6 @@ static void brw_upload_vs_prog(struct brw_context *brw)
struct brw_vertex_program *vp =
(struct brw_vertex_program *)brw->vertex_program;
- assert (vp && !vp->program.IsNVProgram);
-
memset(&key, 0, sizeof(key));
/* Just upload the program verbatim for now. Always send it all
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 584fdbdfc37..1638ef81115 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -1270,9 +1270,27 @@ post_vs_emit( struct brw_vs_compile *c,
}
static uint32_t
-get_predicate(uint32_t swizzle)
+get_predicate(const struct prog_instruction *inst)
{
- switch (swizzle) {
+ if (inst->DstReg.CondMask == COND_TR)
+ return BRW_PREDICATE_NONE;
+
+ /* All of GLSL only produces predicates for COND_NE and one channel per
+ * vector. Fail badly if someone starts doing something else, as it might
+ * mean infinite looping or something.
+ *
+ * We'd like to support all the condition codes, but our hardware doesn't
+ * quite match the Mesa IR, which is modeled after the NV extensions. For
+ * those, the instruction may update the condition codes or not, then any
+ * later instruction may use one of those condition codes. For gen4, the
+ * instruction may update the flags register based on one of the condition
+ * codes output by the instruction, and then further instructions may
+ * predicate on that. We can probably support this, but it won't
+ * necessarily be easy.
+ */
+ assert(inst->DstReg.CondMask == COND_NE);
+
+ switch (inst->DstReg.CondSwizzle) {
case SWIZZLE_XXXX:
return BRW_PREDICATE_ALIGN16_REPLICATE_X;
case SWIZZLE_YYYY:
@@ -1282,7 +1300,8 @@ get_predicate(uint32_t swizzle)
case SWIZZLE_WWWW:
return BRW_PREDICATE_ALIGN16_REPLICATE_W;
default:
- _mesa_problem(NULL, "Unexpected predicate: 0x%08x\n", swizzle);
+ _mesa_problem(NULL, "Unexpected predicate: 0x%08x\n",
+ inst->DstReg.CondMask);
return BRW_PREDICATE_NORMAL;
}
}
@@ -1294,6 +1313,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
#define MAX_IF_DEPTH 32
#define MAX_LOOP_DEPTH 32
struct brw_compile *p = &c->func;
+ struct brw_context *brw = p->brw;
const GLuint nr_insns = c->vp->program.Base.NumInstructions;
GLuint insn, if_depth = 0, loop_depth = 0;
GLuint end_offset = 0;
@@ -1492,8 +1512,8 @@ void brw_vs_emit(struct brw_vs_compile *c )
case OPCODE_IF:
assert(if_depth < MAX_IF_DEPTH);
if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
- if_inst[if_depth]->header.predicate_control =
- get_predicate(inst->DstReg.CondSwizzle);
+ /* Note that brw_IF smashes the predicate_control field. */
+ if_inst[if_depth]->header.predicate_control = get_predicate(inst);
if_depth++;
break;
case OPCODE_ELSE:
@@ -1503,45 +1523,48 @@ void brw_vs_emit(struct brw_vs_compile *c )
assert(if_depth > 0);
brw_ENDIF(p, if_inst[--if_depth]);
break;
-#if 0
case OPCODE_BGNLOOP:
loop_inst[loop_depth++] = brw_DO(p, BRW_EXECUTE_8);
break;
case OPCODE_BRK:
+ brw_set_predicate_control(p, get_predicate(inst));
brw_BREAK(p);
- brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_CONT:
+ brw_set_predicate_control(p, get_predicate(inst));
brw_CONT(p);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_ENDLOOP:
{
struct brw_instruction *inst0, *inst1;
+ GLuint br = 1;
+
loop_depth--;
+
+ if (BRW_IS_IGDNG(brw))
+ br = 2;
+
inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
/* patch all the BREAK/CONT instructions from last BEGINLOOP */
while (inst0 > loop_inst[loop_depth]) {
inst0--;
if (inst0->header.opcode == BRW_OPCODE_BREAK) {
- inst0->bits3.if_else.jump_count = inst1 - inst0 + 1;
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0 + 1);
inst0->bits3.if_else.pop_count = 0;
}
else if (inst0->header.opcode == BRW_OPCODE_CONTINUE) {
- inst0->bits3.if_else.jump_count = inst1 - inst0;
+ inst0->bits3.if_else.jump_count = br * (inst1 - inst0);
inst0->bits3.if_else.pop_count = 0;
}
}
}
break;
-#else
- (void) loop_inst;
- (void) loop_depth;
-#endif
case OPCODE_BRA:
- brw_set_predicate_control(p, BRW_PREDICATE_NORMAL);
+ brw_set_predicate_control(p, get_predicate(inst));
brw_ADD(p, brw_ip_reg(), brw_ip_reg(), brw_imm_d(1*16));
- brw_set_predicate_control_flag_value(p, 0xff);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
case OPCODE_CAL:
brw_set_access_mode(p, BRW_ALIGN_1);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ae98b5492db..872b1f3ecf4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.h
+++ b/src/mesa/drivers/dri/i965/brw_wm.h
@@ -38,6 +38,8 @@
#include "brw_context.h"
#include "brw_eu.h"
+#define SATURATE (1<<5)
+
/* A big lookup table is used to figure out which and how many
* additional regs will inserted before the main payload in the WM
* program execution. These mainly relate to depth and stencil
@@ -203,7 +205,6 @@ struct brw_wm_compile {
GLuint fp_temp;
GLuint fp_interp_emitted;
GLuint fp_fragcolor_emitted;
- GLuint fp_deriv_emitted;
struct prog_src_register pixel_xy;
struct prog_src_register delta_xy;
@@ -299,5 +300,10 @@ void brw_wm_lookup_iz( GLuint line_aa,
GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp);
void brw_wm_glsl_emit(struct brw_context *brw, struct brw_wm_compile *c);
+void emit_ddxy(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ GLboolean is_ddx,
+ const struct brw_reg *arg0);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 981864323ec..bf80a2942a4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -34,8 +34,6 @@
#include "brw_context.h"
#include "brw_wm.h"
-#define SATURATE (1<<5)
-
/* Not quite sure how correct this is - need to understand horiz
* vs. vertical strides a little better.
*/
@@ -281,6 +279,79 @@ static void emit_frontfacing( struct brw_compile *p,
brw_set_predicate_control_flag_value(p, 0xff);
}
+/* For OPCODE_DDX and OPCODE_DDY, per channel of output we've got input
+ * looking like:
+ *
+ * arg0: ss0.tl ss0.tr ss0.bl ss0.br ss1.tl ss1.tr ss1.bl ss1.br
+ *
+ * and we're trying to produce:
+ *
+ * DDX DDY
+ * dst: (ss0.tr - ss0.tl) (ss0.tl - ss0.bl)
+ * (ss0.tr - ss0.tl) (ss0.tr - ss0.br)
+ * (ss0.br - ss0.bl) (ss0.tl - ss0.bl)
+ * (ss0.br - ss0.bl) (ss0.tr - ss0.br)
+ * (ss1.tr - ss1.tl) (ss1.tl - ss1.bl)
+ * (ss1.tr - ss1.tl) (ss1.tr - ss1.br)
+ * (ss1.br - ss1.bl) (ss1.tl - ss1.bl)
+ * (ss1.br - ss1.bl) (ss1.tr - ss1.br)
+ *
+ * and add another set of two more subspans if in 16-pixel dispatch mode.
+ *
+ * For DDX, it ends up being easy: width = 2, horiz=0 gets us the same result
+ * for each pair, and vertstride = 2 jumps us 2 elements after processing a
+ * pair. But for DDY, it's harder, as we want to produce the pairs swizzled
+ * between each other. We could probably do it like ddx and swizzle the right
+ * order later, but bail for now and just produce
+ * ((ss0.tl - ss0.bl)x4 (ss1.tl - ss1.bl)x4)
+ */
+void emit_ddxy(struct brw_compile *p,
+ const struct brw_reg *dst,
+ GLuint mask,
+ GLboolean is_ddx,
+ const struct brw_reg *arg0)
+{
+ int i;
+ struct brw_reg src0, src1;
+
+ if (mask & SATURATE)
+ brw_set_saturate(p, 1);
+ for (i = 0; i < 4; i++ ) {
+ if (mask & (1<<i)) {
+ if (is_ddx) {
+ src0 = brw_reg(arg0[i].file, arg0[i].nr, 1,
+ BRW_REGISTER_TYPE_F,
+ BRW_VERTICAL_STRIDE_2,
+ BRW_WIDTH_2,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+ src1 = brw_reg(arg0[i].file, arg0[i].nr, 0,
+ BRW_REGISTER_TYPE_F,
+ BRW_VERTICAL_STRIDE_2,
+ BRW_WIDTH_2,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+ } else {
+ src0 = brw_reg(arg0[i].file, arg0[i].nr, 0,
+ BRW_REGISTER_TYPE_F,
+ BRW_VERTICAL_STRIDE_4,
+ BRW_WIDTH_4,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+ src1 = brw_reg(arg0[i].file, arg0[i].nr, 2,
+ BRW_REGISTER_TYPE_F,
+ BRW_VERTICAL_STRIDE_4,
+ BRW_WIDTH_4,
+ BRW_HORIZONTAL_STRIDE_0,
+ BRW_SWIZZLE_XYZW, WRITEMASK_XYZW);
+ }
+ brw_ADD(p, dst[i], src0, negate(src1));
+ }
+ }
+ if (mask & SATURATE)
+ brw_set_saturate(p, 0);
+}
+
static void emit_alu1( struct brw_compile *p,
struct brw_instruction *(*func)(struct brw_compile *,
struct brw_reg,
@@ -1272,6 +1343,14 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_alu1(p, brw_RNDD, dst, dst_flags, args[0]);
break;
+ case OPCODE_DDX:
+ emit_ddxy(p, dst, dst_flags, GL_TRUE, args[0]);
+ break;
+
+ case OPCODE_DDY:
+ emit_ddxy(p, dst, dst_flags, GL_FALSE, args[0]);
+ break;
+
case OPCODE_DP3:
emit_dp3(p, dst, dst_flags, args[0], args[1]);
break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index 123fe841c3f..4e3edfbbffa 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -494,38 +494,6 @@ static void emit_interp( struct brw_wm_compile *c,
c->fp_interp_emitted |= 1<<idx;
}
-static void emit_ddx( struct brw_wm_compile *c,
- const struct prog_instruction *inst )
-{
- GLuint idx = inst->SrcReg[0].Index;
- struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
-
- c->fp_deriv_emitted |= 1<<idx;
- emit_op(c,
- OPCODE_DDX,
- inst->DstReg,
- 0,
- interp,
- get_pixel_w(c),
- src_undef());
-}
-
-static void emit_ddy( struct brw_wm_compile *c,
- const struct prog_instruction *inst )
-{
- GLuint idx = inst->SrcReg[0].Index;
- struct prog_src_register interp = src_reg(PROGRAM_PAYLOAD, idx);
-
- c->fp_deriv_emitted |= 1<<idx;
- emit_op(c,
- OPCODE_DDY,
- inst->DstReg,
- 0,
- interp,
- get_pixel_w(c),
- src_undef());
-}
-
/***********************************************************************
* Hacks to extend the program parameter and constant lists.
*/
@@ -1186,12 +1154,6 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
*/
out->DstReg.WriteMask = 0;
break;
- case OPCODE_DDX:
- emit_ddx(c, inst);
- break;
- case OPCODE_DDY:
- emit_ddy(c, inst);
- break;
case OPCODE_END:
emit_fb_write(c);
break;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 7c210abbce3..c9fe1dd8ad2 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -22,6 +22,7 @@ static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
{
int i;
+
for (i = 0; i < fp->Base.NumInstructions; i++) {
const struct prog_instruction *inst = &fp->Base.Instructions[i];
switch (inst->Opcode) {
@@ -31,8 +32,6 @@ GLboolean brw_wm_is_glsl(const struct gl_fragment_program *fp)
case OPCODE_CAL:
case OPCODE_BRK:
case OPCODE_RET:
- case OPCODE_DDX:
- case OPCODE_DDY:
case OPCODE_NOISE1:
case OPCODE_NOISE2:
case OPCODE_NOISE3:
@@ -293,7 +292,7 @@ static void prealloc_reg(struct brw_wm_compile *c)
int i, j;
struct brw_reg reg;
int urb_read_length = 0;
- GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted | c->fp_deriv_emitted;
+ GLuint inputs = FRAG_BIT_WPOS | c->fp_interp_emitted;
GLuint reg_index = 0;
memset(c->used_grf, GL_FALSE, sizeof(c->used_grf));
@@ -1474,61 +1473,6 @@ static void emit_sne(struct brw_wm_compile *c,
emit_sop(c, inst, BRW_CONDITIONAL_NEQ);
}
-static void emit_ddx(struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- struct brw_compile *p = &c->func;
- GLuint mask = inst->DstReg.WriteMask;
- struct brw_reg interp[4];
- struct brw_reg dst;
- struct brw_reg src0, w;
- GLuint nr, i;
- src0 = get_src_reg(c, inst, 0, 0);
- w = get_src_reg(c, inst, 1, 3);
- nr = src0.nr;
- interp[0] = brw_vec1_grf(nr, 0);
- interp[1] = brw_vec1_grf(nr, 4);
- interp[2] = brw_vec1_grf(nr+1, 0);
- interp[3] = brw_vec1_grf(nr+1, 4);
- brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
- for(i = 0; i < 4; i++ ) {
- if (mask & (1<<i)) {
- dst = get_dst_reg(c, inst, i);
- brw_MOV(p, dst, interp[i]);
- brw_MUL(p, dst, dst, w);
- }
- }
- brw_set_saturate(p, 0);
-}
-
-static void emit_ddy(struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- struct brw_compile *p = &c->func;
- GLuint mask = inst->DstReg.WriteMask;
- struct brw_reg interp[4];
- struct brw_reg dst;
- struct brw_reg src0, w;
- GLuint nr, i;
-
- src0 = get_src_reg(c, inst, 0, 0);
- nr = src0.nr;
- w = get_src_reg(c, inst, 1, 3);
- interp[0] = brw_vec1_grf(nr, 0);
- interp[1] = brw_vec1_grf(nr, 4);
- interp[2] = brw_vec1_grf(nr+1, 0);
- interp[3] = brw_vec1_grf(nr+1, 4);
- brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
- for(i = 0; i < 4; i++ ) {
- if (mask & (1<<i)) {
- dst = get_dst_reg(c, inst, i);
- brw_MOV(p, dst, suboffset(interp[i], 1));
- brw_MUL(p, dst, dst, w);
- }
- }
- brw_set_saturate(p, 0);
-}
-
static INLINE struct brw_reg high_words( struct brw_reg reg )
{
return stride( suboffset( retype( reg, BRW_REGISTER_TYPE_W ), 1 ),
@@ -2780,6 +2724,21 @@ static void post_wm_emit( struct brw_wm_compile *c )
brw_resolve_cals(&c->func);
}
+static void
+get_argument_regs(struct brw_wm_compile *c,
+ const struct prog_instruction *inst,
+ int index,
+ struct brw_reg *regs,
+ int mask)
+{
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ if (mask & (1 << i))
+ regs[i] = get_src_reg(c, inst, index, i);
+ }
+}
+
static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
{
#define MAX_IF_DEPTH 32
@@ -2797,6 +2756,9 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
for (i = 0; i < c->nr_fp_insns; i++) {
const struct prog_instruction *inst = &c->prog_instructions[i];
+ int dst_flags;
+ struct brw_reg args[3][4], dst[4];
+ int j;
c->cur_inst = i;
@@ -2814,6 +2776,10 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
else
brw_set_conditionalmod(p, BRW_CONDITIONAL_NONE);
+ dst_flags = inst->DstReg.WriteMask;
+ if (inst->SaturateMode == SATURATE_ZERO_ONE)
+ dst_flags |= SATURATE;
+
switch (inst->Opcode) {
case WM_PIXELXY:
emit_pixel_xy(c, inst);
@@ -2899,10 +2865,16 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
emit_min_max(c, inst);
break;
case OPCODE_DDX:
- emit_ddx(c, inst);
- break;
case OPCODE_DDY:
- emit_ddy(c, inst);
+ for (j = 0; j < 4; j++) {
+ if (inst->DstReg.WriteMask & (1 << j))
+ dst[j] = get_dst_reg(c, inst, j);
+ else
+ dst[j] = brw_null_reg();
+ }
+ get_argument_regs(c, inst, 0, args[0], WRITEMASK_XYZW);
+ emit_ddxy(p, dst, dst_flags, (inst->Opcode == OPCODE_DDX),
+ args[0]);
break;
case OPCODE_SLT:
emit_slt(c, inst);
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index 9c68bfd78b2..b4493940292 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass1.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
@@ -178,6 +178,11 @@ void brw_wm_pass1( struct brw_wm_compile *c )
read1 = writemask;
break;
+ case OPCODE_DDX:
+ case OPCODE_DDY:
+ read0 = writemask;
+ break;
+
case OPCODE_MAD:
case OPCODE_CMP:
case OPCODE_LRP:
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index c55c5c426e0..7f6fb66d52f 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -207,8 +207,12 @@ intel_bufferobj_subdata(GLcontext * ctx,
if (intel_obj->sys_buffer)
memcpy((char *)intel_obj->sys_buffer + offset, data, size);
- else
+ else {
+ /* Flush any existing batchbuffer that might reference this data. */
+ intelFlush(ctx);
+
dri_bo_subdata(intel_obj->buffer, offset, size, data);
+ }
}
diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c
index bce23724b38..fb62f0f430a 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -38,6 +38,7 @@
#include "intel_fbo.h"
#include "intel_pixel.h"
#include "intel_regions.h"
+#include "intel_batchbuffer.h"
#define FILE_DEBUG_FLAG DEBUG_BLIT
@@ -170,7 +171,8 @@ intelClear(GLcontext *ctx, GLbitfield mask)
}
DBG("\n");
}
- _mesa_meta_clear(&intel->ctx, tri_mask);
+
+ _mesa_meta_Clear(&intel->ctx, tri_mask);
}
if (swrast_mask) {
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 7e21b94acc4..d49d95768db 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -507,7 +507,8 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
if (screen->dri2.loader &&
(screen->dri2.loader->base.version >= 2)
- && (screen->dri2.loader->flushFrontBuffer != NULL)) {
+ && (screen->dri2.loader->flushFrontBuffer != NULL) &&
+ intel->driDrawable && intel->driDrawable->loaderPrivate) {
(*screen->dri2.loader->flushFrontBuffer)(intel->driDrawable,
intel->driDrawable->loaderPrivate);
@@ -587,11 +588,6 @@ intelInitDriverFunctions(struct dd_function_table *functions)
functions->GetString = intelGetString;
functions->UpdateState = intelInvalidateState;
- functions->CopyColorTable = _swrast_CopyColorTable;
- functions->CopyColorSubTable = _swrast_CopyColorSubTable;
- functions->CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
- functions->CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
-
intelInitTextureFuncs(functions);
intelInitTextureImageFuncs(functions);
intelInitTextureSubImageFuncs(functions);
@@ -922,6 +918,14 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
GLboolean
intelUnbindContext(__DRIcontextPrivate * driContextPriv)
{
+ struct intel_context *intel =
+ (struct intel_context *) driContextPriv->driverPrivate;
+
+ /* Deassociate the context with the drawables.
+ */
+ intel->driDrawable = NULL;
+ intel->driReadDrawable = NULL;
+
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 804c0348401..8dfb24290d5 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -715,5 +715,5 @@ intel_fbo_init(struct intel_context *intel)
intel->ctx.Driver.FinishRenderTexture = intel_finish_render_texture;
intel->ctx.Driver.ResizeBuffers = intel_resize_buffers;
intel->ctx.Driver.ValidateFramebuffer = intel_validate_framebuffer;
- intel->ctx.Driver.BlitFramebuffer = _mesa_meta_blit_framebuffer;
+ intel->ctx.Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
}
diff --git a/src/mesa/drivers/dri/intel/intel_generatemipmap.c b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
index fe986092db6..5958b36c971 100644
--- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c
+++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
@@ -125,6 +125,8 @@ intel_generate_mipmap_2d(GLcontext *ctx,
GLuint fb_name;
GLboolean success = GL_FALSE;
struct gl_framebuffer *saved_fbo = NULL;
+ struct gl_buffer_object *saved_array_buffer = NULL;
+ struct gl_buffer_object *saved_element_buffer = NULL;
_mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
GL_CURRENT_BIT | GL_COLOR_BUFFER_BIT |
@@ -133,6 +135,16 @@ intel_generate_mipmap_2d(GLcontext *ctx,
old_active_texture = ctx->Texture.CurrentUnit;
_mesa_reference_framebuffer(&saved_fbo, ctx->DrawBuffer);
+ /* use default array/index buffers */
+ _mesa_reference_buffer_object(ctx, &saved_array_buffer,
+ ctx->Array.ArrayBufferObj);
+ _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
+ ctx->Shared->NullBufferObj);
+ _mesa_reference_buffer_object(ctx, &saved_element_buffer,
+ ctx->Array.ElementArrayBufferObj);
+ _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj,
+ ctx->Shared->NullBufferObj);
+
_mesa_Disable(GL_POLYGON_STIPPLE);
_mesa_Disable(GL_DEPTH_TEST);
_mesa_Disable(GL_STENCIL_TEST);
@@ -205,6 +217,15 @@ fail:
meta_restore_fragment_program(&intel->meta);
meta_restore_vertex_program(&intel->meta);
+ /* restore array/index buffers */
+ _mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
+ saved_array_buffer);
+ _mesa_reference_buffer_object(ctx, &saved_array_buffer, NULL);
+ _mesa_reference_buffer_object(ctx, &ctx->Array.ElementArrayBufferObj,
+ saved_element_buffer);
+ _mesa_reference_buffer_object(ctx, &saved_element_buffer, NULL);
+
+
_mesa_DeleteFramebuffersEXT(1, &fb_name);
_mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
if (saved_fbo)
@@ -223,10 +244,6 @@ fail:
*
* The texture object's miptree must be mapped.
*
- * It would be really nice if this was just called by Mesa whenever mipmaps
- * needed to be regenerated, rather than us having to remember to do so in
- * each texture image modification path.
- *
* This function should also include an accelerated path.
*/
void
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
index 07ca8f7ddb5..f058b3c8e4d 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
@@ -240,5 +240,5 @@ intelCopyPixels(GLcontext * ctx,
return;
/* this will use swrast if needed */
- _mesa_meta_copy_pixels(ctx, srcx, srcy, width, height, destx, desty, type);
+ _mesa_meta_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
}
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_draw.c b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
index 7fbb89fd6aa..5ffa847fd4a 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -54,7 +54,7 @@
#include "intel_fbo.h"
-/** XXX compare perf of this vs. _mesa_meta_draw_pixels(STENCIL) */
+/** XXX compare perf of this vs. _mesa_meta_DrawPixels(STENCIL) */
static GLboolean
intel_stencil_drawpixels(GLcontext * ctx,
GLint x, GLint y,
@@ -265,7 +265,7 @@ intelDrawPixels(GLcontext * ctx,
/* XXX this function doesn't seem to work reliably even when all
* the pre-requisite conditions are met.
* Note that this function is never hit with conform.
- * Fall back to swrast because even the _mesa_meta_draw_pixels() approach
+ * Fall back to swrast because even the _mesa_meta_DrawPixels() approach
* isn't working because of an apparent stencil bug.
*/
if (intel_stencil_drawpixels(ctx, x, y, width, height, format, type,
@@ -280,6 +280,6 @@ intelDrawPixels(GLcontext * ctx,
}
#endif
- _mesa_meta_draw_pixels(ctx, x, y, width, height, format, type,
- unpack, pixels);
+ _mesa_meta_DrawPixels(ctx, x, y, width, height, format, type,
+ unpack, pixels);
}
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 1e739434577..28eabbc0054 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -448,24 +448,22 @@ intel_map_unmap_framebuffer(struct intel_context *intel,
struct gl_framebuffer *fb,
GLboolean map)
{
- GLcontext *ctx = &intel->ctx;
- GLuint i, j;
-
- /* color buffers */
- if (fb == ctx->DrawBuffer) {
- for (j = 0; j < fb->_NumColorDrawBuffers; j++) {
- if (map)
- intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[j]);
- else
- intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[j]);
- }
- } else {
+ GLuint i;
+
+ /* color draw buffers */
+ for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
if (map)
- intel_renderbuffer_map(intel, fb->_ColorReadBuffer);
+ intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]);
else
- intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer);
+ intel_renderbuffer_unmap(intel, fb->_ColorDrawBuffers[i]);
}
+ /* color read buffer */
+ if (map)
+ intel_renderbuffer_map(intel, fb->_ColorReadBuffer);
+ else
+ intel_renderbuffer_unmap(intel, fb->_ColorReadBuffer);
+
/* check for render to textures */
for (i = 0; i < BUFFER_COUNT; i++) {
struct gl_renderbuffer_attachment *att =
@@ -484,20 +482,17 @@ intel_map_unmap_framebuffer(struct intel_context *intel,
/* depth buffer (Note wrapper!) */
if (fb->_DepthBuffer) {
if (map)
- intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
+ intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
else
- intel_renderbuffer_unmap(intel,
- fb->_DepthBuffer->Wrapped);
+ intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped);
}
/* stencil buffer (Note wrapper!) */
if (fb->_StencilBuffer) {
if (map)
- intel_renderbuffer_map(intel,
- fb->_StencilBuffer->Wrapped);
+ intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped);
else
- intel_renderbuffer_unmap(intel,
- fb->_StencilBuffer->Wrapped);
+ intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped);
}
}
@@ -524,7 +519,8 @@ intelSpanRenderStart(GLcontext * ctx)
}
intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE);
- intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
}
/**
@@ -547,7 +543,8 @@ intelSpanRenderFinish(GLcontext * ctx)
}
intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
- intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
UNLOCK_HARDWARE(intel);
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 028b49c14d3..ac557a92005 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_copy.c
@@ -30,7 +30,8 @@
#include "main/image.h"
#include "main/teximage.h"
#include "main/mipmap.h"
-#include "swrast/swrast.h"
+
+#include "drivers/common/meta.h"
#include "intel_screen.h"
#include "intel_context.h"
@@ -90,7 +91,6 @@ do_copy_texsubimage(struct intel_context *intel,
GLint x, GLint y, GLsizei width, GLsizei height)
{
GLcontext *ctx = &intel->ctx;
- struct gl_texture_object *texObj = intelImage->base.TexObject;
const struct intel_region *src =
get_teximage_source(intel, internalFormat);
@@ -170,11 +170,6 @@ do_copy_texsubimage(struct intel_context *intel,
UNLOCK_HARDWARE(intel);
- /* GL_SGIS_generate_mipmap */
- if (intelImage->level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target, texObj);
- }
-
return GL_TRUE;
}
@@ -221,8 +216,8 @@ intelCopyTexImage1D(GLcontext * ctx, GLenum target, GLint level,
return;
fail:
- _swrast_copy_teximage1d(ctx, target, level, internalFormat, x, y,
- width, border);
+ _mesa_meta_CopyTexImage1D(ctx, target, level, internalFormat, x, y,
+ width, border);
}
@@ -269,8 +264,8 @@ intelCopyTexImage2D(GLcontext * ctx, GLenum target, GLint level,
return;
fail:
- _swrast_copy_teximage2d(ctx, target, level, internalFormat, x, y,
- width, height, border);
+ _mesa_meta_CopyTexImage2D(ctx, target, level, internalFormat, x, y,
+ width, height, border);
}
@@ -294,7 +289,7 @@ intelCopyTexSubImage1D(GLcontext * ctx, GLenum target, GLint level,
if (!do_copy_texsubimage(intel_context(ctx), target,
intel_texture_image(texImage),
internalFormat, xoffset, 0, x, y, width, 1)) {
- _swrast_copy_texsubimage1d(ctx, target, level, xoffset, x, y, width);
+ _mesa_meta_CopyTexSubImage1D(ctx, target, level, xoffset, x, y, width);
}
}
@@ -320,10 +315,10 @@ intelCopyTexSubImage2D(GLcontext * ctx, GLenum target, GLint level,
internalFormat,
xoffset, yoffset, x, y, width, height)) {
- DBG("%s - fallback to swrast\n", __FUNCTION__);
+ DBG("%s - fallback to _mesa_meta_CopyTexSubImage2D\n", __FUNCTION__);
- _swrast_copy_texsubimage2d(ctx, target, level,
- xoffset, yoffset, x, y, width, height);
+ _mesa_meta_CopyTexSubImage2D(ctx, target, level,
+ xoffset, yoffset, x, y, width, height);
}
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c
index a206fe6805b..66201b1f465 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -546,11 +546,6 @@ intelTexImage(GLcontext * ctx,
}
UNLOCK_HARDWARE(intel);
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target, texObj);
- }
}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_subimage.c b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
index 89037073f84..751ec2c98c2 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -129,11 +129,6 @@ intelTexSubimage(GLcontext * ctx,
}
UNLOCK_HARDWARE(intel);
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- intel_generate_mipmap(ctx, target, texObj);
- }
}
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index 42635bf9d90..fbce70c37bc 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -55,8 +55,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
X86_SOURCES =
-DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200 \
- -Wall
+DRIVER_DEFINES = -DRADEON_R200 -Wall
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 5d8d6f66589..fe775eac99a 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -62,8 +62,7 @@ DRIVER_SOURCES = \
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
-DRIVER_DEFINES = -DCOMPILE_R300 -DR200_MERGED=0 \
- -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R300 \
+DRIVER_DEFINES = -DRADEON_R300
# -DRADEON_BO_TRACK \
-Wall
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
index 305dc074ee8..c7227bbd15b 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
@@ -352,7 +352,7 @@ void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compi
if (emit.current_node < 3) {
int shift = 3 - emit.current_node;
int i;
- for(i = 0; i <= emit.current_node; ++i)
+ for(i = emit.current_node; i >= 0; --i)
code->code_addr[shift + i] = code->code_addr[i];
for(i = 0; i < shift; ++i)
code->code_addr[i] = 0;
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
index 93a516105e6..dad27fc98e6 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -89,6 +89,7 @@ static unsigned long t_dst_index(struct r300_vertex_program_code *vp,
static unsigned long t_src_class(gl_register_file file)
{
switch (file) {
+ case PROGRAM_BUILTIN:
case PROGRAM_TEMPORARY:
return PVS_SRC_REG_TEMPORARY;
case PROGRAM_INPUT:
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
index bbbf0dd7768..b636f90a968 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -150,14 +150,37 @@ void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * progr
c->Program.InputsRead = program->InputsRead;
c->Program.OutputsWritten = program->OutputsWritten;
- for(i = 0; i < program->Parameters->NumParameters; ++i) {
- struct rc_constant constant;
+ int isNVProgram = 0;
- constant.Type = RC_CONSTANT_EXTERNAL;
- constant.Size = 4;
- constant.u.External = i;
+ if (program->Target == GL_VERTEX_PROGRAM_ARB) {
+ struct gl_vertex_program * vp = (struct gl_vertex_program *) program;
+ isNVProgram = vp->IsNVProgram;
+ }
+
+ if (isNVProgram) {
+ /* NV_vertex_program has a fixed-sized constant environment.
+ * This could be handled more efficiently for programs that
+ * do not use relative addressing.
+ */
+ for(i = 0; i < 96; ++i) {
+ struct rc_constant constant;
- rc_constants_add(&c->Program.Constants, &constant);
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+
+ rc_constants_add(&c->Program.Constants, &constant);
+ }
+ } else {
+ for(i = 0; i < program->Parameters->NumParameters; ++i) {
+ struct rc_constant constant;
+
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+
+ rc_constants_add(&c->Program.Constants, &constant);
+ }
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index 8071899eaa4..f23ce301cab 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -511,23 +511,23 @@ static void sincos_constants(struct radeon_compiler* c, GLuint *constants)
* MAD dest, tmp.y, weight, tmp.x
*/
static void sin_approx(
- struct radeon_compiler* c, struct rc_instruction * after,
+ struct radeon_compiler* c, struct rc_instruction * before,
struct prog_dst_register dst, struct prog_src_register src, const GLuint* constants)
{
GLuint tempreg = rc_find_free_temporary(c);
- emit2(c, after->Prev, OPCODE_MUL, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
+ emit2(c, before->Prev, OPCODE_MUL, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
swizzle(src, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
srcreg(PROGRAM_CONSTANT, constants[0]));
- emit3(c, after->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_X),
+ emit3(c, before->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_X),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
absolute(swizzle(src, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
- emit3(c, after->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_Y),
+ emit3(c, before->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_Y),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
absolute(swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
negate(swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)));
- emit3(c, after->Prev, OPCODE_MAD, 0, dst,
+ emit3(c, before->Prev, OPCODE_MAD, 0, dst,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
@@ -567,7 +567,7 @@ GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
negate(swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)));
- sin_approx(c, inst->Prev, inst->I.DstReg,
+ sin_approx(c, inst, inst->I.DstReg,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
constants);
} else if (inst->I.Opcode == OPCODE_SIN) {
@@ -582,7 +582,7 @@ GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
negate(swizzle(srcreg(PROGRAM_CONSTANT, constants[0]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z)));
- sin_approx(c, inst->Prev, inst->I.DstReg,
+ sin_approx(c, inst, inst->I.DstReg,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
constants);
} else {
@@ -600,12 +600,12 @@ GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
struct prog_dst_register dst = inst->I.DstReg;
dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_X;
- sin_approx(c, inst->Prev, dst,
+ sin_approx(c, inst, dst,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
constants);
dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_Y;
- sin_approx(c, inst->Prev, dst,
+ sin_approx(c, inst, dst,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
constants);
}
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
index 469c278b510..0bdc90b4a84 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
@@ -99,8 +99,8 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler,
{
int i;
+ fp->wpos_attr = FRAG_ATTRIB_MAX;
if (!(compiler->Base.Program.InputsRead & FRAG_BIT_WPOS)) {
- fp->wpos_attr = FRAG_ATTRIB_MAX;
return;
}
@@ -112,6 +112,13 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler,
}
}
+ /* No free texcoord found, fall-back to software rendering */
+ if (fp->wpos_attr == FRAG_ATTRIB_MAX)
+ {
+ compiler->Base.Error = 1;
+ return;
+ }
+
rc_transform_fragment_wpos(&compiler->Base, FRAG_ATTRIB_WPOS, fp->wpos_attr);
}
@@ -127,8 +134,8 @@ static void rewriteFog(struct r300_fragment_program_compiler *compiler, struct r
struct prog_src_register src;
int i;
+ fp->fog_attr = FRAG_ATTRIB_MAX;
if (!(compiler->Base.Program.InputsRead & FRAG_BIT_FOGC)) {
- fp->fog_attr = FRAG_ATTRIB_MAX;
return;
}
@@ -140,6 +147,13 @@ static void rewriteFog(struct r300_fragment_program_compiler *compiler, struct r
}
}
+ /* No free texcoord found, fall-back to software rendering */
+ if (fp->fog_attr == FRAG_ATTRIB_MAX)
+ {
+ compiler->Base.Error = 1;
+ return;
+ }
+
memset(&src, 0, sizeof(src));
src.File = PROGRAM_INPUT;
src.Index = fp->fog_attr;
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index b5ddfdc9f82..3cd38753b8a 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -475,7 +475,7 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
/* update only if we have disabled all tcl fallbacks */
if (rmesa->options.hw_tcl_enabled) {
- if ((old_fallback & R300_RASTER_FALLBACK_MASK) == bit) {
+ if ((old_fallback & R300_TCL_FALLBACK_MASK) == bit) {
R300_STATECHANGE(rmesa, vap_cntl_status);
rmesa->hw.vap_cntl_status.cmd[1] &= ~R300_VAP_TCL_BYPASS;
}
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index dd0f27f9cba..2f7b67c1431 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -43,6 +43,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "compiler/radeon_compiler.h"
#include "compiler/radeon_nqssadce.h"
#include "r300_context.h"
+#include "r300_fragprog_common.h"
#include "r300_state.h"
/**
@@ -203,6 +204,34 @@ static void t_inputs_outputs(struct r300_vertex_program_compiler * c)
}
}
+/**
+ * The NV_vertex_program spec mandates that all registers be
+ * initialized to zero. We do this here unconditionally.
+ *
+ * \note We rely on dead-code elimination in the compiler.
+ */
+static void initialize_NV_registers(struct radeon_compiler * compiler)
+{
+ unsigned int reg;
+ struct rc_instruction * inst;
+
+ for(reg = 0; reg < 12; ++reg) {
+ inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = reg;
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_0000;
+ }
+
+ inst = rc_insert_new_instruction(compiler, &compiler->Program.Instructions);
+ inst->I.Opcode = OPCODE_ARL;
+ inst->I.DstReg.File = PROGRAM_ADDRESS;
+ inst->I.DstReg.Index = 0;
+ inst->I.DstReg.WriteMask = WRITEMASK_X;
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_0000;
+}
static struct r300_vertex_program *build_program(GLcontext *ctx,
struct r300_vertex_program_key *wanted_key,
@@ -234,6 +263,9 @@ static struct r300_vertex_program *build_program(GLcontext *ctx,
rc_mesa_to_rc_program(&compiler.Base, &vp->Base->Base);
+ if (mesa_vp->IsNVProgram)
+ initialize_NV_registers(&compiler.Base);
+
rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X);
if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) {
@@ -267,6 +299,20 @@ struct r300_vertex_program * r300SelectAndTranslateVertexShader(GLcontext *ctx)
struct r300_vertex_program *vp;
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
+
+ if (!r300->selected_fp) {
+ /* This can happen when GetProgramiv is called to check
+ * whether the program runs natively.
+ *
+ * To be honest, this is not a very good solution,
+ * but solving the problem of reporting good values
+ * for those queries is tough anyway considering that
+ * we recompile vertex programs based on the precise
+ * fragment program that is in use.
+ */
+ r300SelectAndTranslateFragmentShader(ctx);
+ }
+
wanted_key.FpReads = r300->selected_fp->InputsRead;
wanted_key.FogAttr = r300->selected_fp->fog_attr;
wanted_key.WPosAttr = r300->selected_fp->wpos_attr;
diff --git a/src/mesa/drivers/dri/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
index 250570f6b89..da4812d3234 100644
--- a/src/mesa/drivers/dri/r300/radeon_context.h
+++ b/src/mesa/drivers/dri/r300/radeon_context.h
@@ -51,26 +51,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_screen.h"
-#if R200_MERGED
-extern void radeonFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
-
-#define FALLBACK( radeon, bit, mode ) do { \
- if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
- __FUNCTION__, bit, mode ); \
- radeonFallback( (radeon)->glCtx, bit, mode ); \
-} while (0)
-#else
#define FALLBACK( radeon, bit, mode ) fprintf(stderr, "%s:%s\n", __LINE__, __FILE__);
-#endif
/* TCL fallbacks */
extern void radeonTclFallback(GLcontext * ctx, GLuint bit, GLboolean mode);
-#if R200_MERGED
-#define TCL_FALLBACK( ctx, bit, mode ) radeonTclFallback( ctx, bit, mode )
-#else
#define TCL_FALLBACK( ctx, bit, mode ) ;
-#endif
#endif /* __RADEON_CONTEXT_H__ */
diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile
index d925a2dfe39..7d5a7b1ab6f 100644
--- a/src/mesa/drivers/dri/r600/Makefile
+++ b/src/mesa/drivers/dri/r600/Makefile
@@ -29,6 +29,7 @@ COMMON_SOURCES = \
RADEON_COMMON_SOURCES = \
radeon_bo_legacy.c \
radeon_common_context.c \
+ radeon_buffer_objects.c \
radeon_common.c \
radeon_cs_legacy.c \
radeon_dma.c \
@@ -65,8 +66,7 @@ DRIVER_SOURCES = \
C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
-DRIVER_DEFINES = -DCOMPILE_R600 -DR200_MERGED=0 \
- -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R600 \
+DRIVER_DEFINES = -DRADEON_R600 \
# -DRADEON_BO_TRACK \
-Wall
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index 07a7bcf11f1..969144ba123 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -59,6 +59,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_debug.h"
#include "r600_context.h"
#include "radeon_common_context.h"
+#include "radeon_buffer_objects.h"
#include "radeon_span.h"
#include "r600_cmdbuf.h"
#include "r600_emit.h"
@@ -257,6 +258,7 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
r600InitTextureFuncs(&functions);
r700InitShaderFuncs(&functions);
r700InitIoctlFuncs(&functions);
+ radeonInitBufferObjectFuncs(&functions);
if (!radeonInitContext(&r600->radeon, &functions,
glVisual, driContextPriv,
@@ -284,8 +286,8 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
ctx->Const.MaxTextureMaxAnisotropy = 16.0;
ctx->Const.MaxTextureLodBias = 16.0;
- ctx->Const.MaxTextureLevels = 13;
- ctx->Const.MaxTextureRectSize = 4096;
+ ctx->Const.MaxTextureLevels = 13; /* hw support 14 */
+ ctx->Const.MaxTextureRectSize = 4096; /* hw support 8192 */
ctx->Const.MinPointSize = 0x0001 / 8.0;
ctx->Const.MinPointSizeAA = 0x0001 / 8.0;
@@ -330,26 +332,27 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
_tnl_allow_pixel_fog(ctx, GL_FALSE);
_tnl_allow_vertex_fog(ctx, GL_TRUE);
- /* currently bogus data */
- ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
- ctx->Const.VertexProgram.MaxNativeInstructions =
- VSF_MAX_FRAGMENT_LENGTH / 4;
- ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */
- ctx->Const.VertexProgram.MaxTemps = 32;
- ctx->Const.VertexProgram.MaxNativeTemps =
- /*VSF_MAX_FRAGMENT_TEMPS */ 32;
- ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */
- ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
-
- ctx->Const.FragmentProgram.MaxNativeTemps = PFS_NUM_TEMP_REGS;
- ctx->Const.FragmentProgram.MaxNativeAttribs = 11; /* copy i915... */
- ctx->Const.FragmentProgram.MaxNativeParameters = PFS_NUM_CONST_REGS;
- ctx->Const.FragmentProgram.MaxNativeAluInstructions = PFS_MAX_ALU_INST;
- ctx->Const.FragmentProgram.MaxNativeTexInstructions = PFS_MAX_TEX_INST;
- ctx->Const.FragmentProgram.MaxNativeInstructions =
- PFS_MAX_ALU_INST + PFS_MAX_TEX_INST;
- ctx->Const.FragmentProgram.MaxNativeTexIndirections =
- PFS_MAX_TEX_INDIRECT;
+ /* 256 for reg-based consts, inline consts also supported */
+ ctx->Const.VertexProgram.MaxInstructions = 8192; /* in theory no limit */
+ ctx->Const.VertexProgram.MaxNativeInstructions = 8192;
+ ctx->Const.VertexProgram.MaxNativeAttribs = 160;
+ ctx->Const.VertexProgram.MaxTemps = 128;
+ ctx->Const.VertexProgram.MaxNativeTemps = 128;
+ ctx->Const.VertexProgram.MaxNativeParameters = 256;
+ ctx->Const.VertexProgram.MaxNativeAddressRegs = 1; /* ??? */
+
+ ctx->Const.FragmentProgram.MaxNativeTemps = 128;
+ ctx->Const.FragmentProgram.MaxNativeAttribs = 32;
+ ctx->Const.FragmentProgram.MaxNativeParameters = 256;
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = 8192;
+ /* 8 per clause on r6xx, 16 on rv670/r7xx */
+ if ((screen->chip_family == CHIP_FAMILY_RV670) ||
+ (screen->chip_family >= CHIP_FAMILY_RV770))
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = 16;
+ else
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = 8;
+ ctx->Const.FragmentProgram.MaxNativeInstructions = 8192;
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections = 8; /* ??? */
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* and these are?? */
ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
@@ -374,6 +377,8 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
+ r700InitDraw(ctx);
+
radeon_fbo_init(&r600->radeon);
radeonInitSpanFuncs( ctx );
@@ -385,9 +390,6 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
if (driQueryOptionb(&r600->radeon.optionCache, "no_rast")) {
radeon_warning("disabling 3D acceleration\n");
-#if R200_MERGED
- FALLBACK(&r600->radeon, RADEON_FALLBACK_DISABLE, 1);
-#endif
}
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h
index 8ae05a301c7..a296ea23fa4 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r700_chip.h"
#include "r600_tex.h"
#include "r700_oglprog.h"
+#include "r700_vertprog.h"
struct r600_context;
typedef struct r600_context context_t;
@@ -85,29 +86,10 @@ extern int hw_tcl_on;
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
-#define PFS_MAX_ALU_INST 64
-#define PFS_MAX_TEX_INST 64
-#define PFS_MAX_TEX_INDIRECT 4
-#define PFS_NUM_TEMP_REGS 32
-#define PFS_NUM_CONST_REGS 16
-
-#define R600_MAX_AOS_ARRAYS 16
-
-#define REG_COORDS 0
-#define REG_COLOR0 1
-#define REG_TEX0 2
-
#define R600_FALLBACK_NONE 0
#define R600_FALLBACK_TCL 1
#define R600_FALLBACK_RAST 2
-enum
-{
- NO_SHIFT = 0,
- LEFT_SHIFT = 1,
- RIGHT_SHIFT = 2,
-};
-
struct r600_hw_state {
struct radeon_state_atom sq;
struct radeon_state_atom db;
@@ -144,6 +126,34 @@ struct r600_hw_state {
struct radeon_state_atom tx_brdr_clr;
};
+typedef struct StreamDesc
+{
+ GLint size; //number of data element
+ GLenum type; //data element type
+ GLsizei stride;
+
+ struct radeon_bo *bo;
+ GLint bo_offset;
+
+ GLuint dwords;
+ GLuint dst_loc;
+ GLuint _signed;
+ GLboolean normalize;
+ GLboolean is_named_bo;
+ GLubyte element;
+} StreamDesc;
+
+typedef struct r700_index_buffer
+{
+ struct radeon_bo *bo;
+ int bo_offset;
+
+ GLboolean is_32bit;
+ GLuint count;
+
+ GLboolean bHostIb;
+} r700_index_buffer;
+
/**
* \brief R600 context structure.
*/
@@ -155,11 +165,16 @@ struct r600_context {
struct r600_hw_state atoms;
+ struct r700_vertex_program *selected_vp;
+
/* Vertex buffers
*/
GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
+ GLint nNumActiveAos;
+ StreamDesc stream_desc[VERT_ATTRIB_MAX];
+ struct r700_index_buffer ind_buf;
};
#define R700_CONTEXT(ctx) ((context_t *)(ctx->DriverCtx))
@@ -193,6 +208,7 @@ extern GLboolean r700SyncSurf(context_t *context,
extern void r700SetupStreams(GLcontext * ctx);
extern void r700Start3D(context_t *context);
extern void r600InitAtoms(context_t *context);
+extern void r700InitDraw(GLcontext *ctx);
#define RADEON_D_CAPTURE 0
#define RADEON_D_PLAYBACK 1
diff --git a/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h b/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h
index 9d5aa3c7e49..edd85b0facc 100644
--- a/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h
+++ b/src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h
@@ -1366,6 +1366,7 @@ enum {
DB_DEPTH_INFO__READ_SIZE_bit = 1 << 3,
DB_DEPTH_INFO__ARRAY_MODE_mask = 0x0f << 15,
DB_DEPTH_INFO__ARRAY_MODE_shift = 15,
+ ARRAY_1D_TILED_THIN1 = 0x02,
ARRAY_2D_TILED_THIN1 = 0x04,
TILE_SURFACE_ENABLE_bit = 1 << 25,
TILE_COMPACT_bit = 1 << 26,
@@ -1449,6 +1450,7 @@ enum {
CB_COLOR0_INFO__ARRAY_MODE_shift = 8,
ARRAY_LINEAR_GENERAL = 0x00,
ARRAY_LINEAR_ALIGNED = 0x01,
+/* ARRAY_1D_TILED_THIN1 = 0x02, */
/* ARRAY_2D_TILED_THIN1 = 0x04, */
NUMBER_TYPE_mask = 0x07 << 12,
NUMBER_TYPE_shift = 12,
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 2d8480daaf7..903b6968be1 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -213,7 +213,7 @@ GLboolean is_reduction_opcode(PVSDWORD* dest)
{
if (dest->dst.op3 == 0)
{
- if ( (dest->dst.opcode == SQ_OP2_INST_DOT4 || dest->dst.opcode == SQ_OP2_INST_DOT4_IEEE) )
+ if ( (dest->dst.opcode == SQ_OP2_INST_DOT4 || dest->dst.opcode == SQ_OP2_INST_DOT4_IEEE || dest->dst.opcode == SQ_OP2_INST_CUBE) )
{
return GL_TRUE;
}
@@ -350,6 +350,7 @@ unsigned int r700GetNumOperands(r700_AssemblerBase* pAsm)
case SQ_OP2_INST_PRED_SETNE:
case SQ_OP2_INST_DOT4:
case SQ_OP2_INST_DOT4_IEEE:
+ case SQ_OP2_INST_CUBE:
return 2;
case SQ_OP2_INST_MOV:
@@ -469,6 +470,9 @@ int Init_r700_AssemblerBase(SHADER_PIPE_TYPE spt, r700_AssemblerBase* pAsm, R700
pAsm->number_of_inputs = 0;
+ pAsm->is_tex = GL_FALSE;
+ pAsm->need_tex_barrier = GL_FALSE;
+
return 0;
}
@@ -682,7 +686,7 @@ GLboolean add_tex_instruction(r700_AssemblerBase* pAsm,
// If this clause constains any TEX instruction that is dependent on a previous instruction,
// set the barrier bit
- if( pAsm->pInstDeps[pAsm->uiCurInst].nDstDep > (-1) )
+ if( pAsm->pInstDeps[pAsm->uiCurInst].nDstDep > (-1) || pAsm->need_tex_barrier == GL_TRUE )
{
pAsm->cf_current_tex_clause_ptr->m_Word1.f.barrier = 0x1;
}
@@ -786,6 +790,133 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
return GL_TRUE;
}
+GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
+ GLuint destination_register,
+ GLenum type,
+ GLint size,
+ GLubyte element,
+ GLuint _signed,
+ GLboolean normalize,
+ VTX_FETCH_METHOD * pFetchMethod)
+{
+ GLuint client_size_inbyte;
+ GLuint data_format;
+ GLuint mega_fetch_count;
+ GLuint is_mega_fetch_flag;
+
+ R700VertexGenericFetch* vfetch_instruction_ptr;
+ R700VertexGenericFetch* assembled_vfetch_instruction_ptr
+ = pAsm->vfetch_instruction_ptr_array[element];
+
+ if (assembled_vfetch_instruction_ptr == NULL)
+ {
+ vfetch_instruction_ptr = (R700VertexGenericFetch*) CALLOC_STRUCT(R700VertexGenericFetch);
+ if (vfetch_instruction_ptr == NULL)
+ {
+ return GL_FALSE;
+ }
+ Init_R700VertexGenericFetch(vfetch_instruction_ptr);
+ }
+ else
+ {
+ vfetch_instruction_ptr = assembled_vfetch_instruction_ptr;
+ }
+
+ data_format = GetSurfaceFormat(type, size, &client_size_inbyte);
+
+ if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here
+ {
+ //TODO : mini fetch
+ }
+ else
+ {
+ mega_fetch_count = MEGA_FETCH_BYTES - 1;
+ is_mega_fetch_flag = 0x1;
+ pFetchMethod->mega_fetch_remainder = MEGA_FETCH_BYTES - client_size_inbyte;
+ }
+
+ vfetch_instruction_ptr->m_Word0.f.vtx_inst = SQ_VTX_INST_FETCH;
+ vfetch_instruction_ptr->m_Word0.f.fetch_type = SQ_VTX_FETCH_VERTEX_DATA;
+ vfetch_instruction_ptr->m_Word0.f.fetch_whole_quad = 0x0;
+
+ vfetch_instruction_ptr->m_Word0.f.buffer_id = element;
+ vfetch_instruction_ptr->m_Word0.f.src_gpr = 0x0;
+ vfetch_instruction_ptr->m_Word0.f.src_rel = SQ_ABSOLUTE;
+ vfetch_instruction_ptr->m_Word0.f.src_sel_x = SQ_SEL_X;
+ vfetch_instruction_ptr->m_Word0.f.mega_fetch_count = mega_fetch_count;
+
+ vfetch_instruction_ptr->m_Word1.f.dst_sel_x = (size < 1) ? SQ_SEL_0 : SQ_SEL_X;
+ vfetch_instruction_ptr->m_Word1.f.dst_sel_y = (size < 2) ? SQ_SEL_0 : SQ_SEL_Y;
+ vfetch_instruction_ptr->m_Word1.f.dst_sel_z = (size < 3) ? SQ_SEL_0 : SQ_SEL_Z;
+ vfetch_instruction_ptr->m_Word1.f.dst_sel_w = (size < 4) ? SQ_SEL_1 : SQ_SEL_W;
+
+ vfetch_instruction_ptr->m_Word1.f.use_const_fields = 1;
+ vfetch_instruction_ptr->m_Word1.f.data_format = data_format;
+ vfetch_instruction_ptr->m_Word2.f.endian_swap = SQ_ENDIAN_NONE;
+
+ if(1 == _signed)
+ {
+ vfetch_instruction_ptr->m_Word1.f.format_comp_all = SQ_FORMAT_COMP_SIGNED;
+ }
+ else
+ {
+ vfetch_instruction_ptr->m_Word1.f.format_comp_all = SQ_FORMAT_COMP_UNSIGNED;
+ }
+
+ if(GL_TRUE == normalize)
+ {
+ vfetch_instruction_ptr->m_Word1.f.num_format_all = SQ_NUM_FORMAT_NORM;
+ }
+ else
+ {
+ vfetch_instruction_ptr->m_Word1.f.num_format_all = SQ_NUM_FORMAT_INT;
+ }
+
+ // Destination register
+ vfetch_instruction_ptr->m_Word1_GPR.f.dst_gpr = destination_register;
+ vfetch_instruction_ptr->m_Word1_GPR.f.dst_rel = SQ_ABSOLUTE;
+
+ vfetch_instruction_ptr->m_Word2.f.offset = 0;
+ vfetch_instruction_ptr->m_Word2.f.const_buf_no_stride = 0x0;
+
+ vfetch_instruction_ptr->m_Word2.f.mega_fetch = is_mega_fetch_flag;
+
+ if (assembled_vfetch_instruction_ptr == NULL)
+ {
+ if ( GL_FALSE == add_vfetch_instruction(pAsm, (R700VertexInstruction *)vfetch_instruction_ptr) )
+ {
+ return GL_FALSE;
+ }
+
+ if (pAsm->vfetch_instruction_ptr_array[element] != NULL)
+ {
+ return GL_FALSE;
+ }
+ else
+ {
+ pAsm->vfetch_instruction_ptr_array[element] = vfetch_instruction_ptr;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm)
+{
+ GLint i;
+ pAsm->cf_current_clause_type = CF_EMPTY_CLAUSE;
+ pAsm->cf_current_vtx_clause_ptr = NULL;
+
+ for (i=0; i<VERT_ATTRIB_MAX; i++)
+ {
+ pAsm->vfetch_instruction_ptr_array[ i ] = NULL;
+ }
+
+ cleanup_vfetch_shaderinst(pAsm->pR700Shader);
+
+ return GL_TRUE;
+}
+
GLuint gethelpr(r700_AssemblerBase* pAsm)
{
GLuint r = pAsm->uHelpReg;
@@ -1149,41 +1280,55 @@ GLboolean tex_dst(r700_AssemblerBase *pAsm)
GLboolean tex_src(r700_AssemblerBase *pAsm)
{
struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
-
+
GLboolean bValidTexCoord = GL_FALSE;
- switch (pILInst->SrcReg[0].File)
+ if(pAsm->aArgSubst[1] >= 0)
{
- case PROGRAM_TEMPORARY:
bValidTexCoord = GL_TRUE;
-
- pAsm->S[0].src.reg = pILInst->SrcReg[0].Index + pAsm->starting_temp_register_number;
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
-
- break;
- case PROGRAM_INPUT:
- switch (pILInst->SrcReg[0].Index)
- {
- case FRAG_ATTRIB_COL0:
- case FRAG_ATTRIB_COL1:
- case FRAG_ATTRIB_TEX0:
- case FRAG_ATTRIB_TEX1:
- case FRAG_ATTRIB_TEX2:
- case FRAG_ATTRIB_TEX3:
- case FRAG_ATTRIB_TEX4:
- case FRAG_ATTRIB_TEX5:
- case FRAG_ATTRIB_TEX6:
- case FRAG_ATTRIB_TEX7:
+ pAsm->S[0].src.reg = pAsm->aArgSubst[1];
+ }
+ else
+ {
+ switch (pILInst->SrcReg[0].File) {
+ case PROGRAM_CONSTANT:
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_STATE_VAR:
+ break;
+ case PROGRAM_TEMPORARY:
bValidTexCoord = GL_TRUE;
-
- pAsm->S[0].src.reg = pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
- pAsm->S[0].src.rtype = SRC_REG_INPUT;
- }
+ pAsm->S[0].src.reg = pILInst->SrcReg[0].Index +
+ pAsm->starting_temp_register_number;
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ break;
+ case PROGRAM_INPUT:
+ switch (pILInst->SrcReg[0].Index)
+ {
+ case FRAG_ATTRIB_COL0:
+ case FRAG_ATTRIB_COL1:
+ case FRAG_ATTRIB_TEX0:
+ case FRAG_ATTRIB_TEX1:
+ case FRAG_ATTRIB_TEX2:
+ case FRAG_ATTRIB_TEX3:
+ case FRAG_ATTRIB_TEX4:
+ case FRAG_ATTRIB_TEX5:
+ case FRAG_ATTRIB_TEX6:
+ case FRAG_ATTRIB_TEX7:
+ bValidTexCoord = GL_TRUE;
+ pAsm->S[0].src.reg =
+ pAsm->uiFP_AttributeMap[pILInst->SrcReg[0].Index];
+ pAsm->S[0].src.rtype = SRC_REG_INPUT;
+ break;
+ }
break;
+ }
}
if(GL_TRUE == bValidTexCoord)
- {
+ {
setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
}
else
@@ -1201,7 +1346,7 @@ GLboolean tex_src(r700_AssemblerBase *pAsm)
pAsm->S[0].src.negy = (pILInst->SrcReg[0].Negate >> 1) & 0x1;
pAsm->S[0].src.negz = (pILInst->SrcReg[0].Negate >> 2) & 0x1;
pAsm->S[0].src.negw = (pILInst->SrcReg[0].Negate >> 3) & 0x1;
-
+
return GL_TRUE;
}
@@ -1933,9 +2078,9 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
GLuint contiguous_slots_needed;
GLuint uNumSrc = r700GetNumOperands(pAsm);
- GLuint channel_swizzle, j;
- GLuint chan_counter[4] = {0, 0, 0, 0};
- PVSSRC * pSource[3];
+ //GLuint channel_swizzle, j;
+ //GLuint chan_counter[4] = {0, 0, 0, 0};
+ //PVSSRC * pSource[3];
GLboolean bSplitInst = GL_FALSE;
if (1 == pAsm->D.dst.math)
@@ -1947,7 +2092,9 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
{
is_single_scalar_operation = GL_FALSE;
number_of_scalar_operations = 4;
-
+
+/* current assembler doesn't do more than 1 register per source */
+#if 0
/* check read port, only very preliminary algorithm, not count in
src0/1 same comp case and prev slot repeat case; also not count relative
addressing. TODO: improve performance. */
@@ -1982,6 +2129,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
{
bSplitInst = GL_TRUE;
}
+#endif
}
contiguous_slots_needed = 0;
@@ -2016,7 +2164,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- if (pAsm->D.dst.math == 0)
+ if (uNumSrc > 1)
{
// Process source 1
current_source_index = 1;
@@ -2202,7 +2350,7 @@ GLboolean next_ins(r700_AssemblerBase *pAsm)
{
struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
- if( GL_TRUE == IsTex(pILInst->Opcode) )
+ if( GL_TRUE == pAsm->is_tex )
{
if (pILInst->TexSrcTarget == TEXTURE_RECT_INDEX) {
if( GL_FALSE == assemble_tex_instruction(pAsm, GL_FALSE) )
@@ -2246,7 +2394,8 @@ GLboolean next_ins(r700_AssemblerBase *pAsm)
pAsm->S[0].bits = 0;
pAsm->S[1].bits = 0;
pAsm->S[2].bits = 0;
-
+ pAsm->is_tex = GL_FALSE;
+ pAsm->need_tex_barrier = GL_FALSE;
return GL_TRUE;
}
@@ -2870,6 +3019,11 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+
/* dst.y = max(src.x, 0.0) */
pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
pAsm->D.dst.rtype = dstType;
@@ -2881,11 +3035,6 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
pAsm->S[0].src.rtype = srcType;
pAsm->S[0].src.reg = srcReg;
setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
- noneg_PVSSRC(&(pAsm->S[0].src));
- pAsm->S[0].src.swizzlex = SQ_SEL_X;
- pAsm->S[0].src.swizzley = SQ_SEL_X;
- pAsm->S[0].src.swizzlez = SQ_SEL_X;
- pAsm->S[0].src.swizzlew = SQ_SEL_X;
pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
pAsm->S[1].src.reg = tmp;
setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
@@ -2899,34 +3048,47 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
return GL_FALSE;
}
- /* before: dst.w = log(src.y)
- * after : dst.x = log(src.y)
- * why change dest register is that dst.w has been initialized as 1 before
- */
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+
+ swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y, SQ_SEL_Y);
+
+ /* dst.z = log(src.y) */
pAsm->D.dst.opcode = SQ_OP2_INST_LOG_CLAMPED;
pAsm->D.dst.math = 1;
pAsm->D.dst.rtype = dstType;
pAsm->D.dst.reg = dstReg;
- pAsm->D.dst.writex = 1;
+ pAsm->D.dst.writex = 0;
pAsm->D.dst.writey = 0;
- pAsm->D.dst.writez = 0;
+ pAsm->D.dst.writez = 1;
pAsm->D.dst.writew = 0;
pAsm->S[0].src.rtype = srcType;
pAsm->S[0].src.reg = srcReg;
setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
- noneg_PVSSRC(&(pAsm->S[0].src));
- pAsm->S[0].src.swizzlex = SQ_SEL_Y;
- pAsm->S[0].src.swizzley = SQ_SEL_Y;
- pAsm->S[0].src.swizzlez = SQ_SEL_Y;
- pAsm->S[0].src.swizzlew = SQ_SEL_Y;
if( GL_FALSE == next_ins(pAsm) )
{
return GL_FALSE;
}
- /* before: tmp.x = amd MUL_LIT(src.w, dst.w, src.x ) */
- /* after : tmp.x = amd MUL_LIT(src.w, dst.x, src.x ) */
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+
+ if( GL_FALSE == assemble_src(pAsm, 0, 2) )
+ {
+ return GL_FALSE;
+ }
+
+ swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_W, SQ_SEL_W, SQ_SEL_W, SQ_SEL_W);
+
+ swizzleagain_PVSSRC(&(pAsm->S[2].src), SQ_SEL_X, SQ_SEL_X, SQ_SEL_X, SQ_SEL_X);
+
+ /* tmp.x = amd MUL_LIT(src.w, dst.z, src.x ) */
pAsm->D.dst.opcode = SQ_OP3_INST_MUL_LIT;
+ pAsm->D.dst.math = 1;
pAsm->D.dst.op3 = 1;
pAsm->D.dst.rtype = DST_REG_TEMPORARY;
pAsm->D.dst.reg = tmp;
@@ -2938,29 +3100,19 @@ GLboolean assemble_LIT(r700_AssemblerBase *pAsm)
pAsm->S[0].src.rtype = srcType;
pAsm->S[0].src.reg = srcReg;
setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
- noneg_PVSSRC(&(pAsm->S[0].src));
- pAsm->S[0].src.swizzlex = SQ_SEL_W;
- pAsm->S[0].src.swizzley = SQ_SEL_W;
- pAsm->S[0].src.swizzlez = SQ_SEL_W;
- pAsm->S[0].src.swizzlew = SQ_SEL_W;
pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
pAsm->S[1].src.reg = dstReg;
setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
noneg_PVSSRC(&(pAsm->S[1].src));
- pAsm->S[1].src.swizzlex = SQ_SEL_X;
- pAsm->S[1].src.swizzley = SQ_SEL_X;
- pAsm->S[1].src.swizzlez = SQ_SEL_X;
- pAsm->S[1].src.swizzlew = SQ_SEL_X;
+ pAsm->S[1].src.swizzlex = SQ_SEL_Z;
+ pAsm->S[1].src.swizzley = SQ_SEL_Z;
+ pAsm->S[1].src.swizzlez = SQ_SEL_Z;
+ pAsm->S[1].src.swizzlew = SQ_SEL_Z;
pAsm->S[2].src.rtype = srcType;
pAsm->S[2].src.reg = srcReg;
setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
- noneg_PVSSRC(&(pAsm->S[2].src));
- pAsm->S[2].src.swizzlex = SQ_SEL_X;
- pAsm->S[2].src.swizzley = SQ_SEL_X;
- pAsm->S[2].src.swizzlez = SQ_SEL_X;
- pAsm->S[2].src.swizzlew = SQ_SEL_X;
if( GL_FALSE == next_ins(pAsm) )
{
@@ -3366,7 +3518,10 @@ GLboolean assemble_STP(r700_AssemblerBase *pAsm)
GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
{
GLboolean src_const;
+ GLboolean need_barrier = GL_FALSE;
+ checkop1(pAsm);
+
switch (pAsm->pILInst[pAsm->uiCurInst].SrcReg[0].File)
{
case PROGRAM_CONSTANT:
@@ -3374,29 +3529,30 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
src_const = GL_TRUE;
+ break;
case PROGRAM_TEMPORARY:
case PROGRAM_INPUT:
+ default:
src_const = GL_FALSE;
+ break;
}
- if (GL_TRUE == src_const)
+ if (GL_TRUE == src_const)
{
- radeon_error("TODO: Texture coordinates from a constant register not supported.\n");
- return GL_FALSE;
+ if ( GL_FALSE == mov_temp(pAsm, 0) )
+ return GL_FALSE;
+ need_barrier = GL_TRUE;
}
- switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
+ switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
{
case OPCODE_TEX:
- pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
break;
- case OPCODE_TXB:
+ case OPCODE_TXB:
radeon_error("do not support TXB yet\n");
return GL_FALSE;
break;
- case OPCODE_TXP:
- /* TODO : tex proj version : divid first 3 components by 4th */
- pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+ case OPCODE_TXP:
break;
default:
radeon_error("Internal error: bad texture op (not TEX)\n");
@@ -3404,6 +3560,190 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
break;
}
+ if (pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
+ {
+ GLuint tmp = gethelpr(pAsm);
+ pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ pAsm->D.dst.math = 1;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp;
+ pAsm->D.dst.writew = 1;
+
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+ swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_W, SQ_SEL_W, SQ_SEL_W, SQ_SEL_W);
+ if( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ pAsm->D.dst.opcode = SQ_OP2_INST_MUL;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp;
+ pAsm->D.dst.writex = 1;
+ pAsm->D.dst.writey = 1;
+ pAsm->D.dst.writez = 1;
+ pAsm->D.dst.writew = 0;
+
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+ setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+ pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[1].src.reg = tmp;
+ setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_W);
+
+ if( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ pAsm->aArgSubst[1] = tmp;
+ need_barrier = GL_TRUE;
+ }
+
+ if (pAsm->pILInst[pAsm->uiCurInst].TexSrcTarget == TEXTURE_CUBE_INDEX )
+ {
+ GLuint tmp1 = gethelpr(pAsm);
+ GLuint tmp2 = gethelpr(pAsm);
+
+ /* tmp1.xyzw = CUBE(R0.zzxy, R0.yxzz) */
+ pAsm->D.dst.opcode = SQ_OP2_INST_CUBE;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp1;
+ nomask_PVSDST(&(pAsm->D.dst));
+
+ if( GL_FALSE == assemble_src(pAsm, 0, -1) )
+ {
+ return GL_FALSE;
+ }
+
+ if( GL_FALSE == assemble_src(pAsm, 0, 1) )
+ {
+ return GL_FALSE;
+ }
+
+ swizzleagain_PVSSRC(&(pAsm->S[0].src), SQ_SEL_Z, SQ_SEL_Z, SQ_SEL_X, SQ_SEL_Y);
+ swizzleagain_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Y, SQ_SEL_X, SQ_SEL_Z, SQ_SEL_Z);
+
+ if( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
+
+ /* tmp1.z = ABS(tmp1.z) dont have abs support in assembler currently
+ * have to do explicit instruction
+ */
+ pAsm->D.dst.opcode = SQ_OP2_INST_MAX;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp1;
+ pAsm->D.dst.writez = 1;
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp1;
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
+ pAsm->S[1].bits = pAsm->S[0].bits;
+ flipneg_PVSSRC(&(pAsm->S[1].src));
+
+ next_ins(pAsm);
+
+ /* tmp1.z = RCP_e(|tmp1.z|) */
+ pAsm->D.dst.opcode = SQ_OP2_INST_RECIP_IEEE;
+ pAsm->D.dst.math = 1;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp1;
+ pAsm->D.dst.writez = 1;
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp1;
+ pAsm->S[0].src.swizzlex = SQ_SEL_Z;
+
+ next_ins(pAsm);
+
+ /* MULADD R0.x, R0.x, PS1, (0x3FC00000, 1.5f).x
+ * MULADD R0.y, R0.y, PS1, (0x3FC00000, 1.5f).x
+ * muladd has no writemask, have to use another temp
+ * also no support for imm constants, so add 1 here
+ */
+ pAsm->D.dst.opcode = SQ_OP3_INST_MULADD;
+ pAsm->D.dst.op3 = 1;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp2;
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp1;
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
+ setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+ pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[1].src.reg = tmp1;
+ setswizzle_PVSSRC(&(pAsm->S[1].src), SQ_SEL_Z);
+ setaddrmode_PVSSRC(&(pAsm->S[2].src), ADDR_ABSOLUTE);
+ pAsm->S[2].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[2].src.reg = tmp1;
+ setswizzle_PVSSRC(&(pAsm->S[2].src), SQ_SEL_1);
+
+ next_ins(pAsm);
+
+ /* ADD the remaining .5 */
+ pAsm->D.dst.opcode = SQ_OP2_INST_ADD;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp2;
+ pAsm->D.dst.writex = 1;
+ pAsm->D.dst.writey = 1;
+ pAsm->D.dst.writez = 0;
+ pAsm->D.dst.writew = 0;
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp2;
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
+ setaddrmode_PVSSRC(&(pAsm->S[1].src), ADDR_ABSOLUTE);
+ pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[1].src.reg = 252; // SQ_ALU_SRC_0_5
+ noswizzle_PVSSRC(&(pAsm->S[1].src));
+
+ next_ins(pAsm);
+
+ /* tmp1.xy = temp2.xy */
+ pAsm->D.dst.opcode = SQ_OP2_INST_MOV;
+ setaddrmode_PVSDST(&(pAsm->D.dst), ADDR_ABSOLUTE);
+ pAsm->D.dst.rtype = DST_REG_TEMPORARY;
+ pAsm->D.dst.reg = tmp1;
+ pAsm->D.dst.writex = 1;
+ pAsm->D.dst.writey = 1;
+ pAsm->D.dst.writez = 0;
+ pAsm->D.dst.writew = 0;
+
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = tmp2;
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
+
+ next_ins(pAsm);
+ pAsm->aArgSubst[1] = tmp1;
+ need_barrier = GL_TRUE;
+
+ }
+
+ pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+ pAsm->is_tex = GL_TRUE;
+ if ( GL_TRUE == need_barrier )
+ {
+ pAsm->need_tex_barrier = GL_TRUE;
+ }
// Set src1 to tex unit id
pAsm->S[1].src.reg = pAsm->pILInst[pAsm->uiCurInst].TexSrcUnit;
pAsm->S[1].src.rtype = SRC_REG_TEMPORARY;
@@ -3418,16 +3758,31 @@ GLboolean assemble_TEX(r700_AssemblerBase *pAsm)
{
return GL_FALSE;
}
-
+
if( GL_FALSE == tex_src(pAsm) )
{
return GL_FALSE;
}
- if ( GL_FALSE == next_ins(pAsm) )
+ if(pAsm->pILInst[pAsm->uiCurInst].Opcode == OPCODE_TXP)
{
- return GL_FALSE;
+ /* hopefully did swizzles before */
+ noswizzle_PVSSRC(&(pAsm->S[0].src));
}
+
+ if(pAsm->pILInst[pAsm->uiCurInst].TexSrcTarget == TEXTURE_CUBE_INDEX)
+ {
+ /* SAMPLE dst, tmp.yxwy, CUBE */
+ pAsm->S[0].src.swizzlex = SQ_SEL_Y;
+ pAsm->S[0].src.swizzley = SQ_SEL_X;
+ pAsm->S[0].src.swizzlez = SQ_SEL_W;
+ pAsm->S[0].src.swizzlew = SQ_SEL_Y;
+ }
+
+ if ( GL_FALSE == next_ins(pAsm) )
+ {
+ return GL_FALSE;
+ }
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h
index f9c4d849c65..0d4283e4bad 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.h
+++ b/src/mesa/drivers/dri/r600/r700_assembler.h
@@ -374,6 +374,10 @@ typedef struct r700_AssemblerBase
struct prog_instruction * pILInst;
GLuint uiCurInst;
GLboolean bR6xx;
+ /* helper to decide which type of instruction to assemble */
+ GLboolean is_tex;
+ /* we inserted helper intructions and need barrier on next TEX ins */
+ GLboolean need_tex_barrier;
} r700_AssemblerBase;
//Internal use
@@ -411,6 +415,15 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm,
GLuint number_of_elements,
GLenum dataElementType,
VTX_FETCH_METHOD* pFetchMethod);
+GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm,
+ GLuint destination_register,
+ GLenum type,
+ GLint size,
+ GLubyte element,
+ GLuint _signed,
+ GLboolean normalize,
+ VTX_FETCH_METHOD * pFetchMethod);
+GLboolean cleanup_vfetch_instructions(r700_AssemblerBase* pAsm);
GLuint gethelpr(r700_AssemblerBase* pAsm);
void resethelpr(r700_AssemblerBase* pAsm);
void checkop_init(r700_AssemblerBase* pAsm);
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index 312cacffda3..3b7f6fffe03 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -208,11 +208,97 @@ static void r700SetupVTXConstants(GLcontext * ctx,
}
+extern int getTypeSize(GLenum type);
+static void r700SetupVTXConstants2(GLcontext * ctx,
+ void * pAos,
+ StreamDesc * pStreamDesc)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ struct radeon_aos * paos = (struct radeon_aos *)pAos;
+ unsigned int nVBsize;
+ BATCH_LOCALS(&context->radeon);
+
+ unsigned int uSQ_VTX_CONSTANT_WORD0_0;
+ unsigned int uSQ_VTX_CONSTANT_WORD1_0;
+ unsigned int uSQ_VTX_CONSTANT_WORD2_0 = 0;
+ unsigned int uSQ_VTX_CONSTANT_WORD3_0 = 0;
+ unsigned int uSQ_VTX_CONSTANT_WORD6_0 = 0;
+
+ if (!paos->bo)
+ return;
+
+ if ((context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV610) ||
+ (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV620) ||
+ (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS780) ||
+ (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RS880) ||
+ (context->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV710))
+ r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, TC_ACTION_ENA_bit);
+ else
+ r700SyncSurf(context, paos->bo, RADEON_GEM_DOMAIN_GTT, 0, VC_ACTION_ENA_bit);
+
+ if(0 == pStreamDesc->stride)
+ {
+ nVBsize = paos->count * pStreamDesc->size * getTypeSize(pStreamDesc->type);
+ }
+ else
+ {
+ nVBsize = paos->count * pStreamDesc->stride;
+ }
+
+ uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
+ uSQ_VTX_CONSTANT_WORD1_0 = nVBsize - 1;
+
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); /* TODO */
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, pStreamDesc->stride, SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift,
+ SQ_VTX_CONSTANT_WORD2_0__STRIDE_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, GetSurfaceFormat(pStreamDesc->type, pStreamDesc->size, NULL),
+ SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_shift,
+ SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_mask); /* TODO : trace back api for initial data type, not only GL_FLOAT */
+
+ if(GL_TRUE == pStreamDesc->normalize)
+ {
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_NORM,
+ SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ }
+ //else
+ //{
+ // SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_INT,
+ // SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ //}
+
+ if(1 == pStreamDesc->_signed)
+ {
+ SETbit(uSQ_VTX_CONSTANT_WORD2_0, SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit);
+ }
+
+ SETfield(uSQ_VTX_CONSTANT_WORD3_0, 1, MEM_REQUEST_SIZE_shift, MEM_REQUEST_SIZE_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD6_0, SQ_TEX_VTX_VALID_BUFFER,
+ SQ_TEX_RESOURCE_WORD6_0__TYPE_shift, SQ_TEX_RESOURCE_WORD6_0__TYPE_mask);
+
+ BEGIN_BATCH_NO_AUTOSTATE(9 + 2);
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+ R600_OUT_BATCH((pStreamDesc->element + SQ_FETCH_RESOURCE_VS_OFFSET) * FETCH_RESOURCE_STRIDE);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD0_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD1_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD2_0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD3_0);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(uSQ_VTX_CONSTANT_WORD6_0);
+ R600_OUT_BATCH_RELOC(uSQ_VTX_CONSTANT_WORD0_0,
+ paos->bo,
+ uSQ_VTX_CONSTANT_WORD0_0,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ COMMIT_BATCH();
+
+}
+
void r700SetupStreams(GLcontext *ctx)
{
context_t *context = R700_CONTEXT(ctx);
- struct r700_vertex_program *vpc
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ struct r700_vertex_program *vp = context->selected_vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int i, j = 0;
@@ -221,7 +307,7 @@ void r700SetupStreams(GLcontext *ctx)
R600_STATECHANGE(context, vtx);
for(i=0; i<VERT_ATTRIB_MAX; i++) {
- if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
+ if(vp->mesa_program->Base.InputsRead & (1 << i)) {
rcommon_emit_vector(ctx,
&context->radeon.tcl.aos[j],
vb->AttribPtr[i]->data,
@@ -237,8 +323,7 @@ void r700SetupStreams(GLcontext *ctx)
static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
{
context_t *context = R700_CONTEXT(ctx);
- struct r700_vertex_program *vpc
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ struct r700_vertex_program *vp = context->selected_vp;
unsigned int i, j = 0;
BATCH_LOCALS(&context->radeon);
radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
@@ -258,14 +343,24 @@ static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
COMMIT_BATCH();
for(i=0; i<VERT_ATTRIB_MAX; i++) {
- if(vpc->mesa_program.Base.InputsRead & (1 << i)) {
- /* currently aos are packed */
- r700SetupVTXConstants(ctx,
- i,
- (void*)(&context->radeon.tcl.aos[j]),
- (unsigned int)context->radeon.tcl.aos[j].components,
- (unsigned int)context->radeon.tcl.aos[j].stride * 4,
- (unsigned int)context->radeon.tcl.aos[j].count);
+ if(vp->mesa_program->Base.InputsRead & (1 << i))
+ {
+ if(1 == context->selected_vp->uiVersion)
+ {
+ /* currently aos are packed */
+ r700SetupVTXConstants(ctx,
+ i,
+ (void*)(&context->radeon.tcl.aos[j]),
+ (unsigned int)context->radeon.tcl.aos[j].components,
+ (unsigned int)context->radeon.tcl.aos[j].stride * 4,
+ (unsigned int)context->radeon.tcl.aos[j].count);
+ }
+ else
+ { /* context->selected_vp->uiVersion == 2 : aos not always packed */
+ r700SetupVTXConstants2(ctx,
+ (void*)(&context->radeon.tcl.aos[j]),
+ &(context->stream_desc[j]));
+ }
j++;
}
}
@@ -353,7 +448,7 @@ static void r700SetDepthTarget(context_t *context)
SETfield(r700->DB_DEPTH_INFO.u32All, DEPTH_16,
DB_DEPTH_INFO__FORMAT_shift, DB_DEPTH_INFO__FORMAT_mask);
}
- SETfield(r700->DB_DEPTH_INFO.u32All, ARRAY_2D_TILED_THIN1,
+ SETfield(r700->DB_DEPTH_INFO.u32All, ARRAY_1D_TILED_THIN1,
DB_DEPTH_INFO__ARRAY_MODE_shift, DB_DEPTH_INFO__ARRAY_MODE_mask);
/* r700->DB_PREFETCH_LIMIT.bits.DEPTH_HEIGHT_TILE_MAX = (context->currentDraw->h >> 3) - 1; */ /* z buffer sie may much bigger than what need, so use actual used h. */
}
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 3c8c1fd7a34..5290ef31be3 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -46,7 +46,7 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
{
struct gl_program *pProgram = NULL;
- struct r700_vertex_program *vp;
+ struct r700_vertex_program_cont *vpc;
struct r700_fragment_program *fp;
radeon_print(RADEON_SHADER, RADEON_VERBOSE,
@@ -56,16 +56,11 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp = CALLOC_STRUCT(r700_vertex_program);
+ vpc = CALLOC_STRUCT(r700_vertex_program_cont);
pProgram = _mesa_init_vertex_program(ctx,
- &vp->mesa_program,
+ &vpc->mesa_program,
target,
id);
- vp->translated = GL_FALSE;
- vp->loaded = GL_FALSE;
-
- vp->shaderbo = NULL;
-
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
@@ -89,7 +84,8 @@ static struct gl_program *r700NewProgram(GLcontext * ctx,
static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
- struct r700_vertex_program * vp;
+ struct r700_vertex_program_cont * vpc;
+ struct r700_vertex_program *vp, *tmp;
struct r700_fragment_program * fp;
radeon_print(RADEON_SHADER, RADEON_VERBOSE,
@@ -99,14 +95,20 @@ static void r700DeleteProgram(GLcontext * ctx, struct gl_program *prog)
{
case GL_VERTEX_STATE_PROGRAM_NV:
case GL_VERTEX_PROGRAM_ARB:
- vp = (struct r700_vertex_program*)prog;
- /* Release DMA region */
-
- r600DeleteShader(ctx, vp->shaderbo);
-
- /* Clean up */
- Clean_Up_Assembler(&(vp->r700AsmCode));
- Clean_Up_Shader(&(vp->r700Shader));
+ vpc = (struct r700_vertex_program_cont*)prog;
+ vp = vpc->progs;
+ while (vp) {
+ tmp = vp->next;
+ /* Release DMA region */
+
+ r600DeleteShader(ctx, vp->shaderbo);
+
+ /* Clean up */
+ Clean_Up_Assembler(&(vp->r700AsmCode));
+ Clean_Up_Shader(&(vp->r700Shader));
+ _mesa_free(vp);
+ vp = tmp;
+ }
break;
case GL_FRAGMENT_PROGRAM_NV:
case GL_FRAGMENT_PROGRAM_ARB:
diff --git a/src/mesa/drivers/dri/r600/r700_render.c b/src/mesa/drivers/dri/r600/r700_render.c
index 3566bf3ca78..5627984cf96 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -43,6 +43,7 @@
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
#include "tnl/t_pipeline.h"
+#include "vbo/vbo_context.h"
#include "r600_context.h"
#include "r600_cmdbuf.h"
@@ -53,6 +54,7 @@
#include "r700_fragprog.h"
#include "r700_state.h"
+#include "radeon_buffer_objects.h"
#include "radeon_common_context.h"
void r700WaitForIdle(context_t *context);
@@ -260,6 +262,16 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
+ GLboolean bUseDrawIndex;
+ if( (NULL != context->ind_buf.bo) && (GL_TRUE != context->ind_buf.bHostIb) )
+ {
+ bUseDrawIndex = GL_TRUE;
+ }
+ else
+ {
+ bUseDrawIndex = GL_FALSE;
+ }
+
type = r700PrimitiveType(prim);
num_indices = r700NumVerts(end - start, prim);
@@ -270,67 +282,146 @@ static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim
if (type < 0 || num_indices <= 0)
return;
+ if(GL_TRUE == bUseDrawIndex)
+ {
+ total_emit = 3 /* VGT_PRIMITIVE_TYPE */
+ + 2 /* VGT_INDEX_TYPE */
+ + 2 /* NUM_INSTANCES */
+ + 5+2; /* DRAW_INDEX */
+ }
+ else
+ {
total_emit = 3 /* VGT_PRIMITIVE_TYPE */
- + 2 /* VGT_INDEX_TYPE */
- + 2 /* NUM_INSTANCES */
- + num_indices + 3; /* DRAW_INDEX_IMMD */
+ + 2 /* VGT_INDEX_TYPE */
+ + 2 /* NUM_INSTANCES */
+ + num_indices + 3; /* DRAW_INDEX_IMMD */
+ }
- BEGIN_BATCH_NO_AUTOSTATE(total_emit);
+ BEGIN_BATCH_NO_AUTOSTATE(total_emit);
// prim
- SETfield(vgt_primitive_type, type,
- VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
- R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
- R600_OUT_BATCH(vgt_primitive_type);
+ SETfield(vgt_primitive_type, type,
+ VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift, VGT_PRIMITIVE_TYPE__PRIM_TYPE_mask);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
+ R600_OUT_BATCH(mmVGT_PRIMITIVE_TYPE - ASIC_CONFIG_BASE_INDEX);
+ R600_OUT_BATCH(vgt_primitive_type);
// index type
- SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
- R600_OUT_BATCH(vgt_index_type);
+ SETfield(vgt_index_type, DI_INDEX_SIZE_32_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+
+ if(GL_TRUE == bUseDrawIndex)
+ {
+ if(GL_TRUE != context->ind_buf.is_32bit)
+ {
+ SETfield(vgt_index_type, DI_INDEX_SIZE_16_BIT, INDEX_TYPE_shift, INDEX_TYPE_mask);
+ }
+ }
+
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
+ R600_OUT_BATCH(vgt_index_type);
// num instances
R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
R600_OUT_BATCH(1);
// draw packet
- vgt_num_indices = num_indices;
+ vgt_num_indices = num_indices;
+
+ if(GL_TRUE == bUseDrawIndex)
+ {
+ SETfield(vgt_draw_initiator, DI_SRC_SEL_DMA, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+ }
+ else
+ {
SETfield(vgt_draw_initiator, DI_SRC_SEL_IMMEDIATE, SOURCE_SELECT_shift, SOURCE_SELECT_mask);
+ }
+
SETfield(vgt_draw_initiator, DI_MAJOR_MODE_0, MAJOR_MODE_shift, MAJOR_MODE_mask);
+ if(GL_TRUE == bUseDrawIndex)
+ {
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX, 3));
+ R600_OUT_BATCH(context->ind_buf.bo_offset);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(vgt_num_indices);
+ R600_OUT_BATCH(vgt_draw_initiator);
+ R600_OUT_BATCH_RELOC(context->ind_buf.bo_offset,
+ context->ind_buf.bo,
+ context->ind_buf.bo_offset,
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ }
+ else
+ {
R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (num_indices + 1)));
R600_OUT_BATCH(vgt_num_indices);
R600_OUT_BATCH(vgt_draw_initiator);
+ }
+ if(NULL == context->ind_buf.bo)
+ {
for (i = start; i < (start + num_indices); i++) {
- if(vb->Elts)
- R600_OUT_BATCH(vb->Elts[i]);
- else
- R600_OUT_BATCH(i);
+ if(vb->Elts)
+ {
+ R600_OUT_BATCH(vb->Elts[i]);
+ }
+ else
+ R600_OUT_BATCH(i);
}
- END_BATCH();
- COMMIT_BATCH();
+ }
+ else
+ {
+ if(GL_TRUE == context->ind_buf.bHostIb)
+ {
+ if(GL_TRUE != context->ind_buf.is_32bit)
+ {
+ GLushort * pIndex = (GLushort*)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+ pIndex += start;
+ for (i = 0; i < num_indices; i++)
+ {
+ R600_OUT_BATCH(*pIndex);
+ pIndex++;
+ }
+ }
+ else
+ {
+ GLuint * pIndex = (GLuint*)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+ pIndex += start;
+
+ for (i = 0; i < num_indices; i++)
+ {
+ R600_OUT_BATCH(*pIndex);
+ pIndex++;
+ }
+ }
+ }
+ }
+ END_BATCH();
+ COMMIT_BATCH();
}
/* start 3d, idle, cb/db flush */
#define PRE_EMIT_STATE_BUFSZ 10 + 5 + 14
-static GLuint r700PredictRenderSize(GLcontext* ctx)
+static GLuint r700PredictRenderSize(GLcontext* ctx, GLuint nr_prims)
{
context_t *context = R700_CONTEXT(ctx);
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct r700_vertex_program *vpc
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
- struct vertex_buffer *vb = &tnl->vb;
+ struct r700_vertex_program *vp = context->selected_vp;
GLboolean flushed;
GLuint dwords, i;
GLuint state_size;
/* pre calculate aos count so state prediction works */
- context->radeon.tcl.aos_count = _mesa_bitcount(vpc->mesa_program.Base.InputsRead);
+ context->radeon.tcl.aos_count = _mesa_bitcount(vp->mesa_program->Base.InputsRead);
dwords = PRE_EMIT_STATE_BUFSZ;
- for (i = 0; i < vb->PrimitiveCount; i++)
- dwords += vb->Primitive[i].count + 10;
+ if (nr_prims)
+ dwords += nr_prims * 14;
+ else {
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *vb = &tnl->vb;
+
+ for (i = 0; i < vb->PrimitiveCount; i++)
+ dwords += vb->Primitive[i].count + 10;
+ }
state_size = radeonCountStateEmitSize(&context->radeon);
flushed = rcommonEnsureCmdBufSpace(&context->radeon,
dwords + state_size, __FUNCTION__);
@@ -365,13 +456,12 @@ static GLboolean r700RunRender(GLcontext * ctx,
/* mark vtx as dirty since it changes per-draw */
R600_STATECHANGE(context, vtx);
- r700UpdateShaders(ctx);
r700SetScissor(context);
r700SetupVertexProgram(ctx);
r700SetupFragmentProgram(ctx);
r600UpdateTextureState(ctx);
- GLuint emit_end = r700PredictRenderSize(ctx)
+ GLuint emit_end = r700PredictRenderSize(ctx, 0)
+ context->radeon.cmdbuf.cs->cdw;
r700SetupStreams(ctx);
@@ -427,7 +517,10 @@ static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/
/* TODO : sw fallback */
+ /* Need shader bo's setup before bo check */
+ r700UpdateShaders(ctx);
/**
+
* Ensure all enabled and complete textures are uploaded along with any buffers being used.
*/
if(!r600ValidateBuffers(ctx))
@@ -476,4 +569,587 @@ const struct tnl_pipeline_stage *r700_pipeline[] =
0,
};
+#define CONVERT( TYPE, MACRO ) do { \
+ GLuint i, j, sz; \
+ sz = input->Size; \
+ if (input->Normalized) { \
+ for (i = 0; i < count; i++) { \
+ const TYPE *in = (TYPE *)src_ptr; \
+ for (j = 0; j < sz; j++) { \
+ *dst_ptr++ = MACRO(*in); \
+ in++; \
+ } \
+ src_ptr += stride; \
+ } \
+ } else { \
+ for (i = 0; i < count; i++) { \
+ const TYPE *in = (TYPE *)src_ptr; \
+ for (j = 0; j < sz; j++) { \
+ *dst_ptr++ = (GLfloat)(*in); \
+ in++; \
+ } \
+ src_ptr += stride; \
+ } \
+ } \
+} while (0)
+
+/**
+ * Convert attribute data type to float
+ * If the attribute uses named buffer object replace the bo with newly allocated bo
+ */
+static void r700ConvertAttrib(GLcontext *ctx, int count,
+ const struct gl_client_array *input,
+ struct StreamDesc *attr)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ const GLvoid *src_ptr;
+ GLboolean mapped_named_bo = GL_FALSE;
+ GLfloat *dst_ptr;
+ GLuint stride;
+
+ stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size : input->StrideB;
+
+ /* Convert value for first element only */
+ if (input->StrideB == 0)
+ {
+ count = 1;
+ }
+
+ if (input->BufferObj->Name)
+ {
+ if (!input->BufferObj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+ }
+ else
+ {
+ src_ptr = input->Ptr;
+ }
+
+ radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset,
+ sizeof(GLfloat) * input->Size * count, 32);
+ dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+
+ assert(src_ptr != NULL);
+
+ switch (input->Type)
+ {
+ case GL_DOUBLE:
+ CONVERT(GLdouble, (GLfloat));
+ break;
+ case GL_UNSIGNED_INT:
+ CONVERT(GLuint, UINT_TO_FLOAT);
+ break;
+ case GL_INT:
+ CONVERT(GLint, INT_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_SHORT:
+ CONVERT(GLushort, USHORT_TO_FLOAT);
+ break;
+ case GL_SHORT:
+ CONVERT(GLshort, SHORT_TO_FLOAT);
+ break;
+ case GL_UNSIGNED_BYTE:
+ assert(input->Format != GL_BGRA);
+ CONVERT(GLubyte, UBYTE_TO_FLOAT);
+ break;
+ case GL_BYTE:
+ CONVERT(GLbyte, BYTE_TO_FLOAT);
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+ }
+}
+
+static void r700AlignDataToDword(GLcontext *ctx,
+ const struct gl_client_array *input,
+ int count,
+ struct StreamDesc *attr)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ const int dst_stride = (input->StrideB + 3) & ~3;
+ const int size = getTypeSize(input->Type) * input->Size * count;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ radeonAllocDmaRegion(&context->radeon, &attr->bo, &attr->bo_offset, size, 32);
+
+ if (!input->BufferObj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ {
+ GLvoid *src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
+ GLvoid *dst_ptr = ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+ int i;
+
+ for (i = 0; i < count; ++i)
+ {
+ _mesa_memcpy(dst_ptr, src_ptr, input->StrideB);
+ src_ptr += input->StrideB;
+ dst_ptr += dst_stride;
+ }
+ }
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, input->BufferObj);
+ }
+
+ attr->stride = dst_stride;
+}
+
+static void r700SetupStreams2(GLcontext *ctx, const struct gl_client_array *input[], int count)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ GLuint stride;
+ int ret;
+ int i, index;
+
+ R600_STATECHANGE(context, vtx);
+
+ for(index = 0; index < context->nNumActiveAos; index++)
+ {
+ struct radeon_aos *aos = &context->radeon.tcl.aos[index];
+ i = context->stream_desc[index].element;
+
+ stride = (input[i]->StrideB == 0) ? getTypeSize(input[i]->Type) * input[i]->Size : input[i]->StrideB;
+
+ if (input[i]->Type == GL_DOUBLE || input[i]->Type == GL_UNSIGNED_INT || input[i]->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+ getTypeSize(input[i]->Type) != 4 ||
+#endif
+ stride < 4)
+ {
+ r700ConvertAttrib(ctx, count, input[i], &context->stream_desc[index]);
+ }
+ else
+ {
+ if (input[i]->BufferObj->Name)
+ {
+ if (stride % 4 != 0)
+ {
+ assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
+ r700AlignDataToDword(ctx, input[i], count, &context->stream_desc[index]);
+ context->stream_desc[index].is_named_bo = GL_FALSE;
+ }
+ else
+ {
+ context->stream_desc[index].stride = input[i]->StrideB;
+ context->stream_desc[index].bo_offset = (intptr_t) input[i]->Ptr;
+ context->stream_desc[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
+ context->stream_desc[index].is_named_bo = GL_TRUE;
+ }
+ }
+ else
+ {
+ int size;
+ int local_count = count;
+ uint32_t *dst;
+
+ if (input[i]->StrideB == 0)
+ {
+ size = getTypeSize(input[i]->Type) * input[i]->Size;
+ local_count = 1;
+ }
+ else
+ {
+ size = getTypeSize(input[i]->Type) * input[i]->Size * local_count;
+ }
+
+ radeonAllocDmaRegion(&context->radeon, &context->stream_desc[index].bo,
+ &context->stream_desc[index].bo_offset, size, 32);
+ assert(context->stream_desc[index].bo->ptr != NULL);
+ dst = (uint32_t *)ADD_POINTERS(context->stream_desc[index].bo->ptr,
+ context->stream_desc[index].bo_offset);
+
+ switch (context->stream_desc[index].dwords)
+ {
+ case 1:
+ radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ context->stream_desc[index].stride = 4;
+ break;
+ case 2:
+ radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ context->stream_desc[index].stride = 8;
+ break;
+ case 3:
+ radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ context->stream_desc[index].stride = 12;
+ break;
+ case 4:
+ radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count);
+ context->stream_desc[index].stride = 16;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+ }
+
+ aos->count = context->stream_desc[index].stride == 0 ? 1 : count;
+ aos->stride = context->stream_desc[index].stride / sizeof(float);
+ aos->components = context->stream_desc[index].dwords;
+ aos->bo = context->stream_desc[index].bo;
+ aos->offset = context->stream_desc[index].bo_offset;
+
+ if(context->stream_desc[index].is_named_bo)
+ {
+ radeon_cs_space_add_persistent_bo(context->radeon.cmdbuf.cs,
+ context->stream_desc[index].bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+ }
+
+ context->radeon.tcl.aos_count = context->nNumActiveAos;
+ ret = radeon_cs_space_check_with_bo(context->radeon.cmdbuf.cs,
+ first_elem(&context->radeon.dma.reserved)->bo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+}
+
+static void r700FreeData(GLcontext *ctx)
+{
+ /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
+ * to prevent double unref in radeonReleaseArrays
+ * called during context destroy
+ */
+ context_t *context = R700_CONTEXT(ctx);
+
+ int i;
+
+ for (i = 0; i < context->nNumActiveAos; i++)
+ {
+ if (!context->stream_desc[i].is_named_bo)
+ {
+ radeon_bo_unref(context->stream_desc[i].bo);
+ }
+ context->radeon.tcl.aos[i].bo = NULL;
+ }
+
+ if (context->ind_buf.bo != NULL)
+ {
+ if(context->ind_buf.bHostIb != GL_TRUE)
+ {
+ radeon_bo_unref(context->ind_buf.bo);
+ }
+ else
+ {
+ FREE(context->ind_buf.bo->ptr);
+ FREE(context->ind_buf.bo);
+ context->ind_buf.bo = NULL;
+ }
+ }
+}
+
+static void r700FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ GLvoid *src_ptr;
+ GLuint *out;
+ int i;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+ mapped_named_bo = GL_TRUE;
+ assert(mesa_ind_buf->obj->Pointer != NULL);
+ }
+ src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+ if (mesa_ind_buf->type == GL_UNSIGNED_BYTE)
+ {
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+ GLubyte *in = (GLubyte *)src_ptr;
+
+ if(context->ind_buf.bHostIb != GL_TRUE)
+ {
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+
+ assert(context->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+ }
+ else
+ {
+ context->ind_buf.bo = MALLOC_STRUCT(radeon_bo);
+ context->ind_buf.bo->ptr = ALIGN_MALLOC(size, 4);
+ context->ind_buf.bo_offset = 0;
+ out = (GLuint *)context->ind_buf.bo->ptr;
+ }
+
+ for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
+ {
+ *out++ = in[i] | in[i + 1] << 16;
+ }
+
+ if (i < mesa_ind_buf->count)
+ {
+ *out++ = in[i];
+ }
+
+#if MESA_BIG_ENDIAN
+ }
+ else
+ { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
+ GLushort *in = (GLushort *)src_ptr;
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+
+ if(context->ind_buf.bHostIb != GL_TRUE)
+ {
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+
+ assert(context->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+ }
+ else
+ {
+ context->ind_buf.bo = MALLOC_STRUCT(radeon_bo);
+ context->ind_buf.bo->ptr = ALIGN_MALLOC(size, 4);
+ context->ind_buf.bo_offset = 0;
+ out = (GLuint *)context->ind_buf.bo->ptr;
+ }
+
+ for (i = 0; i + 1 < mesa_ind_buf->count; i += 2)
+ {
+ *out++ = in[i] | in[i + 1] << 16;
+ }
+
+ if (i < mesa_ind_buf->count)
+ {
+ *out++ = in[i];
+ }
+#endif
+ }
+
+ context->ind_buf.is_32bit = GL_FALSE;
+ context->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+ }
+}
+
+static void r700SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
+{
+ context_t *context = R700_CONTEXT(ctx);
+
+ if (!mesa_ind_buf) {
+ context->ind_buf.bo = NULL;
+ return;
+ }
+
+ context->ind_buf.bHostIb = GL_FALSE;
+
+#if MESA_BIG_ENDIAN
+ if (mesa_ind_buf->type == GL_UNSIGNED_INT)
+ {
+#else
+ if (mesa_ind_buf->type != GL_UNSIGNED_BYTE)
+ {
+#endif
+ const GLvoid *src_ptr;
+ GLvoid *dst_ptr;
+ GLboolean mapped_named_bo = GL_FALSE;
+
+ if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer)
+ {
+ ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY_ARB, mesa_ind_buf->obj);
+ assert(mesa_ind_buf->obj->Pointer != NULL);
+ mapped_named_bo = GL_TRUE;
+ }
+
+ src_ptr = ADD_POINTERS(mesa_ind_buf->obj->Pointer, mesa_ind_buf->ptr);
+
+ const GLuint size = mesa_ind_buf->count * getTypeSize(mesa_ind_buf->type);
+
+ if(context->ind_buf.bHostIb != GL_TRUE)
+ {
+ radeonAllocDmaRegion(&context->radeon, &context->ind_buf.bo,
+ &context->ind_buf.bo_offset, size, 4);
+ assert(context->ind_buf.bo->ptr != NULL);
+ dst_ptr = ADD_POINTERS(context->ind_buf.bo->ptr, context->ind_buf.bo_offset);
+ }
+ else
+ {
+ context->ind_buf.bo = MALLOC_STRUCT(radeon_bo);
+ context->ind_buf.bo->ptr = ALIGN_MALLOC(size, 4);
+ context->ind_buf.bo_offset = 0;
+ dst_ptr = context->ind_buf.bo->ptr;
+ }
+
+ _mesa_memcpy(dst_ptr, src_ptr, size);
+
+ context->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
+ context->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo)
+ {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+ }
+ }
+ else
+ {
+ r700FixupIndexBuffer(ctx, mesa_ind_buf);
+ }
+}
+
+static GLboolean r700TryDrawPrims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLuint min_index,
+ GLuint max_index )
+{
+ context_t *context = R700_CONTEXT(ctx);
+ radeonContextPtr radeon = &context->radeon;
+ GLuint i, id = 0;
+ struct radeon_renderbuffer *rrb;
+
+ if (ctx->NewState)
+ {
+ _mesa_update_state( ctx );
+ }
+
+ _tnl_UpdateFixedFunctionProgram(ctx);
+ r700SetVertexFormat(ctx, arrays, max_index + 1);
+ r700SetupIndexBuffer(ctx, ib);
+ /* shaders need to be updated before buffers are validated */
+ r700UpdateShaders2(ctx);
+ if (!r600ValidateBuffers(ctx))
+ return GL_FALSE;
+
+ /* always emit CB base to prevent
+ * lock ups on some chips.
+ */
+ R600_STATECHANGE(context, cb_target);
+ /* mark vtx as dirty since it changes per-draw */
+ R600_STATECHANGE(context, vtx);
+
+ r700SetScissor(context);
+ r700SetupVertexProgram(ctx);
+ r700SetupFragmentProgram(ctx);
+ r600UpdateTextureState(ctx);
+
+ GLuint emit_end = r700PredictRenderSize(ctx, nr_prims)
+ + context->radeon.cmdbuf.cs->cdw;
+
+ r700SetupStreams2(ctx, arrays, max_index + 1);
+
+ radeonEmitState(radeon);
+
+ radeon_debug_add_indent();
+ for (i = 0; i < nr_prims; ++i)
+ {
+ r700RunRenderPrimitive(ctx,
+ prim[i].start,
+ prim[i].start + prim[i].count,
+ prim[i].mode);
+ }
+ radeon_debug_remove_indent();
+
+ /* Flush render op cached for last several quads. */
+ r700WaitForIdleClean(context);
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (rrb && rrb->bo)
+ r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+ CB_ACTION_ENA_bit | (1 << (id + 6)));
+
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if (rrb && rrb->bo)
+ r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
+ DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
+
+ r700FreeData(ctx);
+
+ if (emit_end < context->radeon.cmdbuf.cs->cdw)
+ {
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n", context->radeon.cmdbuf.cs->cdw - emit_end);
+ }
+
+ return GL_TRUE;
+}
+
+static void r700DrawPrimsRe(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index)
+{
+ GLboolean retval = GL_FALSE;
+
+ /* This check should get folded into just the places that
+ * min/max index are really needed.
+ */
+ if (!index_bounds_valid) {
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+ }
+
+ if (min_index) {
+ vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r700DrawPrimsRe );
+ return;
+ }
+
+ /* Make an attempt at drawing */
+ retval = r700TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+
+ /* If failed run tnl pipeline - it should take care of fallbacks */
+ if (!retval)
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+}
+
+static void r700DrawPrims(GLcontext *ctx,
+ const struct gl_client_array *arrays[],
+ const struct _mesa_prim *prim,
+ GLuint nr_prims,
+ const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
+ GLuint min_index,
+ GLuint max_index)
+{
+ context_t *context = R700_CONTEXT(ctx);
+
+ /* For non indexed drawing, using tnl pipe. */
+ if(!ib)
+ {
+ context->ind_buf.bo = NULL;
+
+ _tnl_vbo_draw_prims(ctx, arrays, prim, nr_prims, ib,
+ index_bounds_valid, min_index, max_index);
+ return;
+ }
+
+ r700DrawPrimsRe(ctx, arrays, prim, nr_prims, ib, index_bounds_valid, min_index, max_index);
+}
+
+void r700InitDraw(GLcontext *ctx)
+{
+ struct vbo_context *vbo = vbo_context(ctx);
+
+ /* to be enabled */
+ /*
+ vbo->draw_prims = r700DrawPrims;
+ */
+}
+
diff --git a/src/mesa/drivers/dri/r600/r700_shader.c b/src/mesa/drivers/dri/r600/r700_shader.c
index b4fd51c1370..955ea4e4e1d 100644
--- a/src/mesa/drivers/dri/r600/r700_shader.c
+++ b/src/mesa/drivers/dri/r600/r700_shader.c
@@ -60,6 +60,55 @@ void AddInstToList(TypedShaderList * plstCFInstructions, R700ShaderInstruction *
plstCFInstructions->uNumOfNode++;
}
+void TakeInstOutFromList(TypedShaderList * plstCFInstructions, R700ShaderInstruction * pInst)
+{
+ GLuint ulIndex = 0;
+ GLboolean bFound = GL_FALSE;
+ R700ShaderInstruction * pPrevInst = NULL;
+ R700ShaderInstruction * pCurInst = plstCFInstructions->pHead;
+
+ /* Need go thro list to make sure pInst is there. */
+ while(NULL != pCurInst)
+ {
+ if(pCurInst == pInst)
+ {
+ bFound = GL_TRUE;
+ break;
+ }
+
+ pPrevInst = pCurInst;
+ pCurInst = pCurInst->pNextInst;
+ }
+ if(GL_TRUE == bFound)
+ {
+ plstCFInstructions->uNumOfNode--;
+
+ pCurInst = pInst->pNextInst;
+ ulIndex = pInst->m_uIndex;
+ while(NULL != pCurInst)
+ {
+ pCurInst->m_uIndex = ulIndex;
+ ulIndex++;
+ pCurInst = pCurInst->pNextInst;
+ }
+
+ if(plstCFInstructions->pHead == pInst)
+ {
+ plstCFInstructions->pHead = pInst->pNextInst;
+ }
+ if(plstCFInstructions->pTail == pInst)
+ {
+ plstCFInstructions->pTail = pPrevInst;
+ }
+ if(NULL != pPrevInst)
+ {
+ pPrevInst->pNextInst = pInst->pNextInst;
+ }
+
+ FREE(pInst);
+ }
+}
+
void Init_R700_Shader(R700_Shader * pShader)
{
pShader->Type = R700_SHADER_INVALID;
@@ -488,6 +537,47 @@ void DebugPrint(void)
{
}
+void cleanup_vfetch_shaderinst(R700_Shader *pShader)
+{
+ R700ShaderInstruction *pInst;
+ R700ShaderInstruction *pInstToFree;
+ R700VertexInstruction *pVTXInst;
+ R700ControlFlowInstruction *pCFInst;
+
+ pInst = pShader->lstVTXInstructions.pHead;
+ while(NULL != pInst)
+ {
+ pVTXInst = (R700VertexInstruction *)pInst;
+ pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pVTXInst->m_ShaderInstType);
+
+ if(NULL != pVTXInst->m_pLinkedGenericClause)
+ {
+ pCFInst = (R700ControlFlowInstruction*)(pVTXInst->m_pLinkedGenericClause);
+
+ TakeInstOutFromList(&(pShader->lstCFInstructions),
+ (R700ShaderInstruction*)pCFInst);
+
+ pShader->uShaderBinaryDWORDSize -= GetInstructionSize(pCFInst->m_ShaderInstType);
+ }
+
+ pInst = pInst->pNextInst;
+ };
+
+ //destroy each item in pShader->lstVTXInstructions;
+ pInst = pShader->lstVTXInstructions.pHead;
+ while(NULL != pInst)
+ {
+ pInstToFree = pInst;
+ pInst = pInst->pNextInst;
+ FREE(pInstToFree);
+ };
+
+ //set NULL pShader->lstVTXInstructions
+ pShader->lstVTXInstructions.pHead=NULL;
+ pShader->lstVTXInstructions.pTail=NULL;
+ pShader->lstVTXInstructions.uNumOfNode=0;
+}
+
void Clean_Up_Shader(R700_Shader *pShader)
{
FREE(pShader->pProgram);
diff --git a/src/mesa/drivers/dri/r600/r700_shader.h b/src/mesa/drivers/dri/r600/r700_shader.h
index bfd01e1a93a..997cb05aaf8 100644
--- a/src/mesa/drivers/dri/r600/r700_shader.h
+++ b/src/mesa/drivers/dri/r600/r700_shader.h
@@ -143,6 +143,7 @@ void LoadProgram(R700_Shader *pShader);
void UpdateShaderRegisters(R700_Shader *pShader);
void DeleteInstructions(R700_Shader *pShader);
void DebugPrint(void);
+void cleanup_vfetch_shaderinst(R700_Shader *pShader);
void Clean_Up_Shader(R700_Shader *pShader);
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index e91aa43118f..fbff109455d 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -92,7 +92,25 @@ void r700UpdateShaders (GLcontext * ctx) //----------------------------------
}
}
- r700SelectVertexShader(ctx);
+ r700SelectVertexShader(ctx, 1);
+ r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ context->radeon.NewGLState = 0;
+}
+
+void r700UpdateShaders2(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+
+ /* should only happenen once, just after context is created */
+ /* TODO: shouldn't we fallback to sw here? */
+ if (!ctx->FragmentProgram._Current) {
+ _mesa_fprintf(stderr, "No ctx->FragmentProgram._Current!!\n");
+ return;
+ }
+
+ r700SelectFragmentShader(ctx);
+
+ r700SelectVertexShader(ctx, 2);
r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
context->radeon.NewGLState = 0;
}
@@ -845,9 +863,9 @@ static void r700PointSize(GLcontext * ctx, GLfloat size)
size = CLAMP(size, ctx->Const.MinPointSize, ctx->Const.MaxPointSize);
/* format is 12.4 fixed point */
- SETfield(r700->PA_SU_POINT_SIZE.u32All, (int)(size * 16),
+ SETfield(r700->PA_SU_POINT_SIZE.u32All, (int)(size * 8.0),
PA_SU_POINT_SIZE__HEIGHT_shift, PA_SU_POINT_SIZE__HEIGHT_mask);
- SETfield(r700->PA_SU_POINT_SIZE.u32All, (int)(size * 16),
+ SETfield(r700->PA_SU_POINT_SIZE.u32All, (int)(size * 8.0),
PA_SU_POINT_SIZE__WIDTH_shift, PA_SU_POINT_SIZE__WIDTH_mask);
}
@@ -862,11 +880,11 @@ static void r700PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa
/* format is 12.4 fixed point */
switch (pname) {
case GL_POINT_SIZE_MIN:
- SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MinSize * 16.0),
+ SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MinSize * 8.0),
MIN_SIZE_shift, MIN_SIZE_mask);
break;
case GL_POINT_SIZE_MAX:
- SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MaxSize * 16.0),
+ SETfield(r700->PA_SU_POINT_MINMAX.u32All, (int)(ctx->Point.MaxSize * 8.0),
MAX_SIZE_shift, MAX_SIZE_mask);
break;
case GL_POINT_DISTANCE_ATTENUATION:
@@ -1130,20 +1148,25 @@ static void r700PolygonOffset(GLcontext * ctx, GLfloat factor, GLfloat units) //
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
GLfloat constant = units;
+ GLchar depth = 0;
+
+ R600_STATECHANGE(context, poly);
switch (ctx->Visual.depthBits) {
case 16:
constant *= 4.0;
+ depth = -16;
break;
case 24:
constant *= 2.0;
+ depth = -24;
break;
}
factor *= 12.0;
-
- R600_STATECHANGE(context, poly);
-
+ SETfield(r700->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All, depth,
+ POLY_OFFSET_NEG_NUM_DB_BITS_shift, POLY_OFFSET_NEG_NUM_DB_BITS_mask);
+ //r700->PA_SU_POLY_OFFSET_CLAMP.f32All = constant; //???
r700->PA_SU_POLY_OFFSET_FRONT_SCALE.f32All = factor;
r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.f32All = constant;
r700->PA_SU_POLY_OFFSET_BACK_SCALE.f32All = factor;
@@ -1272,10 +1295,11 @@ void r700SetScissor(context_t *context) //---------------
return;
}
if (context->radeon.state.scissor.enabled) {
+ /* r600 has exclusive scissors */
x1 = context->radeon.state.scissor.rect.x1;
y1 = context->radeon.state.scissor.rect.y1;
- x2 = context->radeon.state.scissor.rect.x2;
- y2 = context->radeon.state.scissor.rect.y2;
+ x2 = context->radeon.state.scissor.rect.x2 + 1;
+ y2 = context->radeon.state.scissor.rect.y2 + 1;
} else {
if (context->radeon.radeonScreen->driScreen->dri2.enabled) {
x1 = 0;
diff --git a/src/mesa/drivers/dri/r600/r700_state.h b/src/mesa/drivers/dri/r600/r700_state.h
index 0f53d5b4c59..209189d8d72 100644
--- a/src/mesa/drivers/dri/r600/r700_state.h
+++ b/src/mesa/drivers/dri/r600/r700_state.h
@@ -35,6 +35,7 @@
extern void r700UpdateStateParameters(GLcontext * ctx, GLuint new_state);
extern void r700UpdateShaders (GLcontext * ctx);
+extern void r700UpdateShaders2(GLcontext * ctx);
extern void r700UpdateViewportOffset(GLcontext * ctx);
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index d107f99e7ba..e7a209be9d8 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -35,12 +35,14 @@
#include "main/mtypes.h"
#include "tnl/t_context.h"
+#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_statevars.h"
#include "radeon_debug.h"
#include "r600_context.h"
#include "r600_cmdbuf.h"
+#include "shader/programopt.c"
#include "r700_debug.h"
#include "r700_vertprog.h"
@@ -157,7 +159,35 @@ GLboolean Process_Vertex_Program_Vfetch_Instructions(
return GL_TRUE;
}
-void Map_Vertex_Program(struct r700_vertex_program *vp,
+GLboolean Process_Vertex_Program_Vfetch_Instructions2(
+ GLcontext *ctx,
+ struct r700_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp)
+{
+ int i;
+ context_t *context = R700_CONTEXT(ctx);
+
+ VTX_FETCH_METHOD vtxFetchMethod;
+ vtxFetchMethod.bEnableMini = GL_FALSE;
+ vtxFetchMethod.mega_fetch_remainder = 0;
+
+ for(i=0; i<context->nNumActiveAos; i++)
+ {
+ assemble_vfetch_instruction2(&vp->r700AsmCode,
+ vp->r700AsmCode.ucVP_AttributeMap[context->stream_desc[i].element],
+ context->stream_desc[i].type,
+ context->stream_desc[i].size,
+ context->stream_desc[i].element,
+ context->stream_desc[i]._signed,
+ context->stream_desc[i].normalize,
+ &vtxFetchMethod);
+ }
+
+ return GL_TRUE;
+}
+
+void Map_Vertex_Program(GLcontext *ctx,
+ struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp)
{
GLuint ui;
@@ -173,11 +203,22 @@ void Map_Vertex_Program(struct r700_vertex_program *vp,
pAsm->number_used_registers += num_inputs;
// Create VFETCH instructions for inputs
- if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions(vp, mesa_vp) )
- {
- radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions return error. \n");
- return; //error
- }
+ if(1 == vp->uiVersion)
+ {
+ if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions(vp, mesa_vp) )
+ {
+ radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions return error. \n");
+ return;
+ }
+ }
+ else
+ {
+ if (GL_TRUE != Process_Vertex_Program_Vfetch_Instructions2(ctx, vp, mesa_vp) )
+ {
+ radeon_error("Calling Process_Vertex_Program_Vfetch_Instructions2 return error. \n");
+ return;
+ }
+ }
// Map Outputs
pAsm->number_of_exports = Map_Vertex_Output(pAsm, mesa_vp, pAsm->number_used_registers);
@@ -258,28 +299,61 @@ GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
return GL_TRUE;
}
-GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
- struct gl_vertex_program *mesa_vp)
+struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
+ struct gl_vertex_program *mesa_vp,
+ GLint nVer)
{
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_vertex_program *vp;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *vb = &tnl->vb;
+ unsigned int unBit;
+ unsigned int i;
+
+ vp = _mesa_calloc(sizeof(*vp));
+ vp->uiVersion = nVer;
+ vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base);
+
+ if (mesa_vp->IsPositionInvariant)
+ {
+ _mesa_insert_mvp_code(ctx, vp->mesa_program);
+ }
+
+ for(i=0; i<VERT_ATTRIB_MAX; i++)
+ {
+ unBit = 1 << i;
+ if(vp->mesa_program->Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */
+ {
+ vp->aos_desc[i].size = vb->AttribPtr[i]->size;
+ vp->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/
+ vp->aos_desc[i].type = GL_FLOAT;
+ }
+ }
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ {
+ vp->r700AsmCode.bR6xx = 1;
+ }
+
//Init_Program
Init_r700_AssemblerBase(SPT_VP, &(vp->r700AsmCode), &(vp->r700Shader) );
- Map_Vertex_Program( vp, mesa_vp );
+ Map_Vertex_Program(ctx, vp, vp->mesa_program );
- if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, mesa_vp))
+ if(GL_FALSE == Find_Instruction_Dependencies_vp(vp, vp->mesa_program))
{
- return GL_FALSE;
+ return NULL;
}
- if(GL_FALSE == AssembleInstr(mesa_vp->Base.NumInstructions,
- &(mesa_vp->Base.Instructions[0]),
+ if(GL_FALSE == AssembleInstr(vp->mesa_program->Base.NumInstructions,
+ &(vp->mesa_program->Base.Instructions[0]),
&(vp->r700AsmCode)) )
{
- return GL_FALSE;
+ return NULL;
}
- if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), mesa_vp->Base.OutputsWritten) )
+ if(GL_FALSE == Process_Vertex_Exports(&(vp->r700AsmCode), vp->mesa_program->Base.OutputsWritten) )
{
- return GL_FALSE;
+ return NULL;
}
vp->r700Shader.nRegs = (vp->r700AsmCode.number_used_registers == 0) ? 0
@@ -289,72 +363,216 @@ GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
vp->translated = GL_TRUE;
- return GL_TRUE;
+ return vp;
}
-void r700SelectVertexShader(GLcontext *ctx)
+void r700SelectVertexShader(GLcontext *ctx, GLint nVersion)
{
context_t *context = R700_CONTEXT(ctx);
- struct r700_vertex_program *vpc
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ struct r700_vertex_program_cont *vpc;
+ struct r700_vertex_program *vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *vb = &tnl->vb;
unsigned int unBit;
unsigned int i;
+ GLboolean match;
+ GLbitfield InputsRead;
- if (context->radeon.NewGLState & (_NEW_PROGRAM_CONSTANTS|_NEW_PROGRAM))
- {
- vpc->needUpdateVF = 1;
- }
+ vpc = (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
- if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ InputsRead = vpc->mesa_program.Base.InputsRead;
+ if (vpc->mesa_program.IsPositionInvariant)
{
- vpc->r700AsmCode.bR6xx = 1;
- }
-
+ InputsRead |= VERT_BIT_POS;
+ }
+
+ for (vp = vpc->progs; vp; vp = vp->next)
+ {
+ match = GL_TRUE;
for(i=0; i<VERT_ATTRIB_MAX; i++)
{
unBit = 1 << i;
- if(vpc->mesa_program.Base.InputsRead & unBit) /* ctx->Array.ArrayObj->xxxxxxx */
+ if(InputsRead & unBit)
{
- vpc->aos_desc[i].size = vb->AttribPtr[i]->size;
- vpc->aos_desc[i].stride = vb->AttribPtr[i]->size * sizeof(GL_FLOAT);/* when emit array, data is packed. vb->AttribPtr[i]->stride;*/
- vpc->aos_desc[i].type = GL_FLOAT;
+ if (vp->aos_desc[i].size != vb->AttribPtr[i]->size)
+ match = GL_FALSE;
+ break;
}
}
+ if (match)
+ {
+ context->selected_vp = vp;
+ return;
+ }
+ }
+
+ vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program), nVersion);
+ if(!vp)
+ {
+ radeon_error("Failed to translate vertex shader. \n");
+ return;
+ }
+ vp->next = vpc->progs;
+ vpc->progs = vp;
+ context->selected_vp = vp;
+ return;
+}
+
+int getTypeSize(GLenum type)
+{
+ switch (type)
+ {
+ case GL_DOUBLE:
+ return sizeof(GLdouble);
+ case GL_FLOAT:
+ return sizeof(GLfloat);
+ case GL_INT:
+ return sizeof(GLint);
+ case GL_UNSIGNED_INT:
+ return sizeof(GLuint);
+ case GL_SHORT:
+ return sizeof(GLshort);
+ case GL_UNSIGNED_SHORT:
+ return sizeof(GLushort);
+ case GL_BYTE:
+ return sizeof(GLbyte);
+ case GL_UNSIGNED_BYTE:
+ return sizeof(GLubyte);
+ default:
+ assert(0);
+ return 0;
+ }
+}
+
+static void r700TranslateAttrib(GLcontext *ctx, GLuint unLoc, int count, const struct gl_client_array *input)
+{
+ context_t *context = R700_CONTEXT(ctx);
+
+ StreamDesc * pStreamDesc = &(context->stream_desc[context->nNumActiveAos]);
+
+ GLuint stride;
+
+ stride = (input->StrideB == 0) ? getTypeSize(input->Type) * input->Size
+ : input->StrideB;
+
+ if (input->Type == GL_DOUBLE || input->Type == GL_UNSIGNED_INT || input->Type == GL_INT ||
+#if MESA_BIG_ENDIAN
+ getTypeSize(input->Type) != 4 ||
+#endif
+ stride < 4)
+ {
+ pStreamDesc->type = GL_FLOAT;
+
+ if (input->StrideB == 0)
+ {
+ pStreamDesc->stride = 0;
+ }
+ else
+ {
+ pStreamDesc->stride = sizeof(GLfloat) * input->Size;
+ }
+ pStreamDesc->dwords = input->Size;
+ pStreamDesc->is_named_bo = GL_FALSE;
+ }
+ else
+ {
+ pStreamDesc->type = input->Type;
+ pStreamDesc->dwords = (getTypeSize(input->Type) * input->Size + 3)/ 4;
+ if (!input->BufferObj->Name)
+ {
+ if (input->StrideB == 0)
+ {
+ pStreamDesc->stride = 0;
+ }
+ else
+ {
+ pStreamDesc->stride = (getTypeSize(pStreamDesc->type) * input->Size + 3) & ~3;
+ }
+
+ pStreamDesc->is_named_bo = GL_FALSE;
+ }
+ }
- if(GL_FALSE == vpc->translated) {
- r700TranslateVertexShader(vpc, &(vpc->mesa_program) );
+ pStreamDesc->size = input->Size;
+ pStreamDesc->dst_loc = context->nNumActiveAos;
+ pStreamDesc->element = unLoc;
+
+ switch (pStreamDesc->type)
+ { //GetSurfaceFormat
+ case GL_FLOAT:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = GL_FALSE;
+ break;
+ case GL_SHORT:
+ pStreamDesc->_signed = 1;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_BYTE:
+ pStreamDesc->_signed = 1;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_UNSIGNED_SHORT:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ case GL_UNSIGNED_BYTE:
+ pStreamDesc->_signed = 0;
+ pStreamDesc->normalize = input->Normalized;
+ break;
+ default:
+ case GL_INT:
+ case GL_UNSIGNED_INT:
+ case GL_DOUBLE:
+ assert(0);
+ break;
}
+ context->nNumActiveAos++;
+}
+
+void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_vertex_program *vpc
+ = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+
+ struct gl_vertex_program * mesa_vp = (struct gl_vertex_program *)&(vpc->mesa_program);
+ unsigned int unLoc = 0;
+ unsigned int unBit = mesa_vp->Base.InputsRead;
+ context->nNumActiveAos = 0;
+
+ while(unBit)
+ {
+ if(unBit & 1)
+ {
+ r700TranslateAttrib(ctx, unLoc, count, arrays[unLoc]);
+ }
+
+ unBit >>= 1;
+ ++unLoc;
+ }
}
void * r700GetActiveVpShaderBo(GLcontext * ctx)
{
- struct r700_vertex_program *vp
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_vertex_program *vp = context->selected_vp;;
- return vp->shaderbo;
+ if (vp)
+ return vp->shaderbo;
+ else
+ return NULL;
}
GLboolean r700SetupVertexProgram(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
- struct r700_vertex_program *vp
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ struct r700_vertex_program *vp = context->selected_vp;
struct gl_program_parameter_list *paramList;
unsigned int unNumParamData;
unsigned int ui;
- if (vp->needUpdateVF)
- {
- vp->loaded = GL_FALSE;
- vp->r700Shader.bNeedsAssembly = GL_TRUE;
- Process_Vertex_Program_Vfetch_Instructions(vp, &(vp->mesa_program));
- r600DeleteShader(ctx, vp->shaderbo);
- }
-
if(GL_FALSE == vp->loaded)
{
if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
@@ -410,7 +628,7 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
*/
/* sent out shader constants. */
- paramList = vp->mesa_program.Base.Parameters;
+ paramList = vp->mesa_program->Base.Parameters;
if(NULL != paramList) {
_mesa_load_state_parameters(ctx, paramList);
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.h b/src/mesa/drivers/dri/r600/r700_vertprog.h
index e2e65021fd3..f9a3e395ee9 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.h
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.h
@@ -43,7 +43,7 @@ typedef struct ArrayDesc //TEMP
struct r700_vertex_program
{
- struct gl_vertex_program mesa_program; /* Must be first */
+ struct gl_vertex_program *mesa_program; /* Must be first */
struct r700_vertex_program *next;
@@ -52,13 +52,20 @@ struct r700_vertex_program
GLboolean translated;
GLboolean loaded;
- GLboolean needUpdateVF;
+ GLint uiVersion;
void * shaderbo;
ArrayDesc aos_desc[VERT_ATTRIB_MAX];
};
+struct r700_vertex_program_cont
+{
+ struct gl_vertex_program mesa_program;
+
+ struct r700_vertex_program *progs;
+};
+
//Internal
unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm,
struct gl_vertex_program *mesa_vp,
@@ -69,19 +76,28 @@ unsigned int Map_Vertex_Input(r700_AssemblerBase *pAsm,
GLboolean Process_Vertex_Program_Vfetch_Instructions(
struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp);
-void Map_Vertex_Program(struct r700_vertex_program *vp,
+GLboolean Process_Vertex_Program_Vfetch_Instructions2(
+ GLcontext *ctx,
+ struct r700_vertex_program *vp,
+ struct gl_vertex_program *mesa_vp);
+void Map_Vertex_Program(GLcontext *ctx,
+ struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp);
GLboolean Find_Instruction_Dependencies_vp(struct r700_vertex_program *vp,
struct gl_vertex_program *mesa_vp);
-GLboolean r700TranslateVertexShader(struct r700_vertex_program *vp,
- struct gl_vertex_program *mesa_vp);
+struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx,
+ struct gl_vertex_program *mesa_vp,
+ GLint nVer);
/* Interface */
-extern void r700SelectVertexShader(GLcontext *ctx);
+extern void r700SelectVertexShader(GLcontext *ctx, GLint nVersion);
+extern void r700SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count);
extern GLboolean r700SetupVertexProgram(GLcontext * ctx);
extern void * r700GetActiveVpShaderBo(GLcontext * ctx);
+extern int getTypeSize(GLenum type);
+
#endif /* _R700_VERTPROG_H_ */
diff --git a/src/mesa/drivers/dri/r600/radeon_buffer_objects.c b/src/mesa/drivers/dri/r600/radeon_buffer_objects.c
new file mode 120000
index 00000000000..f6a5f664701
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_buffer_objects.c
@@ -0,0 +1 @@
+../radeon/radeon_buffer_objects.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_buffer_objects.h b/src/mesa/drivers/dri/r600/radeon_buffer_objects.h
new file mode 120000
index 00000000000..2f134fd17b8
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_buffer_objects.h
@@ -0,0 +1 @@
+../radeon/radeon_buffer_objects.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index 1f286776b5f..b1efc72872f 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -47,8 +47,7 @@ C_SOURCES = \
$(DRIVER_SOURCES) \
$(CS_SOURCES)
-DRIVER_DEFINES = -DRADEON_COMMON=0 \
- -Wall
+DRIVER_DEFINES = -DRADEON_R100 -Wall
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
index a24b6dac265..8fac5c6c512 100644
--- a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
@@ -187,7 +187,11 @@ radeonMapBuffer(GLcontext * ctx,
radeon_bo_map(radeon_obj->bo, access == GL_WRITE_ONLY_ARB);
- return obj->Pointer = radeon_obj->bo->ptr;
+ obj->Pointer = radeon_obj->bo->ptr;
+ obj->Length = obj->Size;
+ obj->Offset = 0;
+
+ return obj->Pointer;
}
@@ -203,9 +207,12 @@ radeonUnmapBuffer(GLcontext * ctx,
if (radeon_obj->bo != NULL) {
radeon_bo_unmap(radeon_obj->bo);
- obj->Pointer = NULL;
}
+ obj->Pointer = NULL;
+ obj->Offset = 0;
+ obj->Length = 0;
+
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index a4c7b40798a..f8a4cdb4954 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -232,13 +232,13 @@ void radeonUpdateScissor( GLcontext *ctx )
__DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
x1 += dPriv->x;
- x2 += dPriv->x + 1;
+ x2 += dPriv->x;
min_x += dPriv->x;
- max_x += dPriv->x + 1;
+ max_x += dPriv->x;
y1 += dPriv->y;
- y2 += dPriv->y + 1;
+ y2 += dPriv->y;
min_y += dPriv->y;
- max_y += dPriv->y + 1;
+ max_y += dPriv->y;
}
rmesa->state.scissor.rect.x1 = CLAMP(x1, min_x, max_x);
@@ -1345,5 +1345,5 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
void radeonUserClear(GLcontext *ctx, GLuint mask)
{
- _mesa_meta_clear(ctx, mask);
+ _mesa_meta_Clear(ctx, mask);
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 71ee06d9a79..6b9b1e3c5e4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -47,7 +47,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
+#if defined(RADEON_R600)
#include "r600_context.h"
#endif
@@ -227,11 +227,8 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
fthrottle_mode = driQueryOptioni(&radeon->optionCache, "fthrottle_mode");
radeon->iw.irq_seq = -1;
radeon->irqsEmitted = 0;
- if (IS_R600_CLASS(radeon->radeonScreen))
- radeon->do_irqs = 0;
- else
- radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
- radeon->radeonScreen->irq);
+ radeon->do_irqs = (fthrottle_mode == DRI_CONF_FTHROTTLE_IRQS &&
+ radeon->radeonScreen->irq);
radeon->do_usleeps = (fthrottle_mode == DRI_CONF_FTHROTTLE_USLEEPS);
diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.c b/src/mesa/drivers/dri/radeon/radeon_debug.c
index 3b6f0038037..413000b6c06 100644
--- a/src/mesa/drivers/dri/radeon/radeon_debug.c
+++ b/src/mesa/drivers/dri/radeon/radeon_debug.c
@@ -39,7 +39,7 @@ static const struct dri_debug_control debug_control[] = {
{"fall", RADEON_FALLBACKS},
{"tex", RADEON_TEXTURE},
{"ioctl", RADEON_IOCTL},
- {"verts", RADEON_RENDER},
+ {"verts", RADEON_VERTS},
{"render", RADEON_RENDER},
{"swrender", RADEON_SWRENDER},
{"state", RADEON_STATE},
diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h
index 2a8302293b2..26da31c1c48 100644
--- a/src/mesa/drivers/dri/radeon/radeon_debug.h
+++ b/src/mesa/drivers/dri/radeon/radeon_debug.h
@@ -149,21 +149,22 @@ static inline void radeon_debug_remove_indent(void)
}
}
+
/* From http://gcc. gnu.org/onlinedocs/gcc-3.2.3/gcc/Variadic-Macros.html .
I suppose we could inline this and use macro to fetch out __LINE__ and stuff in case we run into trouble
with other compilers ... GLUE!
*/
-#define WARN_ONCE(a, ...) { \
- static int warn##__LINE__=1; \
- if(warn##__LINE__){ \
+#define WARN_ONCE(a, ...) do { \
+ static int __warn_once=1; \
+ if(__warn_once){ \
radeon_warning("*********************************WARN_ONCE*********************************\n"); \
radeon_warning("File %s function %s line %d\n", \
__FILE__, __FUNCTION__, __LINE__); \
radeon_warning( (a), ## __VA_ARGS__);\
radeon_warning("***************************************************************************\n"); \
- warn##__LINE__=0;\
+ __warn_once=0;\
} \
- }
+ } while(0)
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.c b/src/mesa/drivers/dri/radeon/radeon_dma.c
index 2eefa3f2b1b..c6edbae9a1b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -207,7 +207,6 @@ again_alloc:
counter on unused buffers for later freeing them from
begin of list */
dma_bo = last_elem(&rmesa->dma.free);
- assert(dma_bo->bo->cref == 1);
remove_from_list(dma_bo);
insert_at_head(&rmesa->dma.reserved, dma_bo);
}
@@ -263,7 +262,7 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa,
void radeonFreeDmaRegions(radeonContextPtr rmesa)
{
- struct radeon_dma_bo *dma_bo = CALLOC_STRUCT(radeon_dma_bo);
+ struct radeon_dma_bo *dma_bo;
struct radeon_dma_bo *temp;
if (RADEON_DEBUG & RADEON_DMA)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -307,6 +306,10 @@ static int radeon_bo_is_idle(struct radeon_bo* bo)
WARN_ONCE("Your libdrm or kernel doesn't have support for busy query.\n"
"This may cause small performance drop for you.\n");
}
+ /* Protect against bug in legacy bo handling that causes bos stay
+ * referenced even after they should be freed */
+ if (bo->cref != 1)
+ return 0;
return ret != -EBUSY;
}
@@ -343,7 +346,9 @@ void radeonReleaseDmaRegions(radeonContextPtr rmesa)
foreach_s(dma_bo, temp, &rmesa->dma.wait) {
if (dma_bo->expire_counter == time) {
WARN_ONCE("Leaking dma buffer object!\n");
- radeon_bo_unref(dma_bo->bo);
+ /* force free of buffer so we don't realy start
+ * leaking stuff now*/
+ while ((dma_bo->bo = radeon_bo_unref(dma_bo->bo))) {}
remove_from_list(dma_bo);
FREE(dma_bo);
continue;
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index d83b166742c..7ac53ec0ca3 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -583,7 +583,7 @@ void radeon_fbo_init(struct radeon_context *radeon)
radeon->glCtx->Driver.FinishRenderTexture = radeon_finish_render_texture;
radeon->glCtx->Driver.ResizeBuffers = radeon_resize_buffers;
radeon->glCtx->Driver.ValidateFramebuffer = radeon_validate_framebuffer;
- radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_blit_framebuffer;
+ radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 5ffb55db5ef..573eb6c9c18 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -48,17 +48,17 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_screen.h"
#include "radeon_common.h"
#include "radeon_span.h"
-#if !RADEON_COMMON
+#if defined(RADEON_R100)
#include "radeon_context.h"
#include "radeon_tex.h"
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R200)
#include "r200_context.h"
#include "r200_ioctl.h"
#include "r200_tex.h"
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#elif defined(RADEON_R300)
#include "r300_context.h"
#include "r300_tex.h"
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#elif defined(RADEON_R600)
#include "r600_context.h"
#include "r700_driconf.h" /* +r6/r7 */
#include "r600_tex.h" /* +r6/r7 */
@@ -82,7 +82,7 @@ DRI_CONF_OPT_BEGIN_V(command_buffer_size,int,def, # min ":" # max ) \
DRI_CONF_DESC(de,"Grösse des Befehlspuffers (in KB)") \
DRI_CONF_OPT_END
-#if !RADEON_COMMON /* R100 */
+#if defined(RADEON_R100) /* R100 */
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
@@ -109,7 +109,7 @@ DRI_CONF_BEGIN
DRI_CONF_END;
static const GLuint __driNConfigOptions = 15;
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R200)
PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
@@ -147,7 +147,7 @@ extern const struct dri_extension NV_vp_extension[];
extern const struct dri_extension ATI_fs_extension[];
extern const struct dri_extension point_extensions[];
-#elif RADEON_COMMON && (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))
+#elif defined(RADEON_R300) || defined(RADEON_R600)
#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1
@@ -220,7 +220,7 @@ static const GLuint __driNConfigOptions = 17;
extern const struct dri_extension gl_20_extension[];
-#endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */
+#endif
extern const struct dri_extension card_extensions[];
extern const struct dri_extension mm_extensions[];
@@ -337,7 +337,7 @@ radeonFillInModes( __DRIscreenPrivate *psp,
return (const __DRIconfig **) configs;
}
-#if !RADEON_COMMON
+#if defined(RADEON_R100)
static const __DRItexOffsetExtension radeonTexOffsetExtension = {
{ __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
radeonSetTexOffset,
@@ -350,7 +350,7 @@ static const __DRItexBufferExtension radeonTexBufferExtension = {
};
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
static const __DRIallocateExtension r200AllocateExtension = {
{ __DRI_ALLOCATE, __DRI_ALLOCATE_VERSION },
r200AllocateMemoryMESA,
@@ -370,7 +370,7 @@ static const __DRItexBufferExtension r200TexBufferExtension = {
};
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#if defined(RADEON_R300)
static const __DRItexOffsetExtension r300texOffsetExtension = {
{ __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
r300SetTexOffset,
@@ -383,7 +383,7 @@ static const __DRItexBufferExtension r300TexBufferExtension = {
};
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#if defined(RADEON_R600)
static const __DRItexOffsetExtension r600texOffsetExtension = {
{ __DRI_TEX_OFFSET, __DRI_TEX_OFFSET_VERSION },
r600SetTexOffset, /* +r6/r7 */
@@ -1222,22 +1222,22 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
screen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
-#if !RADEON_COMMON
+#if defined(RADEON_R100)
screen->extensions[i++] = &radeonTexOffsetExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
if (IS_R200_CLASS(screen))
screen->extensions[i++] = &r200AllocateExtension.base;
screen->extensions[i++] = &r200texOffsetExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#if defined(RADEON_R300)
screen->extensions[i++] = &r300texOffsetExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#if defined(RADEON_R600)
screen->extensions[i++] = &r600texOffsetExtension.base;
#endif
@@ -1376,22 +1376,22 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
screen->extensions[i++] = &driMediaStreamCounterExtension.base;
}
-#if !RADEON_COMMON
+#if defined(RADEON_R100)
screen->extensions[i++] = &radeonTexBufferExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
if (IS_R200_CLASS(screen))
screen->extensions[i++] = &r200AllocateExtension.base;
screen->extensions[i++] = &r200TexBufferExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#if defined(RADEON_R300)
screen->extensions[i++] = &r300TexBufferExtension.base;
#endif
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#if defined(RADEON_R600)
screen->extensions[i++] = &r600TexBufferExtension.base;
#endif
@@ -1589,22 +1589,22 @@ radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
static const __DRIconfig **
radeonInitScreen(__DRIscreenPrivate *psp)
{
-#if !RADEON_COMMON
+#if defined(RADEON_R100)
static const char *driver_name = "Radeon";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 6, 0 };
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R200)
static const char *driver_name = "R200";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 6, 0 };
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#elif defined(RADEON_R300)
static const char *driver_name = "R300";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
static const __DRIversion drm_expected = { 1, 24, 0 };
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#elif defined(RADEON_R600)
static const char *driver_name = "R600";
static const __DRIutilversion2 ddx_expected = { 4, 5, 0, 0 };
static const __DRIversion dri_expected = { 4, 0, 0 };
@@ -1630,13 +1630,13 @@ radeonInitScreen(__DRIscreenPrivate *psp)
* Hello chicken. Hello egg. How are you two today?
*/
driInitExtensions( NULL, card_extensions, GL_FALSE );
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
driInitExtensions( NULL, blend_extensions, GL_FALSE );
driInitSingleExtension( NULL, ARB_vp_extension );
driInitSingleExtension( NULL, NV_vp_extension );
driInitSingleExtension( NULL, ATI_fs_extension );
driInitExtensions( NULL, point_extensions, GL_FALSE );
-#elif (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))
+#elif (defined(RADEON_R300) || defined(RADEON_R600))
driInitSingleExtension( NULL, gl_20_extension );
#endif
@@ -1684,13 +1684,13 @@ __DRIconfig **radeonInitScreen2(__DRIscreenPrivate *psp)
*/
driInitExtensions( NULL, card_extensions, GL_FALSE );
driInitExtensions( NULL, mm_extensions, GL_FALSE );
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
driInitExtensions( NULL, blend_extensions, GL_FALSE );
driInitSingleExtension( NULL, ARB_vp_extension );
driInitSingleExtension( NULL, NV_vp_extension );
driInitSingleExtension( NULL, ATI_fs_extension );
driInitExtensions( NULL, point_extensions, GL_FALSE );
-#elif (defined(RADEON_COMMON_FOR_R300) || defined(RADEON_COMMON_FOR_R600))
+#elif (defined(RADEON_R300) || defined(RADEON_R600))
driInitSingleExtension( NULL, gl_20_extension );
#endif
@@ -1772,13 +1772,13 @@ getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = radeonInitScreen,
.DestroyScreen = radeonDestroyScreen,
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
.CreateContext = r200CreateContext,
.DestroyContext = r200DestroyContext,
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
+#elif defined(RADEON_R600)
.CreateContext = r600CreateContext,
.DestroyContext = radeonDestroyContext,
-#elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
+#elif defined(RADEON_R300)
.CreateContext = r300CreateContext,
.DestroyContext = radeonDestroyContext,
#else
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index 4e100d854ed..0c49c3713af 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -55,7 +55,7 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
/* r200 depth buffer is always tiled - this is the formula
according to the docs unless I typo'ed in it
*/
-#if defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
GLint x, GLint y)
{
@@ -106,6 +106,141 @@ static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
}
#endif
+/* r600 tiling
+ * two main types:
+ * - 1D (akin to macro-linear/micro-tiled on older asics)
+ * - 2D (akin to macro-tiled/micro-tiled on older asics)
+ * only 1D tiling is implemented below
+ */
+#if defined(RADEON_R600)
+static inline GLint r600_1d_tile_helper(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y, GLint is_depth, GLint is_stencil)
+{
+ GLint element_bytes = rrb->cpp;
+ GLint num_samples = 1;
+ GLint tile_width = 8;
+ GLint tile_height = 8;
+ GLint tile_thickness = 1;
+ GLint pitch_elements = rrb->pitch / element_bytes;
+ GLint height = rrb->base.Height;
+ GLint z = 0;
+ GLint sample_number = 0;
+ /* */
+ GLint tile_bytes;
+ GLint tiles_per_row;
+ GLint tiles_per_slice;
+ GLint slice_offset;
+ GLint tile_row_index;
+ GLint tile_column_index;
+ GLint tile_offset;
+ GLint pixel_number = 0;
+ GLint element_offset;
+ GLint offset = 0;
+
+ tile_bytes = tile_width * tile_height * tile_thickness * element_bytes * num_samples;
+ tiles_per_row = pitch_elements / tile_width;
+ tiles_per_slice = tiles_per_row * (height / tile_height);
+ slice_offset = (z / tile_thickness) * tiles_per_slice * tile_bytes;
+ tile_row_index = y / tile_height;
+ tile_column_index = x / tile_width;
+ tile_offset = ((tile_row_index * tiles_per_row) + tile_column_index) * tile_bytes;
+
+ if (is_depth) {
+ GLint pixel_offset = 0;
+
+ pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
+ pixel_number |= ((y >> 0) & 1) << 1; // pn[1] = y[0]
+ pixel_number |= ((x >> 1) & 1) << 2; // pn[2] = x[1]
+ pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
+ pixel_number |= ((x >> 2) & 1) << 4; // pn[4] = x[2]
+ pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
+ switch (element_bytes) {
+ case 2:
+ pixel_offset = pixel_number * element_bytes * num_samples;
+ break;
+ case 4:
+ /* stencil and depth data are stored separately within a tile.
+ * stencil is stored in a contiguous tile before the depth tile.
+ * stencil element is 1 byte, depth element is 3 bytes.
+ * stencil tile is 64 bytes.
+ */
+ if (is_stencil)
+ pixel_offset = pixel_number * 1 * num_samples;
+ else
+ pixel_offset = (pixel_number * 3 * num_samples) + 64;
+ break;
+ }
+ element_offset = pixel_offset + (sample_number * element_bytes);
+ } else {
+ GLint sample_offset;
+
+ switch (element_bytes) {
+ case 1:
+ pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
+ pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
+ pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
+ pixel_number |= ((y >> 1) & 1) << 3; // pn[3] = y[1]
+ pixel_number |= ((y >> 0) & 1) << 4; // pn[4] = y[0]
+ pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
+ break;
+ case 2:
+ pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
+ pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
+ pixel_number |= ((x >> 2) & 1) << 2; // pn[2] = x[2]
+ pixel_number |= ((y >> 0) & 1) << 3; // pn[3] = y[0]
+ pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
+ pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
+ break;
+ case 4:
+ pixel_number |= ((x >> 0) & 1) << 0; // pn[0] = x[0]
+ pixel_number |= ((x >> 1) & 1) << 1; // pn[1] = x[1]
+ pixel_number |= ((y >> 0) & 1) << 2; // pn[2] = y[0]
+ pixel_number |= ((x >> 2) & 1) << 3; // pn[3] = x[2]
+ pixel_number |= ((y >> 1) & 1) << 4; // pn[4] = y[1]
+ pixel_number |= ((y >> 2) & 1) << 5; // pn[5] = y[2]
+ break;
+ }
+ sample_offset = sample_number * (tile_bytes / num_samples);
+ element_offset = sample_offset + (pixel_number * element_bytes);
+ }
+ offset = slice_offset + tile_offset + element_offset;
+ return offset;
+}
+
+/* depth buffers */
+static GLubyte *r600_ptr_depth(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 0);
+ return &ptr[offset];
+}
+
+static GLubyte *r600_ptr_stencil(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset = r600_1d_tile_helper(rrb, x, y, 1, 1);
+ return &ptr[offset];
+}
+
+static GLubyte *r600_ptr_color(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ uint32_t mask = RADEON_BO_FLAGS_MACRO_TILE | RADEON_BO_FLAGS_MICRO_TILE;
+ GLint offset;
+
+ if (rrb->has_surface || !(rrb->bo->flags & mask)) {
+ offset = x * rrb->cpp + y * rrb->pitch;
+ } else {
+ offset = r600_1d_tile_helper(rrb, x, y, 0, 0);
+ }
+ return &ptr[offset];
+}
+
+#else
+
/* radeon tiling on r300-r500 has 4 states,
macro-linear/micro-linear
macro-linear/micro-tiled
@@ -197,7 +332,10 @@ static GLubyte *radeon_ptr_2byte_8x2(const struct radeon_renderbuffer * rrb,
return &ptr[offset];
}
-#ifndef COMPILE_R300
+#endif
+
+#ifndef RADEON_R300
+#ifndef RADEON_R600
static uint32_t
z24s8_to_s8z24(uint32_t val)
{
@@ -210,6 +348,7 @@ s8z24_to_z24s8(uint32_t val)
return (val >> 24) | (val << 8);
}
#endif
+#endif
/*
* Note that all information needed to access pixels in a renderbuffer
@@ -270,7 +409,11 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_RGB565
#define TAG2(x,y) radeon##x##_RGB565##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
#include "spantmp2.h"
/* 16 bit, ARGB1555 color spanline and pixel functions
@@ -280,7 +423,11 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_ARGB1555
#define TAG2(x,y) radeon##x##_ARGB1555##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
#include "spantmp2.h"
/* 16 bit, RGBA4 color spanline and pixel functions
@@ -290,7 +437,11 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_ARGB4444
#define TAG2(x,y) radeon##x##_ARGB4444##y
+#if defined(RADEON_R600)
+#define GET_PTR(X,Y) r600_ptr_color(rrb, (X) + x_off, (Y) + y_off)
+#else
#define GET_PTR(X,Y) radeon_ptr_2byte_8x2(rrb, (X) + x_off, (Y) + y_off)
+#endif
#include "spantmp2.h"
/* 32 bit, xRGB8888 color spanline and pixel functions
@@ -300,11 +451,19 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_xRGB8888
#define TAG2(x,y) radeon##x##_xRGB8888##y
+#if defined(RADEON_R600)
+#define GET_VALUE(_x, _y) ((*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off)) | 0xff000000))
+#define PUT_VALUE(_x, _y, d) { \
+ GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off ); \
+ *_ptr = d; \
+} while (0)
+#else
#define GET_VALUE(_x, _y) ((*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) | 0xff000000))
#define PUT_VALUE(_x, _y, d) { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
+#endif
#include "spantmp2.h"
/* 32 bit, ARGB8888 color spanline and pixel functions
@@ -314,11 +473,19 @@ s8z24_to_z24s8(uint32_t val)
#define TAG(x) radeon##x##_ARGB8888
#define TAG2(x,y) radeon##x##_ARGB8888##y
+#if defined(RADEON_R600)
+#define GET_VALUE(_x, _y) (*(GLuint*)(r600_ptr_color(rrb, _x + x_off, _y + y_off)))
+#define PUT_VALUE(_x, _y, d) { \
+ GLuint *_ptr = (GLuint*)r600_ptr_color( rrb, _x + x_off, _y + y_off ); \
+ *_ptr = d; \
+} while (0)
+#else
#define GET_VALUE(_x, _y) (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)))
#define PUT_VALUE(_x, _y, d) { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
+#endif
#include "spantmp2.h"
/* ================================================================
@@ -339,17 +506,23 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLushort
-#if defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off) = d
+#elif defined(RADEON_R600)
+#define WRITE_DEPTH( _x, _y, d ) \
+ *(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off) = d
#else
#define WRITE_DEPTH( _x, _y, d ) \
*(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off) = d
#endif
-#if defined(RADEON_COMMON_FOR_R200)
+#if defined(RADEON_R200)
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)r200_depth_2byte(rrb, _x + x_off, _y + y_off)
+#elif defined(RADEON_R600)
+#define READ_DEPTH( d, _x, _y ) \
+ d = *(GLushort *)r600_ptr_depth(rrb, _x + x_off, _y + y_off)
#else
#define READ_DEPTH( d, _x, _y ) \
d = *(GLushort *)radeon_ptr_2byte_8x2(rrb, _x + x_off, _y + y_off)
@@ -365,7 +538,7 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLuint
-#if defined(COMPILE_R300)
+#if defined(RADEON_R300)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
@@ -374,7 +547,16 @@ do { \
tmp |= ((d << 8) & 0xffffff00); \
*_ptr = tmp; \
} while (0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define WRITE_DEPTH( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0xff000000; \
+ tmp |= ((d) & 0x00ffffff); \
+ *_ptr = tmp; \
+} while (0)
+#elif defined(RADEON_R200)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
@@ -394,12 +576,17 @@ do { \
} while (0)
#endif
-#if defined(COMPILE_R300)
+#if defined(RADEON_R300)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0xffffff00) >> 8; \
}while(0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define READ_DEPTH( d, _x, _y ) \
+ do { \
+ d = (*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off)) & 0x00ffffff); \
+ }while(0)
+#elif defined(RADEON_R200)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = *(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff; \
@@ -420,13 +607,27 @@ do { \
*/
#define VALUE_TYPE GLuint
-#if defined(COMPILE_R300)
+#if defined(RADEON_R300)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
*_ptr = d; \
} while (0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define WRITE_DEPTH( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r600_ptr_depth( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0xff000000; \
+ tmp |= (((d) >> 8) & 0x00ffffff); \
+ *_ptr = tmp; \
+ _ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off); \
+ tmp = *_ptr; \
+ tmp &= 0xffffff00; \
+ tmp |= (d) & 0xff; \
+ *_ptr = tmp; \
+} while (0)
+#elif defined(RADEON_R200)
#define WRITE_DEPTH( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
@@ -442,12 +643,18 @@ do { \
} while (0)
#endif
-#if defined(COMPILE_R300)
+#if defined(RADEON_R300)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = (*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off))); \
}while(0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define READ_DEPTH( d, _x, _y ) \
+ do { \
+ d = ((*(GLuint*)(r600_ptr_depth(rrb, _x + x_off, _y + y_off))) << 8) & 0xffffff00; \
+ d |= (*(GLuint*)(r600_ptr_stencil(rrb, _x + x_off, _y + y_off))) & 0x000000ff; \
+ }while(0)
+#elif defined(RADEON_R200)
#define READ_DEPTH( d, _x, _y ) \
do { \
d = s8z24_to_z24s8(*(GLuint*)(r200_depth_4byte(rrb, _x + x_off, _y + y_off))); \
@@ -467,7 +674,7 @@ do { \
/* 24 bit depth, 8 bit stencil depthbuffer functions
*/
-#ifdef COMPILE_R300
+#ifdef RADEON_R300
#define WRITE_STENCIL( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte(rrb, _x + x_off, _y + y_off); \
@@ -476,7 +683,16 @@ do { \
tmp |= (d) & 0xff; \
*_ptr = tmp; \
} while (0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define WRITE_STENCIL( _x, _y, d ) \
+do { \
+ GLuint *_ptr = (GLuint*)r600_ptr_stencil(rrb, _x + x_off, _y + y_off); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0xffffff00; \
+ tmp |= (d) & 0xff; \
+ *_ptr = tmp; \
+} while (0)
+#elif defined(RADEON_R200)
#define WRITE_STENCIL( _x, _y, d ) \
do { \
GLuint *_ptr = (GLuint*)r200_depth_4byte(rrb, _x + x_off, _y + y_off); \
@@ -496,14 +712,21 @@ do { \
} while (0)
#endif
-#ifdef COMPILE_R300
+#ifdef RADEON_R300
#define READ_STENCIL( d, _x, _y ) \
do { \
GLuint *_ptr = (GLuint*)radeon_ptr_4byte( rrb, _x + x_off, _y + y_off ); \
GLuint tmp = *_ptr; \
d = tmp & 0x000000ff; \
} while (0)
-#elif defined(RADEON_COMMON_FOR_R200)
+#elif defined(RADEON_R600)
+#define READ_STENCIL( d, _x, _y ) \
+do { \
+ GLuint *_ptr = (GLuint*)r600_ptr_stencil( rrb, _x + x_off, _y + y_off ); \
+ GLuint tmp = *_ptr; \
+ d = tmp & 0x000000ff; \
+} while (0)
+#elif defined(RADEON_R200)
#define READ_STENCIL( d, _x, _y ) \
do { \
GLuint *_ptr = (GLuint*)r200_depth_4byte( rrb, _x + x_off, _y + y_off ); \
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index 9d252aa74c5..ae41b90efe5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -833,11 +833,14 @@ static void import_tex_obj_state( r100ContextPtr rmesa,
cmd[TEX_PP_TXFORMAT] |= texobj->pp_txformat & TEXOBJ_TXFORMAT_MASK;
cmd[TEX_PP_BORDER_COLOR] = texobj->pp_border_color;
- if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
- GLuint *txr_cmd = RADEON_DB_STATE( txr[unit] );
+ if (texobj->pp_txformat & RADEON_TXFORMAT_NON_POWER2) {
+ uint32_t *txr_cmd = &rmesa->hw.txr[unit].cmd[TXR_CMD_0];
txr_cmd[TXR_PP_TEX_SIZE] = texobj->pp_txsize; /* NPOT only! */
txr_cmd[TXR_PP_TEX_PITCH] = texobj->pp_txpitch; /* NPOT only! */
- RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.txr[unit] );
+ RADEON_STATECHANGE( rmesa, txr[unit] );
+ }
+
+ if (texobj->base.Target == GL_TEXTURE_RECTANGLE_NV) {
se_coord_fmt |= RADEON_VTX_ST0_NONPARAMETRIC << unit;
}
else {
@@ -1114,7 +1117,6 @@ static GLboolean radeon_validate_texture(GLcontext *ctx, struct gl_texture_objec
RADEON_STATECHANGE( rmesa, ctx );
rmesa->hw.ctx.cmd[CTX_PP_CNTL] |=
(RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << unit;
-
RADEON_STATECHANGE( rmesa, tcl );
rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_ST_BIT(unit);
diff --git a/src/mesa/drivers/dri/radeon/radeon_texture.c b/src/mesa/drivers/dri/radeon/radeon_texture.c
index fad3d1cedaf..049284ef8c5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -659,11 +659,6 @@ static void radeon_teximage(
if (dims == 3)
_mesa_free(dstImageOffsets);
}
-
- /* SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- radeon_generate_mipmap(ctx, target, texObj);
- }
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -792,11 +787,6 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
format, type, pixels, packing))
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
}
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- radeon_generate_mipmap(ctx, target, texObj);
- }
}
radeon_teximage_unmap(image);
diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.c b/src/mesa/drivers/dri/s3v/s3v_tex.c
index 9b92519862a..ec1182f34f7 100644
--- a/src/mesa/drivers/dri/s3v/s3v_tex.c
+++ b/src/mesa/drivers/dri/s3v/s3v_tex.c
@@ -536,24 +536,13 @@ void s3vInitTextureFuncs( GLcontext *ctx )
#endif
ctx->Driver.TexEnv = s3vTexEnv;
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;
ctx->Driver.TexImage2D = s3vTexImage2D;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
ctx->Driver.TexSubImage2D = s3vTexSubImage2D;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
ctx->Driver.BindTexture = s3vBindTexture;
ctx->Driver.DeleteTexture = s3vDeleteTexture;
ctx->Driver.TexParameter = s3vTexParameter;
ctx->Driver.UpdateTexturePalette = 0;
ctx->Driver.IsTextureResident = s3vIsTextureResident;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
s3vInitTextureObjects( ctx );
}
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index b36cd0274a8..f4947daa063 100644
--- a/src/mesa/drivers/dri/swrast/swrast.c
+++ b/src/mesa/drivers/dri/swrast/swrast.c
@@ -43,6 +43,7 @@
#include "tnl/t_pipeline.h"
#include "vbo/vbo.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "utils.h"
#include "swrast_priv.h"
@@ -650,6 +651,8 @@ driCreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
_mesa_enable_2_0_extensions(mesaCtx);
_mesa_enable_2_1_extensions(mesaCtx);
+ _mesa_meta_init(mesaCtx);
+
return ctx;
}
@@ -661,6 +664,7 @@ driDestroyContext(__DRIcontext *ctx)
if (ctx) {
mesaCtx = &ctx->Base;
+ _mesa_meta_free(mesaCtx);
_swsetup_DestroyContext( mesaCtx );
_swrast_DestroyContext( mesaCtx );
_tnl_DestroyContext( mesaCtx );
diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tex.c b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
index 1f7257eaead..f6a48b3ae12 100644
--- a/src/mesa/drivers/dri/tdfx/tdfx_tex.c
+++ b/src/mesa/drivers/dri/tdfx/tdfx_tex.c
@@ -176,6 +176,54 @@ logbase2(int n)
}
+static void
+tdfxGenerateMipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj)
+{
+ GLint mipWidth, mipHeight;
+ tdfxMipMapLevel *mip;
+ struct gl_texture_image *mipImage; /* the new/next image */
+ struct gl_texture_image *texImage;
+ const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
+ GLint level = texObj->BaseLevel;
+ GLsizei width, height, texelBytes;
+ const tdfxMipMapLevel *mml;
+
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ assert(!texImage->IsCompressed);
+
+ mml = TDFX_TEXIMAGE_DATA(texImage);
+
+ width = texImage->Width;
+ height = texImage->Height;
+ while (level < texObj->MaxLevel && level < maxLevels - 1) {
+ mipWidth = width / 2;
+ if (!mipWidth) {
+ mipWidth = 1;
+ }
+ mipHeight = height / 2;
+ if (!mipHeight) {
+ mipHeight = 1;
+ }
+ if ((mipWidth == width) && (mipHeight == height)) {
+ break;
+ }
+ ++level;
+ mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ mip = TDFX_TEXIMAGE_DATA(mipImage);
+ _mesa_halve2x2_teximage2d(ctx,
+ texImage,
+ texelBytes,
+ mml->width, mml->height,
+ texImage->Data, mipImage->Data);
+ texImage = mipImage;
+ mml = mip;
+ width = mipWidth;
+ height = mipHeight;
+ }
+}
+
+
/*
* Compute various texture image parameters.
* Input: w, h - source texture width and height
@@ -1397,45 +1445,6 @@ tdfxTexImage2D(GLcontext *ctx, GLenum target, GLint level,
width, height, 1,
format, type, pixels, packing);
}
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- GLint mipWidth, mipHeight;
- tdfxMipMapLevel *mip;
- struct gl_texture_image *mipImage;
- const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
-
- assert(!texImage->IsCompressed);
-
- while (level < texObj->MaxLevel && level < maxLevels - 1) {
- mipWidth = width / 2;
- if (!mipWidth) {
- mipWidth = 1;
- }
- mipHeight = height / 2;
- if (!mipHeight) {
- mipHeight = 1;
- }
- if ((mipWidth == width) && (mipHeight == height)) {
- break;
- }
- _mesa_TexImage2D(target, ++level, internalFormat,
- mipWidth, mipHeight, border,
- format, type,
- NULL);
- mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
- mip = TDFX_TEXIMAGE_DATA(mipImage);
- _mesa_halve2x2_teximage2d(ctx,
- texImage,
- texelBytes,
- mml->width, mml->height,
- texImage->Data, mipImage->Data);
- texImage = mipImage;
- mml = mip;
- width = mipWidth;
- height = mipHeight;
- }
- }
}
RevalidateTexture(ctx, texObj);
@@ -1507,44 +1516,6 @@ tdfxTexSubImage2D(GLcontext *ctx, GLenum target, GLint level,
format, type, pixels, packing);
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- GLint mipWidth, mipHeight;
- tdfxMipMapLevel *mip;
- struct gl_texture_image *mipImage;
- const GLint maxLevels = _mesa_max_texture_levels(ctx, texObj->Target);
-
- assert(!texImage->IsCompressed);
-
- width = texImage->Width;
- height = texImage->Height;
- while (level < texObj->MaxLevel && level < maxLevels - 1) {
- mipWidth = width / 2;
- if (!mipWidth) {
- mipWidth = 1;
- }
- mipHeight = height / 2;
- if (!mipHeight) {
- mipHeight = 1;
- }
- if ((mipWidth == width) && (mipHeight == height)) {
- break;
- }
- ++level;
- mipImage = _mesa_select_tex_image(ctx, texObj, target, level);
- mip = TDFX_TEXIMAGE_DATA(mipImage);
- _mesa_halve2x2_teximage2d(ctx,
- texImage,
- texelBytes,
- mml->width, mml->height,
- texImage->Data, mipImage->Data);
- texImage = mipImage;
- mml = mip;
- width = mipWidth;
- height = mipHeight;
- }
- }
-
ti->reloadImages = GL_TRUE; /* signal the image needs to be reloaded */
fxMesa->new_state |= TDFX_NEW_TEXTURE; /* XXX this might be a bit much */
}
@@ -1703,11 +1674,6 @@ tdfxCompressedTexImage2D (GLcontext *ctx, GLenum target,
MEMCPY(texImage->Data, data, texImage->CompressedSize);
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- assert(!texImage->IsCompressed);
- }
-
RevalidateTexture(ctx, texObj);
ti->reloadImages = GL_TRUE;
@@ -1770,11 +1736,6 @@ tdfxCompressedTexSubImage2D( GLcontext *ctx, GLenum target,
texImage->Data);
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- assert(!texImage->IsCompressed);
- }
-
RevalidateTexture(ctx, texObj);
ti->reloadImages = GL_TRUE;
@@ -1914,4 +1875,5 @@ void tdfxInitTextureFuncs( struct dd_function_table *functions )
functions->CompressedTexImage2D = tdfxCompressedTexImage2D;
functions->CompressedTexSubImage2D = tdfxCompressedTexSubImage2D;
functions->UpdateTexturePalette = tdfxUpdateTexturePalette;
+ functions->GenerateMipmap = tdfxGenerateMipmap;
}
diff --git a/src/mesa/drivers/dri/unichrome/via_tex.c b/src/mesa/drivers/dri/unichrome/via_tex.c
index d2010f09074..54073e76918 100644
--- a/src/mesa/drivers/dri/unichrome/via_tex.c
+++ b/src/mesa/drivers/dri/unichrome/via_tex.c
@@ -818,11 +818,6 @@ static void viaTexImage(GLcontext *ctx,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- _mesa_generate_mipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
diff --git a/src/mesa/drivers/osmesa/osmesa.c b/src/mesa/drivers/osmesa/osmesa.c
index 904659e3450..692657a5dfd 100644
--- a/src/mesa/drivers/osmesa/osmesa.c
+++ b/src/mesa/drivers/osmesa/osmesa.c
@@ -50,6 +50,7 @@
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "vbo/vbo.h"
@@ -1258,6 +1259,8 @@ OSMesaCreateContextExt( GLenum format, GLint depthBits, GLint stencilBits,
osmesa->bInd = bind;
osmesa->aInd = aind;
+ _mesa_meta_init(&osmesa->mesa);
+
/* Initialize the software rasterizer and helper modules. */
{
GLcontext *ctx = &osmesa->mesa;
@@ -1304,6 +1307,8 @@ OSMesaDestroyContext( OSMesaContext osmesa )
if (osmesa->rb)
_mesa_reference_renderbuffer(&osmesa->rb, NULL);
+ _mesa_meta_free( &osmesa->mesa );
+
_swsetup_DestroyContext( &osmesa->mesa );
_tnl_DestroyContext( &osmesa->mesa );
_vbo_DestroyContext( &osmesa->mesa );
diff --git a/src/mesa/drivers/windows/gdi/mesa.def b/src/mesa/drivers/windows/gdi/mesa.def
index bd3e5b21373..5abcd1d927e 100644
--- a/src/mesa/drivers/windows/gdi/mesa.def
+++ b/src/mesa/drivers/windows/gdi/mesa.def
@@ -943,6 +943,15 @@ EXPORTS
_mesa_update_framebuffer_visual
_mesa_use_program
_mesa_Viewport
+ _mesa_meta_CopyColorSubTable
+ _mesa_meta_CopyColorTable
+ _mesa_meta_CopyConvolutionFilter1D
+ _mesa_meta_CopyConvolutionFilter2D
+ _mesa_meta_CopyTexImage1D
+ _mesa_meta_CopyTexImage2D
+ _mesa_meta_CopyTexSubImage1D
+ _mesa_meta_CopyTexSubImage2D
+ _mesa_meta_CopyTexSubImage3D
_mesa_wait_query
_swrast_Accum
_swrast_Bitmap
@@ -953,15 +962,6 @@ EXPORTS
_swrast_Clear
_swrast_choose_line
_swrast_choose_triangle
- _swrast_CopyColorSubTable
- _swrast_CopyColorTable
- _swrast_CopyConvolutionFilter1D
- _swrast_CopyConvolutionFilter2D
- _swrast_copy_teximage1d
- _swrast_copy_teximage2d
- _swrast_copy_texsubimage1d
- _swrast_copy_texsubimage2d
- _swrast_copy_texsubimage3d
_swrast_CreateContext
_swrast_DestroyContext
_swrast_exec_fragment_program
diff --git a/src/mesa/drivers/windows/gdi/wmesa.c b/src/mesa/drivers/windows/gdi/wmesa.c
index e1971db6933..8929b22af16 100644
--- a/src/mesa/drivers/windows/gdi/wmesa.c
+++ b/src/mesa/drivers/windows/gdi/wmesa.c
@@ -12,6 +12,7 @@
#include "framebuffer.h"
#include "renderbuffer.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "vbo/vbo.h"
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
@@ -1515,6 +1516,8 @@ WMesaContext WMesaCreateContext(HDC hDC,
_mesa_enable_2_0_extensions(ctx);
_mesa_enable_2_1_extensions(ctx);
+ _mesa_meta_init(ctx);
+
/* Initialize the software rasterizer and helper modules. */
if (!_swrast_CreateContext(ctx) ||
!_vbo_CreateContext(ctx) ||
@@ -1558,6 +1561,8 @@ void WMesaDestroyContext( WMesaContext pwc )
DeleteObject(pwc->clearPen);
DeleteObject(pwc->clearBrush);
+ _mesa_meta_free(ctx);
+
_swsetup_DestroyContext(ctx);
_tnl_DestroyContext(ctx);
_vbo_DestroyContext(ctx);
diff --git a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c
index 342a742867a..7ac425a1092 100644
--- a/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c
+++ b/src/mesa/drivers/windows/gldirect/mesasw/gld_wgl_mesasw.c
@@ -1346,6 +1346,8 @@ static void wmesa_update_state_first_time(
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference( ctx );
TNLcontext *tnl = TNL_CONTEXT(ctx);
+ _mesa_init_driver_functions(&ctx->Driver);
+
/*
* XXX these function pointers could be initialized just once during
* context creation since they don't depend on any state changes.
@@ -1362,8 +1364,6 @@ static void wmesa_update_state_first_time(
ctx->Driver.Viewport = wmesa_viewport;
- ctx->Driver.Accum = _swrast_Accum;
- ctx->Driver.Bitmap = _swrast_Bitmap;
ctx->Driver.Clear = clear;
ctx->Driver.Flush = flush;
@@ -1371,28 +1371,6 @@ static void wmesa_update_state_first_time(
ctx->Driver.ClearColor = clear_color;
ctx->Driver.Enable = enable;
- ctx->Driver.CopyPixels = _swrast_CopyPixels;
- ctx->Driver.DrawPixels = _swrast_DrawPixels;
- ctx->Driver.ReadPixels = _swrast_ReadPixels;
-
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;
- ctx->Driver.TexImage2D = _mesa_store_teximage2d;
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
- ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
-
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
- ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
- ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
- ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
- ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
// Does not apply for Mesa 5.x
//ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
diff --git a/src/mesa/drivers/windows/icd/mesa.def b/src/mesa/drivers/windows/icd/mesa.def
index 465b380a0cb..25ac08a2f0f 100644
--- a/src/mesa/drivers/windows/icd/mesa.def
+++ b/src/mesa/drivers/windows/icd/mesa.def
@@ -75,6 +75,15 @@ EXPORTS
_mesa_strcmp
_mesa_test_proxy_teximage
_mesa_Viewport
+ _mesa_meta_CopyColorSubTable
+ _mesa_meta_CopyColorTable
+ _mesa_meta_CopyConvolutionFilter1D
+ _mesa_meta_CopyConvolutionFilter2D
+ _mesa_meta_CopyTexImage1D
+ _mesa_meta_CopyTexImage2D
+ _mesa_meta_CopyTexSubImage1D
+ _mesa_meta_CopyTexSubImage2D
+ _mesa_meta_CopyTexSubImage3D
_swrast_Accum
_swrast_Bitmap
_swrast_CopyPixels
@@ -84,15 +93,6 @@ EXPORTS
_swrast_Clear
_swrast_choose_line
_swrast_choose_triangle
- _swrast_CopyColorSubTable
- _swrast_CopyColorTable
- _swrast_CopyConvolutionFilter1D
- _swrast_CopyConvolutionFilter2D
- _swrast_copy_teximage1d
- _swrast_copy_teximage2d
- _swrast_copy_texsubimage1d
- _swrast_copy_texsubimage2d
- _swrast_copy_texsubimage3d
_swrast_CreateContext
_swrast_DestroyContext
_swrast_InvalidateState
diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c
index 662c61ae7e7..79b058634cf 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -1648,8 +1648,7 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
xmesa_register_swrast_functions( mesaCtx );
_swsetup_Wakeup(mesaCtx);
- if (TEST_META_FUNCS)
- _mesa_meta_init(mesaCtx);
+ _mesa_meta_init(mesaCtx);
return c;
}
@@ -1665,8 +1664,7 @@ void XMesaDestroyContext( XMesaContext c )
FXdestroyContext( XMESA_BUFFER(mesaCtx->DrawBuffer) );
#endif
- if (TEST_META_FUNCS)
- _mesa_meta_free( mesaCtx );
+ _mesa_meta_free( mesaCtx );
_swsetup_DestroyContext( mesaCtx );
_swrast_DestroyContext( mesaCtx );
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 4e9c001cc76..e2d4aa9b2d1 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -1150,11 +1150,11 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
driver->Enable = enable;
driver->Viewport = xmesa_viewport;
if (TEST_META_FUNCS) {
- driver->Clear = _mesa_meta_clear;
- driver->CopyPixels = _mesa_meta_copy_pixels;
- driver->BlitFramebuffer = _mesa_meta_blit_framebuffer;
- driver->DrawPixels = _mesa_meta_draw_pixels;
- driver->Bitmap = _mesa_meta_bitmap;
+ driver->Clear = _mesa_meta_Clear;
+ driver->CopyPixels = _mesa_meta_CopyPixels;
+ driver->BlitFramebuffer = _mesa_meta_BlitFramebuffer;
+ driver->DrawPixels = _mesa_meta_DrawPixels;
+ driver->Bitmap = _mesa_meta_Bitmap;
}
else {
driver->Clear = clear_buffers;
diff --git a/src/mesa/glapi/EXT_provoking_vertex.xml b/src/mesa/glapi/EXT_provoking_vertex.xml
index f528a2c7d36..71d2c729091 100644
--- a/src/mesa/glapi/EXT_provoking_vertex.xml
+++ b/src/mesa/glapi/EXT_provoking_vertex.xml
@@ -19,4 +19,17 @@
</category>
+<category name="GL_ARB_provoking_vertex" number="64">
+
+ <enum name="FIRST_VERTEX_CONVENTION" value="0x8E4D"/>
+ <enum name="LAST_VERTEX_CONVENTION" value="0x8E4E"/>
+ <enum name="PROVOKING_VERTEX" value="0x8E4F"/>
+ <enum name="QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION" value="0x8E4C"/>
+
+ <function name="ProvokingVertex" alias="ProvokingVertexEXT">
+ <param name="mode" type="GLenum"/>
+ </function>
+
+</category>
+
</OpenGLAPI>
diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h
index 3da0f631435..d9a3690f2ad 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -5677,6 +5677,11 @@ KEYWORD1 void KEYWORD2 NAME(ProvokingVertexEXT)(GLenum mode)
DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertexEXT(0x%x);\n", mode));
}
+KEYWORD1 void KEYWORD2 NAME(ProvokingVertex)(GLenum mode)
+{
+ DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertex(0x%x);\n", mode));
+}
+
KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_788)(GLenum target, GLenum pname, GLvoid ** params);
KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_788)(GLenum target, GLenum pname, GLvoid ** params)
@@ -6923,6 +6928,7 @@ static _glapi_proc UNUSED_TABLE_NAME[] = {
TABLE_ENTRY(RenderbufferStorage),
TABLE_ENTRY(BlitFramebuffer),
TABLE_ENTRY(FramebufferTextureLayer),
+ TABLE_ENTRY(ProvokingVertex),
};
#endif /*UNUSED_TABLE_NAME*/
diff --git a/src/mesa/glapi/glprocs.h b/src/mesa/glapi/glprocs.h
index fc0fcd331a3..c29f8b57be9 100644
--- a/src/mesa/glapi/glprocs.h
+++ b/src/mesa/glapi/glprocs.h
@@ -1147,6 +1147,7 @@ static const char gl_string_table[] =
"glRenderbufferStorage\0"
"glBlitFramebuffer\0"
"glFramebufferTextureLayer\0"
+ "glProvokingVertex\0"
;
@@ -2353,6 +2354,7 @@ static const glprocs_table_t static_functions[] = {
NAME_FUNC_OFFSET(19722, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
NAME_FUNC_OFFSET(19744, gl_dispatch_stub_783, gl_dispatch_stub_783, NULL, _gloffset_BlitFramebufferEXT),
NAME_FUNC_OFFSET(19762, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+ NAME_FUNC_OFFSET(19788, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
NAME_FUNC_OFFSET(-1, NULL, NULL, NULL, 0)
};
diff --git a/src/mesa/glapi/mesadef.py b/src/mesa/glapi/mesadef.py
index 0f410fc4825..342c9cde460 100644
--- a/src/mesa/glapi/mesadef.py
+++ b/src/mesa/glapi/mesadef.py
@@ -155,6 +155,15 @@ def PrintTail():
print '\t_mesa_strcmp'
print '\t_mesa_test_proxy_teximage'
print '\t_mesa_Viewport'
+ print '\t_mesa_meta_CopyColorSubTable'
+ print '\t_mesa_meta_CopyColorTable'
+ print '\t_mesa_meta_CopyConvolutionFilter1D'
+ print '\t_mesa_meta_CopyConvolutionFilter2D'
+ print '\t_mesa_meta_CopyTexImage1D'
+ print '\t_mesa_meta_CopyTexImage2D'
+ print '\t_mesa_meta_CopyTexSubImage1D'
+ print '\t_mesa_meta_CopyTexSubImage2D'
+ print '\t_mesa_meta_CopyTexSubImage3D'
print '\t_swrast_Accum'
print '\t_swrast_alloc_buffers'
print '\t_swrast_Bitmap'
@@ -164,15 +173,6 @@ def PrintTail():
print '\t_swrast_Clear'
print '\t_swrast_choose_line'
print '\t_swrast_choose_triangle'
- print '\t_swrast_CopyColorSubTable'
- print '\t_swrast_CopyColorTable'
- print '\t_swrast_CopyConvolutionFilter1D'
- print '\t_swrast_CopyConvolutionFilter2D'
- print '\t_swrast_copy_teximage1d'
- print '\t_swrast_copy_teximage2d'
- print '\t_swrast_copy_texsubimage1d'
- print '\t_swrast_copy_texsubimage2d'
- print '\t_swrast_copy_texsubimage3d'
print '\t_swrast_CreateContext'
print '\t_swrast_DestroyContext'
print '\t_swrast_InvalidateState'
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index 02550ae1088..63176390751 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -54,13 +54,9 @@
#endif
#include "clear.h"
#include "clip.h"
-#if FEATURE_colortable
#include "colortab.h"
-#endif
#include "context.h"
-#if FEATURE_convolve
#include "convolve.h"
-#endif
#include "depth.h"
#if FEATURE_dlist
#include "dlist.h"
@@ -93,9 +89,7 @@
#include "macros.h"
#include "matrix.h"
#include "multisample.h"
-#if FEATURE_pixel_transfer
#include "pixel.h"
-#endif
#include "pixelstore.h"
#include "points.h"
#include "polygon.h"
@@ -284,17 +278,9 @@ _mesa_init_exec_table(struct _glapi_table *exec)
SET_MapGrid2f(exec, _mesa_MapGrid2f);
#endif
SET_MultMatrixd(exec, _mesa_MultMatrixd);
-#if FEATURE_pixel_transfer
- SET_GetPixelMapfv(exec, _mesa_GetPixelMapfv);
- SET_GetPixelMapuiv(exec, _mesa_GetPixelMapuiv);
- SET_GetPixelMapusv(exec, _mesa_GetPixelMapusv);
- SET_PixelMapfv(exec, _mesa_PixelMapfv);
- SET_PixelMapuiv(exec, _mesa_PixelMapuiv);
- SET_PixelMapusv(exec, _mesa_PixelMapusv);
- SET_PixelTransferf(exec, _mesa_PixelTransferf);
- SET_PixelTransferi(exec, _mesa_PixelTransferi);
- SET_PixelZoom(exec, _mesa_PixelZoom);
-#endif
+
+ _mesa_init_pixel_dispatch(exec);
+
SET_PixelStoref(exec, _mesa_PixelStoref);
SET_PointSize(exec, _mesa_PointSize);
SET_PolygonMode(exec, _mesa_PolygonMode);
@@ -395,32 +381,8 @@ _mesa_init_exec_table(struct _glapi_table *exec)
SET_BlendEquation(exec, _mesa_BlendEquation);
SET_BlendEquationSeparateEXT(exec, _mesa_BlendEquationSeparateEXT);
-#if FEATURE_colortable
- SET_ColorSubTable(exec, _mesa_ColorSubTable);
- SET_ColorTable(exec, _mesa_ColorTable);
- SET_ColorTableParameterfv(exec, _mesa_ColorTableParameterfv);
- SET_ColorTableParameteriv(exec, _mesa_ColorTableParameteriv);
- SET_CopyColorSubTable(exec, _mesa_CopyColorSubTable);
- SET_CopyColorTable(exec, _mesa_CopyColorTable);
- SET_GetColorTable(exec, _mesa_GetColorTable);
- SET_GetColorTableParameterfv(exec, _mesa_GetColorTableParameterfv);
- SET_GetColorTableParameteriv(exec, _mesa_GetColorTableParameteriv);
-#endif
-
-#if FEATURE_convolve
- SET_ConvolutionFilter1D(exec, _mesa_ConvolutionFilter1D);
- SET_ConvolutionFilter2D(exec, _mesa_ConvolutionFilter2D);
- SET_ConvolutionParameterf(exec, _mesa_ConvolutionParameterf);
- SET_ConvolutionParameterfv(exec, _mesa_ConvolutionParameterfv);
- SET_ConvolutionParameteri(exec, _mesa_ConvolutionParameteri);
- SET_ConvolutionParameteriv(exec, _mesa_ConvolutionParameteriv);
- SET_CopyConvolutionFilter1D(exec, _mesa_CopyConvolutionFilter1D);
- SET_CopyConvolutionFilter2D(exec, _mesa_CopyConvolutionFilter2D);
- SET_GetConvolutionFilter(exec, _mesa_GetConvolutionFilter);
- SET_GetConvolutionParameterfv(exec, _mesa_GetConvolutionParameterfv);
- SET_GetConvolutionParameteriv(exec, _mesa_GetConvolutionParameteriv);
- SET_SeparableFilter2D(exec, _mesa_SeparableFilter2D);
-#endif
+ _mesa_init_colortable_dispatch(exec);
+ _mesa_init_convolve_dispatch(exec);
#if FEATURE_histogram
SET_GetHistogram(exec, _mesa_GetHistogram);
SET_GetHistogramParameterfv(exec, _mesa_GetHistogramParameterfv);
@@ -428,7 +390,6 @@ _mesa_init_exec_table(struct _glapi_table *exec)
SET_GetMinmax(exec, _mesa_GetMinmax);
SET_GetMinmaxParameterfv(exec, _mesa_GetMinmaxParameterfv);
SET_GetMinmaxParameteriv(exec, _mesa_GetMinmaxParameteriv);
- SET_GetSeparableFilter(exec, _mesa_GetSeparableFilter);
SET_Histogram(exec, _mesa_Histogram);
SET_Minmax(exec, _mesa_Minmax);
SET_ResetHistogram(exec, _mesa_ResetHistogram);
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index 4a1448deee6..e71e5a6ce86 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -52,6 +52,51 @@ index_bytes(GLenum type, GLsizei count)
/**
+ * Find the max index in the given element/index buffer
+ */
+GLuint
+_mesa_max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
+ const void *indices,
+ struct gl_buffer_object *elementBuf)
+{
+ const GLubyte *map = NULL;
+ GLuint max = 0;
+ GLuint i;
+
+ if (_mesa_is_bufferobj(elementBuf)) {
+ /* elements are in a user-defined buffer object. need to map it */
+ map = ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER,
+ GL_READ_ONLY, elementBuf);
+ /* Actual address is the sum of pointers */
+ indices = (const GLvoid *) ADD_POINTERS(map, (const GLubyte *) indices);
+ }
+
+ if (type == GL_UNSIGNED_INT) {
+ for (i = 0; i < count; i++)
+ if (((GLuint *) indices)[i] > max)
+ max = ((GLuint *) indices)[i];
+ }
+ else if (type == GL_UNSIGNED_SHORT) {
+ for (i = 0; i < count; i++)
+ if (((GLushort *) indices)[i] > max)
+ max = ((GLushort *) indices)[i];
+ }
+ else {
+ ASSERT(type == GL_UNSIGNED_BYTE);
+ for (i = 0; i < count; i++)
+ if (((GLubyte *) indices)[i] > max)
+ max = ((GLubyte *) indices)[i];
+ }
+
+ if (map) {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuf);
+ }
+
+ return max;
+}
+
+
+/**
* Check if OK to draw arrays/elements.
*/
static GLboolean
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index 1d3ae157d73..6064d15fe6c 100644
--- a/src/mesa/main/api_validate.h
+++ b/src/mesa/main/api_validate.h
@@ -30,6 +30,12 @@
#include "mtypes.h"
+
+extern GLuint
+_mesa_max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
+ const void *indices,
+ struct gl_buffer_object *elementBuf);
+
extern GLboolean
_mesa_validate_DrawArrays(GLcontext *ctx,
GLenum mode, GLint start, GLsizei count);
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index b95e00af5bb..189b5e16558 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -1173,7 +1173,7 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
ASSERT(ctx->Driver.BufferData);
if (!ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj )) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB(access)");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()");
}
}
@@ -1262,7 +1262,7 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
ASSERT(ctx->Driver.MapBuffer);
map = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
if (!map) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
return NULL;
}
else {
@@ -1593,7 +1593,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
map = ctx->Driver.MapBufferRange(ctx, target, offset, length,
access, bufObj);
if (!map) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
}
else {
/* The driver callback should have set all these fields.
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index 5a7de5f2098..5ede76c1fb1 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -31,6 +31,11 @@
#include "macros.h"
#include "state.h"
#include "teximage.h"
+#include "texstate.h"
+#include "glapi/dispatch.h"
+
+
+#if FEATURE_colortable
/**
@@ -278,7 +283,7 @@ _mesa_ColorTable( GLenum target, GLenum internalFormat,
static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_texture_object *texObj = NULL;
struct gl_color_table *table = NULL;
GLboolean proxy = GL_FALSE;
@@ -443,7 +448,7 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
static const GLfloat one[4] = { 1.0, 1.0, 1.0, 1.0 };
static const GLfloat zero[4] = { 0.0, 0.0, 0.0, 0.0 };
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_texture_object *texObj = NULL;
struct gl_color_table *table = NULL;
const GLfloat *scale = one, *bias = zero;
@@ -535,37 +540,44 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_CopyColorTable(GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
- /* Select buffer to read from */
+ if (!ctx->ReadBuffer->_ColorReadBuffer) {
+ return; /* no readbuffer - OK */
+ }
+
ctx->Driver.CopyColorTable( ctx, target, internalformat, x, y, width );
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_CopyColorSubTable(GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width)
{
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (!ctx->ReadBuffer->_ColorReadBuffer) {
+ return; /* no readbuffer - OK */
+ }
+
ctx->Driver.CopyColorSubTable( ctx, target, start, x, y, width );
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetColorTable( GLenum target, GLenum format,
GLenum type, GLvoid *data )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_color_table *table = NULL;
GLfloat rgba[MAX_COLOR_TABLE_SIZE][4];
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
@@ -694,7 +706,7 @@ _mesa_GetColorTable( GLenum target, GLenum format,
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
GLfloat *scale, *bias;
@@ -739,7 +751,7 @@ _mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params)
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
{
GLfloat fparams[4];
@@ -762,11 +774,11 @@ _mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params)
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_color_table *table = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -889,11 +901,11 @@ _mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params )
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
{
GET_CURRENT_CONTEXT(ctx);
- struct gl_texture_unit *texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ struct gl_texture_unit *texUnit = _mesa_get_current_tex_unit(ctx);
struct gl_color_table *table = NULL;
ASSERT_OUTSIDE_BEGIN_END(ctx);
@@ -1044,6 +1056,25 @@ _mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params )
}
}
+
+void
+_mesa_init_colortable_dispatch(struct _glapi_table *disp)
+{
+ SET_ColorSubTable(disp, _mesa_ColorSubTable);
+ SET_ColorTable(disp, _mesa_ColorTable);
+ SET_ColorTableParameterfv(disp, _mesa_ColorTableParameterfv);
+ SET_ColorTableParameteriv(disp, _mesa_ColorTableParameteriv);
+ SET_CopyColorSubTable(disp, _mesa_CopyColorSubTable);
+ SET_CopyColorTable(disp, _mesa_CopyColorTable);
+ SET_GetColorTable(disp, _mesa_GetColorTable);
+ SET_GetColorTableParameterfv(disp, _mesa_GetColorTableParameterfv);
+ SET_GetColorTableParameteriv(disp, _mesa_GetColorTableParameteriv);
+}
+
+
+#endif /* FEATURE_colortable */
+
+
/**********************************************************************/
/***** Initialization *****/
/**********************************************************************/
diff --git a/src/mesa/main/colortab.h b/src/mesa/main/colortab.h
index b6ff737a65f..652fb582463 100644
--- a/src/mesa/main/colortab.h
+++ b/src/mesa/main/colortab.h
@@ -27,9 +27,16 @@
#define COLORTAB_H
-#include "mtypes.h"
+#include "main/mtypes.h"
-#if _HAVE_FULL_GL
+#if FEATURE_colortable
+
+#define _MESA_INIT_COLORTABLE_FUNCTIONS(driver, impl) \
+ do { \
+ (driver)->CopyColorTable = impl ## CopyColorTable; \
+ (driver)->CopyColorSubTable = impl ## CopyColorSubTable; \
+ (driver)->UpdateTexturePalette = impl ## UpdateTexturePalette; \
+ } while (0)
extern void GLAPIENTRY
_mesa_ColorTable( GLenum target, GLenum internalformat,
@@ -41,32 +48,35 @@ _mesa_ColorSubTable( GLenum target, GLsizei start,
GLsizei count, GLenum format, GLenum type,
const GLvoid *table );
-extern void GLAPIENTRY
-_mesa_CopyColorSubTable(GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width);
-
-extern void GLAPIENTRY
-_mesa_CopyColorTable(GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width);
+extern void
+_mesa_init_colortable_dispatch(struct _glapi_table *disp);
-extern void GLAPIENTRY
-_mesa_GetColorTable( GLenum target, GLenum format,
- GLenum type, GLvoid *table );
+#else /* FEATURE_colortable */
-extern void GLAPIENTRY
-_mesa_ColorTableParameterfv(GLenum target, GLenum pname,
- const GLfloat *params);
+#define _MESA_INIT_COLORTABLE_FUNCTIONS(driver, impl) do { } while (0)
-extern void GLAPIENTRY
-_mesa_ColorTableParameteriv(GLenum target, GLenum pname,
- const GLint *params);
+static INLINE void GLAPIENTRY
+_mesa_ColorTable( GLenum target, GLenum internalformat,
+ GLsizei width, GLenum format, GLenum type,
+ const GLvoid *table )
+{
+ ASSERT_NO_FEATURE();
+}
-extern void GLAPIENTRY
-_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params );
+static INLINE void GLAPIENTRY
+_mesa_ColorSubTable( GLenum target, GLsizei start,
+ GLsizei count, GLenum format, GLenum type,
+ const GLvoid *table )
+{
+ ASSERT_NO_FEATURE();
+}
-extern void GLAPIENTRY
-_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params );
+static INLINE void
+_mesa_init_colortable_dispatch(struct _glapi_table *disp)
+{
+}
+#endif /* FEATURE_colortable */
extern void
@@ -81,20 +91,5 @@ _mesa_init_colortables( GLcontext *ctx );
extern void
_mesa_free_colortables_data( GLcontext *ctx );
-#else
-
-/** No-op */
-#define _mesa_init_colortable( p ) ((void) 0)
-
-/** No-op */
-#define _mesa_free_colortable_data( p ) ((void) 0)
-
-/** No-op */
-#define _mesa_init_colortables( p ) ((void)0)
-
-/** No-op */
-#define _mesa_free_colortables_data( p ) ((void)0)
-
-#endif
-#endif
+#endif /* COLORTAB_H */
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index 9319505a75d..380663ec971 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -107,8 +107,7 @@ extern "C" {
/**
* finite macro.
*/
-#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(BUILD_FOR_SNAP)
-# define __WIN32__
+#if defined(_MSC_VER)
# define finite _finite
#elif defined(__WATCOMC__)
# define finite _finite
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index f6d4ac45957..1907c799df9 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -90,9 +90,7 @@
#include "blend.h"
#include "buffers.h"
#include "bufferobj.h"
-#if FEATURE_colortable
#include "colortab.h"
-#endif
#include "context.h"
#include "cpuinfo.h"
#include "debug.h"
@@ -686,9 +684,7 @@ init_attrib_groups(GLcontext *ctx)
#endif
_mesa_init_buffer_objects( ctx );
_mesa_init_color( ctx );
-#if FEATURE_colortable
_mesa_init_colortables( ctx );
-#endif
_mesa_init_current( ctx );
_mesa_init_depth( ctx );
_mesa_init_debug( ctx );
@@ -1015,9 +1011,7 @@ _mesa_free_context_data( GLcontext *ctx )
_mesa_free_texture_data( ctx );
_mesa_free_matrix_data( ctx );
_mesa_free_viewport_data( ctx );
-#if FEATURE_colortable
_mesa_free_colortables_data( ctx );
-#endif
_mesa_free_program_data(ctx);
_mesa_free_shader_state(ctx);
#if FEATURE_ARB_occlusion_query
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 70951112a18..8db3e79d384 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -40,6 +40,10 @@
#include "mtypes.h"
#include "pixel.h"
#include "state.h"
+#include "glapi/dispatch.h"
+
+
+#if FEATURE_convolve
/*
@@ -256,7 +260,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
{
GET_CURRENT_CONTEXT(ctx);
@@ -299,7 +303,7 @@ _mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -351,7 +355,7 @@ _mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
{
GET_CURRENT_CONTEXT(ctx);
@@ -394,7 +398,7 @@ _mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -459,7 +463,7 @@ _mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width)
{
GLint baseFormat;
@@ -482,12 +486,16 @@ _mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLi
return;
}
+ if (!ctx->ReadBuffer->_ColorReadBuffer) {
+ return; /* no readbuffer - OK */
+ }
+
ctx->Driver.CopyConvolutionFilter1D( ctx, target,
internalFormat, x, y, width);
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height)
{
GLint baseFormat;
@@ -514,12 +522,16 @@ _mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLi
return;
}
+ if (!ctx->ReadBuffer->_ColorReadBuffer) {
+ return; /* no readbuffer - OK */
+ }
+
ctx->Driver.CopyConvolutionFilter2D( ctx, target, internalFormat, x, y,
width, height );
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
GLvoid *image)
{
@@ -578,7 +590,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -639,7 +651,7 @@ _mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params)
{
GET_CURRENT_CONTEXT(ctx);
@@ -709,7 +721,7 @@ _mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params)
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
GLvoid *row, GLvoid *column, GLvoid *span)
{
@@ -776,7 +788,7 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column)
{
const GLint colStart = MAX_CONVOLUTION_WIDTH * 4;
@@ -1425,3 +1437,25 @@ _mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,
*height = *height - (MAX2(ctx->Separable2D.Height, 1) - 1);
}
}
+
+
+void
+_mesa_init_convolve_dispatch(struct _glapi_table *disp)
+{
+ SET_ConvolutionFilter1D(disp, _mesa_ConvolutionFilter1D);
+ SET_ConvolutionFilter2D(disp, _mesa_ConvolutionFilter2D);
+ SET_ConvolutionParameterf(disp, _mesa_ConvolutionParameterf);
+ SET_ConvolutionParameterfv(disp, _mesa_ConvolutionParameterfv);
+ SET_ConvolutionParameteri(disp, _mesa_ConvolutionParameteri);
+ SET_ConvolutionParameteriv(disp, _mesa_ConvolutionParameteriv);
+ SET_CopyConvolutionFilter1D(disp, _mesa_CopyConvolutionFilter1D);
+ SET_CopyConvolutionFilter2D(disp, _mesa_CopyConvolutionFilter2D);
+ SET_GetConvolutionFilter(disp, _mesa_GetConvolutionFilter);
+ SET_GetConvolutionParameterfv(disp, _mesa_GetConvolutionParameterfv);
+ SET_GetConvolutionParameteriv(disp, _mesa_GetConvolutionParameteriv);
+ SET_SeparableFilter2D(disp, _mesa_SeparableFilter2D);
+ SET_GetSeparableFilter(disp, _mesa_GetSeparableFilter);
+}
+
+
+#endif /* FEATURE_convolve */
diff --git a/src/mesa/main/convolve.h b/src/mesa/main/convolve.h
index 4505cdae01e..59492bc7c54 100644
--- a/src/mesa/main/convolve.h
+++ b/src/mesa/main/convolve.h
@@ -28,10 +28,17 @@
#define CONVOLVE_H
-#include "mtypes.h"
+#include "main/mtypes.h"
-#if _HAVE_FULL_GL
+#if FEATURE_convolve
+
+#define _MESA_INIT_CONVOLVE_FUNCTIONS(driver, impl) \
+ do { \
+ (driver)->CopyConvolutionFilter1D = impl ## CopyConvolutionFilter1D; \
+ (driver)->CopyConvolutionFilter2D = impl ## CopyConvolutionFilter2D; \
+ } while (0)
+
extern void GLAPIENTRY
_mesa_ConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width,
GLenum format, GLenum type, const GLvoid *image);
@@ -41,74 +48,79 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width,
GLsizei height, GLenum format, GLenum type,
const GLvoid *image);
-extern void GLAPIENTRY
-_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat params);
-
-extern void GLAPIENTRY
-_mesa_ConvolutionParameterfv(GLenum target, GLenum pname,
- const GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint params);
-
-extern void GLAPIENTRY
-_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params);
-
-extern void GLAPIENTRY
-_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width);
+extern void
+_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
+ const GLfloat *srcImage, GLfloat *dstImage);
-extern void GLAPIENTRY
-_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLsizei height);
+extern void
+_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage);
-extern void GLAPIENTRY
-_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
- GLvoid *image);
+extern void
+_mesa_convolve_sep_image(const GLcontext *ctx,
+ GLsizei *width, GLsizei *height,
+ const GLfloat *srcImage, GLfloat *dstImage);
-extern void GLAPIENTRY
-_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params);
+extern void
+_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,
+ GLsizei *width, GLsizei *height);
-extern void GLAPIENTRY
-_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params);
+extern void
+_mesa_init_convolve_dispatch(struct _glapi_table *disp);
-extern void GLAPIENTRY
-_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
- GLvoid *row, GLvoid *column, GLvoid *span);
+#else /* FEATURE_convolve */
-extern void GLAPIENTRY
-_mesa_SeparableFilter2D(GLenum target, GLenum internalformat,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *row, const GLvoid *column);
+#define _MESA_INIT_CONVOLVE_FUNCTIONS(driver, impl) do { } while (0)
+static INLINE void GLAPIENTRY
+_mesa_ConvolutionFilter1D(GLenum target, GLenum internalformat, GLsizei width,
+ GLenum format, GLenum type, const GLvoid *image)
+{
+ ASSERT_NO_FEATURE();
+}
+static INLINE void GLAPIENTRY
+_mesa_ConvolutionFilter2D(GLenum target, GLenum internalformat, GLsizei width,
+ GLsizei height, GLenum format, GLenum type,
+ const GLvoid *image)
+{
+ ASSERT_NO_FEATURE();
+}
-extern void
+static INLINE void
_mesa_convolve_1d_image(const GLcontext *ctx, GLsizei *width,
- const GLfloat *srcImage, GLfloat *dstImage);
-
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ ASSERT_NO_FEATURE();
+}
-extern void
+static INLINE void
_mesa_convolve_2d_image(const GLcontext *ctx, GLsizei *width, GLsizei *height,
- const GLfloat *srcImage, GLfloat *dstImage);
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ ASSERT_NO_FEATURE();
+}
-extern void
+static INLINE void
_mesa_convolve_sep_image(const GLcontext *ctx,
GLsizei *width, GLsizei *height,
- const GLfloat *srcImage, GLfloat *dstImage);
-
+ const GLfloat *srcImage, GLfloat *dstImage)
+{
+ ASSERT_NO_FEATURE();
+}
-extern void
+static INLINE void
_mesa_adjust_image_for_convolution(const GLcontext *ctx, GLuint dimensions,
- GLsizei *width, GLsizei *height);
+ GLsizei *width, GLsizei *height)
+{
+}
+
+static INLINE void
+_mesa_init_convolve_dispatch(struct _glapi_table *disp)
+{
+}
-#else
-#define _mesa_adjust_image_for_convolution(c, d, w, h) ((void)0)
-#define _mesa_convolve_1d_image(c,w,s,d) ((void)0)
-#define _mesa_convolve_2d_image(c,w,h,s,d) ((void)0)
-#define _mesa_convolve_sep_image(c,w,h,s,d) ((void)0)
-#endif
+#endif /* FEATURE_convolve */
-#endif
+#endif /* CONVOLVE_H */
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index d721f699fd1..9c25de41871 100644
--- a/src/mesa/main/dlist.c
+++ b/src/mesa/main/dlist.c
@@ -329,6 +329,34 @@ typedef enum
OPCODE_STENCIL_OP_SEPARATE,
OPCODE_STENCIL_MASK_SEPARATE,
+ /* GL_ARB_shader_objects */
+ OPCODE_USE_PROGRAM,
+ OPCODE_UNIFORM_1F,
+ OPCODE_UNIFORM_2F,
+ OPCODE_UNIFORM_3F,
+ OPCODE_UNIFORM_4F,
+ OPCODE_UNIFORM_1FV,
+ OPCODE_UNIFORM_2FV,
+ OPCODE_UNIFORM_3FV,
+ OPCODE_UNIFORM_4FV,
+ OPCODE_UNIFORM_1I,
+ OPCODE_UNIFORM_2I,
+ OPCODE_UNIFORM_3I,
+ OPCODE_UNIFORM_4I,
+ OPCODE_UNIFORM_1IV,
+ OPCODE_UNIFORM_2IV,
+ OPCODE_UNIFORM_3IV,
+ OPCODE_UNIFORM_4IV,
+ OPCODE_UNIFORM_MATRIX22,
+ OPCODE_UNIFORM_MATRIX33,
+ OPCODE_UNIFORM_MATRIX44,
+ OPCODE_UNIFORM_MATRIX23,
+ OPCODE_UNIFORM_MATRIX32,
+ OPCODE_UNIFORM_MATRIX24,
+ OPCODE_UNIFORM_MATRIX42,
+ OPCODE_UNIFORM_MATRIX34,
+ OPCODE_UNIFORM_MATRIX43,
+
/* GL_EXT_framebuffer_blit */
OPCODE_BLIT_FRAMEBUFFER,
@@ -576,6 +604,30 @@ _mesa_delete_list(GLcontext *ctx, struct gl_display_list *dlist)
n += InstSize[n[0].opcode];
break;
#endif
+ case OPCODE_UNIFORM_1FV:
+ case OPCODE_UNIFORM_2FV:
+ case OPCODE_UNIFORM_3FV:
+ case OPCODE_UNIFORM_4FV:
+ case OPCODE_UNIFORM_1IV:
+ case OPCODE_UNIFORM_2IV:
+ case OPCODE_UNIFORM_3IV:
+ case OPCODE_UNIFORM_4IV:
+ _mesa_free(n[3].data);
+ n += InstSize[n[0].opcode];
+ break;
+ case OPCODE_UNIFORM_MATRIX22:
+ case OPCODE_UNIFORM_MATRIX33:
+ case OPCODE_UNIFORM_MATRIX44:
+ case OPCODE_UNIFORM_MATRIX24:
+ case OPCODE_UNIFORM_MATRIX42:
+ case OPCODE_UNIFORM_MATRIX23:
+ case OPCODE_UNIFORM_MATRIX32:
+ case OPCODE_UNIFORM_MATRIX34:
+ case OPCODE_UNIFORM_MATRIX43:
+ _mesa_free(n[4].data);
+ n += InstSize[n[0].opcode];
+ break;
+
case OPCODE_CONTINUE:
n = (Node *) n[1].next;
_mesa_free(block);
@@ -5804,6 +5856,493 @@ save_ProvokingVertexEXT(GLenum mode)
}
+/* aka UseProgram() */
+static void GLAPIENTRY
+save_UseProgramObjectARB(GLhandleARB program)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_USE_PROGRAM, 1);
+ if (n) {
+ n[1].ui = program;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UseProgramObjectARB(ctx->Exec, (program));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Uniform1fARB(GLint location, GLfloat x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1F, 2);
+ if (n) {
+ n[1].i = location;
+ n[2].f = x;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform1fARB(ctx->Exec, (location, x));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Uniform2fARB(GLint location, GLfloat x, GLfloat y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2F, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].f = x;
+ n[3].f = y;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform2fARB(ctx->Exec, (location, x, y));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Uniform3fARB(GLint location, GLfloat x, GLfloat y, GLfloat z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3F, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform3fARB(ctx->Exec, (location, x, y, z));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4F, 5);
+ if (n) {
+ n[1].i = location;
+ n[2].f = x;
+ n[3].f = y;
+ n[4].f = z;
+ n[5].f = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform4fARB(ctx->Exec, (location, x, y, z, w));
+ }
+}
+
+
+/** Return copy of memory */
+static void *
+memdup(const void *src, GLsizei bytes)
+{
+ void *b = bytes >= 0 ? _mesa_malloc(bytes) : NULL;
+ if (b)
+ _mesa_memcpy(b, src, bytes);
+ return b;
+}
+
+
+static void GLAPIENTRY
+save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1FV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 1 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform1fvARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2FV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 2 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform2fvARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3FV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 3 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform3fvARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4FV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 4 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform4fvARB(ctx->Exec, (location, count, v));
+ }
+}
+
+
+static void GLAPIENTRY
+save_Uniform1iARB(GLint location, GLint x)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1I, 2);
+ if (n) {
+ n[1].i = location;
+ n[2].i = x;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform1iARB(ctx->Exec, (location, x));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform2iARB(GLint location, GLint x, GLint y)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2I, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = x;
+ n[3].i = y;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform2iARB(ctx->Exec, (location, x, y));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3I, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = x;
+ n[3].i = y;
+ n[4].i = z;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform3iARB(ctx->Exec, (location, x, y, z));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4I, 5);
+ if (n) {
+ n[1].i = location;
+ n[2].i = x;
+ n[3].i = y;
+ n[4].i = z;
+ n[5].i = w;
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform4iARB(ctx->Exec, (location, x, y, z, w));
+ }
+}
+
+
+
+static void GLAPIENTRY
+save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_1IV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 1 * sizeof(GLint));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform1ivARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_2IV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 2 * sizeof(GLint));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform2ivARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_3IV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 3 * sizeof(GLint));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform3ivARB(ctx->Exec, (location, count, v));
+ }
+}
+
+static void GLAPIENTRY
+save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_4IV, 3);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].data = memdup(v, count * 4 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_Uniform4ivARB(ctx->Exec, (location, count, v));
+ }
+}
+
+
+static void GLAPIENTRY
+save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX22, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 2 * 2 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix2fvARB(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+static void GLAPIENTRY
+save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX33, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 3 * 3 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix3fvARB(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+static void GLAPIENTRY
+save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX44, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 4 * 4 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix4fvARB(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+
+static void GLAPIENTRY
+save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX23, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 2 * 3 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+static void GLAPIENTRY
+save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX32, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 3 * 2 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+
+static void GLAPIENTRY
+save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX24, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 2 * 4 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+static void GLAPIENTRY
+save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX42, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 4 * 2 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+
+static void GLAPIENTRY
+save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX34, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 3 * 4 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+static void GLAPIENTRY
+save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose,
+ const GLfloat *m)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ Node *n;
+ ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+ n = ALLOC_INSTRUCTION(ctx, OPCODE_UNIFORM_MATRIX43, 4);
+ if (n) {
+ n[1].i = location;
+ n[2].i = count;
+ n[3].b = transpose;
+ n[4].data = memdup(m, count * 4 * 3 * sizeof(GLfloat));
+ }
+ if (ctx->ExecuteFlag) {
+ CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m));
+ }
+}
+
+
/**
* Save an error-generating command into display list.
@@ -6640,6 +7179,98 @@ execute_list(GLcontext *ctx, GLuint list)
n[9].i, n[10].e));
break;
#endif
+
+ case OPCODE_USE_PROGRAM:
+ CALL_UseProgramObjectARB(ctx->Exec, (n[1].ui));
+ break;
+ case OPCODE_UNIFORM_1F:
+ CALL_Uniform1fARB(ctx->Exec, (n[1].i, n[2].f));
+ break;
+ case OPCODE_UNIFORM_2F:
+ CALL_Uniform2fARB(ctx->Exec, (n[1].i, n[2].f, n[3].f));
+ break;
+ case OPCODE_UNIFORM_3F:
+ CALL_Uniform3fARB(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f));
+ break;
+ case OPCODE_UNIFORM_4F:
+ CALL_Uniform4fARB(ctx->Exec,
+ (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f));
+ break;
+ case OPCODE_UNIFORM_1FV:
+ CALL_Uniform1fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_2FV:
+ CALL_Uniform2fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_3FV:
+ CALL_Uniform3fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_4FV:
+ CALL_Uniform4fvARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_1I:
+ CALL_Uniform1iARB(ctx->Exec, (n[1].i, n[2].i));
+ break;
+ case OPCODE_UNIFORM_2I:
+ CALL_Uniform2iARB(ctx->Exec, (n[1].i, n[2].i, n[3].i));
+ break;
+ case OPCODE_UNIFORM_3I:
+ CALL_Uniform3iARB(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i));
+ break;
+ case OPCODE_UNIFORM_4I:
+ CALL_Uniform4iARB(ctx->Exec,
+ (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i));
+ break;
+ case OPCODE_UNIFORM_1IV:
+ CALL_Uniform1ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_2IV:
+ CALL_Uniform2ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_3IV:
+ CALL_Uniform3ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+ case OPCODE_UNIFORM_4IV:
+ CALL_Uniform4ivARB(ctx->Exec, (n[1].i, n[2].i, n[3].data));
+ break;
+
+ case OPCODE_UNIFORM_MATRIX22:
+ CALL_UniformMatrix2fvARB(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX33:
+ CALL_UniformMatrix3fvARB(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX44:
+ CALL_UniformMatrix4fvARB(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX23:
+ CALL_UniformMatrix2x3fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX32:
+ CALL_UniformMatrix3x2fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX24:
+ CALL_UniformMatrix2x4fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX42:
+ CALL_UniformMatrix4x2fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX34:
+ CALL_UniformMatrix3x4fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+ case OPCODE_UNIFORM_MATRIX43:
+ CALL_UniformMatrix4x3fv(ctx->Exec,
+ (n[1].i, n[2].i, n[3].b, n[4].data));
+ break;
+
case OPCODE_TEX_BUMP_PARAMETER_ATI:
{
GLfloat values[4];
@@ -8309,6 +8940,34 @@ _mesa_init_dlist_table(struct _glapi_table *table)
SET_BlitFramebufferEXT(table, save_BlitFramebufferEXT);
#endif
+ /* GL_ARB_shader_objects */
+ SET_UseProgramObjectARB(table, save_UseProgramObjectARB);
+ SET_Uniform1fARB(table, save_Uniform1fARB);
+ SET_Uniform2fARB(table, save_Uniform2fARB);
+ SET_Uniform3fARB(table, save_Uniform3fARB);
+ SET_Uniform4fARB(table, save_Uniform4fARB);
+ SET_Uniform1fvARB(table, save_Uniform1fvARB);
+ SET_Uniform2fvARB(table, save_Uniform2fvARB);
+ SET_Uniform3fvARB(table, save_Uniform3fvARB);
+ SET_Uniform4fvARB(table, save_Uniform4fvARB);
+ SET_Uniform1iARB(table, save_Uniform1iARB);
+ SET_Uniform2iARB(table, save_Uniform2iARB);
+ SET_Uniform3iARB(table, save_Uniform3iARB);
+ SET_Uniform4iARB(table, save_Uniform4iARB);
+ SET_Uniform1ivARB(table, save_Uniform1ivARB);
+ SET_Uniform2ivARB(table, save_Uniform2ivARB);
+ SET_Uniform3ivARB(table, save_Uniform3ivARB);
+ SET_Uniform4ivARB(table, save_Uniform4ivARB);
+ SET_UniformMatrix2fvARB(table, save_UniformMatrix2fvARB);
+ SET_UniformMatrix3fvARB(table, save_UniformMatrix3fvARB);
+ SET_UniformMatrix4fvARB(table, save_UniformMatrix4fvARB);
+ SET_UniformMatrix2x3fv(table, save_UniformMatrix2x3fv);
+ SET_UniformMatrix3x2fv(table, save_UniformMatrix3x2fv);
+ SET_UniformMatrix2x4fv(table, save_UniformMatrix2x4fv);
+ SET_UniformMatrix4x2fv(table, save_UniformMatrix4x2fv);
+ SET_UniformMatrix3x4fv(table, save_UniformMatrix3x4fv);
+ SET_UniformMatrix4x3fv(table, save_UniformMatrix4x3fv);
+
/* ARB 30/31/32. GL_ARB_shader_objects, GL_ARB_vertex/fragment_shader */
SET_BindAttribLocationARB(table, exec_BindAttribLocationARB);
SET_GetAttribLocationARB(table, exec_GetAttribLocationARB);
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 4c1f46102d1..8e6b01f73b9 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -233,7 +233,7 @@ enable_texture(GLcontext *ctx, GLboolean state, GLbitfield texBit)
const GLbitfield newenabled = state
? (texUnit->Enabled | texBit) : (texUnit->Enabled & ~texBit);
- if (!ctx->DrawBuffer->Visual.rgbMode || texUnit->Enabled == newenabled)
+ if (texUnit->Enabled == newenabled)
return GL_FALSE;
FLUSH_VERTICES(ctx, _NEW_TEXTURE);
@@ -935,11 +935,6 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
/* GL_EXT_depth_bounds_test */
case GL_DEPTH_BOUNDS_TEST_EXT:
CHECK_EXTENSION(EXT_depth_bounds_test, cap);
- if (state && ctx->DrawBuffer->Visual.depthBits == 0) {
- _mesa_warning(ctx,
- "glEnable(GL_DEPTH_BOUNDS_TEST_EXT) but no depth buffer");
- return;
- }
if (ctx->Depth.BoundsTest == state)
return;
FLUSH_VERTICES(ctx, _NEW_DEPTH);
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
index 2d1594eb7a2..606d50c59ad 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -519,6 +519,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_FEEDBACK_BUFFER_SIZE\0"
"GL_FEEDBACK_BUFFER_TYPE\0"
"GL_FILL\0"
+ "GL_FIRST_VERTEX_CONVENTION\0"
"GL_FIRST_VERTEX_CONVENTION_EXT\0"
"GL_FLAT\0"
"GL_FLOAT\0"
@@ -702,6 +703,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_INVERSE_TRANSPOSE_NV\0"
"GL_INVERT\0"
"GL_KEEP\0"
+ "GL_LAST_VERTEX_CONVENTION\0"
"GL_LAST_VERTEX_CONVENTION_EXT\0"
"GL_LEFT\0"
"GL_LEQUAL\0"
@@ -1288,6 +1290,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_PROJECTION\0"
"GL_PROJECTION_MATRIX\0"
"GL_PROJECTION_STACK_DEPTH\0"
+ "GL_PROVOKING_VERTEX\0"
"GL_PROVOKING_VERTEX_EXT\0"
"GL_PROXY_COLOR_TABLE\0"
"GL_PROXY_HISTOGRAM\0"
@@ -1309,6 +1312,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_Q\0"
"GL_QUADRATIC_ATTENUATION\0"
"GL_QUADS\0"
+ "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION\0"
"GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT\0"
"GL_QUAD_MESH_SUN\0"
"GL_QUAD_STRIP\0"
@@ -1896,7 +1900,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_ZOOM_Y\0"
;
-static const enum_elt all_enums[1858] =
+static const enum_elt all_enums[1862] =
{
{ 0, 0x00000600 }, /* GL_2D */
{ 6, 0x00001407 }, /* GL_2_BYTES */
@@ -2381,1460 +2385,1464 @@ static const enum_elt all_enums[1858] =
{ 9670, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
{ 9694, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
{ 9718, 0x00001B02 }, /* GL_FILL */
- { 9726, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION_EXT */
- { 9757, 0x00001D00 }, /* GL_FLAT */
- { 9765, 0x00001406 }, /* GL_FLOAT */
- { 9774, 0x00008B5A }, /* GL_FLOAT_MAT2 */
- { 9788, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
- { 9806, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
- { 9822, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
- { 9838, 0x00008B5B }, /* GL_FLOAT_MAT3 */
- { 9852, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
- { 9870, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
- { 9886, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
- { 9902, 0x00008B5C }, /* GL_FLOAT_MAT4 */
- { 9916, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
- { 9934, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
- { 9950, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
- { 9966, 0x00008B50 }, /* GL_FLOAT_VEC2 */
- { 9980, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
- { 9998, 0x00008B51 }, /* GL_FLOAT_VEC3 */
- { 10012, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
- { 10030, 0x00008B52 }, /* GL_FLOAT_VEC4 */
- { 10044, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
- { 10062, 0x00000B60 }, /* GL_FOG */
- { 10069, 0x00000080 }, /* GL_FOG_BIT */
- { 10080, 0x00000B66 }, /* GL_FOG_COLOR */
- { 10093, 0x00008451 }, /* GL_FOG_COORD */
- { 10106, 0x00008451 }, /* GL_FOG_COORDINATE */
- { 10124, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
- { 10148, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
- { 10187, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
- { 10230, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
- { 10262, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
- { 10293, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
- { 10322, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
- { 10347, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
- { 10366, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
- { 10400, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
- { 10427, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
- { 10453, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
- { 10477, 0x00008450 }, /* GL_FOG_COORD_SRC */
- { 10494, 0x00000B62 }, /* GL_FOG_DENSITY */
- { 10509, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
- { 10533, 0x00000B64 }, /* GL_FOG_END */
- { 10544, 0x00000C54 }, /* GL_FOG_HINT */
- { 10556, 0x00000B61 }, /* GL_FOG_INDEX */
- { 10569, 0x00000B65 }, /* GL_FOG_MODE */
- { 10581, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
- { 10600, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
- { 10625, 0x00000B63 }, /* GL_FOG_START */
- { 10638, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
- { 10656, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
- { 10680, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
- { 10699, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
- { 10722, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
- { 10757, 0x00008D40 }, /* GL_FRAMEBUFFER */
- { 10772, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
- { 10809, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
- { 10845, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
- { 10886, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
- { 10927, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
- { 10964, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
- { 11001, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
- { 11039, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
- { 11081, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
- { 11119, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
- { 11161, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
- { 11196, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
- { 11235, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
- { 11284, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
- { 11332, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
- { 11384, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
- { 11424, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
- { 11468, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
- { 11508, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
- { 11552, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
- { 11579, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
- { 11603, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
- { 11631, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
- { 11654, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
- { 11673, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
- { 11710, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
- { 11751, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
- { 11792, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
- { 11834, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
- { 11885, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
- { 11923, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
- { 11968, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
- { 12017, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
- { 12055, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
- { 12097, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- { 12129, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
- { 12154, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
- { 12181, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
- { 12212, 0x00000404 }, /* GL_FRONT */
- { 12221, 0x00000408 }, /* GL_FRONT_AND_BACK */
- { 12239, 0x00000B46 }, /* GL_FRONT_FACE */
- { 12253, 0x00000400 }, /* GL_FRONT_LEFT */
- { 12267, 0x00000401 }, /* GL_FRONT_RIGHT */
- { 12282, 0x00008006 }, /* GL_FUNC_ADD */
- { 12294, 0x00008006 }, /* GL_FUNC_ADD_EXT */
- { 12310, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
- { 12335, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
- { 12364, 0x0000800A }, /* GL_FUNC_SUBTRACT */
- { 12381, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
- { 12402, 0x00008191 }, /* GL_GENERATE_MIPMAP */
- { 12421, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
- { 12445, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
- { 12474, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
- { 12498, 0x00000206 }, /* GL_GEQUAL */
- { 12508, 0x00000204 }, /* GL_GREATER */
- { 12519, 0x00001904 }, /* GL_GREEN */
- { 12528, 0x00000D19 }, /* GL_GREEN_BIAS */
- { 12542, 0x00000D53 }, /* GL_GREEN_BITS */
- { 12556, 0x00000D18 }, /* GL_GREEN_SCALE */
- { 12571, 0x00008000 }, /* GL_HINT_BIT */
- { 12583, 0x00008024 }, /* GL_HISTOGRAM */
- { 12596, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
- { 12620, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
- { 12648, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
- { 12671, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
- { 12698, 0x00008024 }, /* GL_HISTOGRAM_EXT */
- { 12715, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
- { 12735, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
- { 12759, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
- { 12783, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
- { 12811, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
- { 12839, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
- { 12871, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
- { 12893, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
- { 12919, 0x0000802D }, /* GL_HISTOGRAM_SINK */
- { 12937, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
- { 12959, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
- { 12978, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
- { 13001, 0x0000862A }, /* GL_IDENTITY_NV */
- { 13016, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
- { 13036, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
- { 13076, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
- { 13114, 0x00001E02 }, /* GL_INCR */
- { 13122, 0x00008507 }, /* GL_INCR_WRAP */
- { 13135, 0x00008507 }, /* GL_INCR_WRAP_EXT */
- { 13152, 0x00008222 }, /* GL_INDEX */
- { 13161, 0x00008077 }, /* GL_INDEX_ARRAY */
- { 13176, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
- { 13206, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
- { 13240, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
- { 13263, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
- { 13285, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
- { 13305, 0x00000D51 }, /* GL_INDEX_BITS */
- { 13319, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
- { 13340, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
- { 13358, 0x00000C30 }, /* GL_INDEX_MODE */
- { 13372, 0x00000D13 }, /* GL_INDEX_OFFSET */
- { 13388, 0x00000D12 }, /* GL_INDEX_SHIFT */
- { 13403, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
- { 13422, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
- { 13441, 0x00001404 }, /* GL_INT */
- { 13448, 0x00008049 }, /* GL_INTENSITY */
- { 13461, 0x0000804C }, /* GL_INTENSITY12 */
- { 13476, 0x0000804C }, /* GL_INTENSITY12_EXT */
- { 13495, 0x0000804D }, /* GL_INTENSITY16 */
- { 13510, 0x0000804D }, /* GL_INTENSITY16_EXT */
- { 13529, 0x0000804A }, /* GL_INTENSITY4 */
- { 13543, 0x0000804A }, /* GL_INTENSITY4_EXT */
- { 13561, 0x0000804B }, /* GL_INTENSITY8 */
- { 13575, 0x0000804B }, /* GL_INTENSITY8_EXT */
- { 13593, 0x00008049 }, /* GL_INTENSITY_EXT */
- { 13610, 0x00008575 }, /* GL_INTERPOLATE */
- { 13625, 0x00008575 }, /* GL_INTERPOLATE_ARB */
- { 13644, 0x00008575 }, /* GL_INTERPOLATE_EXT */
- { 13663, 0x00008B53 }, /* GL_INT_VEC2 */
- { 13675, 0x00008B53 }, /* GL_INT_VEC2_ARB */
- { 13691, 0x00008B54 }, /* GL_INT_VEC3 */
- { 13703, 0x00008B54 }, /* GL_INT_VEC3_ARB */
- { 13719, 0x00008B55 }, /* GL_INT_VEC4 */
- { 13731, 0x00008B55 }, /* GL_INT_VEC4_ARB */
- { 13747, 0x00000500 }, /* GL_INVALID_ENUM */
- { 13763, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
- { 13796, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
- { 13833, 0x00000502 }, /* GL_INVALID_OPERATION */
- { 13854, 0x00000501 }, /* GL_INVALID_VALUE */
- { 13871, 0x0000862B }, /* GL_INVERSE_NV */
- { 13885, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
- { 13909, 0x0000150A }, /* GL_INVERT */
- { 13919, 0x00001E00 }, /* GL_KEEP */
- { 13927, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
- { 13957, 0x00000406 }, /* GL_LEFT */
- { 13965, 0x00000203 }, /* GL_LEQUAL */
- { 13975, 0x00000201 }, /* GL_LESS */
- { 13983, 0x00004000 }, /* GL_LIGHT0 */
- { 13993, 0x00004001 }, /* GL_LIGHT1 */
- { 14003, 0x00004002 }, /* GL_LIGHT2 */
- { 14013, 0x00004003 }, /* GL_LIGHT3 */
- { 14023, 0x00004004 }, /* GL_LIGHT4 */
- { 14033, 0x00004005 }, /* GL_LIGHT5 */
- { 14043, 0x00004006 }, /* GL_LIGHT6 */
- { 14053, 0x00004007 }, /* GL_LIGHT7 */
- { 14063, 0x00000B50 }, /* GL_LIGHTING */
- { 14075, 0x00000040 }, /* GL_LIGHTING_BIT */
- { 14091, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
- { 14114, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
- { 14143, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
- { 14176, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
- { 14204, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
- { 14228, 0x00001B01 }, /* GL_LINE */
- { 14236, 0x00002601 }, /* GL_LINEAR */
- { 14246, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
- { 14268, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
- { 14298, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
- { 14329, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
- { 14353, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
- { 14378, 0x00000001 }, /* GL_LINES */
- { 14387, 0x00000004 }, /* GL_LINE_BIT */
- { 14399, 0x00000002 }, /* GL_LINE_LOOP */
- { 14412, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
- { 14432, 0x00000B20 }, /* GL_LINE_SMOOTH */
- { 14447, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
- { 14467, 0x00000B24 }, /* GL_LINE_STIPPLE */
- { 14483, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
- { 14507, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
- { 14530, 0x00000003 }, /* GL_LINE_STRIP */
- { 14544, 0x00000702 }, /* GL_LINE_TOKEN */
- { 14558, 0x00000B21 }, /* GL_LINE_WIDTH */
- { 14572, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
- { 14598, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
- { 14618, 0x00008B82 }, /* GL_LINK_STATUS */
- { 14633, 0x00000B32 }, /* GL_LIST_BASE */
- { 14646, 0x00020000 }, /* GL_LIST_BIT */
- { 14658, 0x00000B33 }, /* GL_LIST_INDEX */
- { 14672, 0x00000B30 }, /* GL_LIST_MODE */
- { 14685, 0x00000101 }, /* GL_LOAD */
- { 14693, 0x00000BF1 }, /* GL_LOGIC_OP */
- { 14705, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
- { 14722, 0x00008CA1 }, /* GL_LOWER_LEFT */
- { 14736, 0x00001909 }, /* GL_LUMINANCE */
- { 14749, 0x00008041 }, /* GL_LUMINANCE12 */
- { 14764, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
- { 14787, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
- { 14814, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
- { 14836, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
- { 14862, 0x00008041 }, /* GL_LUMINANCE12_EXT */
- { 14881, 0x00008042 }, /* GL_LUMINANCE16 */
- { 14896, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
- { 14919, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
- { 14946, 0x00008042 }, /* GL_LUMINANCE16_EXT */
- { 14965, 0x0000803F }, /* GL_LUMINANCE4 */
- { 14979, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
- { 15000, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
- { 15025, 0x0000803F }, /* GL_LUMINANCE4_EXT */
- { 15043, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
- { 15064, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
- { 15089, 0x00008040 }, /* GL_LUMINANCE8 */
- { 15103, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
- { 15124, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
- { 15149, 0x00008040 }, /* GL_LUMINANCE8_EXT */
- { 15167, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
- { 15186, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
- { 15202, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
- { 15222, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
- { 15244, 0x00000D91 }, /* GL_MAP1_INDEX */
- { 15258, 0x00000D92 }, /* GL_MAP1_NORMAL */
- { 15273, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
- { 15297, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
- { 15321, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
- { 15345, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
- { 15369, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
- { 15386, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
- { 15403, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
- { 15431, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
- { 15460, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
- { 15489, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
- { 15518, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
- { 15547, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
- { 15576, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
- { 15605, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
- { 15633, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
- { 15661, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
- { 15689, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
- { 15717, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
- { 15745, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
- { 15773, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
- { 15801, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
- { 15829, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
- { 15857, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
- { 15873, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
- { 15893, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
- { 15915, 0x00000DB1 }, /* GL_MAP2_INDEX */
- { 15929, 0x00000DB2 }, /* GL_MAP2_NORMAL */
- { 15944, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
- { 15968, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
- { 15992, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
- { 16016, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
- { 16040, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
- { 16057, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
- { 16074, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
- { 16102, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
- { 16131, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
- { 16160, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
- { 16189, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
- { 16218, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
- { 16247, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
- { 16276, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
- { 16304, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
- { 16332, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
- { 16360, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
- { 16388, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
- { 16416, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
- { 16444, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
- { 16472, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
- { 16500, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
- { 16528, 0x00000D10 }, /* GL_MAP_COLOR */
- { 16541, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
- { 16567, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
- { 16596, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
- { 16624, 0x00000001 }, /* GL_MAP_READ_BIT */
- { 16640, 0x00000D11 }, /* GL_MAP_STENCIL */
- { 16655, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
- { 16681, 0x00000002 }, /* GL_MAP_WRITE_BIT */
- { 16698, 0x000088C0 }, /* GL_MATRIX0_ARB */
- { 16713, 0x00008630 }, /* GL_MATRIX0_NV */
- { 16727, 0x000088CA }, /* GL_MATRIX10_ARB */
- { 16743, 0x000088CB }, /* GL_MATRIX11_ARB */
- { 16759, 0x000088CC }, /* GL_MATRIX12_ARB */
- { 16775, 0x000088CD }, /* GL_MATRIX13_ARB */
- { 16791, 0x000088CE }, /* GL_MATRIX14_ARB */
- { 16807, 0x000088CF }, /* GL_MATRIX15_ARB */
- { 16823, 0x000088D0 }, /* GL_MATRIX16_ARB */
- { 16839, 0x000088D1 }, /* GL_MATRIX17_ARB */
- { 16855, 0x000088D2 }, /* GL_MATRIX18_ARB */
- { 16871, 0x000088D3 }, /* GL_MATRIX19_ARB */
- { 16887, 0x000088C1 }, /* GL_MATRIX1_ARB */
- { 16902, 0x00008631 }, /* GL_MATRIX1_NV */
- { 16916, 0x000088D4 }, /* GL_MATRIX20_ARB */
- { 16932, 0x000088D5 }, /* GL_MATRIX21_ARB */
- { 16948, 0x000088D6 }, /* GL_MATRIX22_ARB */
- { 16964, 0x000088D7 }, /* GL_MATRIX23_ARB */
- { 16980, 0x000088D8 }, /* GL_MATRIX24_ARB */
- { 16996, 0x000088D9 }, /* GL_MATRIX25_ARB */
- { 17012, 0x000088DA }, /* GL_MATRIX26_ARB */
- { 17028, 0x000088DB }, /* GL_MATRIX27_ARB */
- { 17044, 0x000088DC }, /* GL_MATRIX28_ARB */
- { 17060, 0x000088DD }, /* GL_MATRIX29_ARB */
- { 17076, 0x000088C2 }, /* GL_MATRIX2_ARB */
- { 17091, 0x00008632 }, /* GL_MATRIX2_NV */
- { 17105, 0x000088DE }, /* GL_MATRIX30_ARB */
- { 17121, 0x000088DF }, /* GL_MATRIX31_ARB */
- { 17137, 0x000088C3 }, /* GL_MATRIX3_ARB */
- { 17152, 0x00008633 }, /* GL_MATRIX3_NV */
- { 17166, 0x000088C4 }, /* GL_MATRIX4_ARB */
- { 17181, 0x00008634 }, /* GL_MATRIX4_NV */
- { 17195, 0x000088C5 }, /* GL_MATRIX5_ARB */
- { 17210, 0x00008635 }, /* GL_MATRIX5_NV */
- { 17224, 0x000088C6 }, /* GL_MATRIX6_ARB */
- { 17239, 0x00008636 }, /* GL_MATRIX6_NV */
- { 17253, 0x000088C7 }, /* GL_MATRIX7_ARB */
- { 17268, 0x00008637 }, /* GL_MATRIX7_NV */
- { 17282, 0x000088C8 }, /* GL_MATRIX8_ARB */
- { 17297, 0x000088C9 }, /* GL_MATRIX9_ARB */
- { 17312, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
- { 17338, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
- { 17372, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
- { 17403, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
- { 17436, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
- { 17467, 0x00000BA0 }, /* GL_MATRIX_MODE */
- { 17482, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
- { 17504, 0x00008008 }, /* GL_MAX */
- { 17511, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
- { 17534, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
- { 17566, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
- { 17592, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
- { 17625, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
- { 17651, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- { 17685, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
- { 17704, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
- { 17733, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
- { 17765, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
- { 17801, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
- { 17837, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
- { 17877, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
- { 17903, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
- { 17933, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
- { 17958, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
- { 17987, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
- { 18016, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
- { 18049, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
- { 18069, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
- { 18093, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
- { 18117, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
- { 18141, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
- { 18166, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
- { 18184, 0x00008008 }, /* GL_MAX_EXT */
- { 18195, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
- { 18230, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
- { 18269, 0x00000D31 }, /* GL_MAX_LIGHTS */
- { 18283, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
- { 18303, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
- { 18341, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
- { 18370, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
- { 18394, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
- { 18422, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
- { 18445, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
- { 18482, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
- { 18518, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
- { 18545, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
- { 18574, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
- { 18608, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
- { 18644, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
- { 18671, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
- { 18703, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
- { 18739, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
- { 18768, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
- { 18797, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
- { 18825, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
- { 18863, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- { 18907, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- { 18950, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
- { 18984, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- { 19023, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
- { 19060, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
- { 19098, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- { 19141, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- { 19184, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
- { 19214, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
- { 19245, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
- { 19281, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
- { 19317, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
- { 19347, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
- { 19381, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
- { 19414, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
- { 19443, 0x00008D57 }, /* GL_MAX_SAMPLES */
- { 19458, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
- { 19485, 0x00008504 }, /* GL_MAX_SHININESS_NV */
- { 19505, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
- { 19529, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
- { 19551, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
- { 19577, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
- { 19604, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
- { 19635, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
- { 19659, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
- { 19693, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
- { 19713, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
- { 19740, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
- { 19761, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
- { 19786, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
- { 19811, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
- { 19846, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
- { 19868, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
- { 19894, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
- { 19916, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
- { 19942, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
- { 19976, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
- { 20014, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
- { 20047, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
- { 20084, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
- { 20108, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
- { 20129, 0x00008007 }, /* GL_MIN */
- { 20136, 0x0000802E }, /* GL_MINMAX */
- { 20146, 0x0000802E }, /* GL_MINMAX_EXT */
- { 20160, 0x0000802F }, /* GL_MINMAX_FORMAT */
- { 20177, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
- { 20198, 0x00008030 }, /* GL_MINMAX_SINK */
- { 20213, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
- { 20232, 0x00008007 }, /* GL_MIN_EXT */
- { 20243, 0x00008370 }, /* GL_MIRRORED_REPEAT */
- { 20262, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
- { 20285, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
- { 20308, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
- { 20328, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
- { 20348, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
- { 20378, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
- { 20406, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
- { 20434, 0x00001700 }, /* GL_MODELVIEW */
- { 20447, 0x00001700 }, /* GL_MODELVIEW0_ARB */
- { 20465, 0x0000872A }, /* GL_MODELVIEW10_ARB */
- { 20484, 0x0000872B }, /* GL_MODELVIEW11_ARB */
- { 20503, 0x0000872C }, /* GL_MODELVIEW12_ARB */
- { 20522, 0x0000872D }, /* GL_MODELVIEW13_ARB */
- { 20541, 0x0000872E }, /* GL_MODELVIEW14_ARB */
- { 20560, 0x0000872F }, /* GL_MODELVIEW15_ARB */
- { 20579, 0x00008730 }, /* GL_MODELVIEW16_ARB */
- { 20598, 0x00008731 }, /* GL_MODELVIEW17_ARB */
- { 20617, 0x00008732 }, /* GL_MODELVIEW18_ARB */
- { 20636, 0x00008733 }, /* GL_MODELVIEW19_ARB */
- { 20655, 0x0000850A }, /* GL_MODELVIEW1_ARB */
- { 20673, 0x00008734 }, /* GL_MODELVIEW20_ARB */
- { 20692, 0x00008735 }, /* GL_MODELVIEW21_ARB */
- { 20711, 0x00008736 }, /* GL_MODELVIEW22_ARB */
- { 20730, 0x00008737 }, /* GL_MODELVIEW23_ARB */
- { 20749, 0x00008738 }, /* GL_MODELVIEW24_ARB */
- { 20768, 0x00008739 }, /* GL_MODELVIEW25_ARB */
- { 20787, 0x0000873A }, /* GL_MODELVIEW26_ARB */
- { 20806, 0x0000873B }, /* GL_MODELVIEW27_ARB */
- { 20825, 0x0000873C }, /* GL_MODELVIEW28_ARB */
- { 20844, 0x0000873D }, /* GL_MODELVIEW29_ARB */
- { 20863, 0x00008722 }, /* GL_MODELVIEW2_ARB */
- { 20881, 0x0000873E }, /* GL_MODELVIEW30_ARB */
- { 20900, 0x0000873F }, /* GL_MODELVIEW31_ARB */
- { 20919, 0x00008723 }, /* GL_MODELVIEW3_ARB */
- { 20937, 0x00008724 }, /* GL_MODELVIEW4_ARB */
- { 20955, 0x00008725 }, /* GL_MODELVIEW5_ARB */
- { 20973, 0x00008726 }, /* GL_MODELVIEW6_ARB */
- { 20991, 0x00008727 }, /* GL_MODELVIEW7_ARB */
- { 21009, 0x00008728 }, /* GL_MODELVIEW8_ARB */
- { 21027, 0x00008729 }, /* GL_MODELVIEW9_ARB */
- { 21045, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
- { 21065, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
- { 21092, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
- { 21117, 0x00002100 }, /* GL_MODULATE */
- { 21129, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
- { 21149, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
- { 21176, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
- { 21201, 0x00000103 }, /* GL_MULT */
- { 21209, 0x0000809D }, /* GL_MULTISAMPLE */
- { 21224, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
- { 21244, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
- { 21263, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
- { 21282, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
- { 21306, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
- { 21329, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
- { 21359, 0x00002A25 }, /* GL_N3F_V3F */
- { 21370, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
- { 21390, 0x0000150E }, /* GL_NAND */
- { 21398, 0x00002600 }, /* GL_NEAREST */
- { 21409, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
- { 21440, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
- { 21472, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
- { 21497, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
- { 21523, 0x00000200 }, /* GL_NEVER */
- { 21532, 0x00001102 }, /* GL_NICEST */
- { 21542, 0x00000000 }, /* GL_NONE */
- { 21550, 0x00001505 }, /* GL_NOOP */
- { 21558, 0x00001508 }, /* GL_NOR */
- { 21565, 0x00000BA1 }, /* GL_NORMALIZE */
- { 21578, 0x00008075 }, /* GL_NORMAL_ARRAY */
- { 21594, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
- { 21625, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
- { 21660, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
- { 21684, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
- { 21707, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
- { 21728, 0x00008511 }, /* GL_NORMAL_MAP */
- { 21742, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
- { 21760, 0x00008511 }, /* GL_NORMAL_MAP_NV */
- { 21777, 0x00000205 }, /* GL_NOTEQUAL */
- { 21789, 0x00000000 }, /* GL_NO_ERROR */
- { 21801, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
- { 21835, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
- { 21873, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
- { 21905, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
- { 21947, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
- { 21977, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
- { 22017, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
- { 22048, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
- { 22077, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
- { 22105, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
- { 22135, 0x00002401 }, /* GL_OBJECT_LINEAR */
- { 22152, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
- { 22178, 0x00002501 }, /* GL_OBJECT_PLANE */
- { 22194, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
- { 22229, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
- { 22251, 0x00009112 }, /* GL_OBJECT_TYPE */
- { 22266, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
- { 22285, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
- { 22315, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
- { 22336, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
- { 22364, 0x00000001 }, /* GL_ONE */
- { 22371, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
- { 22399, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
- { 22431, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
- { 22459, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
- { 22491, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
- { 22514, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
- { 22537, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
- { 22560, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
- { 22583, 0x00008598 }, /* GL_OPERAND0_ALPHA */
- { 22601, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
- { 22623, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
- { 22645, 0x00008590 }, /* GL_OPERAND0_RGB */
- { 22661, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
- { 22681, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
- { 22701, 0x00008599 }, /* GL_OPERAND1_ALPHA */
- { 22719, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
- { 22741, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
- { 22763, 0x00008591 }, /* GL_OPERAND1_RGB */
- { 22779, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
- { 22799, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
- { 22819, 0x0000859A }, /* GL_OPERAND2_ALPHA */
- { 22837, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
- { 22859, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
- { 22881, 0x00008592 }, /* GL_OPERAND2_RGB */
- { 22897, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
- { 22917, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
- { 22937, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
- { 22958, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
- { 22977, 0x00001507 }, /* GL_OR */
- { 22983, 0x00000A01 }, /* GL_ORDER */
- { 22992, 0x0000150D }, /* GL_OR_INVERTED */
- { 23007, 0x0000150B }, /* GL_OR_REVERSE */
- { 23021, 0x00000505 }, /* GL_OUT_OF_MEMORY */
- { 23038, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
- { 23056, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
- { 23077, 0x00008758 }, /* GL_PACK_INVERT_MESA */
- { 23097, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
- { 23115, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
- { 23134, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
- { 23154, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
- { 23174, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
- { 23192, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
- { 23211, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
- { 23236, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
- { 23260, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
- { 23281, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
- { 23303, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
- { 23325, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
- { 23350, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
- { 23374, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
- { 23395, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
- { 23417, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
- { 23439, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
- { 23461, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
- { 23492, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
- { 23512, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
- { 23537, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
- { 23557, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
- { 23582, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
- { 23602, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
- { 23627, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
- { 23647, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
- { 23672, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
- { 23692, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
- { 23717, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
- { 23737, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
- { 23762, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
- { 23782, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
- { 23807, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
- { 23827, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
- { 23852, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
- { 23872, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
- { 23897, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
- { 23917, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
- { 23942, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
- { 23960, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
- { 23981, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
- { 24010, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
- { 24043, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
- { 24068, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
- { 24091, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
- { 24122, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
- { 24157, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
- { 24184, 0x00001B00 }, /* GL_POINT */
- { 24193, 0x00000000 }, /* GL_POINTS */
- { 24203, 0x00000002 }, /* GL_POINT_BIT */
- { 24216, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
- { 24246, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
- { 24280, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
- { 24314, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
- { 24349, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
- { 24378, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
- { 24411, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
- { 24444, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
- { 24478, 0x00000B11 }, /* GL_POINT_SIZE */
- { 24492, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
- { 24518, 0x00008127 }, /* GL_POINT_SIZE_MAX */
- { 24536, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
- { 24558, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
- { 24580, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
- { 24603, 0x00008126 }, /* GL_POINT_SIZE_MIN */
- { 24621, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
- { 24643, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
- { 24665, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
- { 24688, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
- { 24708, 0x00000B10 }, /* GL_POINT_SMOOTH */
- { 24724, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
- { 24745, 0x00008861 }, /* GL_POINT_SPRITE */
- { 24761, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
- { 24781, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
- { 24810, 0x00008861 }, /* GL_POINT_SPRITE_NV */
- { 24829, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
- { 24855, 0x00000701 }, /* GL_POINT_TOKEN */
- { 24870, 0x00000009 }, /* GL_POLYGON */
- { 24881, 0x00000008 }, /* GL_POLYGON_BIT */
- { 24896, 0x00000B40 }, /* GL_POLYGON_MODE */
- { 24912, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
- { 24935, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
- { 24960, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
- { 24983, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
- { 25006, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
- { 25030, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
- { 25054, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
- { 25072, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
- { 25095, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
- { 25114, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
- { 25137, 0x00000703 }, /* GL_POLYGON_TOKEN */
- { 25154, 0x00001203 }, /* GL_POSITION */
- { 25166, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
- { 25198, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
- { 25234, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
- { 25267, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
- { 25304, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
- { 25335, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
- { 25370, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
- { 25402, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
- { 25438, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
- { 25471, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
- { 25503, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
- { 25539, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
- { 25572, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
- { 25609, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
- { 25639, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
- { 25673, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
- { 25704, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
- { 25739, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
- { 25770, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
- { 25805, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
- { 25837, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
- { 25873, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
- { 25903, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
- { 25937, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
- { 25968, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
- { 26003, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
- { 26035, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
- { 26066, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
- { 26101, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
- { 26133, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
- { 26169, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
- { 26198, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
- { 26231, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
- { 26261, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
- { 26295, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
- { 26334, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
- { 26367, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
- { 26407, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
- { 26441, 0x00008578 }, /* GL_PREVIOUS */
- { 26453, 0x00008578 }, /* GL_PREVIOUS_ARB */
- { 26469, 0x00008578 }, /* GL_PREVIOUS_EXT */
- { 26485, 0x00008577 }, /* GL_PRIMARY_COLOR */
- { 26502, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
- { 26523, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
- { 26544, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
- { 26577, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
- { 26609, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
- { 26632, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
- { 26655, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
- { 26685, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
- { 26714, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
- { 26742, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
- { 26764, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
- { 26792, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
- { 26820, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
- { 26842, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
- { 26863, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- { 26903, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- { 26942, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
- { 26972, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- { 27007, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
- { 27040, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
- { 27074, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- { 27113, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- { 27152, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
- { 27174, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
- { 27200, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
- { 27224, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
- { 27247, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
- { 27269, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
- { 27290, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
- { 27311, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
- { 27338, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
- { 27370, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
- { 27402, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
- { 27437, 0x00001701 }, /* GL_PROJECTION */
- { 27451, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
- { 27472, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
- { 27498, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
- { 27522, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
- { 27543, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
- { 27562, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
- { 27585, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
- { 27624, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
- { 27662, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
- { 27682, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
- { 27712, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
- { 27736, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
- { 27756, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
- { 27786, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
- { 27810, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
- { 27830, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
- { 27863, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
- { 27889, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
- { 27919, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
- { 27950, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
- { 27980, 0x00002003 }, /* GL_Q */
- { 27985, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
- { 28010, 0x00000007 }, /* GL_QUADS */
- { 28019, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
- { 28067, 0x00008614 }, /* GL_QUAD_MESH_SUN */
- { 28084, 0x00000008 }, /* GL_QUAD_STRIP */
- { 28098, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
- { 28120, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
- { 28146, 0x00008866 }, /* GL_QUERY_RESULT */
- { 28162, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
- { 28182, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
- { 28208, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
- { 28238, 0x00002002 }, /* GL_R */
- { 28243, 0x00002A10 }, /* GL_R3_G3_B2 */
- { 28255, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
- { 28288, 0x00000C02 }, /* GL_READ_BUFFER */
- { 28303, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
- { 28323, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
- { 28355, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
- { 28379, 0x000088B8 }, /* GL_READ_ONLY */
- { 28392, 0x000088B8 }, /* GL_READ_ONLY_ARB */
- { 28409, 0x000088BA }, /* GL_READ_WRITE */
- { 28423, 0x000088BA }, /* GL_READ_WRITE_ARB */
- { 28441, 0x00001903 }, /* GL_RED */
- { 28448, 0x00008016 }, /* GL_REDUCE */
- { 28458, 0x00008016 }, /* GL_REDUCE_EXT */
- { 28472, 0x00000D15 }, /* GL_RED_BIAS */
- { 28484, 0x00000D52 }, /* GL_RED_BITS */
- { 28496, 0x00000D14 }, /* GL_RED_SCALE */
- { 28509, 0x00008512 }, /* GL_REFLECTION_MAP */
- { 28527, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
- { 28549, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
- { 28570, 0x00001C00 }, /* GL_RENDER */
- { 28580, 0x00008D41 }, /* GL_RENDERBUFFER */
- { 28596, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
- { 28623, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
- { 28651, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
- { 28677, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
- { 28704, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
- { 28724, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
- { 28751, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
- { 28774, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
- { 28801, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
- { 28833, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
- { 28869, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
- { 28894, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
- { 28918, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
- { 28947, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
- { 28969, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
- { 28995, 0x00001F01 }, /* GL_RENDERER */
- { 29007, 0x00000C40 }, /* GL_RENDER_MODE */
- { 29022, 0x00002901 }, /* GL_REPEAT */
- { 29032, 0x00001E01 }, /* GL_REPLACE */
- { 29043, 0x00008062 }, /* GL_REPLACE_EXT */
- { 29058, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
- { 29081, 0x0000803A }, /* GL_RESCALE_NORMAL */
- { 29099, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
- { 29121, 0x00000102 }, /* GL_RETURN */
- { 29131, 0x00001907 }, /* GL_RGB */
- { 29138, 0x00008052 }, /* GL_RGB10 */
- { 29147, 0x00008059 }, /* GL_RGB10_A2 */
- { 29159, 0x00008059 }, /* GL_RGB10_A2_EXT */
- { 29175, 0x00008052 }, /* GL_RGB10_EXT */
- { 29188, 0x00008053 }, /* GL_RGB12 */
- { 29197, 0x00008053 }, /* GL_RGB12_EXT */
- { 29210, 0x00008054 }, /* GL_RGB16 */
- { 29219, 0x00008054 }, /* GL_RGB16_EXT */
- { 29232, 0x0000804E }, /* GL_RGB2_EXT */
- { 29244, 0x0000804F }, /* GL_RGB4 */
- { 29252, 0x0000804F }, /* GL_RGB4_EXT */
- { 29264, 0x000083A1 }, /* GL_RGB4_S3TC */
- { 29277, 0x00008050 }, /* GL_RGB5 */
- { 29285, 0x00008057 }, /* GL_RGB5_A1 */
- { 29296, 0x00008057 }, /* GL_RGB5_A1_EXT */
- { 29311, 0x00008050 }, /* GL_RGB5_EXT */
- { 29323, 0x00008051 }, /* GL_RGB8 */
- { 29331, 0x00008051 }, /* GL_RGB8_EXT */
- { 29343, 0x00001908 }, /* GL_RGBA */
- { 29351, 0x0000805A }, /* GL_RGBA12 */
- { 29361, 0x0000805A }, /* GL_RGBA12_EXT */
- { 29375, 0x0000805B }, /* GL_RGBA16 */
- { 29385, 0x0000805B }, /* GL_RGBA16_EXT */
- { 29399, 0x00008055 }, /* GL_RGBA2 */
- { 29408, 0x00008055 }, /* GL_RGBA2_EXT */
- { 29421, 0x00008056 }, /* GL_RGBA4 */
- { 29430, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
- { 29449, 0x00008056 }, /* GL_RGBA4_EXT */
- { 29462, 0x000083A3 }, /* GL_RGBA4_S3TC */
- { 29476, 0x00008058 }, /* GL_RGBA8 */
- { 29485, 0x00008058 }, /* GL_RGBA8_EXT */
- { 29498, 0x00008F97 }, /* GL_RGBA8_SNORM */
- { 29513, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
- { 29531, 0x00000C31 }, /* GL_RGBA_MODE */
- { 29544, 0x000083A2 }, /* GL_RGBA_S3TC */
- { 29557, 0x00008F93 }, /* GL_RGBA_SNORM */
- { 29571, 0x000083A0 }, /* GL_RGB_S3TC */
- { 29583, 0x00008573 }, /* GL_RGB_SCALE */
- { 29596, 0x00008573 }, /* GL_RGB_SCALE_ARB */
- { 29613, 0x00008573 }, /* GL_RGB_SCALE_EXT */
- { 29630, 0x00000407 }, /* GL_RIGHT */
- { 29639, 0x00002000 }, /* GL_S */
- { 29644, 0x00008B5D }, /* GL_SAMPLER_1D */
- { 29658, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
- { 29679, 0x00008B5E }, /* GL_SAMPLER_2D */
- { 29693, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
- { 29714, 0x00008B5F }, /* GL_SAMPLER_3D */
- { 29728, 0x00008B60 }, /* GL_SAMPLER_CUBE */
- { 29744, 0x000080A9 }, /* GL_SAMPLES */
- { 29755, 0x000086B4 }, /* GL_SAMPLES_3DFX */
- { 29771, 0x000080A9 }, /* GL_SAMPLES_ARB */
- { 29786, 0x00008914 }, /* GL_SAMPLES_PASSED */
- { 29804, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
- { 29826, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
- { 29854, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
- { 29886, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
- { 29909, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
- { 29936, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
- { 29954, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
- { 29977, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
- { 29999, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
- { 30018, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
- { 30041, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
- { 30067, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
- { 30097, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
- { 30122, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
- { 30151, 0x00080000 }, /* GL_SCISSOR_BIT */
- { 30166, 0x00000C10 }, /* GL_SCISSOR_BOX */
- { 30181, 0x00000C11 }, /* GL_SCISSOR_TEST */
- { 30197, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
- { 30222, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
- { 30262, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
- { 30306, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
- { 30339, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
- { 30369, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
- { 30401, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
- { 30431, 0x00001C02 }, /* GL_SELECT */
- { 30441, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
- { 30469, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
- { 30494, 0x00008012 }, /* GL_SEPARABLE_2D */
- { 30510, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
- { 30537, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
- { 30568, 0x0000150F }, /* GL_SET */
- { 30575, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
- { 30596, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
- { 30620, 0x00008B4F }, /* GL_SHADER_TYPE */
- { 30635, 0x00000B54 }, /* GL_SHADE_MODEL */
- { 30650, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
- { 30678, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
- { 30701, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
- { 30731, 0x00001601 }, /* GL_SHININESS */
- { 30744, 0x00001402 }, /* GL_SHORT */
- { 30753, 0x00009119 }, /* GL_SIGNALED */
- { 30765, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
- { 30786, 0x000081F9 }, /* GL_SINGLE_COLOR */
- { 30802, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
- { 30822, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
- { 30841, 0x00008C46 }, /* GL_SLUMINANCE */
- { 30855, 0x00008C47 }, /* GL_SLUMINANCE8 */
- { 30870, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
- { 30892, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
- { 30912, 0x00001D01 }, /* GL_SMOOTH */
- { 30922, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
- { 30955, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
- { 30982, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
- { 31015, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
- { 31042, 0x00008588 }, /* GL_SOURCE0_ALPHA */
- { 31059, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
- { 31080, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
- { 31101, 0x00008580 }, /* GL_SOURCE0_RGB */
- { 31116, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
- { 31135, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
- { 31154, 0x00008589 }, /* GL_SOURCE1_ALPHA */
- { 31171, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
- { 31192, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
- { 31213, 0x00008581 }, /* GL_SOURCE1_RGB */
- { 31228, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
- { 31247, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
- { 31266, 0x0000858A }, /* GL_SOURCE2_ALPHA */
- { 31283, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
- { 31304, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
- { 31325, 0x00008582 }, /* GL_SOURCE2_RGB */
- { 31340, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
- { 31359, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
- { 31378, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
- { 31398, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
- { 31416, 0x00001202 }, /* GL_SPECULAR */
- { 31428, 0x00002402 }, /* GL_SPHERE_MAP */
- { 31442, 0x00001206 }, /* GL_SPOT_CUTOFF */
- { 31457, 0x00001204 }, /* GL_SPOT_DIRECTION */
- { 31475, 0x00001205 }, /* GL_SPOT_EXPONENT */
- { 31492, 0x00008588 }, /* GL_SRC0_ALPHA */
- { 31506, 0x00008580 }, /* GL_SRC0_RGB */
- { 31518, 0x00008589 }, /* GL_SRC1_ALPHA */
- { 31532, 0x00008581 }, /* GL_SRC1_RGB */
- { 31544, 0x0000858A }, /* GL_SRC2_ALPHA */
- { 31558, 0x00008582 }, /* GL_SRC2_RGB */
- { 31570, 0x00000302 }, /* GL_SRC_ALPHA */
- { 31583, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
- { 31605, 0x00000300 }, /* GL_SRC_COLOR */
- { 31618, 0x00008C40 }, /* GL_SRGB */
- { 31626, 0x00008C41 }, /* GL_SRGB8 */
- { 31635, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
- { 31651, 0x00008C42 }, /* GL_SRGB_ALPHA */
- { 31665, 0x00000503 }, /* GL_STACK_OVERFLOW */
- { 31683, 0x00000504 }, /* GL_STACK_UNDERFLOW */
- { 31702, 0x000088E6 }, /* GL_STATIC_COPY */
- { 31717, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
- { 31736, 0x000088E4 }, /* GL_STATIC_DRAW */
- { 31751, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
- { 31770, 0x000088E5 }, /* GL_STATIC_READ */
- { 31785, 0x000088E5 }, /* GL_STATIC_READ_ARB */
- { 31804, 0x00001802 }, /* GL_STENCIL */
- { 31815, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
- { 31837, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
- { 31863, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
- { 31884, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
- { 31909, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
- { 31930, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
- { 31955, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
- { 31987, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
- { 32023, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
- { 32055, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
- { 32091, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
- { 32111, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
- { 32138, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
- { 32164, 0x00000D57 }, /* GL_STENCIL_BITS */
- { 32180, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
- { 32202, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
- { 32225, 0x00000B94 }, /* GL_STENCIL_FAIL */
- { 32241, 0x00000B92 }, /* GL_STENCIL_FUNC */
- { 32257, 0x00001901 }, /* GL_STENCIL_INDEX */
- { 32274, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
- { 32297, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
- { 32319, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
- { 32341, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
- { 32363, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
- { 32384, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
- { 32411, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
- { 32438, 0x00000B97 }, /* GL_STENCIL_REF */
- { 32453, 0x00000B90 }, /* GL_STENCIL_TEST */
- { 32469, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
- { 32498, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
- { 32520, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
- { 32541, 0x00000C33 }, /* GL_STEREO */
- { 32551, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
- { 32575, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
- { 32600, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
- { 32624, 0x000088E2 }, /* GL_STREAM_COPY */
- { 32639, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
- { 32658, 0x000088E0 }, /* GL_STREAM_DRAW */
- { 32673, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
- { 32692, 0x000088E1 }, /* GL_STREAM_READ */
- { 32707, 0x000088E1 }, /* GL_STREAM_READ_ARB */
- { 32726, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
- { 32743, 0x000084E7 }, /* GL_SUBTRACT */
- { 32755, 0x000084E7 }, /* GL_SUBTRACT_ARB */
- { 32771, 0x00009113 }, /* GL_SYNC_CONDITION */
- { 32789, 0x00009116 }, /* GL_SYNC_FENCE */
- { 32803, 0x00009115 }, /* GL_SYNC_FLAGS */
- { 32817, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
- { 32844, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
- { 32874, 0x00009114 }, /* GL_SYNC_STATUS */
- { 32889, 0x00002001 }, /* GL_T */
- { 32894, 0x00002A2A }, /* GL_T2F_C3F_V3F */
- { 32909, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
- { 32928, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
- { 32944, 0x00002A2B }, /* GL_T2F_N3F_V3F */
- { 32959, 0x00002A27 }, /* GL_T2F_V3F */
- { 32970, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
- { 32989, 0x00002A28 }, /* GL_T4F_V4F */
- { 33000, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
- { 33023, 0x00001702 }, /* GL_TEXTURE */
- { 33034, 0x000084C0 }, /* GL_TEXTURE0 */
- { 33046, 0x000084C0 }, /* GL_TEXTURE0_ARB */
- { 33062, 0x000084C1 }, /* GL_TEXTURE1 */
- { 33074, 0x000084CA }, /* GL_TEXTURE10 */
- { 33087, 0x000084CA }, /* GL_TEXTURE10_ARB */
- { 33104, 0x000084CB }, /* GL_TEXTURE11 */
- { 33117, 0x000084CB }, /* GL_TEXTURE11_ARB */
- { 33134, 0x000084CC }, /* GL_TEXTURE12 */
- { 33147, 0x000084CC }, /* GL_TEXTURE12_ARB */
- { 33164, 0x000084CD }, /* GL_TEXTURE13 */
- { 33177, 0x000084CD }, /* GL_TEXTURE13_ARB */
- { 33194, 0x000084CE }, /* GL_TEXTURE14 */
- { 33207, 0x000084CE }, /* GL_TEXTURE14_ARB */
- { 33224, 0x000084CF }, /* GL_TEXTURE15 */
- { 33237, 0x000084CF }, /* GL_TEXTURE15_ARB */
- { 33254, 0x000084D0 }, /* GL_TEXTURE16 */
- { 33267, 0x000084D0 }, /* GL_TEXTURE16_ARB */
- { 33284, 0x000084D1 }, /* GL_TEXTURE17 */
- { 33297, 0x000084D1 }, /* GL_TEXTURE17_ARB */
- { 33314, 0x000084D2 }, /* GL_TEXTURE18 */
- { 33327, 0x000084D2 }, /* GL_TEXTURE18_ARB */
- { 33344, 0x000084D3 }, /* GL_TEXTURE19 */
- { 33357, 0x000084D3 }, /* GL_TEXTURE19_ARB */
- { 33374, 0x000084C1 }, /* GL_TEXTURE1_ARB */
- { 33390, 0x000084C2 }, /* GL_TEXTURE2 */
- { 33402, 0x000084D4 }, /* GL_TEXTURE20 */
- { 33415, 0x000084D4 }, /* GL_TEXTURE20_ARB */
- { 33432, 0x000084D5 }, /* GL_TEXTURE21 */
- { 33445, 0x000084D5 }, /* GL_TEXTURE21_ARB */
- { 33462, 0x000084D6 }, /* GL_TEXTURE22 */
- { 33475, 0x000084D6 }, /* GL_TEXTURE22_ARB */
- { 33492, 0x000084D7 }, /* GL_TEXTURE23 */
- { 33505, 0x000084D7 }, /* GL_TEXTURE23_ARB */
- { 33522, 0x000084D8 }, /* GL_TEXTURE24 */
- { 33535, 0x000084D8 }, /* GL_TEXTURE24_ARB */
- { 33552, 0x000084D9 }, /* GL_TEXTURE25 */
- { 33565, 0x000084D9 }, /* GL_TEXTURE25_ARB */
- { 33582, 0x000084DA }, /* GL_TEXTURE26 */
- { 33595, 0x000084DA }, /* GL_TEXTURE26_ARB */
- { 33612, 0x000084DB }, /* GL_TEXTURE27 */
- { 33625, 0x000084DB }, /* GL_TEXTURE27_ARB */
- { 33642, 0x000084DC }, /* GL_TEXTURE28 */
- { 33655, 0x000084DC }, /* GL_TEXTURE28_ARB */
- { 33672, 0x000084DD }, /* GL_TEXTURE29 */
- { 33685, 0x000084DD }, /* GL_TEXTURE29_ARB */
- { 33702, 0x000084C2 }, /* GL_TEXTURE2_ARB */
- { 33718, 0x000084C3 }, /* GL_TEXTURE3 */
- { 33730, 0x000084DE }, /* GL_TEXTURE30 */
- { 33743, 0x000084DE }, /* GL_TEXTURE30_ARB */
- { 33760, 0x000084DF }, /* GL_TEXTURE31 */
- { 33773, 0x000084DF }, /* GL_TEXTURE31_ARB */
- { 33790, 0x000084C3 }, /* GL_TEXTURE3_ARB */
- { 33806, 0x000084C4 }, /* GL_TEXTURE4 */
- { 33818, 0x000084C4 }, /* GL_TEXTURE4_ARB */
- { 33834, 0x000084C5 }, /* GL_TEXTURE5 */
- { 33846, 0x000084C5 }, /* GL_TEXTURE5_ARB */
- { 33862, 0x000084C6 }, /* GL_TEXTURE6 */
- { 33874, 0x000084C6 }, /* GL_TEXTURE6_ARB */
- { 33890, 0x000084C7 }, /* GL_TEXTURE7 */
- { 33902, 0x000084C7 }, /* GL_TEXTURE7_ARB */
- { 33918, 0x000084C8 }, /* GL_TEXTURE8 */
- { 33930, 0x000084C8 }, /* GL_TEXTURE8_ARB */
- { 33946, 0x000084C9 }, /* GL_TEXTURE9 */
- { 33958, 0x000084C9 }, /* GL_TEXTURE9_ARB */
- { 33974, 0x00000DE0 }, /* GL_TEXTURE_1D */
- { 33988, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
- { 34012, 0x00000DE1 }, /* GL_TEXTURE_2D */
- { 34026, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
- { 34050, 0x0000806F }, /* GL_TEXTURE_3D */
- { 34064, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
- { 34086, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
- { 34112, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
- { 34134, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
- { 34156, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
- { 34188, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
- { 34210, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
- { 34242, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
- { 34264, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
- { 34292, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
- { 34324, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
- { 34357, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
- { 34389, 0x00040000 }, /* GL_TEXTURE_BIT */
- { 34404, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
- { 34425, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
- { 34450, 0x00001005 }, /* GL_TEXTURE_BORDER */
- { 34468, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
- { 34492, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
- { 34523, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
- { 34553, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
- { 34583, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
- { 34618, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
- { 34649, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- { 34687, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
- { 34714, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
- { 34746, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
- { 34780, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
- { 34804, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
- { 34832, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
- { 34856, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
- { 34884, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
- { 34917, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
- { 34941, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
- { 34963, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
- { 34985, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
- { 35011, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
- { 35045, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
- { 35078, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
- { 35115, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
- { 35143, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
- { 35175, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
- { 35198, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
- { 35236, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
- { 35278, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
- { 35309, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
- { 35337, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
- { 35367, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
- { 35395, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
- { 35415, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
- { 35439, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
- { 35470, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
- { 35505, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
- { 35536, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
- { 35571, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
- { 35602, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
- { 35637, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
- { 35668, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
- { 35703, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
- { 35734, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
- { 35769, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
- { 35800, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
- { 35835, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
- { 35864, 0x00008071 }, /* GL_TEXTURE_DEPTH */
- { 35881, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
- { 35903, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
- { 35929, 0x00002300 }, /* GL_TEXTURE_ENV */
- { 35944, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
- { 35965, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
- { 35985, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
- { 36011, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
- { 36031, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
- { 36048, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
- { 36065, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
- { 36082, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
- { 36099, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
- { 36124, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
- { 36146, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
- { 36172, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
- { 36190, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
- { 36216, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
- { 36242, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
- { 36272, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
- { 36299, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
- { 36324, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
- { 36344, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
- { 36368, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
- { 36395, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
- { 36422, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
- { 36449, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
- { 36475, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
- { 36505, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
- { 36527, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
- { 36545, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
- { 36575, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
- { 36603, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
- { 36631, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
- { 36659, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
- { 36680, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
- { 36699, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
- { 36721, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
- { 36740, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
- { 36760, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
- { 36790, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
- { 36821, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
- { 36846, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
- { 36870, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
- { 36890, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
- { 36914, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
- { 36934, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
- { 36957, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
- { 36981, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
- { 37011, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
- { 37036, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
- { 37070, 0x00001000 }, /* GL_TEXTURE_WIDTH */
- { 37087, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
- { 37105, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
- { 37123, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
- { 37141, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
- { 37160, 0xFFFFFFFFFFFFFFFF }, /* GL_TIMEOUT_IGNORED */
- { 37179, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
- { 37199, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
- { 37218, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
- { 37247, 0x00001000 }, /* GL_TRANSFORM_BIT */
- { 37264, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
- { 37290, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
- { 37320, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
- { 37352, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
- { 37382, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
- { 37416, 0x0000862C }, /* GL_TRANSPOSE_NV */
- { 37432, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
- { 37463, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
- { 37498, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
- { 37526, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
- { 37558, 0x00000004 }, /* GL_TRIANGLES */
- { 37571, 0x00000006 }, /* GL_TRIANGLE_FAN */
- { 37587, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
- { 37608, 0x00000005 }, /* GL_TRIANGLE_STRIP */
- { 37626, 0x00000001 }, /* GL_TRUE */
- { 37634, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
- { 37654, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
- { 37677, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
- { 37697, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
- { 37718, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
- { 37740, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
- { 37762, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
- { 37782, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
- { 37803, 0x00009118 }, /* GL_UNSIGNALED */
- { 37817, 0x00001401 }, /* GL_UNSIGNED_BYTE */
- { 37834, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
- { 37861, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
- { 37884, 0x00001405 }, /* GL_UNSIGNED_INT */
- { 37900, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
- { 37927, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
- { 37948, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
- { 37972, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
- { 38003, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
- { 38027, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
- { 38055, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
- { 38078, 0x00001403 }, /* GL_UNSIGNED_SHORT */
- { 38096, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
- { 38126, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
- { 38152, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
- { 38182, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
- { 38208, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
- { 38232, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
- { 38260, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
- { 38288, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
- { 38315, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
- { 38347, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
- { 38378, 0x00008CA2 }, /* GL_UPPER_LEFT */
- { 38392, 0x00002A20 }, /* GL_V2F */
- { 38399, 0x00002A21 }, /* GL_V3F */
- { 38406, 0x00008B83 }, /* GL_VALIDATE_STATUS */
- { 38425, 0x00001F00 }, /* GL_VENDOR */
- { 38435, 0x00001F02 }, /* GL_VERSION */
- { 38446, 0x00008074 }, /* GL_VERTEX_ARRAY */
- { 38462, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
- { 38486, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
- { 38516, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
- { 38547, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
- { 38582, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
- { 38606, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
- { 38627, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
- { 38650, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
- { 38671, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
- { 38698, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
- { 38726, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
- { 38754, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
- { 38782, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
- { 38810, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
- { 38838, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
- { 38866, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
- { 38893, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
- { 38920, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
- { 38947, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
- { 38974, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
- { 39001, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
- { 39028, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
- { 39055, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
- { 39082, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
- { 39109, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
- { 39147, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
- { 39189, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
- { 39220, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
- { 39255, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
- { 39289, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
- { 39327, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
- { 39358, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
- { 39393, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
- { 39421, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
- { 39453, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
- { 39483, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
- { 39517, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
- { 39545, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
- { 39577, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
- { 39597, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
- { 39619, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
- { 39648, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
- { 39669, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
- { 39698, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
- { 39731, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
- { 39763, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
- { 39790, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
- { 39821, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
- { 39851, 0x00008B31 }, /* GL_VERTEX_SHADER */
- { 39868, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
- { 39889, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
- { 39916, 0x00000BA2 }, /* GL_VIEWPORT */
- { 39928, 0x00000800 }, /* GL_VIEWPORT_BIT */
- { 39944, 0x0000911D }, /* GL_WAIT_FAILED */
- { 39959, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
- { 39979, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
- { 40010, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
- { 40045, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
- { 40073, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
- { 40098, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
- { 40125, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
- { 40150, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
- { 40174, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
- { 40193, 0x000088B9 }, /* GL_WRITE_ONLY */
- { 40207, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
- { 40225, 0x00001506 }, /* GL_XOR */
- { 40232, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
- { 40251, 0x00008757 }, /* GL_YCBCR_MESA */
- { 40265, 0x00000000 }, /* GL_ZERO */
- { 40273, 0x00000D16 }, /* GL_ZOOM_X */
- { 40283, 0x00000D17 }, /* GL_ZOOM_Y */
+ { 9726, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION */
+ { 9753, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION_EXT */
+ { 9784, 0x00001D00 }, /* GL_FLAT */
+ { 9792, 0x00001406 }, /* GL_FLOAT */
+ { 9801, 0x00008B5A }, /* GL_FLOAT_MAT2 */
+ { 9815, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
+ { 9833, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
+ { 9849, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
+ { 9865, 0x00008B5B }, /* GL_FLOAT_MAT3 */
+ { 9879, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
+ { 9897, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
+ { 9913, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
+ { 9929, 0x00008B5C }, /* GL_FLOAT_MAT4 */
+ { 9943, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
+ { 9961, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
+ { 9977, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
+ { 9993, 0x00008B50 }, /* GL_FLOAT_VEC2 */
+ { 10007, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
+ { 10025, 0x00008B51 }, /* GL_FLOAT_VEC3 */
+ { 10039, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
+ { 10057, 0x00008B52 }, /* GL_FLOAT_VEC4 */
+ { 10071, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
+ { 10089, 0x00000B60 }, /* GL_FOG */
+ { 10096, 0x00000080 }, /* GL_FOG_BIT */
+ { 10107, 0x00000B66 }, /* GL_FOG_COLOR */
+ { 10120, 0x00008451 }, /* GL_FOG_COORD */
+ { 10133, 0x00008451 }, /* GL_FOG_COORDINATE */
+ { 10151, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
+ { 10175, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+ { 10214, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
+ { 10257, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+ { 10289, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+ { 10320, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+ { 10349, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
+ { 10374, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
+ { 10393, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
+ { 10427, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
+ { 10454, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
+ { 10480, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
+ { 10504, 0x00008450 }, /* GL_FOG_COORD_SRC */
+ { 10521, 0x00000B62 }, /* GL_FOG_DENSITY */
+ { 10536, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
+ { 10560, 0x00000B64 }, /* GL_FOG_END */
+ { 10571, 0x00000C54 }, /* GL_FOG_HINT */
+ { 10583, 0x00000B61 }, /* GL_FOG_INDEX */
+ { 10596, 0x00000B65 }, /* GL_FOG_MODE */
+ { 10608, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
+ { 10627, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
+ { 10652, 0x00000B63 }, /* GL_FOG_START */
+ { 10665, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
+ { 10683, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
+ { 10707, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
+ { 10726, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
+ { 10749, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+ { 10784, 0x00008D40 }, /* GL_FRAMEBUFFER */
+ { 10799, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+ { 10836, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+ { 10872, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+ { 10913, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+ { 10954, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+ { 10991, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+ { 11028, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+ { 11066, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
+ { 11108, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+ { 11146, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
+ { 11188, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+ { 11223, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+ { 11262, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
+ { 11311, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+ { 11359, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
+ { 11411, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+ { 11451, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
+ { 11495, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+ { 11535, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
+ { 11579, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
+ { 11606, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
+ { 11630, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
+ { 11658, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
+ { 11681, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
+ { 11700, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+ { 11737, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
+ { 11778, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+ { 11819, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+ { 11861, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+ { 11912, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+ { 11950, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+ { 11995, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
+ { 12044, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+ { 12082, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+ { 12124, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ { 12156, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
+ { 12181, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
+ { 12208, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
+ { 12239, 0x00000404 }, /* GL_FRONT */
+ { 12248, 0x00000408 }, /* GL_FRONT_AND_BACK */
+ { 12266, 0x00000B46 }, /* GL_FRONT_FACE */
+ { 12280, 0x00000400 }, /* GL_FRONT_LEFT */
+ { 12294, 0x00000401 }, /* GL_FRONT_RIGHT */
+ { 12309, 0x00008006 }, /* GL_FUNC_ADD */
+ { 12321, 0x00008006 }, /* GL_FUNC_ADD_EXT */
+ { 12337, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
+ { 12362, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
+ { 12391, 0x0000800A }, /* GL_FUNC_SUBTRACT */
+ { 12408, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
+ { 12429, 0x00008191 }, /* GL_GENERATE_MIPMAP */
+ { 12448, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
+ { 12472, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
+ { 12501, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
+ { 12525, 0x00000206 }, /* GL_GEQUAL */
+ { 12535, 0x00000204 }, /* GL_GREATER */
+ { 12546, 0x00001904 }, /* GL_GREEN */
+ { 12555, 0x00000D19 }, /* GL_GREEN_BIAS */
+ { 12569, 0x00000D53 }, /* GL_GREEN_BITS */
+ { 12583, 0x00000D18 }, /* GL_GREEN_SCALE */
+ { 12598, 0x00008000 }, /* GL_HINT_BIT */
+ { 12610, 0x00008024 }, /* GL_HISTOGRAM */
+ { 12623, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
+ { 12647, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
+ { 12675, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
+ { 12698, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
+ { 12725, 0x00008024 }, /* GL_HISTOGRAM_EXT */
+ { 12742, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
+ { 12762, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
+ { 12786, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
+ { 12810, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
+ { 12838, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+ { 12866, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
+ { 12898, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
+ { 12920, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
+ { 12946, 0x0000802D }, /* GL_HISTOGRAM_SINK */
+ { 12964, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
+ { 12986, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
+ { 13005, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
+ { 13028, 0x0000862A }, /* GL_IDENTITY_NV */
+ { 13043, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
+ { 13063, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+ { 13103, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+ { 13141, 0x00001E02 }, /* GL_INCR */
+ { 13149, 0x00008507 }, /* GL_INCR_WRAP */
+ { 13162, 0x00008507 }, /* GL_INCR_WRAP_EXT */
+ { 13179, 0x00008222 }, /* GL_INDEX */
+ { 13188, 0x00008077 }, /* GL_INDEX_ARRAY */
+ { 13203, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ { 13233, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
+ { 13267, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
+ { 13290, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
+ { 13312, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
+ { 13332, 0x00000D51 }, /* GL_INDEX_BITS */
+ { 13346, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
+ { 13367, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
+ { 13385, 0x00000C30 }, /* GL_INDEX_MODE */
+ { 13399, 0x00000D13 }, /* GL_INDEX_OFFSET */
+ { 13415, 0x00000D12 }, /* GL_INDEX_SHIFT */
+ { 13430, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
+ { 13449, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
+ { 13468, 0x00001404 }, /* GL_INT */
+ { 13475, 0x00008049 }, /* GL_INTENSITY */
+ { 13488, 0x0000804C }, /* GL_INTENSITY12 */
+ { 13503, 0x0000804C }, /* GL_INTENSITY12_EXT */
+ { 13522, 0x0000804D }, /* GL_INTENSITY16 */
+ { 13537, 0x0000804D }, /* GL_INTENSITY16_EXT */
+ { 13556, 0x0000804A }, /* GL_INTENSITY4 */
+ { 13570, 0x0000804A }, /* GL_INTENSITY4_EXT */
+ { 13588, 0x0000804B }, /* GL_INTENSITY8 */
+ { 13602, 0x0000804B }, /* GL_INTENSITY8_EXT */
+ { 13620, 0x00008049 }, /* GL_INTENSITY_EXT */
+ { 13637, 0x00008575 }, /* GL_INTERPOLATE */
+ { 13652, 0x00008575 }, /* GL_INTERPOLATE_ARB */
+ { 13671, 0x00008575 }, /* GL_INTERPOLATE_EXT */
+ { 13690, 0x00008B53 }, /* GL_INT_VEC2 */
+ { 13702, 0x00008B53 }, /* GL_INT_VEC2_ARB */
+ { 13718, 0x00008B54 }, /* GL_INT_VEC3 */
+ { 13730, 0x00008B54 }, /* GL_INT_VEC3_ARB */
+ { 13746, 0x00008B55 }, /* GL_INT_VEC4 */
+ { 13758, 0x00008B55 }, /* GL_INT_VEC4_ARB */
+ { 13774, 0x00000500 }, /* GL_INVALID_ENUM */
+ { 13790, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+ { 13823, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
+ { 13860, 0x00000502 }, /* GL_INVALID_OPERATION */
+ { 13881, 0x00000501 }, /* GL_INVALID_VALUE */
+ { 13898, 0x0000862B }, /* GL_INVERSE_NV */
+ { 13912, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
+ { 13936, 0x0000150A }, /* GL_INVERT */
+ { 13946, 0x00001E00 }, /* GL_KEEP */
+ { 13954, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION */
+ { 13980, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
+ { 14010, 0x00000406 }, /* GL_LEFT */
+ { 14018, 0x00000203 }, /* GL_LEQUAL */
+ { 14028, 0x00000201 }, /* GL_LESS */
+ { 14036, 0x00004000 }, /* GL_LIGHT0 */
+ { 14046, 0x00004001 }, /* GL_LIGHT1 */
+ { 14056, 0x00004002 }, /* GL_LIGHT2 */
+ { 14066, 0x00004003 }, /* GL_LIGHT3 */
+ { 14076, 0x00004004 }, /* GL_LIGHT4 */
+ { 14086, 0x00004005 }, /* GL_LIGHT5 */
+ { 14096, 0x00004006 }, /* GL_LIGHT6 */
+ { 14106, 0x00004007 }, /* GL_LIGHT7 */
+ { 14116, 0x00000B50 }, /* GL_LIGHTING */
+ { 14128, 0x00000040 }, /* GL_LIGHTING_BIT */
+ { 14144, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
+ { 14167, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+ { 14196, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
+ { 14229, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+ { 14257, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
+ { 14281, 0x00001B01 }, /* GL_LINE */
+ { 14289, 0x00002601 }, /* GL_LINEAR */
+ { 14299, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
+ { 14321, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+ { 14351, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+ { 14382, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
+ { 14406, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
+ { 14431, 0x00000001 }, /* GL_LINES */
+ { 14440, 0x00000004 }, /* GL_LINE_BIT */
+ { 14452, 0x00000002 }, /* GL_LINE_LOOP */
+ { 14465, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
+ { 14485, 0x00000B20 }, /* GL_LINE_SMOOTH */
+ { 14500, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
+ { 14520, 0x00000B24 }, /* GL_LINE_STIPPLE */
+ { 14536, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
+ { 14560, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
+ { 14583, 0x00000003 }, /* GL_LINE_STRIP */
+ { 14597, 0x00000702 }, /* GL_LINE_TOKEN */
+ { 14611, 0x00000B21 }, /* GL_LINE_WIDTH */
+ { 14625, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
+ { 14651, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
+ { 14671, 0x00008B82 }, /* GL_LINK_STATUS */
+ { 14686, 0x00000B32 }, /* GL_LIST_BASE */
+ { 14699, 0x00020000 }, /* GL_LIST_BIT */
+ { 14711, 0x00000B33 }, /* GL_LIST_INDEX */
+ { 14725, 0x00000B30 }, /* GL_LIST_MODE */
+ { 14738, 0x00000101 }, /* GL_LOAD */
+ { 14746, 0x00000BF1 }, /* GL_LOGIC_OP */
+ { 14758, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
+ { 14775, 0x00008CA1 }, /* GL_LOWER_LEFT */
+ { 14789, 0x00001909 }, /* GL_LUMINANCE */
+ { 14802, 0x00008041 }, /* GL_LUMINANCE12 */
+ { 14817, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
+ { 14840, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
+ { 14867, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
+ { 14889, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
+ { 14915, 0x00008041 }, /* GL_LUMINANCE12_EXT */
+ { 14934, 0x00008042 }, /* GL_LUMINANCE16 */
+ { 14949, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
+ { 14972, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
+ { 14999, 0x00008042 }, /* GL_LUMINANCE16_EXT */
+ { 15018, 0x0000803F }, /* GL_LUMINANCE4 */
+ { 15032, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
+ { 15053, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
+ { 15078, 0x0000803F }, /* GL_LUMINANCE4_EXT */
+ { 15096, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
+ { 15117, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
+ { 15142, 0x00008040 }, /* GL_LUMINANCE8 */
+ { 15156, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
+ { 15177, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
+ { 15202, 0x00008040 }, /* GL_LUMINANCE8_EXT */
+ { 15220, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
+ { 15239, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
+ { 15255, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
+ { 15275, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
+ { 15297, 0x00000D91 }, /* GL_MAP1_INDEX */
+ { 15311, 0x00000D92 }, /* GL_MAP1_NORMAL */
+ { 15326, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
+ { 15350, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
+ { 15374, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
+ { 15398, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
+ { 15422, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
+ { 15439, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
+ { 15456, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+ { 15484, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+ { 15513, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+ { 15542, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+ { 15571, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+ { 15600, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+ { 15629, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+ { 15658, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+ { 15686, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+ { 15714, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+ { 15742, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+ { 15770, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+ { 15798, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+ { 15826, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+ { 15854, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+ { 15882, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+ { 15910, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
+ { 15926, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
+ { 15946, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
+ { 15968, 0x00000DB1 }, /* GL_MAP2_INDEX */
+ { 15982, 0x00000DB2 }, /* GL_MAP2_NORMAL */
+ { 15997, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
+ { 16021, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
+ { 16045, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
+ { 16069, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
+ { 16093, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
+ { 16110, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
+ { 16127, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+ { 16155, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+ { 16184, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+ { 16213, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+ { 16242, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+ { 16271, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+ { 16300, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+ { 16329, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+ { 16357, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+ { 16385, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+ { 16413, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+ { 16441, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+ { 16469, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+ { 16497, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
+ { 16525, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+ { 16553, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+ { 16581, 0x00000D10 }, /* GL_MAP_COLOR */
+ { 16594, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
+ { 16620, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
+ { 16649, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
+ { 16677, 0x00000001 }, /* GL_MAP_READ_BIT */
+ { 16693, 0x00000D11 }, /* GL_MAP_STENCIL */
+ { 16708, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
+ { 16734, 0x00000002 }, /* GL_MAP_WRITE_BIT */
+ { 16751, 0x000088C0 }, /* GL_MATRIX0_ARB */
+ { 16766, 0x00008630 }, /* GL_MATRIX0_NV */
+ { 16780, 0x000088CA }, /* GL_MATRIX10_ARB */
+ { 16796, 0x000088CB }, /* GL_MATRIX11_ARB */
+ { 16812, 0x000088CC }, /* GL_MATRIX12_ARB */
+ { 16828, 0x000088CD }, /* GL_MATRIX13_ARB */
+ { 16844, 0x000088CE }, /* GL_MATRIX14_ARB */
+ { 16860, 0x000088CF }, /* GL_MATRIX15_ARB */
+ { 16876, 0x000088D0 }, /* GL_MATRIX16_ARB */
+ { 16892, 0x000088D1 }, /* GL_MATRIX17_ARB */
+ { 16908, 0x000088D2 }, /* GL_MATRIX18_ARB */
+ { 16924, 0x000088D3 }, /* GL_MATRIX19_ARB */
+ { 16940, 0x000088C1 }, /* GL_MATRIX1_ARB */
+ { 16955, 0x00008631 }, /* GL_MATRIX1_NV */
+ { 16969, 0x000088D4 }, /* GL_MATRIX20_ARB */
+ { 16985, 0x000088D5 }, /* GL_MATRIX21_ARB */
+ { 17001, 0x000088D6 }, /* GL_MATRIX22_ARB */
+ { 17017, 0x000088D7 }, /* GL_MATRIX23_ARB */
+ { 17033, 0x000088D8 }, /* GL_MATRIX24_ARB */
+ { 17049, 0x000088D9 }, /* GL_MATRIX25_ARB */
+ { 17065, 0x000088DA }, /* GL_MATRIX26_ARB */
+ { 17081, 0x000088DB }, /* GL_MATRIX27_ARB */
+ { 17097, 0x000088DC }, /* GL_MATRIX28_ARB */
+ { 17113, 0x000088DD }, /* GL_MATRIX29_ARB */
+ { 17129, 0x000088C2 }, /* GL_MATRIX2_ARB */
+ { 17144, 0x00008632 }, /* GL_MATRIX2_NV */
+ { 17158, 0x000088DE }, /* GL_MATRIX30_ARB */
+ { 17174, 0x000088DF }, /* GL_MATRIX31_ARB */
+ { 17190, 0x000088C3 }, /* GL_MATRIX3_ARB */
+ { 17205, 0x00008633 }, /* GL_MATRIX3_NV */
+ { 17219, 0x000088C4 }, /* GL_MATRIX4_ARB */
+ { 17234, 0x00008634 }, /* GL_MATRIX4_NV */
+ { 17248, 0x000088C5 }, /* GL_MATRIX5_ARB */
+ { 17263, 0x00008635 }, /* GL_MATRIX5_NV */
+ { 17277, 0x000088C6 }, /* GL_MATRIX6_ARB */
+ { 17292, 0x00008636 }, /* GL_MATRIX6_NV */
+ { 17306, 0x000088C7 }, /* GL_MATRIX7_ARB */
+ { 17321, 0x00008637 }, /* GL_MATRIX7_NV */
+ { 17335, 0x000088C8 }, /* GL_MATRIX8_ARB */
+ { 17350, 0x000088C9 }, /* GL_MATRIX9_ARB */
+ { 17365, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ { 17391, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+ { 17425, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+ { 17456, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+ { 17489, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+ { 17520, 0x00000BA0 }, /* GL_MATRIX_MODE */
+ { 17535, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
+ { 17557, 0x00008008 }, /* GL_MAX */
+ { 17564, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
+ { 17587, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+ { 17619, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
+ { 17645, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+ { 17678, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+ { 17704, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 17738, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
+ { 17757, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+ { 17786, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+ { 17818, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
+ { 17854, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+ { 17890, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
+ { 17930, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
+ { 17956, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
+ { 17986, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
+ { 18011, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
+ { 18040, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+ { 18069, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
+ { 18102, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
+ { 18122, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
+ { 18146, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
+ { 18170, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
+ { 18194, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
+ { 18219, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
+ { 18237, 0x00008008 }, /* GL_MAX_EXT */
+ { 18248, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+ { 18283, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
+ { 18322, 0x00000D31 }, /* GL_MAX_LIGHTS */
+ { 18336, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
+ { 18356, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+ { 18394, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+ { 18423, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
+ { 18447, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
+ { 18475, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
+ { 18498, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 18535, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 18571, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+ { 18598, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+ { 18627, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+ { 18661, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
+ { 18697, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+ { 18724, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+ { 18756, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+ { 18792, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+ { 18821, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+ { 18850, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
+ { 18878, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+ { 18916, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 18960, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 19003, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 19037, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 19076, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 19113, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 19151, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 19194, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 19237, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+ { 19267, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+ { 19298, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 19334, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 19370, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
+ { 19400, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+ { 19434, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
+ { 19467, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+ { 19496, 0x00008D57 }, /* GL_MAX_SAMPLES */
+ { 19511, 0x00009111 }, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+ { 19538, 0x00008504 }, /* GL_MAX_SHININESS_NV */
+ { 19558, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
+ { 19582, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
+ { 19604, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
+ { 19630, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+ { 19657, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
+ { 19688, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
+ { 19712, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 19746, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
+ { 19766, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
+ { 19793, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
+ { 19814, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
+ { 19839, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
+ { 19864, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
+ { 19899, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
+ { 19921, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
+ { 19947, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
+ { 19969, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
+ { 19995, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+ { 20029, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
+ { 20067, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+ { 20100, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
+ { 20137, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
+ { 20161, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
+ { 20182, 0x00008007 }, /* GL_MIN */
+ { 20189, 0x0000802E }, /* GL_MINMAX */
+ { 20199, 0x0000802E }, /* GL_MINMAX_EXT */
+ { 20213, 0x0000802F }, /* GL_MINMAX_FORMAT */
+ { 20230, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
+ { 20251, 0x00008030 }, /* GL_MINMAX_SINK */
+ { 20266, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
+ { 20285, 0x00008007 }, /* GL_MIN_EXT */
+ { 20296, 0x00008370 }, /* GL_MIRRORED_REPEAT */
+ { 20315, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
+ { 20338, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
+ { 20361, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
+ { 20381, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
+ { 20401, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ { 20431, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
+ { 20459, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+ { 20487, 0x00001700 }, /* GL_MODELVIEW */
+ { 20500, 0x00001700 }, /* GL_MODELVIEW0_ARB */
+ { 20518, 0x0000872A }, /* GL_MODELVIEW10_ARB */
+ { 20537, 0x0000872B }, /* GL_MODELVIEW11_ARB */
+ { 20556, 0x0000872C }, /* GL_MODELVIEW12_ARB */
+ { 20575, 0x0000872D }, /* GL_MODELVIEW13_ARB */
+ { 20594, 0x0000872E }, /* GL_MODELVIEW14_ARB */
+ { 20613, 0x0000872F }, /* GL_MODELVIEW15_ARB */
+ { 20632, 0x00008730 }, /* GL_MODELVIEW16_ARB */
+ { 20651, 0x00008731 }, /* GL_MODELVIEW17_ARB */
+ { 20670, 0x00008732 }, /* GL_MODELVIEW18_ARB */
+ { 20689, 0x00008733 }, /* GL_MODELVIEW19_ARB */
+ { 20708, 0x0000850A }, /* GL_MODELVIEW1_ARB */
+ { 20726, 0x00008734 }, /* GL_MODELVIEW20_ARB */
+ { 20745, 0x00008735 }, /* GL_MODELVIEW21_ARB */
+ { 20764, 0x00008736 }, /* GL_MODELVIEW22_ARB */
+ { 20783, 0x00008737 }, /* GL_MODELVIEW23_ARB */
+ { 20802, 0x00008738 }, /* GL_MODELVIEW24_ARB */
+ { 20821, 0x00008739 }, /* GL_MODELVIEW25_ARB */
+ { 20840, 0x0000873A }, /* GL_MODELVIEW26_ARB */
+ { 20859, 0x0000873B }, /* GL_MODELVIEW27_ARB */
+ { 20878, 0x0000873C }, /* GL_MODELVIEW28_ARB */
+ { 20897, 0x0000873D }, /* GL_MODELVIEW29_ARB */
+ { 20916, 0x00008722 }, /* GL_MODELVIEW2_ARB */
+ { 20934, 0x0000873E }, /* GL_MODELVIEW30_ARB */
+ { 20953, 0x0000873F }, /* GL_MODELVIEW31_ARB */
+ { 20972, 0x00008723 }, /* GL_MODELVIEW3_ARB */
+ { 20990, 0x00008724 }, /* GL_MODELVIEW4_ARB */
+ { 21008, 0x00008725 }, /* GL_MODELVIEW5_ARB */
+ { 21026, 0x00008726 }, /* GL_MODELVIEW6_ARB */
+ { 21044, 0x00008727 }, /* GL_MODELVIEW7_ARB */
+ { 21062, 0x00008728 }, /* GL_MODELVIEW8_ARB */
+ { 21080, 0x00008729 }, /* GL_MODELVIEW9_ARB */
+ { 21098, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
+ { 21118, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
+ { 21145, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
+ { 21170, 0x00002100 }, /* GL_MODULATE */
+ { 21182, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
+ { 21202, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
+ { 21229, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
+ { 21254, 0x00000103 }, /* GL_MULT */
+ { 21262, 0x0000809D }, /* GL_MULTISAMPLE */
+ { 21277, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
+ { 21297, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
+ { 21316, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
+ { 21335, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
+ { 21359, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
+ { 21382, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+ { 21412, 0x00002A25 }, /* GL_N3F_V3F */
+ { 21423, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
+ { 21443, 0x0000150E }, /* GL_NAND */
+ { 21451, 0x00002600 }, /* GL_NEAREST */
+ { 21462, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+ { 21493, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+ { 21525, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
+ { 21550, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
+ { 21576, 0x00000200 }, /* GL_NEVER */
+ { 21585, 0x00001102 }, /* GL_NICEST */
+ { 21595, 0x00000000 }, /* GL_NONE */
+ { 21603, 0x00001505 }, /* GL_NOOP */
+ { 21611, 0x00001508 }, /* GL_NOR */
+ { 21618, 0x00000BA1 }, /* GL_NORMALIZE */
+ { 21631, 0x00008075 }, /* GL_NORMAL_ARRAY */
+ { 21647, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ { 21678, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
+ { 21713, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
+ { 21737, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
+ { 21760, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
+ { 21781, 0x00008511 }, /* GL_NORMAL_MAP */
+ { 21795, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
+ { 21813, 0x00008511 }, /* GL_NORMAL_MAP_NV */
+ { 21830, 0x00000205 }, /* GL_NOTEQUAL */
+ { 21842, 0x00000000 }, /* GL_NO_ERROR */
+ { 21854, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+ { 21888, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
+ { 21926, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
+ { 21958, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
+ { 22000, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
+ { 22030, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
+ { 22070, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
+ { 22101, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
+ { 22130, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
+ { 22158, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
+ { 22188, 0x00002401 }, /* GL_OBJECT_LINEAR */
+ { 22205, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
+ { 22231, 0x00002501 }, /* GL_OBJECT_PLANE */
+ { 22247, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
+ { 22282, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
+ { 22304, 0x00009112 }, /* GL_OBJECT_TYPE */
+ { 22319, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
+ { 22338, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
+ { 22368, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
+ { 22389, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
+ { 22417, 0x00000001 }, /* GL_ONE */
+ { 22424, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ { 22452, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
+ { 22484, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ { 22512, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
+ { 22544, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
+ { 22567, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
+ { 22590, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
+ { 22613, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
+ { 22636, 0x00008598 }, /* GL_OPERAND0_ALPHA */
+ { 22654, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
+ { 22676, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
+ { 22698, 0x00008590 }, /* GL_OPERAND0_RGB */
+ { 22714, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
+ { 22734, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
+ { 22754, 0x00008599 }, /* GL_OPERAND1_ALPHA */
+ { 22772, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
+ { 22794, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
+ { 22816, 0x00008591 }, /* GL_OPERAND1_RGB */
+ { 22832, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
+ { 22852, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
+ { 22872, 0x0000859A }, /* GL_OPERAND2_ALPHA */
+ { 22890, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
+ { 22912, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
+ { 22934, 0x00008592 }, /* GL_OPERAND2_RGB */
+ { 22950, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
+ { 22970, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
+ { 22990, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
+ { 23011, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
+ { 23030, 0x00001507 }, /* GL_OR */
+ { 23036, 0x00000A01 }, /* GL_ORDER */
+ { 23045, 0x0000150D }, /* GL_OR_INVERTED */
+ { 23060, 0x0000150B }, /* GL_OR_REVERSE */
+ { 23074, 0x00000505 }, /* GL_OUT_OF_MEMORY */
+ { 23091, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
+ { 23109, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
+ { 23130, 0x00008758 }, /* GL_PACK_INVERT_MESA */
+ { 23150, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
+ { 23168, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
+ { 23187, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
+ { 23207, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
+ { 23227, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
+ { 23245, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
+ { 23264, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
+ { 23289, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
+ { 23313, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
+ { 23334, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
+ { 23356, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
+ { 23378, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
+ { 23403, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
+ { 23427, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
+ { 23448, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
+ { 23470, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
+ { 23492, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
+ { 23514, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
+ { 23545, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
+ { 23565, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+ { 23590, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
+ { 23610, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+ { 23635, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
+ { 23655, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+ { 23680, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
+ { 23700, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+ { 23725, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
+ { 23745, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+ { 23770, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
+ { 23790, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+ { 23815, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
+ { 23835, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+ { 23860, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
+ { 23880, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+ { 23905, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
+ { 23925, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+ { 23950, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
+ { 23970, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+ { 23995, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
+ { 24013, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
+ { 24034, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
+ { 24063, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
+ { 24096, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
+ { 24121, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
+ { 24144, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+ { 24175, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
+ { 24210, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
+ { 24237, 0x00001B00 }, /* GL_POINT */
+ { 24246, 0x00000000 }, /* GL_POINTS */
+ { 24256, 0x00000002 }, /* GL_POINT_BIT */
+ { 24269, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
+ { 24299, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
+ { 24333, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
+ { 24367, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
+ { 24402, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
+ { 24431, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
+ { 24464, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
+ { 24497, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
+ { 24531, 0x00000B11 }, /* GL_POINT_SIZE */
+ { 24545, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
+ { 24571, 0x00008127 }, /* GL_POINT_SIZE_MAX */
+ { 24589, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
+ { 24611, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
+ { 24633, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
+ { 24656, 0x00008126 }, /* GL_POINT_SIZE_MIN */
+ { 24674, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
+ { 24696, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
+ { 24718, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
+ { 24741, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
+ { 24761, 0x00000B10 }, /* GL_POINT_SMOOTH */
+ { 24777, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
+ { 24798, 0x00008861 }, /* GL_POINT_SPRITE */
+ { 24814, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
+ { 24834, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
+ { 24863, 0x00008861 }, /* GL_POINT_SPRITE_NV */
+ { 24882, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
+ { 24908, 0x00000701 }, /* GL_POINT_TOKEN */
+ { 24923, 0x00000009 }, /* GL_POLYGON */
+ { 24934, 0x00000008 }, /* GL_POLYGON_BIT */
+ { 24949, 0x00000B40 }, /* GL_POLYGON_MODE */
+ { 24965, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
+ { 24988, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
+ { 25013, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
+ { 25036, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
+ { 25059, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
+ { 25083, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
+ { 25107, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
+ { 25125, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
+ { 25148, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
+ { 25167, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
+ { 25190, 0x00000703 }, /* GL_POLYGON_TOKEN */
+ { 25207, 0x00001203 }, /* GL_POSITION */
+ { 25219, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+ { 25251, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
+ { 25287, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+ { 25320, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
+ { 25357, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+ { 25388, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
+ { 25423, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+ { 25455, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
+ { 25491, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 25524, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+ { 25556, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
+ { 25592, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+ { 25625, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
+ { 25662, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+ { 25692, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
+ { 25726, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+ { 25757, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
+ { 25792, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+ { 25823, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
+ { 25858, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+ { 25890, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
+ { 25926, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+ { 25956, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
+ { 25990, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+ { 26021, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
+ { 26056, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+ { 26088, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+ { 26119, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
+ { 26154, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+ { 26186, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
+ { 26222, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
+ { 26251, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
+ { 26284, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
+ { 26314, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
+ { 26348, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+ { 26387, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+ { 26420, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+ { 26460, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+ { 26494, 0x00008578 }, /* GL_PREVIOUS */
+ { 26506, 0x00008578 }, /* GL_PREVIOUS_ARB */
+ { 26522, 0x00008578 }, /* GL_PREVIOUS_EXT */
+ { 26538, 0x00008577 }, /* GL_PRIMARY_COLOR */
+ { 26555, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
+ { 26576, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
+ { 26597, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+ { 26630, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ { 26662, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
+ { 26685, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
+ { 26708, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
+ { 26738, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
+ { 26767, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
+ { 26795, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
+ { 26817, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+ { 26845, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+ { 26873, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
+ { 26895, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
+ { 26916, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ { 26956, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ { 26995, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+ { 27025, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ { 27060, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+ { 27093, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ { 27127, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ { 27166, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ { 27205, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
+ { 27227, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
+ { 27253, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
+ { 27277, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
+ { 27300, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
+ { 27322, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
+ { 27343, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
+ { 27364, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
+ { 27391, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+ { 27423, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ { 27455, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+ { 27490, 0x00001701 }, /* GL_PROJECTION */
+ { 27504, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
+ { 27525, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
+ { 27551, 0x00008E4F }, /* GL_PROVOKING_VERTEX */
+ { 27571, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
+ { 27595, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
+ { 27616, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
+ { 27635, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
+ { 27658, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+ { 27697, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+ { 27735, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
+ { 27755, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+ { 27785, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
+ { 27809, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
+ { 27829, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+ { 27859, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
+ { 27883, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
+ { 27903, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+ { 27936, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
+ { 27962, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
+ { 27992, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+ { 28023, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
+ { 28053, 0x00002003 }, /* GL_Q */
+ { 28058, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
+ { 28083, 0x00000007 }, /* GL_QUADS */
+ { 28092, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+ { 28136, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
+ { 28184, 0x00008614 }, /* GL_QUAD_MESH_SUN */
+ { 28201, 0x00000008 }, /* GL_QUAD_STRIP */
+ { 28215, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
+ { 28237, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
+ { 28263, 0x00008866 }, /* GL_QUERY_RESULT */
+ { 28279, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
+ { 28299, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
+ { 28325, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
+ { 28355, 0x00002002 }, /* GL_R */
+ { 28360, 0x00002A10 }, /* GL_R3_G3_B2 */
+ { 28372, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ { 28405, 0x00000C02 }, /* GL_READ_BUFFER */
+ { 28420, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
+ { 28440, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
+ { 28472, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
+ { 28496, 0x000088B8 }, /* GL_READ_ONLY */
+ { 28509, 0x000088B8 }, /* GL_READ_ONLY_ARB */
+ { 28526, 0x000088BA }, /* GL_READ_WRITE */
+ { 28540, 0x000088BA }, /* GL_READ_WRITE_ARB */
+ { 28558, 0x00001903 }, /* GL_RED */
+ { 28565, 0x00008016 }, /* GL_REDUCE */
+ { 28575, 0x00008016 }, /* GL_REDUCE_EXT */
+ { 28589, 0x00000D15 }, /* GL_RED_BIAS */
+ { 28601, 0x00000D52 }, /* GL_RED_BITS */
+ { 28613, 0x00000D14 }, /* GL_RED_SCALE */
+ { 28626, 0x00008512 }, /* GL_REFLECTION_MAP */
+ { 28644, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
+ { 28666, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
+ { 28687, 0x00001C00 }, /* GL_RENDER */
+ { 28697, 0x00008D41 }, /* GL_RENDERBUFFER */
+ { 28713, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
+ { 28740, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
+ { 28768, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
+ { 28794, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
+ { 28821, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
+ { 28841, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
+ { 28868, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
+ { 28891, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
+ { 28918, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+ { 28950, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
+ { 28986, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
+ { 29011, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
+ { 29035, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
+ { 29064, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
+ { 29086, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
+ { 29112, 0x00001F01 }, /* GL_RENDERER */
+ { 29124, 0x00000C40 }, /* GL_RENDER_MODE */
+ { 29139, 0x00002901 }, /* GL_REPEAT */
+ { 29149, 0x00001E01 }, /* GL_REPLACE */
+ { 29160, 0x00008062 }, /* GL_REPLACE_EXT */
+ { 29175, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
+ { 29198, 0x0000803A }, /* GL_RESCALE_NORMAL */
+ { 29216, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
+ { 29238, 0x00000102 }, /* GL_RETURN */
+ { 29248, 0x00001907 }, /* GL_RGB */
+ { 29255, 0x00008052 }, /* GL_RGB10 */
+ { 29264, 0x00008059 }, /* GL_RGB10_A2 */
+ { 29276, 0x00008059 }, /* GL_RGB10_A2_EXT */
+ { 29292, 0x00008052 }, /* GL_RGB10_EXT */
+ { 29305, 0x00008053 }, /* GL_RGB12 */
+ { 29314, 0x00008053 }, /* GL_RGB12_EXT */
+ { 29327, 0x00008054 }, /* GL_RGB16 */
+ { 29336, 0x00008054 }, /* GL_RGB16_EXT */
+ { 29349, 0x0000804E }, /* GL_RGB2_EXT */
+ { 29361, 0x0000804F }, /* GL_RGB4 */
+ { 29369, 0x0000804F }, /* GL_RGB4_EXT */
+ { 29381, 0x000083A1 }, /* GL_RGB4_S3TC */
+ { 29394, 0x00008050 }, /* GL_RGB5 */
+ { 29402, 0x00008057 }, /* GL_RGB5_A1 */
+ { 29413, 0x00008057 }, /* GL_RGB5_A1_EXT */
+ { 29428, 0x00008050 }, /* GL_RGB5_EXT */
+ { 29440, 0x00008051 }, /* GL_RGB8 */
+ { 29448, 0x00008051 }, /* GL_RGB8_EXT */
+ { 29460, 0x00001908 }, /* GL_RGBA */
+ { 29468, 0x0000805A }, /* GL_RGBA12 */
+ { 29478, 0x0000805A }, /* GL_RGBA12_EXT */
+ { 29492, 0x0000805B }, /* GL_RGBA16 */
+ { 29502, 0x0000805B }, /* GL_RGBA16_EXT */
+ { 29516, 0x00008055 }, /* GL_RGBA2 */
+ { 29525, 0x00008055 }, /* GL_RGBA2_EXT */
+ { 29538, 0x00008056 }, /* GL_RGBA4 */
+ { 29547, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
+ { 29566, 0x00008056 }, /* GL_RGBA4_EXT */
+ { 29579, 0x000083A3 }, /* GL_RGBA4_S3TC */
+ { 29593, 0x00008058 }, /* GL_RGBA8 */
+ { 29602, 0x00008058 }, /* GL_RGBA8_EXT */
+ { 29615, 0x00008F97 }, /* GL_RGBA8_SNORM */
+ { 29630, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
+ { 29648, 0x00000C31 }, /* GL_RGBA_MODE */
+ { 29661, 0x000083A2 }, /* GL_RGBA_S3TC */
+ { 29674, 0x00008F93 }, /* GL_RGBA_SNORM */
+ { 29688, 0x000083A0 }, /* GL_RGB_S3TC */
+ { 29700, 0x00008573 }, /* GL_RGB_SCALE */
+ { 29713, 0x00008573 }, /* GL_RGB_SCALE_ARB */
+ { 29730, 0x00008573 }, /* GL_RGB_SCALE_EXT */
+ { 29747, 0x00000407 }, /* GL_RIGHT */
+ { 29756, 0x00002000 }, /* GL_S */
+ { 29761, 0x00008B5D }, /* GL_SAMPLER_1D */
+ { 29775, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
+ { 29796, 0x00008B5E }, /* GL_SAMPLER_2D */
+ { 29810, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
+ { 29831, 0x00008B5F }, /* GL_SAMPLER_3D */
+ { 29845, 0x00008B60 }, /* GL_SAMPLER_CUBE */
+ { 29861, 0x000080A9 }, /* GL_SAMPLES */
+ { 29872, 0x000086B4 }, /* GL_SAMPLES_3DFX */
+ { 29888, 0x000080A9 }, /* GL_SAMPLES_ARB */
+ { 29903, 0x00008914 }, /* GL_SAMPLES_PASSED */
+ { 29921, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
+ { 29943, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+ { 29971, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
+ { 30003, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
+ { 30026, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
+ { 30053, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
+ { 30071, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
+ { 30094, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
+ { 30116, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
+ { 30135, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
+ { 30158, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
+ { 30184, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
+ { 30214, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
+ { 30239, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
+ { 30268, 0x00080000 }, /* GL_SCISSOR_BIT */
+ { 30283, 0x00000C10 }, /* GL_SCISSOR_BOX */
+ { 30298, 0x00000C11 }, /* GL_SCISSOR_TEST */
+ { 30314, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
+ { 30339, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+ { 30379, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
+ { 30423, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+ { 30456, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+ { 30486, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+ { 30518, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+ { 30548, 0x00001C02 }, /* GL_SELECT */
+ { 30558, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
+ { 30586, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
+ { 30611, 0x00008012 }, /* GL_SEPARABLE_2D */
+ { 30627, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
+ { 30654, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
+ { 30685, 0x0000150F }, /* GL_SET */
+ { 30692, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
+ { 30713, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
+ { 30737, 0x00008B4F }, /* GL_SHADER_TYPE */
+ { 30752, 0x00000B54 }, /* GL_SHADE_MODEL */
+ { 30767, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
+ { 30795, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
+ { 30818, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+ { 30848, 0x00001601 }, /* GL_SHININESS */
+ { 30861, 0x00001402 }, /* GL_SHORT */
+ { 30870, 0x00009119 }, /* GL_SIGNALED */
+ { 30882, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
+ { 30903, 0x000081F9 }, /* GL_SINGLE_COLOR */
+ { 30919, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
+ { 30939, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
+ { 30958, 0x00008C46 }, /* GL_SLUMINANCE */
+ { 30972, 0x00008C47 }, /* GL_SLUMINANCE8 */
+ { 30987, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
+ { 31009, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
+ { 31029, 0x00001D01 }, /* GL_SMOOTH */
+ { 31039, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
+ { 31072, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
+ { 31099, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
+ { 31132, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
+ { 31159, 0x00008588 }, /* GL_SOURCE0_ALPHA */
+ { 31176, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
+ { 31197, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
+ { 31218, 0x00008580 }, /* GL_SOURCE0_RGB */
+ { 31233, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
+ { 31252, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
+ { 31271, 0x00008589 }, /* GL_SOURCE1_ALPHA */
+ { 31288, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
+ { 31309, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
+ { 31330, 0x00008581 }, /* GL_SOURCE1_RGB */
+ { 31345, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
+ { 31364, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
+ { 31383, 0x0000858A }, /* GL_SOURCE2_ALPHA */
+ { 31400, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
+ { 31421, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
+ { 31442, 0x00008582 }, /* GL_SOURCE2_RGB */
+ { 31457, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
+ { 31476, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
+ { 31495, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
+ { 31515, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
+ { 31533, 0x00001202 }, /* GL_SPECULAR */
+ { 31545, 0x00002402 }, /* GL_SPHERE_MAP */
+ { 31559, 0x00001206 }, /* GL_SPOT_CUTOFF */
+ { 31574, 0x00001204 }, /* GL_SPOT_DIRECTION */
+ { 31592, 0x00001205 }, /* GL_SPOT_EXPONENT */
+ { 31609, 0x00008588 }, /* GL_SRC0_ALPHA */
+ { 31623, 0x00008580 }, /* GL_SRC0_RGB */
+ { 31635, 0x00008589 }, /* GL_SRC1_ALPHA */
+ { 31649, 0x00008581 }, /* GL_SRC1_RGB */
+ { 31661, 0x0000858A }, /* GL_SRC2_ALPHA */
+ { 31675, 0x00008582 }, /* GL_SRC2_RGB */
+ { 31687, 0x00000302 }, /* GL_SRC_ALPHA */
+ { 31700, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
+ { 31722, 0x00000300 }, /* GL_SRC_COLOR */
+ { 31735, 0x00008C40 }, /* GL_SRGB */
+ { 31743, 0x00008C41 }, /* GL_SRGB8 */
+ { 31752, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
+ { 31768, 0x00008C42 }, /* GL_SRGB_ALPHA */
+ { 31782, 0x00000503 }, /* GL_STACK_OVERFLOW */
+ { 31800, 0x00000504 }, /* GL_STACK_UNDERFLOW */
+ { 31819, 0x000088E6 }, /* GL_STATIC_COPY */
+ { 31834, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
+ { 31853, 0x000088E4 }, /* GL_STATIC_DRAW */
+ { 31868, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
+ { 31887, 0x000088E5 }, /* GL_STATIC_READ */
+ { 31902, 0x000088E5 }, /* GL_STATIC_READ_ARB */
+ { 31921, 0x00001802 }, /* GL_STENCIL */
+ { 31932, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
+ { 31954, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
+ { 31980, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
+ { 32001, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
+ { 32026, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
+ { 32047, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
+ { 32072, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+ { 32104, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
+ { 32140, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+ { 32172, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
+ { 32208, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
+ { 32228, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
+ { 32255, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
+ { 32281, 0x00000D57 }, /* GL_STENCIL_BITS */
+ { 32297, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
+ { 32319, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
+ { 32342, 0x00000B94 }, /* GL_STENCIL_FAIL */
+ { 32358, 0x00000B92 }, /* GL_STENCIL_FUNC */
+ { 32374, 0x00001901 }, /* GL_STENCIL_INDEX */
+ { 32391, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
+ { 32414, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
+ { 32436, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
+ { 32458, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
+ { 32480, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
+ { 32501, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
+ { 32528, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
+ { 32555, 0x00000B97 }, /* GL_STENCIL_REF */
+ { 32570, 0x00000B90 }, /* GL_STENCIL_TEST */
+ { 32586, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ { 32615, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
+ { 32637, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
+ { 32658, 0x00000C33 }, /* GL_STEREO */
+ { 32668, 0x000085BE }, /* GL_STORAGE_CACHED_APPLE */
+ { 32692, 0x000085BD }, /* GL_STORAGE_PRIVATE_APPLE */
+ { 32717, 0x000085BF }, /* GL_STORAGE_SHARED_APPLE */
+ { 32741, 0x000088E2 }, /* GL_STREAM_COPY */
+ { 32756, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
+ { 32775, 0x000088E0 }, /* GL_STREAM_DRAW */
+ { 32790, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
+ { 32809, 0x000088E1 }, /* GL_STREAM_READ */
+ { 32824, 0x000088E1 }, /* GL_STREAM_READ_ARB */
+ { 32843, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
+ { 32860, 0x000084E7 }, /* GL_SUBTRACT */
+ { 32872, 0x000084E7 }, /* GL_SUBTRACT_ARB */
+ { 32888, 0x00009113 }, /* GL_SYNC_CONDITION */
+ { 32906, 0x00009116 }, /* GL_SYNC_FENCE */
+ { 32920, 0x00009115 }, /* GL_SYNC_FLAGS */
+ { 32934, 0x00000001 }, /* GL_SYNC_FLUSH_COMMANDS_BIT */
+ { 32961, 0x00009117 }, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+ { 32991, 0x00009114 }, /* GL_SYNC_STATUS */
+ { 33006, 0x00002001 }, /* GL_T */
+ { 33011, 0x00002A2A }, /* GL_T2F_C3F_V3F */
+ { 33026, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
+ { 33045, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
+ { 33061, 0x00002A2B }, /* GL_T2F_N3F_V3F */
+ { 33076, 0x00002A27 }, /* GL_T2F_V3F */
+ { 33087, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
+ { 33106, 0x00002A28 }, /* GL_T4F_V4F */
+ { 33117, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
+ { 33140, 0x00001702 }, /* GL_TEXTURE */
+ { 33151, 0x000084C0 }, /* GL_TEXTURE0 */
+ { 33163, 0x000084C0 }, /* GL_TEXTURE0_ARB */
+ { 33179, 0x000084C1 }, /* GL_TEXTURE1 */
+ { 33191, 0x000084CA }, /* GL_TEXTURE10 */
+ { 33204, 0x000084CA }, /* GL_TEXTURE10_ARB */
+ { 33221, 0x000084CB }, /* GL_TEXTURE11 */
+ { 33234, 0x000084CB }, /* GL_TEXTURE11_ARB */
+ { 33251, 0x000084CC }, /* GL_TEXTURE12 */
+ { 33264, 0x000084CC }, /* GL_TEXTURE12_ARB */
+ { 33281, 0x000084CD }, /* GL_TEXTURE13 */
+ { 33294, 0x000084CD }, /* GL_TEXTURE13_ARB */
+ { 33311, 0x000084CE }, /* GL_TEXTURE14 */
+ { 33324, 0x000084CE }, /* GL_TEXTURE14_ARB */
+ { 33341, 0x000084CF }, /* GL_TEXTURE15 */
+ { 33354, 0x000084CF }, /* GL_TEXTURE15_ARB */
+ { 33371, 0x000084D0 }, /* GL_TEXTURE16 */
+ { 33384, 0x000084D0 }, /* GL_TEXTURE16_ARB */
+ { 33401, 0x000084D1 }, /* GL_TEXTURE17 */
+ { 33414, 0x000084D1 }, /* GL_TEXTURE17_ARB */
+ { 33431, 0x000084D2 }, /* GL_TEXTURE18 */
+ { 33444, 0x000084D2 }, /* GL_TEXTURE18_ARB */
+ { 33461, 0x000084D3 }, /* GL_TEXTURE19 */
+ { 33474, 0x000084D3 }, /* GL_TEXTURE19_ARB */
+ { 33491, 0x000084C1 }, /* GL_TEXTURE1_ARB */
+ { 33507, 0x000084C2 }, /* GL_TEXTURE2 */
+ { 33519, 0x000084D4 }, /* GL_TEXTURE20 */
+ { 33532, 0x000084D4 }, /* GL_TEXTURE20_ARB */
+ { 33549, 0x000084D5 }, /* GL_TEXTURE21 */
+ { 33562, 0x000084D5 }, /* GL_TEXTURE21_ARB */
+ { 33579, 0x000084D6 }, /* GL_TEXTURE22 */
+ { 33592, 0x000084D6 }, /* GL_TEXTURE22_ARB */
+ { 33609, 0x000084D7 }, /* GL_TEXTURE23 */
+ { 33622, 0x000084D7 }, /* GL_TEXTURE23_ARB */
+ { 33639, 0x000084D8 }, /* GL_TEXTURE24 */
+ { 33652, 0x000084D8 }, /* GL_TEXTURE24_ARB */
+ { 33669, 0x000084D9 }, /* GL_TEXTURE25 */
+ { 33682, 0x000084D9 }, /* GL_TEXTURE25_ARB */
+ { 33699, 0x000084DA }, /* GL_TEXTURE26 */
+ { 33712, 0x000084DA }, /* GL_TEXTURE26_ARB */
+ { 33729, 0x000084DB }, /* GL_TEXTURE27 */
+ { 33742, 0x000084DB }, /* GL_TEXTURE27_ARB */
+ { 33759, 0x000084DC }, /* GL_TEXTURE28 */
+ { 33772, 0x000084DC }, /* GL_TEXTURE28_ARB */
+ { 33789, 0x000084DD }, /* GL_TEXTURE29 */
+ { 33802, 0x000084DD }, /* GL_TEXTURE29_ARB */
+ { 33819, 0x000084C2 }, /* GL_TEXTURE2_ARB */
+ { 33835, 0x000084C3 }, /* GL_TEXTURE3 */
+ { 33847, 0x000084DE }, /* GL_TEXTURE30 */
+ { 33860, 0x000084DE }, /* GL_TEXTURE30_ARB */
+ { 33877, 0x000084DF }, /* GL_TEXTURE31 */
+ { 33890, 0x000084DF }, /* GL_TEXTURE31_ARB */
+ { 33907, 0x000084C3 }, /* GL_TEXTURE3_ARB */
+ { 33923, 0x000084C4 }, /* GL_TEXTURE4 */
+ { 33935, 0x000084C4 }, /* GL_TEXTURE4_ARB */
+ { 33951, 0x000084C5 }, /* GL_TEXTURE5 */
+ { 33963, 0x000084C5 }, /* GL_TEXTURE5_ARB */
+ { 33979, 0x000084C6 }, /* GL_TEXTURE6 */
+ { 33991, 0x000084C6 }, /* GL_TEXTURE6_ARB */
+ { 34007, 0x000084C7 }, /* GL_TEXTURE7 */
+ { 34019, 0x000084C7 }, /* GL_TEXTURE7_ARB */
+ { 34035, 0x000084C8 }, /* GL_TEXTURE8 */
+ { 34047, 0x000084C8 }, /* GL_TEXTURE8_ARB */
+ { 34063, 0x000084C9 }, /* GL_TEXTURE9 */
+ { 34075, 0x000084C9 }, /* GL_TEXTURE9_ARB */
+ { 34091, 0x00000DE0 }, /* GL_TEXTURE_1D */
+ { 34105, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
+ { 34129, 0x00000DE1 }, /* GL_TEXTURE_2D */
+ { 34143, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
+ { 34167, 0x0000806F }, /* GL_TEXTURE_3D */
+ { 34181, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
+ { 34203, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
+ { 34229, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
+ { 34251, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
+ { 34273, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+ { 34305, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
+ { 34327, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+ { 34359, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
+ { 34381, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
+ { 34409, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
+ { 34441, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+ { 34474, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
+ { 34506, 0x00040000 }, /* GL_TEXTURE_BIT */
+ { 34521, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
+ { 34542, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
+ { 34567, 0x00001005 }, /* GL_TEXTURE_BORDER */
+ { 34585, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
+ { 34609, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+ { 34640, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+ { 34670, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+ { 34700, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+ { 34735, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+ { 34766, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ { 34804, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
+ { 34831, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+ { 34863, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ { 34897, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
+ { 34921, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
+ { 34949, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
+ { 34973, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
+ { 35001, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+ { 35034, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
+ { 35058, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
+ { 35080, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
+ { 35102, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
+ { 35128, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
+ { 35162, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+ { 35195, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
+ { 35232, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
+ { 35260, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
+ { 35292, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
+ { 35315, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ { 35353, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
+ { 35395, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ { 35426, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+ { 35454, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+ { 35484, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+ { 35512, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
+ { 35532, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
+ { 35556, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+ { 35587, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
+ { 35622, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+ { 35653, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
+ { 35688, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+ { 35719, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
+ { 35754, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+ { 35785, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
+ { 35820, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+ { 35851, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
+ { 35886, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+ { 35917, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
+ { 35952, 0x000088F4 }, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+ { 35981, 0x00008071 }, /* GL_TEXTURE_DEPTH */
+ { 35998, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
+ { 36020, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
+ { 36046, 0x00002300 }, /* GL_TEXTURE_ENV */
+ { 36061, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
+ { 36082, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
+ { 36102, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
+ { 36128, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
+ { 36148, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
+ { 36165, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
+ { 36182, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
+ { 36199, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
+ { 36216, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
+ { 36241, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
+ { 36263, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
+ { 36289, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
+ { 36307, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ { 36333, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
+ { 36359, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
+ { 36389, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
+ { 36416, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
+ { 36441, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
+ { 36461, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
+ { 36485, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+ { 36512, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+ { 36539, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+ { 36566, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
+ { 36592, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
+ { 36622, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
+ { 36644, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
+ { 36662, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+ { 36692, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+ { 36720, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+ { 36748, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+ { 36776, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
+ { 36797, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
+ { 36816, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
+ { 36838, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
+ { 36857, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
+ { 36877, 0x000085B7 }, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+ { 36907, 0x000085B8 }, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+ { 36938, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
+ { 36963, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
+ { 36987, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
+ { 37007, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
+ { 37031, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
+ { 37051, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
+ { 37074, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
+ { 37098, 0x000085BC }, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+ { 37128, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
+ { 37153, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+ { 37187, 0x00001000 }, /* GL_TEXTURE_WIDTH */
+ { 37204, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
+ { 37222, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
+ { 37240, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
+ { 37258, 0x0000911B }, /* GL_TIMEOUT_EXPIRED */
+ { 37277, 0xFFFFFFFFFFFFFFFF }, /* GL_TIMEOUT_IGNORED */
+ { 37296, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
+ { 37316, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
+ { 37335, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+ { 37364, 0x00001000 }, /* GL_TRANSFORM_BIT */
+ { 37381, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
+ { 37407, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
+ { 37437, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+ { 37469, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+ { 37499, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
+ { 37533, 0x0000862C }, /* GL_TRANSPOSE_NV */
+ { 37549, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+ { 37580, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
+ { 37615, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+ { 37643, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
+ { 37675, 0x00000004 }, /* GL_TRIANGLES */
+ { 37688, 0x00000006 }, /* GL_TRIANGLE_FAN */
+ { 37704, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
+ { 37725, 0x00000005 }, /* GL_TRIANGLE_STRIP */
+ { 37743, 0x00000001 }, /* GL_TRUE */
+ { 37751, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
+ { 37771, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
+ { 37794, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
+ { 37814, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
+ { 37835, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
+ { 37857, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
+ { 37879, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
+ { 37899, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
+ { 37920, 0x00009118 }, /* GL_UNSIGNALED */
+ { 37934, 0x00001401 }, /* GL_UNSIGNED_BYTE */
+ { 37951, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+ { 37978, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
+ { 38001, 0x00001405 }, /* GL_UNSIGNED_INT */
+ { 38017, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
+ { 38044, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
+ { 38065, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
+ { 38089, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+ { 38120, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
+ { 38144, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+ { 38172, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
+ { 38195, 0x00001403 }, /* GL_UNSIGNED_SHORT */
+ { 38213, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+ { 38243, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+ { 38269, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+ { 38299, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+ { 38325, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
+ { 38349, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+ { 38377, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+ { 38405, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
+ { 38432, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+ { 38464, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
+ { 38495, 0x00008CA2 }, /* GL_UPPER_LEFT */
+ { 38509, 0x00002A20 }, /* GL_V2F */
+ { 38516, 0x00002A21 }, /* GL_V3F */
+ { 38523, 0x00008B83 }, /* GL_VALIDATE_STATUS */
+ { 38542, 0x00001F00 }, /* GL_VENDOR */
+ { 38552, 0x00001F02 }, /* GL_VERSION */
+ { 38563, 0x00008074 }, /* GL_VERTEX_ARRAY */
+ { 38579, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
+ { 38603, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
+ { 38633, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ { 38664, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
+ { 38699, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
+ { 38723, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
+ { 38744, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
+ { 38767, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
+ { 38788, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+ { 38815, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+ { 38843, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+ { 38871, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+ { 38899, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+ { 38927, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+ { 38955, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+ { 38983, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+ { 39010, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+ { 39037, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+ { 39064, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+ { 39091, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+ { 39118, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+ { 39145, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+ { 39172, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+ { 39199, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+ { 39226, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+ { 39264, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
+ { 39306, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+ { 39337, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
+ { 39372, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+ { 39406, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
+ { 39444, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+ { 39475, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
+ { 39510, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+ { 39538, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
+ { 39570, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+ { 39600, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
+ { 39634, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+ { 39662, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
+ { 39694, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
+ { 39714, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
+ { 39736, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
+ { 39765, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
+ { 39786, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+ { 39815, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
+ { 39848, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
+ { 39880, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+ { 39907, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
+ { 39938, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
+ { 39968, 0x00008B31 }, /* GL_VERTEX_SHADER */
+ { 39985, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
+ { 40006, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
+ { 40033, 0x00000BA2 }, /* GL_VIEWPORT */
+ { 40045, 0x00000800 }, /* GL_VIEWPORT_BIT */
+ { 40061, 0x0000911D }, /* GL_WAIT_FAILED */
+ { 40076, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
+ { 40096, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+ { 40127, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
+ { 40162, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+ { 40190, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+ { 40215, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+ { 40242, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+ { 40267, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
+ { 40291, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
+ { 40310, 0x000088B9 }, /* GL_WRITE_ONLY */
+ { 40324, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
+ { 40342, 0x00001506 }, /* GL_XOR */
+ { 40349, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
+ { 40368, 0x00008757 }, /* GL_YCBCR_MESA */
+ { 40382, 0x00000000 }, /* GL_ZERO */
+ { 40390, 0x00000D16 }, /* GL_ZOOM_X */
+ { 40400, 0x00000D17 }, /* GL_ZOOM_Y */
};
static const unsigned reduced_enums[1347] =
{
476, /* GL_FALSE */
- 692, /* GL_LINES */
- 694, /* GL_LINE_LOOP */
- 701, /* GL_LINE_STRIP */
- 1744, /* GL_TRIANGLES */
- 1747, /* GL_TRIANGLE_STRIP */
- 1745, /* GL_TRIANGLE_FAN */
- 1272, /* GL_QUADS */
- 1275, /* GL_QUAD_STRIP */
- 1159, /* GL_POLYGON */
- 1171, /* GL_POLYGON_STIPPLE_BIT */
- 1120, /* GL_PIXEL_MODE_BIT */
- 679, /* GL_LIGHTING_BIT */
- 505, /* GL_FOG_BIT */
+ 694, /* GL_LINES */
+ 696, /* GL_LINE_LOOP */
+ 703, /* GL_LINE_STRIP */
+ 1748, /* GL_TRIANGLES */
+ 1751, /* GL_TRIANGLE_STRIP */
+ 1749, /* GL_TRIANGLE_FAN */
+ 1275, /* GL_QUADS */
+ 1279, /* GL_QUAD_STRIP */
+ 1161, /* GL_POLYGON */
+ 1173, /* GL_POLYGON_STIPPLE_BIT */
+ 1122, /* GL_PIXEL_MODE_BIT */
+ 681, /* GL_LIGHTING_BIT */
+ 506, /* GL_FOG_BIT */
8, /* GL_ACCUM */
- 711, /* GL_LOAD */
- 1327, /* GL_RETURN */
- 992, /* GL_MULT */
+ 713, /* GL_LOAD */
+ 1331, /* GL_RETURN */
+ 994, /* GL_MULT */
23, /* GL_ADD */
- 1008, /* GL_NEVER */
- 669, /* GL_LESS */
+ 1010, /* GL_NEVER */
+ 671, /* GL_LESS */
466, /* GL_EQUAL */
- 668, /* GL_LEQUAL */
- 591, /* GL_GREATER */
- 1023, /* GL_NOTEQUAL */
- 590, /* GL_GEQUAL */
+ 670, /* GL_LEQUAL */
+ 592, /* GL_GREATER */
+ 1025, /* GL_NOTEQUAL */
+ 591, /* GL_GEQUAL */
47, /* GL_ALWAYS */
- 1468, /* GL_SRC_COLOR */
- 1053, /* GL_ONE_MINUS_SRC_COLOR */
- 1466, /* GL_SRC_ALPHA */
- 1052, /* GL_ONE_MINUS_SRC_ALPHA */
+ 1472, /* GL_SRC_COLOR */
+ 1055, /* GL_ONE_MINUS_SRC_COLOR */
+ 1470, /* GL_SRC_ALPHA */
+ 1054, /* GL_ONE_MINUS_SRC_ALPHA */
445, /* GL_DST_ALPHA */
- 1050, /* GL_ONE_MINUS_DST_ALPHA */
+ 1052, /* GL_ONE_MINUS_DST_ALPHA */
446, /* GL_DST_COLOR */
- 1051, /* GL_ONE_MINUS_DST_COLOR */
- 1467, /* GL_SRC_ALPHA_SATURATE */
- 578, /* GL_FRONT_LEFT */
- 579, /* GL_FRONT_RIGHT */
+ 1053, /* GL_ONE_MINUS_DST_COLOR */
+ 1471, /* GL_SRC_ALPHA_SATURATE */
+ 579, /* GL_FRONT_LEFT */
+ 580, /* GL_FRONT_RIGHT */
69, /* GL_BACK_LEFT */
70, /* GL_BACK_RIGHT */
- 575, /* GL_FRONT */
+ 576, /* GL_FRONT */
68, /* GL_BACK */
- 667, /* GL_LEFT */
- 1369, /* GL_RIGHT */
- 576, /* GL_FRONT_AND_BACK */
+ 669, /* GL_LEFT */
+ 1373, /* GL_RIGHT */
+ 577, /* GL_FRONT_AND_BACK */
63, /* GL_AUX0 */
64, /* GL_AUX1 */
65, /* GL_AUX2 */
66, /* GL_AUX3 */
- 657, /* GL_INVALID_ENUM */
- 661, /* GL_INVALID_VALUE */
- 660, /* GL_INVALID_OPERATION */
- 1473, /* GL_STACK_OVERFLOW */
- 1474, /* GL_STACK_UNDERFLOW */
- 1078, /* GL_OUT_OF_MEMORY */
- 658, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+ 658, /* GL_INVALID_ENUM */
+ 662, /* GL_INVALID_VALUE */
+ 661, /* GL_INVALID_OPERATION */
+ 1477, /* GL_STACK_OVERFLOW */
+ 1478, /* GL_STACK_UNDERFLOW */
+ 1080, /* GL_OUT_OF_MEMORY */
+ 659, /* GL_INVALID_FRAMEBUFFER_OPERATION */
0, /* GL_2D */
2, /* GL_3D */
3, /* GL_3D_COLOR */
4, /* GL_3D_COLOR_TEXTURE */
6, /* GL_4D_COLOR_TEXTURE */
- 1098, /* GL_PASS_THROUGH_TOKEN */
- 1158, /* GL_POINT_TOKEN */
- 702, /* GL_LINE_TOKEN */
- 1172, /* GL_POLYGON_TOKEN */
+ 1100, /* GL_PASS_THROUGH_TOKEN */
+ 1160, /* GL_POINT_TOKEN */
+ 704, /* GL_LINE_TOKEN */
+ 1174, /* GL_POLYGON_TOKEN */
74, /* GL_BITMAP_TOKEN */
444, /* GL_DRAW_PIXEL_TOKEN */
301, /* GL_COPY_PIXEL_TOKEN */
- 695, /* GL_LINE_RESET_TOKEN */
+ 697, /* GL_LINE_RESET_TOKEN */
469, /* GL_EXP */
470, /* GL_EXP2 */
337, /* GL_CW */
125, /* GL_CCW */
146, /* GL_COEFF */
- 1075, /* GL_ORDER */
+ 1077, /* GL_ORDER */
382, /* GL_DOMAIN */
311, /* GL_CURRENT_COLOR */
314, /* GL_CURRENT_INDEX */
@@ -3846,67 +3854,67 @@ static const unsigned reduced_enums[1347] =
328, /* GL_CURRENT_RASTER_POSITION */
329, /* GL_CURRENT_RASTER_POSITION_VALID */
326, /* GL_CURRENT_RASTER_DISTANCE */
- 1151, /* GL_POINT_SMOOTH */
- 1140, /* GL_POINT_SIZE */
- 1150, /* GL_POINT_SIZE_RANGE */
- 1141, /* GL_POINT_SIZE_GRANULARITY */
- 696, /* GL_LINE_SMOOTH */
- 703, /* GL_LINE_WIDTH */
- 705, /* GL_LINE_WIDTH_RANGE */
- 704, /* GL_LINE_WIDTH_GRANULARITY */
- 698, /* GL_LINE_STIPPLE */
- 699, /* GL_LINE_STIPPLE_PATTERN */
- 700, /* GL_LINE_STIPPLE_REPEAT */
- 710, /* GL_LIST_MODE */
- 875, /* GL_MAX_LIST_NESTING */
- 707, /* GL_LIST_BASE */
- 709, /* GL_LIST_INDEX */
- 1161, /* GL_POLYGON_MODE */
- 1168, /* GL_POLYGON_SMOOTH */
- 1170, /* GL_POLYGON_STIPPLE */
+ 1153, /* GL_POINT_SMOOTH */
+ 1142, /* GL_POINT_SIZE */
+ 1152, /* GL_POINT_SIZE_RANGE */
+ 1143, /* GL_POINT_SIZE_GRANULARITY */
+ 698, /* GL_LINE_SMOOTH */
+ 705, /* GL_LINE_WIDTH */
+ 707, /* GL_LINE_WIDTH_RANGE */
+ 706, /* GL_LINE_WIDTH_GRANULARITY */
+ 700, /* GL_LINE_STIPPLE */
+ 701, /* GL_LINE_STIPPLE_PATTERN */
+ 702, /* GL_LINE_STIPPLE_REPEAT */
+ 712, /* GL_LIST_MODE */
+ 877, /* GL_MAX_LIST_NESTING */
+ 709, /* GL_LIST_BASE */
+ 711, /* GL_LIST_INDEX */
+ 1163, /* GL_POLYGON_MODE */
+ 1170, /* GL_POLYGON_SMOOTH */
+ 1172, /* GL_POLYGON_STIPPLE */
455, /* GL_EDGE_FLAG */
304, /* GL_CULL_FACE */
305, /* GL_CULL_FACE_MODE */
- 577, /* GL_FRONT_FACE */
- 678, /* GL_LIGHTING */
- 683, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
- 684, /* GL_LIGHT_MODEL_TWO_SIDE */
- 680, /* GL_LIGHT_MODEL_AMBIENT */
- 1415, /* GL_SHADE_MODEL */
+ 578, /* GL_FRONT_FACE */
+ 680, /* GL_LIGHTING */
+ 685, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
+ 686, /* GL_LIGHT_MODEL_TWO_SIDE */
+ 682, /* GL_LIGHT_MODEL_AMBIENT */
+ 1419, /* GL_SHADE_MODEL */
193, /* GL_COLOR_MATERIAL_FACE */
194, /* GL_COLOR_MATERIAL_PARAMETER */
192, /* GL_COLOR_MATERIAL */
- 504, /* GL_FOG */
- 526, /* GL_FOG_INDEX */
- 522, /* GL_FOG_DENSITY */
- 530, /* GL_FOG_START */
- 524, /* GL_FOG_END */
- 527, /* GL_FOG_MODE */
- 506, /* GL_FOG_COLOR */
+ 505, /* GL_FOG */
+ 527, /* GL_FOG_INDEX */
+ 523, /* GL_FOG_DENSITY */
+ 531, /* GL_FOG_START */
+ 525, /* GL_FOG_END */
+ 528, /* GL_FOG_MODE */
+ 507, /* GL_FOG_COLOR */
369, /* GL_DEPTH_RANGE */
376, /* GL_DEPTH_TEST */
379, /* GL_DEPTH_WRITEMASK */
357, /* GL_DEPTH_CLEAR_VALUE */
368, /* GL_DEPTH_FUNC */
12, /* GL_ACCUM_CLEAR_VALUE */
- 1509, /* GL_STENCIL_TEST */
- 1497, /* GL_STENCIL_CLEAR_VALUE */
- 1499, /* GL_STENCIL_FUNC */
- 1511, /* GL_STENCIL_VALUE_MASK */
- 1498, /* GL_STENCIL_FAIL */
- 1506, /* GL_STENCIL_PASS_DEPTH_FAIL */
- 1507, /* GL_STENCIL_PASS_DEPTH_PASS */
- 1508, /* GL_STENCIL_REF */
- 1512, /* GL_STENCIL_WRITEMASK */
- 844, /* GL_MATRIX_MODE */
- 1013, /* GL_NORMALIZE */
- 1838, /* GL_VIEWPORT */
- 987, /* GL_MODELVIEW_STACK_DEPTH */
- 1251, /* GL_PROJECTION_STACK_DEPTH */
- 1719, /* GL_TEXTURE_STACK_DEPTH */
- 985, /* GL_MODELVIEW_MATRIX */
- 1250, /* GL_PROJECTION_MATRIX */
- 1702, /* GL_TEXTURE_MATRIX */
+ 1513, /* GL_STENCIL_TEST */
+ 1501, /* GL_STENCIL_CLEAR_VALUE */
+ 1503, /* GL_STENCIL_FUNC */
+ 1515, /* GL_STENCIL_VALUE_MASK */
+ 1502, /* GL_STENCIL_FAIL */
+ 1510, /* GL_STENCIL_PASS_DEPTH_FAIL */
+ 1511, /* GL_STENCIL_PASS_DEPTH_PASS */
+ 1512, /* GL_STENCIL_REF */
+ 1516, /* GL_STENCIL_WRITEMASK */
+ 846, /* GL_MATRIX_MODE */
+ 1015, /* GL_NORMALIZE */
+ 1842, /* GL_VIEWPORT */
+ 989, /* GL_MODELVIEW_STACK_DEPTH */
+ 1253, /* GL_PROJECTION_STACK_DEPTH */
+ 1723, /* GL_TEXTURE_STACK_DEPTH */
+ 987, /* GL_MODELVIEW_MATRIX */
+ 1252, /* GL_PROJECTION_MATRIX */
+ 1706, /* GL_TEXTURE_MATRIX */
61, /* GL_ATTRIB_STACK_DEPTH */
136, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
43, /* GL_ALPHA_TEST */
@@ -3916,162 +3924,162 @@ static const unsigned reduced_enums[1347] =
78, /* GL_BLEND_DST */
87, /* GL_BLEND_SRC */
75, /* GL_BLEND */
- 713, /* GL_LOGIC_OP_MODE */
- 631, /* GL_INDEX_LOGIC_OP */
+ 715, /* GL_LOGIC_OP_MODE */
+ 632, /* GL_INDEX_LOGIC_OP */
191, /* GL_COLOR_LOGIC_OP */
67, /* GL_AUX_BUFFERS */
392, /* GL_DRAW_BUFFER */
- 1285, /* GL_READ_BUFFER */
- 1396, /* GL_SCISSOR_BOX */
- 1397, /* GL_SCISSOR_TEST */
- 630, /* GL_INDEX_CLEAR_VALUE */
- 635, /* GL_INDEX_WRITEMASK */
+ 1289, /* GL_READ_BUFFER */
+ 1400, /* GL_SCISSOR_BOX */
+ 1401, /* GL_SCISSOR_TEST */
+ 631, /* GL_INDEX_CLEAR_VALUE */
+ 636, /* GL_INDEX_WRITEMASK */
188, /* GL_COLOR_CLEAR_VALUE */
230, /* GL_COLOR_WRITEMASK */
- 632, /* GL_INDEX_MODE */
- 1362, /* GL_RGBA_MODE */
+ 633, /* GL_INDEX_MODE */
+ 1366, /* GL_RGBA_MODE */
391, /* GL_DOUBLEBUFFER */
- 1513, /* GL_STEREO */
- 1320, /* GL_RENDER_MODE */
- 1099, /* GL_PERSPECTIVE_CORRECTION_HINT */
- 1152, /* GL_POINT_SMOOTH_HINT */
- 697, /* GL_LINE_SMOOTH_HINT */
- 1169, /* GL_POLYGON_SMOOTH_HINT */
- 525, /* GL_FOG_HINT */
- 1683, /* GL_TEXTURE_GEN_S */
- 1684, /* GL_TEXTURE_GEN_T */
- 1682, /* GL_TEXTURE_GEN_R */
- 1681, /* GL_TEXTURE_GEN_Q */
- 1112, /* GL_PIXEL_MAP_I_TO_I */
- 1118, /* GL_PIXEL_MAP_S_TO_S */
- 1114, /* GL_PIXEL_MAP_I_TO_R */
- 1110, /* GL_PIXEL_MAP_I_TO_G */
- 1108, /* GL_PIXEL_MAP_I_TO_B */
- 1106, /* GL_PIXEL_MAP_I_TO_A */
- 1116, /* GL_PIXEL_MAP_R_TO_R */
- 1104, /* GL_PIXEL_MAP_G_TO_G */
- 1102, /* GL_PIXEL_MAP_B_TO_B */
- 1100, /* GL_PIXEL_MAP_A_TO_A */
- 1113, /* GL_PIXEL_MAP_I_TO_I_SIZE */
- 1119, /* GL_PIXEL_MAP_S_TO_S_SIZE */
- 1115, /* GL_PIXEL_MAP_I_TO_R_SIZE */
- 1111, /* GL_PIXEL_MAP_I_TO_G_SIZE */
- 1109, /* GL_PIXEL_MAP_I_TO_B_SIZE */
- 1107, /* GL_PIXEL_MAP_I_TO_A_SIZE */
- 1117, /* GL_PIXEL_MAP_R_TO_R_SIZE */
- 1105, /* GL_PIXEL_MAP_G_TO_G_SIZE */
- 1103, /* GL_PIXEL_MAP_B_TO_B_SIZE */
- 1101, /* GL_PIXEL_MAP_A_TO_A_SIZE */
- 1756, /* GL_UNPACK_SWAP_BYTES */
- 1751, /* GL_UNPACK_LSB_FIRST */
- 1752, /* GL_UNPACK_ROW_LENGTH */
- 1755, /* GL_UNPACK_SKIP_ROWS */
- 1754, /* GL_UNPACK_SKIP_PIXELS */
- 1749, /* GL_UNPACK_ALIGNMENT */
- 1087, /* GL_PACK_SWAP_BYTES */
- 1082, /* GL_PACK_LSB_FIRST */
- 1083, /* GL_PACK_ROW_LENGTH */
- 1086, /* GL_PACK_SKIP_ROWS */
- 1085, /* GL_PACK_SKIP_PIXELS */
- 1079, /* GL_PACK_ALIGNMENT */
- 791, /* GL_MAP_COLOR */
- 796, /* GL_MAP_STENCIL */
- 634, /* GL_INDEX_SHIFT */
- 633, /* GL_INDEX_OFFSET */
- 1298, /* GL_RED_SCALE */
- 1296, /* GL_RED_BIAS */
- 1856, /* GL_ZOOM_X */
- 1857, /* GL_ZOOM_Y */
- 595, /* GL_GREEN_SCALE */
- 593, /* GL_GREEN_BIAS */
+ 1517, /* GL_STEREO */
+ 1324, /* GL_RENDER_MODE */
+ 1101, /* GL_PERSPECTIVE_CORRECTION_HINT */
+ 1154, /* GL_POINT_SMOOTH_HINT */
+ 699, /* GL_LINE_SMOOTH_HINT */
+ 1171, /* GL_POLYGON_SMOOTH_HINT */
+ 526, /* GL_FOG_HINT */
+ 1687, /* GL_TEXTURE_GEN_S */
+ 1688, /* GL_TEXTURE_GEN_T */
+ 1686, /* GL_TEXTURE_GEN_R */
+ 1685, /* GL_TEXTURE_GEN_Q */
+ 1114, /* GL_PIXEL_MAP_I_TO_I */
+ 1120, /* GL_PIXEL_MAP_S_TO_S */
+ 1116, /* GL_PIXEL_MAP_I_TO_R */
+ 1112, /* GL_PIXEL_MAP_I_TO_G */
+ 1110, /* GL_PIXEL_MAP_I_TO_B */
+ 1108, /* GL_PIXEL_MAP_I_TO_A */
+ 1118, /* GL_PIXEL_MAP_R_TO_R */
+ 1106, /* GL_PIXEL_MAP_G_TO_G */
+ 1104, /* GL_PIXEL_MAP_B_TO_B */
+ 1102, /* GL_PIXEL_MAP_A_TO_A */
+ 1115, /* GL_PIXEL_MAP_I_TO_I_SIZE */
+ 1121, /* GL_PIXEL_MAP_S_TO_S_SIZE */
+ 1117, /* GL_PIXEL_MAP_I_TO_R_SIZE */
+ 1113, /* GL_PIXEL_MAP_I_TO_G_SIZE */
+ 1111, /* GL_PIXEL_MAP_I_TO_B_SIZE */
+ 1109, /* GL_PIXEL_MAP_I_TO_A_SIZE */
+ 1119, /* GL_PIXEL_MAP_R_TO_R_SIZE */
+ 1107, /* GL_PIXEL_MAP_G_TO_G_SIZE */
+ 1105, /* GL_PIXEL_MAP_B_TO_B_SIZE */
+ 1103, /* GL_PIXEL_MAP_A_TO_A_SIZE */
+ 1760, /* GL_UNPACK_SWAP_BYTES */
+ 1755, /* GL_UNPACK_LSB_FIRST */
+ 1756, /* GL_UNPACK_ROW_LENGTH */
+ 1759, /* GL_UNPACK_SKIP_ROWS */
+ 1758, /* GL_UNPACK_SKIP_PIXELS */
+ 1753, /* GL_UNPACK_ALIGNMENT */
+ 1089, /* GL_PACK_SWAP_BYTES */
+ 1084, /* GL_PACK_LSB_FIRST */
+ 1085, /* GL_PACK_ROW_LENGTH */
+ 1088, /* GL_PACK_SKIP_ROWS */
+ 1087, /* GL_PACK_SKIP_PIXELS */
+ 1081, /* GL_PACK_ALIGNMENT */
+ 793, /* GL_MAP_COLOR */
+ 798, /* GL_MAP_STENCIL */
+ 635, /* GL_INDEX_SHIFT */
+ 634, /* GL_INDEX_OFFSET */
+ 1302, /* GL_RED_SCALE */
+ 1300, /* GL_RED_BIAS */
+ 1860, /* GL_ZOOM_X */
+ 1861, /* GL_ZOOM_Y */
+ 596, /* GL_GREEN_SCALE */
+ 594, /* GL_GREEN_BIAS */
93, /* GL_BLUE_SCALE */
91, /* GL_BLUE_BIAS */
42, /* GL_ALPHA_SCALE */
40, /* GL_ALPHA_BIAS */
370, /* GL_DEPTH_SCALE */
350, /* GL_DEPTH_BIAS */
- 870, /* GL_MAX_EVAL_ORDER */
- 874, /* GL_MAX_LIGHTS */
- 853, /* GL_MAX_CLIP_PLANES */
- 920, /* GL_MAX_TEXTURE_SIZE */
- 880, /* GL_MAX_PIXEL_MAP_TABLE */
- 849, /* GL_MAX_ATTRIB_STACK_DEPTH */
- 877, /* GL_MAX_MODELVIEW_STACK_DEPTH */
- 878, /* GL_MAX_NAME_STACK_DEPTH */
- 906, /* GL_MAX_PROJECTION_STACK_DEPTH */
- 921, /* GL_MAX_TEXTURE_STACK_DEPTH */
- 935, /* GL_MAX_VIEWPORT_DIMS */
- 850, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
- 1523, /* GL_SUBPIXEL_BITS */
- 629, /* GL_INDEX_BITS */
- 1297, /* GL_RED_BITS */
- 594, /* GL_GREEN_BITS */
+ 872, /* GL_MAX_EVAL_ORDER */
+ 876, /* GL_MAX_LIGHTS */
+ 855, /* GL_MAX_CLIP_PLANES */
+ 922, /* GL_MAX_TEXTURE_SIZE */
+ 882, /* GL_MAX_PIXEL_MAP_TABLE */
+ 851, /* GL_MAX_ATTRIB_STACK_DEPTH */
+ 879, /* GL_MAX_MODELVIEW_STACK_DEPTH */
+ 880, /* GL_MAX_NAME_STACK_DEPTH */
+ 908, /* GL_MAX_PROJECTION_STACK_DEPTH */
+ 923, /* GL_MAX_TEXTURE_STACK_DEPTH */
+ 937, /* GL_MAX_VIEWPORT_DIMS */
+ 852, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
+ 1527, /* GL_SUBPIXEL_BITS */
+ 630, /* GL_INDEX_BITS */
+ 1301, /* GL_RED_BITS */
+ 595, /* GL_GREEN_BITS */
92, /* GL_BLUE_BITS */
41, /* GL_ALPHA_BITS */
351, /* GL_DEPTH_BITS */
- 1495, /* GL_STENCIL_BITS */
+ 1499, /* GL_STENCIL_BITS */
14, /* GL_ACCUM_RED_BITS */
13, /* GL_ACCUM_GREEN_BITS */
10, /* GL_ACCUM_BLUE_BITS */
9, /* GL_ACCUM_ALPHA_BITS */
- 1001, /* GL_NAME_STACK_DEPTH */
+ 1003, /* GL_NAME_STACK_DEPTH */
62, /* GL_AUTO_NORMAL */
- 737, /* GL_MAP1_COLOR_4 */
- 740, /* GL_MAP1_INDEX */
- 741, /* GL_MAP1_NORMAL */
- 742, /* GL_MAP1_TEXTURE_COORD_1 */
- 743, /* GL_MAP1_TEXTURE_COORD_2 */
- 744, /* GL_MAP1_TEXTURE_COORD_3 */
- 745, /* GL_MAP1_TEXTURE_COORD_4 */
- 746, /* GL_MAP1_VERTEX_3 */
- 747, /* GL_MAP1_VERTEX_4 */
- 764, /* GL_MAP2_COLOR_4 */
- 767, /* GL_MAP2_INDEX */
- 768, /* GL_MAP2_NORMAL */
- 769, /* GL_MAP2_TEXTURE_COORD_1 */
- 770, /* GL_MAP2_TEXTURE_COORD_2 */
- 771, /* GL_MAP2_TEXTURE_COORD_3 */
- 772, /* GL_MAP2_TEXTURE_COORD_4 */
- 773, /* GL_MAP2_VERTEX_3 */
- 774, /* GL_MAP2_VERTEX_4 */
- 738, /* GL_MAP1_GRID_DOMAIN */
- 739, /* GL_MAP1_GRID_SEGMENTS */
- 765, /* GL_MAP2_GRID_DOMAIN */
- 766, /* GL_MAP2_GRID_SEGMENTS */
- 1606, /* GL_TEXTURE_1D */
- 1608, /* GL_TEXTURE_2D */
+ 739, /* GL_MAP1_COLOR_4 */
+ 742, /* GL_MAP1_INDEX */
+ 743, /* GL_MAP1_NORMAL */
+ 744, /* GL_MAP1_TEXTURE_COORD_1 */
+ 745, /* GL_MAP1_TEXTURE_COORD_2 */
+ 746, /* GL_MAP1_TEXTURE_COORD_3 */
+ 747, /* GL_MAP1_TEXTURE_COORD_4 */
+ 748, /* GL_MAP1_VERTEX_3 */
+ 749, /* GL_MAP1_VERTEX_4 */
+ 766, /* GL_MAP2_COLOR_4 */
+ 769, /* GL_MAP2_INDEX */
+ 770, /* GL_MAP2_NORMAL */
+ 771, /* GL_MAP2_TEXTURE_COORD_1 */
+ 772, /* GL_MAP2_TEXTURE_COORD_2 */
+ 773, /* GL_MAP2_TEXTURE_COORD_3 */
+ 774, /* GL_MAP2_TEXTURE_COORD_4 */
+ 775, /* GL_MAP2_VERTEX_3 */
+ 776, /* GL_MAP2_VERTEX_4 */
+ 740, /* GL_MAP1_GRID_DOMAIN */
+ 741, /* GL_MAP1_GRID_SEGMENTS */
+ 767, /* GL_MAP2_GRID_DOMAIN */
+ 768, /* GL_MAP2_GRID_SEGMENTS */
+ 1610, /* GL_TEXTURE_1D */
+ 1612, /* GL_TEXTURE_2D */
479, /* GL_FEEDBACK_BUFFER_POINTER */
480, /* GL_FEEDBACK_BUFFER_SIZE */
481, /* GL_FEEDBACK_BUFFER_TYPE */
- 1406, /* GL_SELECTION_BUFFER_POINTER */
- 1407, /* GL_SELECTION_BUFFER_SIZE */
- 1724, /* GL_TEXTURE_WIDTH */
- 1688, /* GL_TEXTURE_HEIGHT */
- 1643, /* GL_TEXTURE_COMPONENTS */
- 1627, /* GL_TEXTURE_BORDER_COLOR */
- 1626, /* GL_TEXTURE_BORDER */
+ 1410, /* GL_SELECTION_BUFFER_POINTER */
+ 1411, /* GL_SELECTION_BUFFER_SIZE */
+ 1728, /* GL_TEXTURE_WIDTH */
+ 1692, /* GL_TEXTURE_HEIGHT */
+ 1647, /* GL_TEXTURE_COMPONENTS */
+ 1631, /* GL_TEXTURE_BORDER_COLOR */
+ 1630, /* GL_TEXTURE_BORDER */
383, /* GL_DONT_CARE */
477, /* GL_FASTEST */
- 1009, /* GL_NICEST */
+ 1011, /* GL_NICEST */
48, /* GL_AMBIENT */
380, /* GL_DIFFUSE */
- 1455, /* GL_SPECULAR */
- 1173, /* GL_POSITION */
- 1458, /* GL_SPOT_DIRECTION */
- 1459, /* GL_SPOT_EXPONENT */
- 1457, /* GL_SPOT_CUTOFF */
+ 1459, /* GL_SPECULAR */
+ 1175, /* GL_POSITION */
+ 1462, /* GL_SPOT_DIRECTION */
+ 1463, /* GL_SPOT_EXPONENT */
+ 1461, /* GL_SPOT_CUTOFF */
275, /* GL_CONSTANT_ATTENUATION */
- 687, /* GL_LINEAR_ATTENUATION */
- 1271, /* GL_QUADRATIC_ATTENUATION */
+ 689, /* GL_LINEAR_ATTENUATION */
+ 1274, /* GL_QUADRATIC_ATTENUATION */
244, /* GL_COMPILE */
245, /* GL_COMPILE_AND_EXECUTE */
120, /* GL_BYTE */
- 1758, /* GL_UNSIGNED_BYTE */
- 1420, /* GL_SHORT */
- 1769, /* GL_UNSIGNED_SHORT */
- 637, /* GL_INT */
- 1761, /* GL_UNSIGNED_INT */
- 485, /* GL_FLOAT */
+ 1762, /* GL_UNSIGNED_BYTE */
+ 1424, /* GL_SHORT */
+ 1773, /* GL_UNSIGNED_SHORT */
+ 638, /* GL_INT */
+ 1765, /* GL_UNSIGNED_INT */
+ 486, /* GL_FLOAT */
1, /* GL_2_BYTES */
5, /* GL_3_BYTES */
7, /* GL_4_BYTES */
@@ -4081,284 +4089,284 @@ static const unsigned reduced_enums[1347] =
52, /* GL_AND_REVERSE */
299, /* GL_COPY */
51, /* GL_AND_INVERTED */
- 1011, /* GL_NOOP */
- 1852, /* GL_XOR */
- 1074, /* GL_OR */
- 1012, /* GL_NOR */
+ 1013, /* GL_NOOP */
+ 1856, /* GL_XOR */
+ 1076, /* GL_OR */
+ 1014, /* GL_NOR */
467, /* GL_EQUIV */
- 664, /* GL_INVERT */
- 1077, /* GL_OR_REVERSE */
+ 665, /* GL_INVERT */
+ 1079, /* GL_OR_REVERSE */
300, /* GL_COPY_INVERTED */
- 1076, /* GL_OR_INVERTED */
- 1002, /* GL_NAND */
- 1411, /* GL_SET */
+ 1078, /* GL_OR_INVERTED */
+ 1004, /* GL_NAND */
+ 1415, /* GL_SET */
464, /* GL_EMISSION */
- 1419, /* GL_SHININESS */
+ 1423, /* GL_SHININESS */
49, /* GL_AMBIENT_AND_DIFFUSE */
190, /* GL_COLOR_INDEXES */
- 952, /* GL_MODELVIEW */
- 1249, /* GL_PROJECTION */
- 1541, /* GL_TEXTURE */
+ 954, /* GL_MODELVIEW */
+ 1251, /* GL_PROJECTION */
+ 1545, /* GL_TEXTURE */
147, /* GL_COLOR */
346, /* GL_DEPTH */
- 1481, /* GL_STENCIL */
+ 1485, /* GL_STENCIL */
189, /* GL_COLOR_INDEX */
- 1500, /* GL_STENCIL_INDEX */
+ 1504, /* GL_STENCIL_INDEX */
358, /* GL_DEPTH_COMPONENT */
- 1293, /* GL_RED */
- 592, /* GL_GREEN */
+ 1297, /* GL_RED */
+ 593, /* GL_GREEN */
90, /* GL_BLUE */
31, /* GL_ALPHA */
- 1328, /* GL_RGB */
- 1347, /* GL_RGBA */
- 715, /* GL_LUMINANCE */
- 736, /* GL_LUMINANCE_ALPHA */
+ 1332, /* GL_RGB */
+ 1351, /* GL_RGBA */
+ 717, /* GL_LUMINANCE */
+ 738, /* GL_LUMINANCE_ALPHA */
73, /* GL_BITMAP */
- 1129, /* GL_POINT */
- 685, /* GL_LINE */
+ 1131, /* GL_POINT */
+ 687, /* GL_LINE */
482, /* GL_FILL */
- 1302, /* GL_RENDER */
+ 1306, /* GL_RENDER */
478, /* GL_FEEDBACK */
- 1405, /* GL_SELECT */
- 484, /* GL_FLAT */
- 1430, /* GL_SMOOTH */
- 665, /* GL_KEEP */
- 1322, /* GL_REPLACE */
- 619, /* GL_INCR */
+ 1409, /* GL_SELECT */
+ 485, /* GL_FLAT */
+ 1434, /* GL_SMOOTH */
+ 666, /* GL_KEEP */
+ 1326, /* GL_REPLACE */
+ 620, /* GL_INCR */
342, /* GL_DECR */
- 1784, /* GL_VENDOR */
- 1319, /* GL_RENDERER */
- 1785, /* GL_VERSION */
+ 1788, /* GL_VENDOR */
+ 1323, /* GL_RENDERER */
+ 1789, /* GL_VERSION */
471, /* GL_EXTENSIONS */
- 1370, /* GL_S */
- 1532, /* GL_T */
- 1282, /* GL_R */
- 1270, /* GL_Q */
- 988, /* GL_MODULATE */
+ 1374, /* GL_S */
+ 1536, /* GL_T */
+ 1286, /* GL_R */
+ 1273, /* GL_Q */
+ 990, /* GL_MODULATE */
341, /* GL_DECAL */
- 1678, /* GL_TEXTURE_ENV_MODE */
- 1677, /* GL_TEXTURE_ENV_COLOR */
- 1676, /* GL_TEXTURE_ENV */
+ 1682, /* GL_TEXTURE_ENV_MODE */
+ 1681, /* GL_TEXTURE_ENV_COLOR */
+ 1680, /* GL_TEXTURE_ENV */
472, /* GL_EYE_LINEAR */
- 1035, /* GL_OBJECT_LINEAR */
- 1456, /* GL_SPHERE_MAP */
- 1680, /* GL_TEXTURE_GEN_MODE */
- 1037, /* GL_OBJECT_PLANE */
+ 1037, /* GL_OBJECT_LINEAR */
+ 1460, /* GL_SPHERE_MAP */
+ 1684, /* GL_TEXTURE_GEN_MODE */
+ 1039, /* GL_OBJECT_PLANE */
473, /* GL_EYE_PLANE */
- 1003, /* GL_NEAREST */
- 686, /* GL_LINEAR */
- 1007, /* GL_NEAREST_MIPMAP_NEAREST */
- 691, /* GL_LINEAR_MIPMAP_NEAREST */
- 1006, /* GL_NEAREST_MIPMAP_LINEAR */
- 690, /* GL_LINEAR_MIPMAP_LINEAR */
- 1701, /* GL_TEXTURE_MAG_FILTER */
- 1709, /* GL_TEXTURE_MIN_FILTER */
- 1726, /* GL_TEXTURE_WRAP_S */
- 1727, /* GL_TEXTURE_WRAP_T */
+ 1005, /* GL_NEAREST */
+ 688, /* GL_LINEAR */
+ 1009, /* GL_NEAREST_MIPMAP_NEAREST */
+ 693, /* GL_LINEAR_MIPMAP_NEAREST */
+ 1008, /* GL_NEAREST_MIPMAP_LINEAR */
+ 692, /* GL_LINEAR_MIPMAP_LINEAR */
+ 1705, /* GL_TEXTURE_MAG_FILTER */
+ 1713, /* GL_TEXTURE_MIN_FILTER */
+ 1730, /* GL_TEXTURE_WRAP_S */
+ 1731, /* GL_TEXTURE_WRAP_T */
126, /* GL_CLAMP */
- 1321, /* GL_REPEAT */
- 1167, /* GL_POLYGON_OFFSET_UNITS */
- 1166, /* GL_POLYGON_OFFSET_POINT */
- 1165, /* GL_POLYGON_OFFSET_LINE */
- 1283, /* GL_R3_G3_B2 */
- 1781, /* GL_V2F */
- 1782, /* GL_V3F */
+ 1325, /* GL_REPEAT */
+ 1169, /* GL_POLYGON_OFFSET_UNITS */
+ 1168, /* GL_POLYGON_OFFSET_POINT */
+ 1167, /* GL_POLYGON_OFFSET_LINE */
+ 1287, /* GL_R3_G3_B2 */
+ 1785, /* GL_V2F */
+ 1786, /* GL_V3F */
123, /* GL_C4UB_V2F */
124, /* GL_C4UB_V3F */
121, /* GL_C3F_V3F */
- 1000, /* GL_N3F_V3F */
+ 1002, /* GL_N3F_V3F */
122, /* GL_C4F_N3F_V3F */
- 1537, /* GL_T2F_V3F */
- 1539, /* GL_T4F_V4F */
- 1535, /* GL_T2F_C4UB_V3F */
- 1533, /* GL_T2F_C3F_V3F */
- 1536, /* GL_T2F_N3F_V3F */
- 1534, /* GL_T2F_C4F_N3F_V3F */
- 1538, /* GL_T4F_C4F_N3F_V4F */
+ 1541, /* GL_T2F_V3F */
+ 1543, /* GL_T4F_V4F */
+ 1539, /* GL_T2F_C4UB_V3F */
+ 1537, /* GL_T2F_C3F_V3F */
+ 1540, /* GL_T2F_N3F_V3F */
+ 1538, /* GL_T2F_C4F_N3F_V3F */
+ 1542, /* GL_T4F_C4F_N3F_V4F */
139, /* GL_CLIP_PLANE0 */
140, /* GL_CLIP_PLANE1 */
141, /* GL_CLIP_PLANE2 */
142, /* GL_CLIP_PLANE3 */
143, /* GL_CLIP_PLANE4 */
144, /* GL_CLIP_PLANE5 */
- 670, /* GL_LIGHT0 */
- 671, /* GL_LIGHT1 */
- 672, /* GL_LIGHT2 */
- 673, /* GL_LIGHT3 */
- 674, /* GL_LIGHT4 */
- 675, /* GL_LIGHT5 */
- 676, /* GL_LIGHT6 */
- 677, /* GL_LIGHT7 */
- 596, /* GL_HINT_BIT */
+ 672, /* GL_LIGHT0 */
+ 673, /* GL_LIGHT1 */
+ 674, /* GL_LIGHT2 */
+ 675, /* GL_LIGHT3 */
+ 676, /* GL_LIGHT4 */
+ 677, /* GL_LIGHT5 */
+ 678, /* GL_LIGHT6 */
+ 679, /* GL_LIGHT7 */
+ 597, /* GL_HINT_BIT */
277, /* GL_CONSTANT_COLOR */
- 1048, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ 1050, /* GL_ONE_MINUS_CONSTANT_COLOR */
272, /* GL_CONSTANT_ALPHA */
- 1046, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ 1048, /* GL_ONE_MINUS_CONSTANT_ALPHA */
76, /* GL_BLEND_COLOR */
- 580, /* GL_FUNC_ADD */
- 936, /* GL_MIN */
- 846, /* GL_MAX */
+ 581, /* GL_FUNC_ADD */
+ 938, /* GL_MIN */
+ 848, /* GL_MAX */
81, /* GL_BLEND_EQUATION */
- 584, /* GL_FUNC_SUBTRACT */
- 582, /* GL_FUNC_REVERSE_SUBTRACT */
+ 585, /* GL_FUNC_SUBTRACT */
+ 583, /* GL_FUNC_REVERSE_SUBTRACT */
280, /* GL_CONVOLUTION_1D */
281, /* GL_CONVOLUTION_2D */
- 1408, /* GL_SEPARABLE_2D */
+ 1412, /* GL_SEPARABLE_2D */
284, /* GL_CONVOLUTION_BORDER_MODE */
288, /* GL_CONVOLUTION_FILTER_SCALE */
286, /* GL_CONVOLUTION_FILTER_BIAS */
- 1294, /* GL_REDUCE */
+ 1298, /* GL_REDUCE */
290, /* GL_CONVOLUTION_FORMAT */
294, /* GL_CONVOLUTION_WIDTH */
292, /* GL_CONVOLUTION_HEIGHT */
- 861, /* GL_MAX_CONVOLUTION_WIDTH */
- 859, /* GL_MAX_CONVOLUTION_HEIGHT */
- 1206, /* GL_POST_CONVOLUTION_RED_SCALE */
- 1202, /* GL_POST_CONVOLUTION_GREEN_SCALE */
- 1197, /* GL_POST_CONVOLUTION_BLUE_SCALE */
- 1193, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
- 1204, /* GL_POST_CONVOLUTION_RED_BIAS */
- 1200, /* GL_POST_CONVOLUTION_GREEN_BIAS */
- 1195, /* GL_POST_CONVOLUTION_BLUE_BIAS */
- 1191, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
- 597, /* GL_HISTOGRAM */
- 1254, /* GL_PROXY_HISTOGRAM */
- 613, /* GL_HISTOGRAM_WIDTH */
- 603, /* GL_HISTOGRAM_FORMAT */
- 609, /* GL_HISTOGRAM_RED_SIZE */
- 605, /* GL_HISTOGRAM_GREEN_SIZE */
- 600, /* GL_HISTOGRAM_BLUE_SIZE */
- 598, /* GL_HISTOGRAM_ALPHA_SIZE */
- 607, /* GL_HISTOGRAM_LUMINANCE_SIZE */
- 611, /* GL_HISTOGRAM_SINK */
- 937, /* GL_MINMAX */
- 939, /* GL_MINMAX_FORMAT */
- 941, /* GL_MINMAX_SINK */
- 1540, /* GL_TABLE_TOO_LARGE_EXT */
- 1760, /* GL_UNSIGNED_BYTE_3_3_2 */
- 1771, /* GL_UNSIGNED_SHORT_4_4_4_4 */
- 1773, /* GL_UNSIGNED_SHORT_5_5_5_1 */
- 1766, /* GL_UNSIGNED_INT_8_8_8_8 */
- 1762, /* GL_UNSIGNED_INT_10_10_10_2 */
- 1164, /* GL_POLYGON_OFFSET_FILL */
- 1163, /* GL_POLYGON_OFFSET_FACTOR */
- 1162, /* GL_POLYGON_OFFSET_BIAS */
- 1325, /* GL_RESCALE_NORMAL */
+ 863, /* GL_MAX_CONVOLUTION_WIDTH */
+ 861, /* GL_MAX_CONVOLUTION_HEIGHT */
+ 1208, /* GL_POST_CONVOLUTION_RED_SCALE */
+ 1204, /* GL_POST_CONVOLUTION_GREEN_SCALE */
+ 1199, /* GL_POST_CONVOLUTION_BLUE_SCALE */
+ 1195, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
+ 1206, /* GL_POST_CONVOLUTION_RED_BIAS */
+ 1202, /* GL_POST_CONVOLUTION_GREEN_BIAS */
+ 1197, /* GL_POST_CONVOLUTION_BLUE_BIAS */
+ 1193, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
+ 598, /* GL_HISTOGRAM */
+ 1257, /* GL_PROXY_HISTOGRAM */
+ 614, /* GL_HISTOGRAM_WIDTH */
+ 604, /* GL_HISTOGRAM_FORMAT */
+ 610, /* GL_HISTOGRAM_RED_SIZE */
+ 606, /* GL_HISTOGRAM_GREEN_SIZE */
+ 601, /* GL_HISTOGRAM_BLUE_SIZE */
+ 599, /* GL_HISTOGRAM_ALPHA_SIZE */
+ 608, /* GL_HISTOGRAM_LUMINANCE_SIZE */
+ 612, /* GL_HISTOGRAM_SINK */
+ 939, /* GL_MINMAX */
+ 941, /* GL_MINMAX_FORMAT */
+ 943, /* GL_MINMAX_SINK */
+ 1544, /* GL_TABLE_TOO_LARGE_EXT */
+ 1764, /* GL_UNSIGNED_BYTE_3_3_2 */
+ 1775, /* GL_UNSIGNED_SHORT_4_4_4_4 */
+ 1777, /* GL_UNSIGNED_SHORT_5_5_5_1 */
+ 1770, /* GL_UNSIGNED_INT_8_8_8_8 */
+ 1766, /* GL_UNSIGNED_INT_10_10_10_2 */
+ 1166, /* GL_POLYGON_OFFSET_FILL */
+ 1165, /* GL_POLYGON_OFFSET_FACTOR */
+ 1164, /* GL_POLYGON_OFFSET_BIAS */
+ 1329, /* GL_RESCALE_NORMAL */
36, /* GL_ALPHA4 */
38, /* GL_ALPHA8 */
32, /* GL_ALPHA12 */
34, /* GL_ALPHA16 */
- 726, /* GL_LUMINANCE4 */
- 732, /* GL_LUMINANCE8 */
- 716, /* GL_LUMINANCE12 */
- 722, /* GL_LUMINANCE16 */
- 727, /* GL_LUMINANCE4_ALPHA4 */
- 730, /* GL_LUMINANCE6_ALPHA2 */
- 733, /* GL_LUMINANCE8_ALPHA8 */
- 719, /* GL_LUMINANCE12_ALPHA4 */
- 717, /* GL_LUMINANCE12_ALPHA12 */
- 723, /* GL_LUMINANCE16_ALPHA16 */
- 638, /* GL_INTENSITY */
- 643, /* GL_INTENSITY4 */
- 645, /* GL_INTENSITY8 */
- 639, /* GL_INTENSITY12 */
- 641, /* GL_INTENSITY16 */
- 1337, /* GL_RGB2_EXT */
- 1338, /* GL_RGB4 */
- 1341, /* GL_RGB5 */
- 1345, /* GL_RGB8 */
- 1329, /* GL_RGB10 */
- 1333, /* GL_RGB12 */
- 1335, /* GL_RGB16 */
- 1352, /* GL_RGBA2 */
- 1354, /* GL_RGBA4 */
- 1342, /* GL_RGB5_A1 */
- 1358, /* GL_RGBA8 */
- 1330, /* GL_RGB10_A2 */
- 1348, /* GL_RGBA12 */
- 1350, /* GL_RGBA16 */
- 1716, /* GL_TEXTURE_RED_SIZE */
- 1686, /* GL_TEXTURE_GREEN_SIZE */
- 1624, /* GL_TEXTURE_BLUE_SIZE */
- 1611, /* GL_TEXTURE_ALPHA_SIZE */
- 1699, /* GL_TEXTURE_LUMINANCE_SIZE */
- 1690, /* GL_TEXTURE_INTENSITY_SIZE */
- 1323, /* GL_REPLACE_EXT */
- 1258, /* GL_PROXY_TEXTURE_1D */
- 1261, /* GL_PROXY_TEXTURE_2D */
- 1722, /* GL_TEXTURE_TOO_LARGE_EXT */
- 1711, /* GL_TEXTURE_PRIORITY */
- 1718, /* GL_TEXTURE_RESIDENT */
- 1614, /* GL_TEXTURE_BINDING_1D */
- 1616, /* GL_TEXTURE_BINDING_2D */
- 1618, /* GL_TEXTURE_BINDING_3D */
- 1084, /* GL_PACK_SKIP_IMAGES */
- 1080, /* GL_PACK_IMAGE_HEIGHT */
- 1753, /* GL_UNPACK_SKIP_IMAGES */
- 1750, /* GL_UNPACK_IMAGE_HEIGHT */
- 1610, /* GL_TEXTURE_3D */
- 1264, /* GL_PROXY_TEXTURE_3D */
- 1673, /* GL_TEXTURE_DEPTH */
- 1725, /* GL_TEXTURE_WRAP_R */
- 847, /* GL_MAX_3D_TEXTURE_SIZE */
- 1786, /* GL_VERTEX_ARRAY */
- 1014, /* GL_NORMAL_ARRAY */
+ 728, /* GL_LUMINANCE4 */
+ 734, /* GL_LUMINANCE8 */
+ 718, /* GL_LUMINANCE12 */
+ 724, /* GL_LUMINANCE16 */
+ 729, /* GL_LUMINANCE4_ALPHA4 */
+ 732, /* GL_LUMINANCE6_ALPHA2 */
+ 735, /* GL_LUMINANCE8_ALPHA8 */
+ 721, /* GL_LUMINANCE12_ALPHA4 */
+ 719, /* GL_LUMINANCE12_ALPHA12 */
+ 725, /* GL_LUMINANCE16_ALPHA16 */
+ 639, /* GL_INTENSITY */
+ 644, /* GL_INTENSITY4 */
+ 646, /* GL_INTENSITY8 */
+ 640, /* GL_INTENSITY12 */
+ 642, /* GL_INTENSITY16 */
+ 1341, /* GL_RGB2_EXT */
+ 1342, /* GL_RGB4 */
+ 1345, /* GL_RGB5 */
+ 1349, /* GL_RGB8 */
+ 1333, /* GL_RGB10 */
+ 1337, /* GL_RGB12 */
+ 1339, /* GL_RGB16 */
+ 1356, /* GL_RGBA2 */
+ 1358, /* GL_RGBA4 */
+ 1346, /* GL_RGB5_A1 */
+ 1362, /* GL_RGBA8 */
+ 1334, /* GL_RGB10_A2 */
+ 1352, /* GL_RGBA12 */
+ 1354, /* GL_RGBA16 */
+ 1720, /* GL_TEXTURE_RED_SIZE */
+ 1690, /* GL_TEXTURE_GREEN_SIZE */
+ 1628, /* GL_TEXTURE_BLUE_SIZE */
+ 1615, /* GL_TEXTURE_ALPHA_SIZE */
+ 1703, /* GL_TEXTURE_LUMINANCE_SIZE */
+ 1694, /* GL_TEXTURE_INTENSITY_SIZE */
+ 1327, /* GL_REPLACE_EXT */
+ 1261, /* GL_PROXY_TEXTURE_1D */
+ 1264, /* GL_PROXY_TEXTURE_2D */
+ 1726, /* GL_TEXTURE_TOO_LARGE_EXT */
+ 1715, /* GL_TEXTURE_PRIORITY */
+ 1722, /* GL_TEXTURE_RESIDENT */
+ 1618, /* GL_TEXTURE_BINDING_1D */
+ 1620, /* GL_TEXTURE_BINDING_2D */
+ 1622, /* GL_TEXTURE_BINDING_3D */
+ 1086, /* GL_PACK_SKIP_IMAGES */
+ 1082, /* GL_PACK_IMAGE_HEIGHT */
+ 1757, /* GL_UNPACK_SKIP_IMAGES */
+ 1754, /* GL_UNPACK_IMAGE_HEIGHT */
+ 1614, /* GL_TEXTURE_3D */
+ 1267, /* GL_PROXY_TEXTURE_3D */
+ 1677, /* GL_TEXTURE_DEPTH */
+ 1729, /* GL_TEXTURE_WRAP_R */
+ 849, /* GL_MAX_3D_TEXTURE_SIZE */
+ 1790, /* GL_VERTEX_ARRAY */
+ 1016, /* GL_NORMAL_ARRAY */
148, /* GL_COLOR_ARRAY */
- 623, /* GL_INDEX_ARRAY */
- 1651, /* GL_TEXTURE_COORD_ARRAY */
+ 624, /* GL_INDEX_ARRAY */
+ 1655, /* GL_TEXTURE_COORD_ARRAY */
456, /* GL_EDGE_FLAG_ARRAY */
- 1792, /* GL_VERTEX_ARRAY_SIZE */
- 1794, /* GL_VERTEX_ARRAY_TYPE */
- 1793, /* GL_VERTEX_ARRAY_STRIDE */
- 1019, /* GL_NORMAL_ARRAY_TYPE */
- 1018, /* GL_NORMAL_ARRAY_STRIDE */
+ 1796, /* GL_VERTEX_ARRAY_SIZE */
+ 1798, /* GL_VERTEX_ARRAY_TYPE */
+ 1797, /* GL_VERTEX_ARRAY_STRIDE */
+ 1021, /* GL_NORMAL_ARRAY_TYPE */
+ 1020, /* GL_NORMAL_ARRAY_STRIDE */
152, /* GL_COLOR_ARRAY_SIZE */
154, /* GL_COLOR_ARRAY_TYPE */
153, /* GL_COLOR_ARRAY_STRIDE */
- 628, /* GL_INDEX_ARRAY_TYPE */
- 627, /* GL_INDEX_ARRAY_STRIDE */
- 1655, /* GL_TEXTURE_COORD_ARRAY_SIZE */
- 1657, /* GL_TEXTURE_COORD_ARRAY_TYPE */
- 1656, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
+ 629, /* GL_INDEX_ARRAY_TYPE */
+ 628, /* GL_INDEX_ARRAY_STRIDE */
+ 1659, /* GL_TEXTURE_COORD_ARRAY_SIZE */
+ 1661, /* GL_TEXTURE_COORD_ARRAY_TYPE */
+ 1660, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
460, /* GL_EDGE_FLAG_ARRAY_STRIDE */
- 1791, /* GL_VERTEX_ARRAY_POINTER */
- 1017, /* GL_NORMAL_ARRAY_POINTER */
+ 1795, /* GL_VERTEX_ARRAY_POINTER */
+ 1019, /* GL_NORMAL_ARRAY_POINTER */
151, /* GL_COLOR_ARRAY_POINTER */
- 626, /* GL_INDEX_ARRAY_POINTER */
- 1654, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ 627, /* GL_INDEX_ARRAY_POINTER */
+ 1658, /* GL_TEXTURE_COORD_ARRAY_POINTER */
459, /* GL_EDGE_FLAG_ARRAY_POINTER */
- 993, /* GL_MULTISAMPLE */
- 1382, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
- 1384, /* GL_SAMPLE_ALPHA_TO_ONE */
- 1389, /* GL_SAMPLE_COVERAGE */
- 1386, /* GL_SAMPLE_BUFFERS */
- 1377, /* GL_SAMPLES */
- 1393, /* GL_SAMPLE_COVERAGE_VALUE */
- 1391, /* GL_SAMPLE_COVERAGE_INVERT */
+ 995, /* GL_MULTISAMPLE */
+ 1386, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
+ 1388, /* GL_SAMPLE_ALPHA_TO_ONE */
+ 1393, /* GL_SAMPLE_COVERAGE */
+ 1390, /* GL_SAMPLE_BUFFERS */
+ 1381, /* GL_SAMPLES */
+ 1397, /* GL_SAMPLE_COVERAGE_VALUE */
+ 1395, /* GL_SAMPLE_COVERAGE_INVERT */
195, /* GL_COLOR_MATRIX */
197, /* GL_COLOR_MATRIX_STACK_DEPTH */
- 855, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
- 1189, /* GL_POST_COLOR_MATRIX_RED_SCALE */
- 1185, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
- 1180, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
- 1176, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
- 1187, /* GL_POST_COLOR_MATRIX_RED_BIAS */
- 1183, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
- 1178, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
- 1174, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
- 1634, /* GL_TEXTURE_COLOR_TABLE_SGI */
- 1265, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
- 1636, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
+ 857, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
+ 1191, /* GL_POST_COLOR_MATRIX_RED_SCALE */
+ 1187, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
+ 1182, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
+ 1178, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
+ 1189, /* GL_POST_COLOR_MATRIX_RED_BIAS */
+ 1185, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
+ 1180, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
+ 1176, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
+ 1638, /* GL_TEXTURE_COLOR_TABLE_SGI */
+ 1268, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
+ 1640, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
80, /* GL_BLEND_DST_RGB */
89, /* GL_BLEND_SRC_RGB */
79, /* GL_BLEND_DST_ALPHA */
88, /* GL_BLEND_SRC_ALPHA */
201, /* GL_COLOR_TABLE */
- 1199, /* GL_POST_CONVOLUTION_COLOR_TABLE */
- 1182, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
- 1253, /* GL_PROXY_COLOR_TABLE */
- 1257, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
- 1256, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
+ 1201, /* GL_POST_CONVOLUTION_COLOR_TABLE */
+ 1184, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
+ 1256, /* GL_PROXY_COLOR_TABLE */
+ 1260, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
+ 1259, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
225, /* GL_COLOR_TABLE_SCALE */
205, /* GL_COLOR_TABLE_BIAS */
210, /* GL_COLOR_TABLE_FORMAT */
@@ -4371,380 +4379,380 @@ static const unsigned reduced_enums[1347] =
216, /* GL_COLOR_TABLE_INTENSITY_SIZE */
71, /* GL_BGR */
72, /* GL_BGRA */
- 869, /* GL_MAX_ELEMENTS_VERTICES */
- 868, /* GL_MAX_ELEMENTS_INDICES */
- 1689, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ 871, /* GL_MAX_ELEMENTS_VERTICES */
+ 870, /* GL_MAX_ELEMENTS_INDICES */
+ 1693, /* GL_TEXTURE_INDEX_SIZE_EXT */
145, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
- 1146, /* GL_POINT_SIZE_MIN */
- 1142, /* GL_POINT_SIZE_MAX */
- 1136, /* GL_POINT_FADE_THRESHOLD_SIZE */
- 1132, /* GL_POINT_DISTANCE_ATTENUATION */
+ 1148, /* GL_POINT_SIZE_MIN */
+ 1144, /* GL_POINT_SIZE_MAX */
+ 1138, /* GL_POINT_FADE_THRESHOLD_SIZE */
+ 1134, /* GL_POINT_DISTANCE_ATTENUATION */
127, /* GL_CLAMP_TO_BORDER */
130, /* GL_CLAMP_TO_EDGE */
- 1710, /* GL_TEXTURE_MIN_LOD */
- 1708, /* GL_TEXTURE_MAX_LOD */
- 1613, /* GL_TEXTURE_BASE_LEVEL */
- 1707, /* GL_TEXTURE_MAX_LEVEL */
- 616, /* GL_IGNORE_BORDER_HP */
+ 1714, /* GL_TEXTURE_MIN_LOD */
+ 1712, /* GL_TEXTURE_MAX_LOD */
+ 1617, /* GL_TEXTURE_BASE_LEVEL */
+ 1711, /* GL_TEXTURE_MAX_LEVEL */
+ 617, /* GL_IGNORE_BORDER_HP */
276, /* GL_CONSTANT_BORDER_HP */
- 1324, /* GL_REPLICATE_BORDER_HP */
+ 1328, /* GL_REPLICATE_BORDER_HP */
282, /* GL_CONVOLUTION_BORDER_COLOR */
- 1043, /* GL_OCCLUSION_TEST_HP */
- 1044, /* GL_OCCLUSION_TEST_RESULT_HP */
- 688, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
- 1628, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
- 1630, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
- 1632, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
- 1633, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- 1631, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
- 1629, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
- 851, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
- 852, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- 1209, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
- 1211, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
- 1208, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
- 1210, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
- 1697, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
- 1698, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
- 1696, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
- 586, /* GL_GENERATE_MIPMAP */
- 587, /* GL_GENERATE_MIPMAP_HINT */
- 528, /* GL_FOG_OFFSET_SGIX */
- 529, /* GL_FOG_OFFSET_VALUE_SGIX */
- 1642, /* GL_TEXTURE_COMPARE_SGIX */
- 1641, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
- 1693, /* GL_TEXTURE_LEQUAL_R_SGIX */
- 1685, /* GL_TEXTURE_GEQUAL_R_SGIX */
+ 1045, /* GL_OCCLUSION_TEST_HP */
+ 1046, /* GL_OCCLUSION_TEST_RESULT_HP */
+ 690, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
+ 1632, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
+ 1634, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
+ 1636, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
+ 1637, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ 1635, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
+ 1633, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
+ 853, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
+ 854, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
+ 1211, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
+ 1213, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
+ 1210, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
+ 1212, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
+ 1701, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
+ 1702, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
+ 1700, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
+ 587, /* GL_GENERATE_MIPMAP */
+ 588, /* GL_GENERATE_MIPMAP_HINT */
+ 529, /* GL_FOG_OFFSET_SGIX */
+ 530, /* GL_FOG_OFFSET_VALUE_SGIX */
+ 1646, /* GL_TEXTURE_COMPARE_SGIX */
+ 1645, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
+ 1697, /* GL_TEXTURE_LEQUAL_R_SGIX */
+ 1689, /* GL_TEXTURE_GEQUAL_R_SGIX */
359, /* GL_DEPTH_COMPONENT16 */
362, /* GL_DEPTH_COMPONENT24 */
365, /* GL_DEPTH_COMPONENT32 */
306, /* GL_CULL_VERTEX_EXT */
308, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
307, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
- 1849, /* GL_WRAP_BORDER_SUN */
- 1635, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
- 681, /* GL_LIGHT_MODEL_COLOR_CONTROL */
- 1423, /* GL_SINGLE_COLOR */
- 1409, /* GL_SEPARATE_SPECULAR_COLOR */
- 1418, /* GL_SHARED_TEXTURE_PALETTE_EXT */
- 539, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
- 540, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
- 547, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
- 542, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
- 538, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
- 537, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
- 541, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
- 548, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
- 559, /* GL_FRAMEBUFFER_DEFAULT */
- 572, /* GL_FRAMEBUFFER_UNDEFINED */
+ 1853, /* GL_WRAP_BORDER_SUN */
+ 1639, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
+ 683, /* GL_LIGHT_MODEL_COLOR_CONTROL */
+ 1427, /* GL_SINGLE_COLOR */
+ 1413, /* GL_SEPARATE_SPECULAR_COLOR */
+ 1422, /* GL_SHARED_TEXTURE_PALETTE_EXT */
+ 540, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
+ 541, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
+ 548, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
+ 543, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
+ 539, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
+ 538, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
+ 542, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
+ 549, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
+ 560, /* GL_FRAMEBUFFER_DEFAULT */
+ 573, /* GL_FRAMEBUFFER_UNDEFINED */
372, /* GL_DEPTH_STENCIL_ATTACHMENT */
- 622, /* GL_INDEX */
- 1759, /* GL_UNSIGNED_BYTE_2_3_3_REV */
- 1774, /* GL_UNSIGNED_SHORT_5_6_5 */
- 1775, /* GL_UNSIGNED_SHORT_5_6_5_REV */
- 1772, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
- 1770, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
- 1767, /* GL_UNSIGNED_INT_8_8_8_8_REV */
- 1765, /* GL_UNSIGNED_INT_2_10_10_10_REV */
- 1705, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
- 1706, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
- 1704, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
- 944, /* GL_MIRRORED_REPEAT */
- 1365, /* GL_RGB_S3TC */
- 1340, /* GL_RGB4_S3TC */
- 1363, /* GL_RGBA_S3TC */
- 1357, /* GL_RGBA4_S3TC */
- 1361, /* GL_RGBA_DXT5_S3TC */
- 1355, /* GL_RGBA4_DXT5_S3TC */
+ 623, /* GL_INDEX */
+ 1763, /* GL_UNSIGNED_BYTE_2_3_3_REV */
+ 1778, /* GL_UNSIGNED_SHORT_5_6_5 */
+ 1779, /* GL_UNSIGNED_SHORT_5_6_5_REV */
+ 1776, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
+ 1774, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
+ 1771, /* GL_UNSIGNED_INT_8_8_8_8_REV */
+ 1769, /* GL_UNSIGNED_INT_2_10_10_10_REV */
+ 1709, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
+ 1710, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
+ 1708, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
+ 946, /* GL_MIRRORED_REPEAT */
+ 1369, /* GL_RGB_S3TC */
+ 1344, /* GL_RGB4_S3TC */
+ 1367, /* GL_RGBA_S3TC */
+ 1361, /* GL_RGBA4_S3TC */
+ 1365, /* GL_RGBA_DXT5_S3TC */
+ 1359, /* GL_RGBA4_DXT5_S3TC */
264, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
259, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
260, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
261, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
- 1005, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
- 1004, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
- 689, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
- 515, /* GL_FOG_COORDINATE_SOURCE */
- 507, /* GL_FOG_COORD */
- 531, /* GL_FRAGMENT_DEPTH */
+ 1007, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
+ 1006, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
+ 691, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
+ 516, /* GL_FOG_COORDINATE_SOURCE */
+ 508, /* GL_FOG_COORD */
+ 532, /* GL_FRAGMENT_DEPTH */
312, /* GL_CURRENT_FOG_COORD */
- 514, /* GL_FOG_COORDINATE_ARRAY_TYPE */
- 513, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
- 512, /* GL_FOG_COORDINATE_ARRAY_POINTER */
- 509, /* GL_FOG_COORDINATE_ARRAY */
+ 515, /* GL_FOG_COORDINATE_ARRAY_TYPE */
+ 514, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
+ 513, /* GL_FOG_COORDINATE_ARRAY_POINTER */
+ 510, /* GL_FOG_COORDINATE_ARRAY */
199, /* GL_COLOR_SUM */
332, /* GL_CURRENT_SECONDARY_COLOR */
- 1402, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
- 1404, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
- 1403, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
- 1401, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
- 1398, /* GL_SECONDARY_COLOR_ARRAY */
+ 1406, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
+ 1408, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
+ 1407, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
+ 1405, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
+ 1402, /* GL_SECONDARY_COLOR_ARRAY */
330, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
28, /* GL_ALIASED_POINT_SIZE_RANGE */
27, /* GL_ALIASED_LINE_WIDTH_RANGE */
- 1542, /* GL_TEXTURE0 */
- 1544, /* GL_TEXTURE1 */
- 1566, /* GL_TEXTURE2 */
- 1588, /* GL_TEXTURE3 */
- 1594, /* GL_TEXTURE4 */
- 1596, /* GL_TEXTURE5 */
- 1598, /* GL_TEXTURE6 */
- 1600, /* GL_TEXTURE7 */
- 1602, /* GL_TEXTURE8 */
- 1604, /* GL_TEXTURE9 */
- 1545, /* GL_TEXTURE10 */
- 1547, /* GL_TEXTURE11 */
- 1549, /* GL_TEXTURE12 */
- 1551, /* GL_TEXTURE13 */
- 1553, /* GL_TEXTURE14 */
- 1555, /* GL_TEXTURE15 */
- 1557, /* GL_TEXTURE16 */
- 1559, /* GL_TEXTURE17 */
- 1561, /* GL_TEXTURE18 */
- 1563, /* GL_TEXTURE19 */
- 1567, /* GL_TEXTURE20 */
- 1569, /* GL_TEXTURE21 */
- 1571, /* GL_TEXTURE22 */
- 1573, /* GL_TEXTURE23 */
- 1575, /* GL_TEXTURE24 */
- 1577, /* GL_TEXTURE25 */
- 1579, /* GL_TEXTURE26 */
- 1581, /* GL_TEXTURE27 */
- 1583, /* GL_TEXTURE28 */
- 1585, /* GL_TEXTURE29 */
- 1589, /* GL_TEXTURE30 */
- 1591, /* GL_TEXTURE31 */
+ 1546, /* GL_TEXTURE0 */
+ 1548, /* GL_TEXTURE1 */
+ 1570, /* GL_TEXTURE2 */
+ 1592, /* GL_TEXTURE3 */
+ 1598, /* GL_TEXTURE4 */
+ 1600, /* GL_TEXTURE5 */
+ 1602, /* GL_TEXTURE6 */
+ 1604, /* GL_TEXTURE7 */
+ 1606, /* GL_TEXTURE8 */
+ 1608, /* GL_TEXTURE9 */
+ 1549, /* GL_TEXTURE10 */
+ 1551, /* GL_TEXTURE11 */
+ 1553, /* GL_TEXTURE12 */
+ 1555, /* GL_TEXTURE13 */
+ 1557, /* GL_TEXTURE14 */
+ 1559, /* GL_TEXTURE15 */
+ 1561, /* GL_TEXTURE16 */
+ 1563, /* GL_TEXTURE17 */
+ 1565, /* GL_TEXTURE18 */
+ 1567, /* GL_TEXTURE19 */
+ 1571, /* GL_TEXTURE20 */
+ 1573, /* GL_TEXTURE21 */
+ 1575, /* GL_TEXTURE22 */
+ 1577, /* GL_TEXTURE23 */
+ 1579, /* GL_TEXTURE24 */
+ 1581, /* GL_TEXTURE25 */
+ 1583, /* GL_TEXTURE26 */
+ 1585, /* GL_TEXTURE27 */
+ 1587, /* GL_TEXTURE28 */
+ 1589, /* GL_TEXTURE29 */
+ 1593, /* GL_TEXTURE30 */
+ 1595, /* GL_TEXTURE31 */
18, /* GL_ACTIVE_TEXTURE */
133, /* GL_CLIENT_ACTIVE_TEXTURE */
- 922, /* GL_MAX_TEXTURE_UNITS */
- 1737, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
- 1740, /* GL_TRANSPOSE_PROJECTION_MATRIX */
- 1742, /* GL_TRANSPOSE_TEXTURE_MATRIX */
- 1734, /* GL_TRANSPOSE_COLOR_MATRIX */
- 1524, /* GL_SUBTRACT */
- 909, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
+ 924, /* GL_MAX_TEXTURE_UNITS */
+ 1741, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
+ 1744, /* GL_TRANSPOSE_PROJECTION_MATRIX */
+ 1746, /* GL_TRANSPOSE_TEXTURE_MATRIX */
+ 1738, /* GL_TRANSPOSE_COLOR_MATRIX */
+ 1528, /* GL_SUBTRACT */
+ 911, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
247, /* GL_COMPRESSED_ALPHA */
251, /* GL_COMPRESSED_LUMINANCE */
252, /* GL_COMPRESSED_LUMINANCE_ALPHA */
249, /* GL_COMPRESSED_INTENSITY */
255, /* GL_COMPRESSED_RGB */
256, /* GL_COMPRESSED_RGBA */
- 1649, /* GL_TEXTURE_COMPRESSION_HINT */
- 1714, /* GL_TEXTURE_RECTANGLE_ARB */
- 1621, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
- 1268, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
- 907, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
+ 1653, /* GL_TEXTURE_COMPRESSION_HINT */
+ 1718, /* GL_TEXTURE_RECTANGLE_ARB */
+ 1625, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
+ 1271, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
+ 909, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
371, /* GL_DEPTH_STENCIL */
- 1763, /* GL_UNSIGNED_INT_24_8 */
- 918, /* GL_MAX_TEXTURE_LOD_BIAS */
- 1703, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
- 919, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
- 1679, /* GL_TEXTURE_FILTER_CONTROL */
- 1694, /* GL_TEXTURE_LOD_BIAS */
+ 1767, /* GL_UNSIGNED_INT_24_8 */
+ 920, /* GL_MAX_TEXTURE_LOD_BIAS */
+ 1707, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
+ 921, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
+ 1683, /* GL_TEXTURE_FILTER_CONTROL */
+ 1698, /* GL_TEXTURE_LOD_BIAS */
232, /* GL_COMBINE4 */
- 912, /* GL_MAX_SHININESS_NV */
- 913, /* GL_MAX_SPOT_EXPONENT_NV */
- 620, /* GL_INCR_WRAP */
+ 914, /* GL_MAX_SHININESS_NV */
+ 915, /* GL_MAX_SPOT_EXPONENT_NV */
+ 621, /* GL_INCR_WRAP */
343, /* GL_DECR_WRAP */
- 964, /* GL_MODELVIEW1_ARB */
- 1020, /* GL_NORMAL_MAP */
- 1299, /* GL_REFLECTION_MAP */
- 1658, /* GL_TEXTURE_CUBE_MAP */
- 1619, /* GL_TEXTURE_BINDING_CUBE_MAP */
- 1666, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
- 1660, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
- 1668, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
- 1662, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
- 1670, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
- 1664, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
- 1266, /* GL_PROXY_TEXTURE_CUBE_MAP */
- 863, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
- 999, /* GL_MULTISAMPLE_FILTER_HINT_NV */
- 523, /* GL_FOG_DISTANCE_MODE_NV */
+ 966, /* GL_MODELVIEW1_ARB */
+ 1022, /* GL_NORMAL_MAP */
+ 1303, /* GL_REFLECTION_MAP */
+ 1662, /* GL_TEXTURE_CUBE_MAP */
+ 1623, /* GL_TEXTURE_BINDING_CUBE_MAP */
+ 1670, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
+ 1664, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
+ 1672, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
+ 1666, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
+ 1674, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
+ 1668, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
+ 1269, /* GL_PROXY_TEXTURE_CUBE_MAP */
+ 865, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
+ 1001, /* GL_MULTISAMPLE_FILTER_HINT_NV */
+ 524, /* GL_FOG_DISTANCE_MODE_NV */
475, /* GL_EYE_RADIAL_NV */
474, /* GL_EYE_PLANE_ABSOLUTE_NV */
231, /* GL_COMBINE */
238, /* GL_COMBINE_RGB */
233, /* GL_COMBINE_ALPHA */
- 1366, /* GL_RGB_SCALE */
+ 1370, /* GL_RGB_SCALE */
24, /* GL_ADD_SIGNED */
- 648, /* GL_INTERPOLATE */
+ 649, /* GL_INTERPOLATE */
271, /* GL_CONSTANT */
- 1215, /* GL_PRIMARY_COLOR */
- 1212, /* GL_PREVIOUS */
- 1438, /* GL_SOURCE0_RGB */
- 1444, /* GL_SOURCE1_RGB */
- 1450, /* GL_SOURCE2_RGB */
- 1454, /* GL_SOURCE3_RGB_NV */
- 1435, /* GL_SOURCE0_ALPHA */
- 1441, /* GL_SOURCE1_ALPHA */
- 1447, /* GL_SOURCE2_ALPHA */
- 1453, /* GL_SOURCE3_ALPHA_NV */
- 1057, /* GL_OPERAND0_RGB */
- 1063, /* GL_OPERAND1_RGB */
- 1069, /* GL_OPERAND2_RGB */
- 1073, /* GL_OPERAND3_RGB_NV */
- 1054, /* GL_OPERAND0_ALPHA */
- 1060, /* GL_OPERAND1_ALPHA */
- 1066, /* GL_OPERAND2_ALPHA */
- 1072, /* GL_OPERAND3_ALPHA_NV */
- 1787, /* GL_VERTEX_ARRAY_BINDING */
- 1712, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
- 1713, /* GL_TEXTURE_RANGE_POINTER_APPLE */
- 1853, /* GL_YCBCR_422_APPLE */
- 1776, /* GL_UNSIGNED_SHORT_8_8_APPLE */
- 1778, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
- 1721, /* GL_TEXTURE_STORAGE_HINT_APPLE */
- 1515, /* GL_STORAGE_PRIVATE_APPLE */
- 1514, /* GL_STORAGE_CACHED_APPLE */
- 1516, /* GL_STORAGE_SHARED_APPLE */
- 1425, /* GL_SLICE_ACCUM_SUN */
- 1274, /* GL_QUAD_MESH_SUN */
- 1746, /* GL_TRIANGLE_MESH_SUN */
- 1826, /* GL_VERTEX_PROGRAM_ARB */
- 1837, /* GL_VERTEX_STATE_PROGRAM_NV */
- 1813, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
- 1819, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
- 1821, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
- 1823, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
+ 1217, /* GL_PRIMARY_COLOR */
+ 1214, /* GL_PREVIOUS */
+ 1442, /* GL_SOURCE0_RGB */
+ 1448, /* GL_SOURCE1_RGB */
+ 1454, /* GL_SOURCE2_RGB */
+ 1458, /* GL_SOURCE3_RGB_NV */
+ 1439, /* GL_SOURCE0_ALPHA */
+ 1445, /* GL_SOURCE1_ALPHA */
+ 1451, /* GL_SOURCE2_ALPHA */
+ 1457, /* GL_SOURCE3_ALPHA_NV */
+ 1059, /* GL_OPERAND0_RGB */
+ 1065, /* GL_OPERAND1_RGB */
+ 1071, /* GL_OPERAND2_RGB */
+ 1075, /* GL_OPERAND3_RGB_NV */
+ 1056, /* GL_OPERAND0_ALPHA */
+ 1062, /* GL_OPERAND1_ALPHA */
+ 1068, /* GL_OPERAND2_ALPHA */
+ 1074, /* GL_OPERAND3_ALPHA_NV */
+ 1791, /* GL_VERTEX_ARRAY_BINDING */
+ 1716, /* GL_TEXTURE_RANGE_LENGTH_APPLE */
+ 1717, /* GL_TEXTURE_RANGE_POINTER_APPLE */
+ 1857, /* GL_YCBCR_422_APPLE */
+ 1780, /* GL_UNSIGNED_SHORT_8_8_APPLE */
+ 1782, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
+ 1725, /* GL_TEXTURE_STORAGE_HINT_APPLE */
+ 1519, /* GL_STORAGE_PRIVATE_APPLE */
+ 1518, /* GL_STORAGE_CACHED_APPLE */
+ 1520, /* GL_STORAGE_SHARED_APPLE */
+ 1429, /* GL_SLICE_ACCUM_SUN */
+ 1278, /* GL_QUAD_MESH_SUN */
+ 1750, /* GL_TRIANGLE_MESH_SUN */
+ 1830, /* GL_VERTEX_PROGRAM_ARB */
+ 1841, /* GL_VERTEX_STATE_PROGRAM_NV */
+ 1817, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
+ 1823, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
+ 1825, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
+ 1827, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
334, /* GL_CURRENT_VERTEX_ATTRIB */
- 1228, /* GL_PROGRAM_LENGTH_ARB */
- 1242, /* GL_PROGRAM_STRING_ARB */
- 986, /* GL_MODELVIEW_PROJECTION_NV */
- 615, /* GL_IDENTITY_NV */
- 662, /* GL_INVERSE_NV */
- 1739, /* GL_TRANSPOSE_NV */
- 663, /* GL_INVERSE_TRANSPOSE_NV */
- 893, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
- 892, /* GL_MAX_PROGRAM_MATRICES_ARB */
- 800, /* GL_MATRIX0_NV */
- 812, /* GL_MATRIX1_NV */
- 824, /* GL_MATRIX2_NV */
- 828, /* GL_MATRIX3_NV */
- 830, /* GL_MATRIX4_NV */
- 832, /* GL_MATRIX5_NV */
- 834, /* GL_MATRIX6_NV */
- 836, /* GL_MATRIX7_NV */
+ 1230, /* GL_PROGRAM_LENGTH_ARB */
+ 1244, /* GL_PROGRAM_STRING_ARB */
+ 988, /* GL_MODELVIEW_PROJECTION_NV */
+ 616, /* GL_IDENTITY_NV */
+ 663, /* GL_INVERSE_NV */
+ 1743, /* GL_TRANSPOSE_NV */
+ 664, /* GL_INVERSE_TRANSPOSE_NV */
+ 895, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
+ 894, /* GL_MAX_PROGRAM_MATRICES_ARB */
+ 802, /* GL_MATRIX0_NV */
+ 814, /* GL_MATRIX1_NV */
+ 826, /* GL_MATRIX2_NV */
+ 830, /* GL_MATRIX3_NV */
+ 832, /* GL_MATRIX4_NV */
+ 834, /* GL_MATRIX5_NV */
+ 836, /* GL_MATRIX6_NV */
+ 838, /* GL_MATRIX7_NV */
318, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
315, /* GL_CURRENT_MATRIX_ARB */
- 1829, /* GL_VERTEX_PROGRAM_POINT_SIZE */
- 1832, /* GL_VERTEX_PROGRAM_TWO_SIDE */
- 1240, /* GL_PROGRAM_PARAMETER_NV */
- 1817, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
- 1244, /* GL_PROGRAM_TARGET_NV */
- 1241, /* GL_PROGRAM_RESIDENT_NV */
- 1731, /* GL_TRACK_MATRIX_NV */
- 1732, /* GL_TRACK_MATRIX_TRANSFORM_NV */
- 1827, /* GL_VERTEX_PROGRAM_BINDING_NV */
- 1222, /* GL_PROGRAM_ERROR_POSITION_ARB */
+ 1833, /* GL_VERTEX_PROGRAM_POINT_SIZE */
+ 1836, /* GL_VERTEX_PROGRAM_TWO_SIDE */
+ 1242, /* GL_PROGRAM_PARAMETER_NV */
+ 1821, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
+ 1246, /* GL_PROGRAM_TARGET_NV */
+ 1243, /* GL_PROGRAM_RESIDENT_NV */
+ 1735, /* GL_TRACK_MATRIX_NV */
+ 1736, /* GL_TRACK_MATRIX_TRANSFORM_NV */
+ 1831, /* GL_VERTEX_PROGRAM_BINDING_NV */
+ 1224, /* GL_PROGRAM_ERROR_POSITION_ARB */
355, /* GL_DEPTH_CLAMP */
- 1795, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
- 1802, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
- 1803, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
- 1804, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
- 1805, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
- 1806, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
- 1807, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
- 1808, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
- 1809, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
- 1810, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
- 1796, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
- 1797, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
- 1798, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
- 1799, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
- 1800, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
- 1801, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
- 748, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
- 755, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
- 756, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
- 757, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
- 758, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
- 759, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
- 760, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
- 761, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
- 762, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
- 763, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
- 749, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
- 750, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
- 751, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
- 752, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
- 753, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
- 754, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
- 775, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
- 782, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
- 783, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
- 784, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
- 785, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
- 786, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
- 787, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
- 1221, /* GL_PROGRAM_BINDING_ARB */
- 789, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
- 790, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
- 776, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
- 777, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
- 778, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
- 779, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
- 780, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
- 781, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
- 1647, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
- 1644, /* GL_TEXTURE_COMPRESSED */
- 1025, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
+ 1799, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
+ 1806, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
+ 1807, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
+ 1808, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
+ 1809, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
+ 1810, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
+ 1811, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
+ 1812, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
+ 1813, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
+ 1814, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
+ 1800, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
+ 1801, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
+ 1802, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
+ 1803, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
+ 1804, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
+ 1805, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
+ 750, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
+ 757, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
+ 758, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
+ 759, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
+ 760, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
+ 761, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
+ 762, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
+ 763, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
+ 764, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
+ 765, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
+ 751, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
+ 752, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
+ 753, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
+ 754, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
+ 755, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
+ 756, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
+ 777, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
+ 784, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
+ 785, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
+ 786, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
+ 787, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
+ 788, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
+ 789, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
+ 1223, /* GL_PROGRAM_BINDING_ARB */
+ 791, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
+ 792, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
+ 778, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
+ 779, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
+ 780, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
+ 781, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
+ 782, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
+ 783, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
+ 1651, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
+ 1648, /* GL_TEXTURE_COMPRESSED */
+ 1027, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
269, /* GL_COMPRESSED_TEXTURE_FORMATS */
- 934, /* GL_MAX_VERTEX_UNITS_ARB */
+ 936, /* GL_MAX_VERTEX_UNITS_ARB */
22, /* GL_ACTIVE_VERTEX_UNITS_ARB */
- 1848, /* GL_WEIGHT_SUM_UNITY_ARB */
- 1825, /* GL_VERTEX_BLEND_ARB */
+ 1852, /* GL_WEIGHT_SUM_UNITY_ARB */
+ 1829, /* GL_VERTEX_BLEND_ARB */
336, /* GL_CURRENT_WEIGHT_ARB */
- 1847, /* GL_WEIGHT_ARRAY_TYPE_ARB */
- 1846, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
- 1845, /* GL_WEIGHT_ARRAY_SIZE_ARB */
- 1844, /* GL_WEIGHT_ARRAY_POINTER_ARB */
- 1841, /* GL_WEIGHT_ARRAY_ARB */
+ 1851, /* GL_WEIGHT_ARRAY_TYPE_ARB */
+ 1850, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
+ 1849, /* GL_WEIGHT_ARRAY_SIZE_ARB */
+ 1848, /* GL_WEIGHT_ARRAY_POINTER_ARB */
+ 1845, /* GL_WEIGHT_ARRAY_ARB */
384, /* GL_DOT3_RGB */
385, /* GL_DOT3_RGBA */
263, /* GL_COMPRESSED_RGB_FXT1_3DFX */
258, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
- 994, /* GL_MULTISAMPLE_3DFX */
- 1387, /* GL_SAMPLE_BUFFERS_3DFX */
- 1378, /* GL_SAMPLES_3DFX */
- 975, /* GL_MODELVIEW2_ARB */
- 978, /* GL_MODELVIEW3_ARB */
- 979, /* GL_MODELVIEW4_ARB */
- 980, /* GL_MODELVIEW5_ARB */
- 981, /* GL_MODELVIEW6_ARB */
- 982, /* GL_MODELVIEW7_ARB */
- 983, /* GL_MODELVIEW8_ARB */
- 984, /* GL_MODELVIEW9_ARB */
- 954, /* GL_MODELVIEW10_ARB */
- 955, /* GL_MODELVIEW11_ARB */
- 956, /* GL_MODELVIEW12_ARB */
- 957, /* GL_MODELVIEW13_ARB */
- 958, /* GL_MODELVIEW14_ARB */
- 959, /* GL_MODELVIEW15_ARB */
- 960, /* GL_MODELVIEW16_ARB */
- 961, /* GL_MODELVIEW17_ARB */
- 962, /* GL_MODELVIEW18_ARB */
- 963, /* GL_MODELVIEW19_ARB */
- 965, /* GL_MODELVIEW20_ARB */
- 966, /* GL_MODELVIEW21_ARB */
- 967, /* GL_MODELVIEW22_ARB */
- 968, /* GL_MODELVIEW23_ARB */
- 969, /* GL_MODELVIEW24_ARB */
- 970, /* GL_MODELVIEW25_ARB */
- 971, /* GL_MODELVIEW26_ARB */
- 972, /* GL_MODELVIEW27_ARB */
- 973, /* GL_MODELVIEW28_ARB */
- 974, /* GL_MODELVIEW29_ARB */
- 976, /* GL_MODELVIEW30_ARB */
- 977, /* GL_MODELVIEW31_ARB */
+ 996, /* GL_MULTISAMPLE_3DFX */
+ 1391, /* GL_SAMPLE_BUFFERS_3DFX */
+ 1382, /* GL_SAMPLES_3DFX */
+ 977, /* GL_MODELVIEW2_ARB */
+ 980, /* GL_MODELVIEW3_ARB */
+ 981, /* GL_MODELVIEW4_ARB */
+ 982, /* GL_MODELVIEW5_ARB */
+ 983, /* GL_MODELVIEW6_ARB */
+ 984, /* GL_MODELVIEW7_ARB */
+ 985, /* GL_MODELVIEW8_ARB */
+ 986, /* GL_MODELVIEW9_ARB */
+ 956, /* GL_MODELVIEW10_ARB */
+ 957, /* GL_MODELVIEW11_ARB */
+ 958, /* GL_MODELVIEW12_ARB */
+ 959, /* GL_MODELVIEW13_ARB */
+ 960, /* GL_MODELVIEW14_ARB */
+ 961, /* GL_MODELVIEW15_ARB */
+ 962, /* GL_MODELVIEW16_ARB */
+ 963, /* GL_MODELVIEW17_ARB */
+ 964, /* GL_MODELVIEW18_ARB */
+ 965, /* GL_MODELVIEW19_ARB */
+ 967, /* GL_MODELVIEW20_ARB */
+ 968, /* GL_MODELVIEW21_ARB */
+ 969, /* GL_MODELVIEW22_ARB */
+ 970, /* GL_MODELVIEW23_ARB */
+ 971, /* GL_MODELVIEW24_ARB */
+ 972, /* GL_MODELVIEW25_ARB */
+ 973, /* GL_MODELVIEW26_ARB */
+ 974, /* GL_MODELVIEW27_ARB */
+ 975, /* GL_MODELVIEW28_ARB */
+ 976, /* GL_MODELVIEW29_ARB */
+ 978, /* GL_MODELVIEW30_ARB */
+ 979, /* GL_MODELVIEW31_ARB */
389, /* GL_DOT3_RGB_EXT */
387, /* GL_DOT3_RGBA_EXT */
- 948, /* GL_MIRROR_CLAMP_EXT */
- 951, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
- 989, /* GL_MODULATE_ADD_ATI */
- 990, /* GL_MODULATE_SIGNED_ADD_ATI */
- 991, /* GL_MODULATE_SUBTRACT_ATI */
- 1854, /* GL_YCBCR_MESA */
- 1081, /* GL_PACK_INVERT_MESA */
+ 950, /* GL_MIRROR_CLAMP_EXT */
+ 953, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
+ 991, /* GL_MODULATE_ADD_ATI */
+ 992, /* GL_MODULATE_SIGNED_ADD_ATI */
+ 993, /* GL_MODULATE_SUBTRACT_ATI */
+ 1858, /* GL_YCBCR_MESA */
+ 1083, /* GL_PACK_INVERT_MESA */
339, /* GL_DEBUG_OBJECT_MESA */
340, /* GL_DEBUG_PRINT_MESA */
338, /* GL_DEBUG_ASSERT_MESA */
@@ -4758,24 +4766,24 @@ static const unsigned reduced_enums[1347] =
447, /* GL_DU8DV8_ATI */
114, /* GL_BUMP_ENVMAP_ATI */
118, /* GL_BUMP_TARGET_ATI */
- 1486, /* GL_STENCIL_BACK_FUNC */
- 1484, /* GL_STENCIL_BACK_FAIL */
- 1488, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
- 1490, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
- 532, /* GL_FRAGMENT_PROGRAM_ARB */
- 1219, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
- 1247, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
- 1246, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
- 1231, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- 1237, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- 1236, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- 882, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
- 905, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
- 904, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
- 895, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- 901, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- 900, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- 865, /* GL_MAX_DRAW_BUFFERS */
+ 1490, /* GL_STENCIL_BACK_FUNC */
+ 1488, /* GL_STENCIL_BACK_FAIL */
+ 1492, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
+ 1494, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
+ 533, /* GL_FRAGMENT_PROGRAM_ARB */
+ 1221, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ 1249, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ 1248, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
+ 1233, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ 1239, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ 1238, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ 884, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
+ 907, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
+ 906, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
+ 897, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
+ 903, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
+ 902, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
+ 867, /* GL_MAX_DRAW_BUFFERS */
393, /* GL_DRAW_BUFFER0 */
396, /* GL_DRAW_BUFFER1 */
417, /* GL_DRAW_BUFFER2 */
@@ -4793,253 +4801,253 @@ static const unsigned reduced_enums[1347] =
409, /* GL_DRAW_BUFFER14 */
412, /* GL_DRAW_BUFFER15 */
82, /* GL_BLEND_EQUATION_ALPHA */
- 845, /* GL_MATRIX_PALETTE_ARB */
- 876, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
- 879, /* GL_MAX_PALETTE_MATRICES_ARB */
+ 847, /* GL_MATRIX_PALETTE_ARB */
+ 878, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
+ 881, /* GL_MAX_PALETTE_MATRICES_ARB */
321, /* GL_CURRENT_PALETTE_MATRIX_ARB */
- 839, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ 841, /* GL_MATRIX_INDEX_ARRAY_ARB */
316, /* GL_CURRENT_MATRIX_INDEX_ARB */
- 841, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
- 843, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
- 842, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
- 840, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
- 1674, /* GL_TEXTURE_DEPTH_SIZE */
+ 843, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
+ 845, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
+ 844, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
+ 842, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
+ 1678, /* GL_TEXTURE_DEPTH_SIZE */
377, /* GL_DEPTH_TEXTURE_MODE */
- 1639, /* GL_TEXTURE_COMPARE_MODE */
- 1637, /* GL_TEXTURE_COMPARE_FUNC */
+ 1643, /* GL_TEXTURE_COMPARE_MODE */
+ 1641, /* GL_TEXTURE_COMPARE_FUNC */
242, /* GL_COMPARE_R_TO_TEXTURE */
- 1153, /* GL_POINT_SPRITE */
+ 1155, /* GL_POINT_SPRITE */
296, /* GL_COORD_REPLACE */
- 1157, /* GL_POINT_SPRITE_R_MODE_NV */
- 1276, /* GL_QUERY_COUNTER_BITS */
+ 1159, /* GL_POINT_SPRITE_R_MODE_NV */
+ 1280, /* GL_QUERY_COUNTER_BITS */
323, /* GL_CURRENT_QUERY */
- 1278, /* GL_QUERY_RESULT */
- 1280, /* GL_QUERY_RESULT_AVAILABLE */
- 928, /* GL_MAX_VERTEX_ATTRIBS */
- 1815, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
+ 1282, /* GL_QUERY_RESULT */
+ 1284, /* GL_QUERY_RESULT_AVAILABLE */
+ 930, /* GL_MAX_VERTEX_ATTRIBS */
+ 1819, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
375, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
374, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
- 914, /* GL_MAX_TEXTURE_COORDS */
- 916, /* GL_MAX_TEXTURE_IMAGE_UNITS */
- 1224, /* GL_PROGRAM_ERROR_STRING_ARB */
- 1226, /* GL_PROGRAM_FORMAT_ASCII_ARB */
- 1225, /* GL_PROGRAM_FORMAT_ARB */
- 1723, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
+ 916, /* GL_MAX_TEXTURE_COORDS */
+ 918, /* GL_MAX_TEXTURE_IMAGE_UNITS */
+ 1226, /* GL_PROGRAM_ERROR_STRING_ARB */
+ 1228, /* GL_PROGRAM_FORMAT_ASCII_ARB */
+ 1227, /* GL_PROGRAM_FORMAT_ARB */
+ 1727, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
353, /* GL_DEPTH_BOUNDS_TEST_EXT */
352, /* GL_DEPTH_BOUNDS_EXT */
53, /* GL_ARRAY_BUFFER */
461, /* GL_ELEMENT_ARRAY_BUFFER */
54, /* GL_ARRAY_BUFFER_BINDING */
462, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
- 1789, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
- 1015, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ 1793, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ 1017, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
149, /* GL_COLOR_ARRAY_BUFFER_BINDING */
- 624, /* GL_INDEX_ARRAY_BUFFER_BINDING */
- 1652, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ 625, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ 1656, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
457, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
- 1399, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
- 510, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
- 1842, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
- 1811, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
- 1227, /* GL_PROGRAM_INSTRUCTIONS_ARB */
- 888, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
- 1233, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- 897, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- 1245, /* GL_PROGRAM_TEMPORARIES_ARB */
- 903, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
- 1235, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
- 899, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
- 1239, /* GL_PROGRAM_PARAMETERS_ARB */
- 902, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
- 1234, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
- 898, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
- 1220, /* GL_PROGRAM_ATTRIBS_ARB */
- 883, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
- 1232, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
- 896, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
- 1218, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
- 881, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
- 1230, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- 894, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- 889, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
- 885, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
- 1248, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
- 1736, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
- 1289, /* GL_READ_ONLY */
- 1850, /* GL_WRITE_ONLY */
- 1291, /* GL_READ_WRITE */
+ 1403, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
+ 511, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
+ 1846, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
+ 1815, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
+ 1229, /* GL_PROGRAM_INSTRUCTIONS_ARB */
+ 890, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
+ 1235, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ 899, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
+ 1247, /* GL_PROGRAM_TEMPORARIES_ARB */
+ 905, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
+ 1237, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ 901, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
+ 1241, /* GL_PROGRAM_PARAMETERS_ARB */
+ 904, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
+ 1236, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
+ 900, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
+ 1222, /* GL_PROGRAM_ATTRIBS_ARB */
+ 885, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
+ 1234, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
+ 898, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
+ 1220, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
+ 883, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
+ 1232, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ 896, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
+ 891, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
+ 887, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
+ 1250, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
+ 1740, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
+ 1293, /* GL_READ_ONLY */
+ 1854, /* GL_WRITE_ONLY */
+ 1295, /* GL_READ_WRITE */
102, /* GL_BUFFER_ACCESS */
105, /* GL_BUFFER_MAPPED */
107, /* GL_BUFFER_MAP_POINTER */
- 1730, /* GL_TIME_ELAPSED_EXT */
- 799, /* GL_MATRIX0_ARB */
- 811, /* GL_MATRIX1_ARB */
- 823, /* GL_MATRIX2_ARB */
- 827, /* GL_MATRIX3_ARB */
- 829, /* GL_MATRIX4_ARB */
- 831, /* GL_MATRIX5_ARB */
- 833, /* GL_MATRIX6_ARB */
- 835, /* GL_MATRIX7_ARB */
- 837, /* GL_MATRIX8_ARB */
- 838, /* GL_MATRIX9_ARB */
- 801, /* GL_MATRIX10_ARB */
- 802, /* GL_MATRIX11_ARB */
- 803, /* GL_MATRIX12_ARB */
- 804, /* GL_MATRIX13_ARB */
- 805, /* GL_MATRIX14_ARB */
- 806, /* GL_MATRIX15_ARB */
- 807, /* GL_MATRIX16_ARB */
- 808, /* GL_MATRIX17_ARB */
- 809, /* GL_MATRIX18_ARB */
- 810, /* GL_MATRIX19_ARB */
- 813, /* GL_MATRIX20_ARB */
- 814, /* GL_MATRIX21_ARB */
- 815, /* GL_MATRIX22_ARB */
- 816, /* GL_MATRIX23_ARB */
- 817, /* GL_MATRIX24_ARB */
- 818, /* GL_MATRIX25_ARB */
- 819, /* GL_MATRIX26_ARB */
- 820, /* GL_MATRIX27_ARB */
- 821, /* GL_MATRIX28_ARB */
- 822, /* GL_MATRIX29_ARB */
- 825, /* GL_MATRIX30_ARB */
- 826, /* GL_MATRIX31_ARB */
- 1519, /* GL_STREAM_DRAW */
- 1521, /* GL_STREAM_READ */
- 1517, /* GL_STREAM_COPY */
- 1477, /* GL_STATIC_DRAW */
- 1479, /* GL_STATIC_READ */
- 1475, /* GL_STATIC_COPY */
+ 1734, /* GL_TIME_ELAPSED_EXT */
+ 801, /* GL_MATRIX0_ARB */
+ 813, /* GL_MATRIX1_ARB */
+ 825, /* GL_MATRIX2_ARB */
+ 829, /* GL_MATRIX3_ARB */
+ 831, /* GL_MATRIX4_ARB */
+ 833, /* GL_MATRIX5_ARB */
+ 835, /* GL_MATRIX6_ARB */
+ 837, /* GL_MATRIX7_ARB */
+ 839, /* GL_MATRIX8_ARB */
+ 840, /* GL_MATRIX9_ARB */
+ 803, /* GL_MATRIX10_ARB */
+ 804, /* GL_MATRIX11_ARB */
+ 805, /* GL_MATRIX12_ARB */
+ 806, /* GL_MATRIX13_ARB */
+ 807, /* GL_MATRIX14_ARB */
+ 808, /* GL_MATRIX15_ARB */
+ 809, /* GL_MATRIX16_ARB */
+ 810, /* GL_MATRIX17_ARB */
+ 811, /* GL_MATRIX18_ARB */
+ 812, /* GL_MATRIX19_ARB */
+ 815, /* GL_MATRIX20_ARB */
+ 816, /* GL_MATRIX21_ARB */
+ 817, /* GL_MATRIX22_ARB */
+ 818, /* GL_MATRIX23_ARB */
+ 819, /* GL_MATRIX24_ARB */
+ 820, /* GL_MATRIX25_ARB */
+ 821, /* GL_MATRIX26_ARB */
+ 822, /* GL_MATRIX27_ARB */
+ 823, /* GL_MATRIX28_ARB */
+ 824, /* GL_MATRIX29_ARB */
+ 827, /* GL_MATRIX30_ARB */
+ 828, /* GL_MATRIX31_ARB */
+ 1523, /* GL_STREAM_DRAW */
+ 1525, /* GL_STREAM_READ */
+ 1521, /* GL_STREAM_COPY */
+ 1481, /* GL_STATIC_DRAW */
+ 1483, /* GL_STATIC_READ */
+ 1479, /* GL_STATIC_COPY */
451, /* GL_DYNAMIC_DRAW */
453, /* GL_DYNAMIC_READ */
449, /* GL_DYNAMIC_COPY */
- 1121, /* GL_PIXEL_PACK_BUFFER */
- 1125, /* GL_PIXEL_UNPACK_BUFFER */
- 1122, /* GL_PIXEL_PACK_BUFFER_BINDING */
- 1126, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
+ 1123, /* GL_PIXEL_PACK_BUFFER */
+ 1127, /* GL_PIXEL_UNPACK_BUFFER */
+ 1124, /* GL_PIXEL_PACK_BUFFER_BINDING */
+ 1128, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
347, /* GL_DEPTH24_STENCIL8 */
- 1720, /* GL_TEXTURE_STENCIL_SIZE */
- 1672, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
- 884, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
- 887, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
- 891, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
- 890, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
- 848, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
- 1510, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ 1724, /* GL_TEXTURE_STENCIL_SIZE */
+ 1676, /* GL_TEXTURE_CUBE_MAP_SEAMLESS */
+ 886, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
+ 889, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
+ 893, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
+ 892, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
+ 850, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
+ 1514, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
17, /* GL_ACTIVE_STENCIL_FACE_EXT */
- 949, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
- 1380, /* GL_SAMPLES_PASSED */
+ 951, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ 1384, /* GL_SAMPLES_PASSED */
109, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
104, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
- 533, /* GL_FRAGMENT_SHADER */
- 1835, /* GL_VERTEX_SHADER */
- 1238, /* GL_PROGRAM_OBJECT_ARB */
- 1412, /* GL_SHADER_OBJECT_ARB */
- 872, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
- 932, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
- 926, /* GL_MAX_VARYING_FLOATS */
- 930, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
- 857, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
- 1041, /* GL_OBJECT_TYPE_ARB */
- 1414, /* GL_SHADER_TYPE */
- 498, /* GL_FLOAT_VEC2 */
- 500, /* GL_FLOAT_VEC3 */
- 502, /* GL_FLOAT_VEC4 */
- 651, /* GL_INT_VEC2 */
- 653, /* GL_INT_VEC3 */
- 655, /* GL_INT_VEC4 */
+ 534, /* GL_FRAGMENT_SHADER */
+ 1839, /* GL_VERTEX_SHADER */
+ 1240, /* GL_PROGRAM_OBJECT_ARB */
+ 1416, /* GL_SHADER_OBJECT_ARB */
+ 874, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
+ 934, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
+ 928, /* GL_MAX_VARYING_FLOATS */
+ 932, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
+ 859, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
+ 1043, /* GL_OBJECT_TYPE_ARB */
+ 1418, /* GL_SHADER_TYPE */
+ 499, /* GL_FLOAT_VEC2 */
+ 501, /* GL_FLOAT_VEC3 */
+ 503, /* GL_FLOAT_VEC4 */
+ 652, /* GL_INT_VEC2 */
+ 654, /* GL_INT_VEC3 */
+ 656, /* GL_INT_VEC4 */
94, /* GL_BOOL */
96, /* GL_BOOL_VEC2 */
98, /* GL_BOOL_VEC3 */
100, /* GL_BOOL_VEC4 */
- 486, /* GL_FLOAT_MAT2 */
- 490, /* GL_FLOAT_MAT3 */
- 494, /* GL_FLOAT_MAT4 */
- 1371, /* GL_SAMPLER_1D */
- 1373, /* GL_SAMPLER_2D */
- 1375, /* GL_SAMPLER_3D */
- 1376, /* GL_SAMPLER_CUBE */
- 1372, /* GL_SAMPLER_1D_SHADOW */
- 1374, /* GL_SAMPLER_2D_SHADOW */
- 488, /* GL_FLOAT_MAT2x3 */
- 489, /* GL_FLOAT_MAT2x4 */
- 492, /* GL_FLOAT_MAT3x2 */
- 493, /* GL_FLOAT_MAT3x4 */
- 496, /* GL_FLOAT_MAT4x2 */
- 497, /* GL_FLOAT_MAT4x3 */
+ 487, /* GL_FLOAT_MAT2 */
+ 491, /* GL_FLOAT_MAT3 */
+ 495, /* GL_FLOAT_MAT4 */
+ 1375, /* GL_SAMPLER_1D */
+ 1377, /* GL_SAMPLER_2D */
+ 1379, /* GL_SAMPLER_3D */
+ 1380, /* GL_SAMPLER_CUBE */
+ 1376, /* GL_SAMPLER_1D_SHADOW */
+ 1378, /* GL_SAMPLER_2D_SHADOW */
+ 489, /* GL_FLOAT_MAT2x3 */
+ 490, /* GL_FLOAT_MAT2x4 */
+ 493, /* GL_FLOAT_MAT3x2 */
+ 494, /* GL_FLOAT_MAT3x4 */
+ 497, /* GL_FLOAT_MAT4x2 */
+ 498, /* GL_FLOAT_MAT4x3 */
345, /* GL_DELETE_STATUS */
246, /* GL_COMPILE_STATUS */
- 706, /* GL_LINK_STATUS */
- 1783, /* GL_VALIDATE_STATUS */
- 636, /* GL_INFO_LOG_LENGTH */
+ 708, /* GL_LINK_STATUS */
+ 1787, /* GL_VALIDATE_STATUS */
+ 637, /* GL_INFO_LOG_LENGTH */
56, /* GL_ATTACHED_SHADERS */
20, /* GL_ACTIVE_UNIFORMS */
21, /* GL_ACTIVE_UNIFORM_MAX_LENGTH */
- 1413, /* GL_SHADER_SOURCE_LENGTH */
+ 1417, /* GL_SHADER_SOURCE_LENGTH */
15, /* GL_ACTIVE_ATTRIBUTES */
16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
- 535, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
- 1416, /* GL_SHADING_LANGUAGE_VERSION */
+ 536, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+ 1420, /* GL_SHADING_LANGUAGE_VERSION */
322, /* GL_CURRENT_PROGRAM */
- 1090, /* GL_PALETTE4_RGB8_OES */
- 1092, /* GL_PALETTE4_RGBA8_OES */
- 1088, /* GL_PALETTE4_R5_G6_B5_OES */
- 1091, /* GL_PALETTE4_RGBA4_OES */
- 1089, /* GL_PALETTE4_RGB5_A1_OES */
- 1095, /* GL_PALETTE8_RGB8_OES */
- 1097, /* GL_PALETTE8_RGBA8_OES */
- 1093, /* GL_PALETTE8_R5_G6_B5_OES */
- 1096, /* GL_PALETTE8_RGBA4_OES */
- 1094, /* GL_PALETTE8_RGB5_A1_OES */
- 618, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
- 617, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
- 1768, /* GL_UNSIGNED_NORMALIZED */
- 1607, /* GL_TEXTURE_1D_ARRAY_EXT */
- 1259, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
- 1609, /* GL_TEXTURE_2D_ARRAY_EXT */
- 1262, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
- 1615, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
- 1617, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
- 1469, /* GL_SRGB */
- 1470, /* GL_SRGB8 */
- 1472, /* GL_SRGB_ALPHA */
- 1471, /* GL_SRGB8_ALPHA8 */
- 1429, /* GL_SLUMINANCE_ALPHA */
- 1428, /* GL_SLUMINANCE8_ALPHA8 */
- 1426, /* GL_SLUMINANCE */
- 1427, /* GL_SLUMINANCE8 */
+ 1092, /* GL_PALETTE4_RGB8_OES */
+ 1094, /* GL_PALETTE4_RGBA8_OES */
+ 1090, /* GL_PALETTE4_R5_G6_B5_OES */
+ 1093, /* GL_PALETTE4_RGBA4_OES */
+ 1091, /* GL_PALETTE4_RGB5_A1_OES */
+ 1097, /* GL_PALETTE8_RGB8_OES */
+ 1099, /* GL_PALETTE8_RGBA8_OES */
+ 1095, /* GL_PALETTE8_R5_G6_B5_OES */
+ 1098, /* GL_PALETTE8_RGBA4_OES */
+ 1096, /* GL_PALETTE8_RGB5_A1_OES */
+ 619, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
+ 618, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
+ 1772, /* GL_UNSIGNED_NORMALIZED */
+ 1611, /* GL_TEXTURE_1D_ARRAY_EXT */
+ 1262, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
+ 1613, /* GL_TEXTURE_2D_ARRAY_EXT */
+ 1265, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
+ 1619, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
+ 1621, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
+ 1473, /* GL_SRGB */
+ 1474, /* GL_SRGB8 */
+ 1476, /* GL_SRGB_ALPHA */
+ 1475, /* GL_SRGB8_ALPHA8 */
+ 1433, /* GL_SLUMINANCE_ALPHA */
+ 1432, /* GL_SLUMINANCE8_ALPHA8 */
+ 1430, /* GL_SLUMINANCE */
+ 1431, /* GL_SLUMINANCE8 */
267, /* GL_COMPRESSED_SRGB */
268, /* GL_COMPRESSED_SRGB_ALPHA */
265, /* GL_COMPRESSED_SLUMINANCE */
266, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
- 1155, /* GL_POINT_SPRITE_COORD_ORIGIN */
- 714, /* GL_LOWER_LEFT */
- 1780, /* GL_UPPER_LEFT */
- 1492, /* GL_STENCIL_BACK_REF */
- 1493, /* GL_STENCIL_BACK_VALUE_MASK */
- 1494, /* GL_STENCIL_BACK_WRITEMASK */
+ 1157, /* GL_POINT_SPRITE_COORD_ORIGIN */
+ 716, /* GL_LOWER_LEFT */
+ 1784, /* GL_UPPER_LEFT */
+ 1496, /* GL_STENCIL_BACK_REF */
+ 1497, /* GL_STENCIL_BACK_VALUE_MASK */
+ 1498, /* GL_STENCIL_BACK_WRITEMASK */
442, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
- 1305, /* GL_RENDERBUFFER_BINDING_EXT */
- 1286, /* GL_READ_FRAMEBUFFER */
+ 1309, /* GL_RENDERBUFFER_BINDING_EXT */
+ 1290, /* GL_READ_FRAMEBUFFER */
441, /* GL_DRAW_FRAMEBUFFER */
- 1287, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
- 1315, /* GL_RENDERBUFFER_SAMPLES */
- 545, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
- 543, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
- 554, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
- 550, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
- 552, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
- 557, /* GL_FRAMEBUFFER_COMPLETE */
- 561, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
- 567, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
- 565, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
- 563, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
- 566, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
- 564, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
- 570, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
- 573, /* GL_FRAMEBUFFER_UNSUPPORTED */
- 571, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- 854, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
+ 1291, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
+ 1319, /* GL_RENDERBUFFER_SAMPLES */
+ 546, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
+ 544, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
+ 555, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
+ 551, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
+ 553, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+ 558, /* GL_FRAMEBUFFER_COMPLETE */
+ 562, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
+ 568, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
+ 566, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
+ 564, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
+ 567, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
+ 565, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
+ 571, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
+ 574, /* GL_FRAMEBUFFER_UNSUPPORTED */
+ 572, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
+ 856, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
155, /* GL_COLOR_ATTACHMENT0 */
157, /* GL_COLOR_ATTACHMENT1 */
171, /* GL_COLOR_ATTACHMENT2 */
@@ -5057,56 +5065,56 @@ static const unsigned reduced_enums[1347] =
166, /* GL_COLOR_ATTACHMENT14 */
168, /* GL_COLOR_ATTACHMENT15 */
348, /* GL_DEPTH_ATTACHMENT */
- 1482, /* GL_STENCIL_ATTACHMENT */
- 536, /* GL_FRAMEBUFFER */
- 1303, /* GL_RENDERBUFFER */
- 1317, /* GL_RENDERBUFFER_WIDTH */
- 1310, /* GL_RENDERBUFFER_HEIGHT */
- 1312, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
- 1505, /* GL_STENCIL_INDEX_EXT */
- 1502, /* GL_STENCIL_INDEX1_EXT */
- 1503, /* GL_STENCIL_INDEX4_EXT */
- 1504, /* GL_STENCIL_INDEX8_EXT */
- 1501, /* GL_STENCIL_INDEX16_EXT */
- 1314, /* GL_RENDERBUFFER_RED_SIZE */
- 1309, /* GL_RENDERBUFFER_GREEN_SIZE */
- 1306, /* GL_RENDERBUFFER_BLUE_SIZE */
- 1304, /* GL_RENDERBUFFER_ALPHA_SIZE */
- 1307, /* GL_RENDERBUFFER_DEPTH_SIZE */
- 1316, /* GL_RENDERBUFFER_STENCIL_SIZE */
- 569, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
- 910, /* GL_MAX_SAMPLES */
- 1273, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
- 483, /* GL_FIRST_VERTEX_CONVENTION_EXT */
- 666, /* GL_LAST_VERTEX_CONVENTION_EXT */
- 1252, /* GL_PROVOKING_VERTEX_EXT */
+ 1486, /* GL_STENCIL_ATTACHMENT */
+ 537, /* GL_FRAMEBUFFER */
+ 1307, /* GL_RENDERBUFFER */
+ 1321, /* GL_RENDERBUFFER_WIDTH */
+ 1314, /* GL_RENDERBUFFER_HEIGHT */
+ 1316, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
+ 1509, /* GL_STENCIL_INDEX_EXT */
+ 1506, /* GL_STENCIL_INDEX1_EXT */
+ 1507, /* GL_STENCIL_INDEX4_EXT */
+ 1508, /* GL_STENCIL_INDEX8_EXT */
+ 1505, /* GL_STENCIL_INDEX16_EXT */
+ 1318, /* GL_RENDERBUFFER_RED_SIZE */
+ 1313, /* GL_RENDERBUFFER_GREEN_SIZE */
+ 1310, /* GL_RENDERBUFFER_BLUE_SIZE */
+ 1308, /* GL_RENDERBUFFER_ALPHA_SIZE */
+ 1311, /* GL_RENDERBUFFER_DEPTH_SIZE */
+ 1320, /* GL_RENDERBUFFER_STENCIL_SIZE */
+ 570, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
+ 912, /* GL_MAX_SAMPLES */
+ 1276, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+ 483, /* GL_FIRST_VERTEX_CONVENTION */
+ 667, /* GL_LAST_VERTEX_CONVENTION */
+ 1254, /* GL_PROVOKING_VERTEX */
302, /* GL_COPY_READ_BUFFER */
303, /* GL_COPY_WRITE_BUFFER */
- 1364, /* GL_RGBA_SNORM */
- 1360, /* GL_RGBA8_SNORM */
- 1422, /* GL_SIGNED_NORMALIZED */
- 911, /* GL_MAX_SERVER_WAIT_TIMEOUT */
- 1040, /* GL_OBJECT_TYPE */
- 1526, /* GL_SYNC_CONDITION */
- 1531, /* GL_SYNC_STATUS */
- 1528, /* GL_SYNC_FLAGS */
- 1527, /* GL_SYNC_FENCE */
- 1530, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
- 1757, /* GL_UNSIGNALED */
- 1421, /* GL_SIGNALED */
+ 1368, /* GL_RGBA_SNORM */
+ 1364, /* GL_RGBA8_SNORM */
+ 1426, /* GL_SIGNED_NORMALIZED */
+ 913, /* GL_MAX_SERVER_WAIT_TIMEOUT */
+ 1042, /* GL_OBJECT_TYPE */
+ 1530, /* GL_SYNC_CONDITION */
+ 1535, /* GL_SYNC_STATUS */
+ 1532, /* GL_SYNC_FLAGS */
+ 1531, /* GL_SYNC_FENCE */
+ 1534, /* GL_SYNC_GPU_COMMANDS_COMPLETE */
+ 1761, /* GL_UNSIGNALED */
+ 1425, /* GL_SIGNALED */
46, /* GL_ALREADY_SIGNALED */
- 1728, /* GL_TIMEOUT_EXPIRED */
+ 1732, /* GL_TIMEOUT_EXPIRED */
270, /* GL_CONDITION_SATISFIED */
- 1840, /* GL_WAIT_FAILED */
+ 1844, /* GL_WAIT_FAILED */
468, /* GL_EVAL_BIT */
- 1284, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
- 708, /* GL_LIST_BIT */
- 1623, /* GL_TEXTURE_BIT */
- 1395, /* GL_SCISSOR_BIT */
+ 1288, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ 710, /* GL_LIST_BIT */
+ 1627, /* GL_TEXTURE_BIT */
+ 1399, /* GL_SCISSOR_BIT */
29, /* GL_ALL_ATTRIB_BITS */
- 996, /* GL_MULTISAMPLE_BIT */
+ 998, /* GL_MULTISAMPLE_BIT */
30, /* GL_ALL_CLIENT_ATTRIB_BITS */
- 1729, /* GL_TIMEOUT_IGNORED */
+ 1733, /* GL_TIMEOUT_IGNORED */
};
typedef int (*cfunc)(const void *, const void *);
diff --git a/src/mesa/main/execmem.c b/src/mesa/main/execmem.c
index 57c1e117c89..4c6139985fe 100644
--- a/src/mesa/main/execmem.c
+++ b/src/mesa/main/execmem.c
@@ -80,11 +80,10 @@ init_heap(void)
exec_heap = mmInit( 0, EXEC_HEAP_SIZE );
if (!exec_mem)
- exec_mem = (unsigned char *) mmap(0, EXEC_HEAP_SIZE,
- PROT_EXEC | PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ exec_mem = mmap(NULL, EXEC_HEAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- return (exec_mem != NULL);
+ return (exec_mem != MAP_FAILED);
}
diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c
index 73adb0e2176..2992abd0751 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -63,6 +63,7 @@ static const struct {
{ 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_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) },
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 825a23090b5..13f49da5a78 100644
--- a/src/mesa/main/fbobject.c
+++ b/src/mesa/main/fbobject.c
@@ -46,6 +46,10 @@
#include "texstore.h"
+/** Set this to 1 to help debug FBO incompleteness problems */
+#define DEBUG_FBO 0
+
+
/**
* Notes:
*
@@ -308,8 +312,8 @@ _mesa_framebuffer_renderbuffer(GLcontext *ctx, struct gl_framebuffer *fb,
static void
att_incomplete(const char *msg)
{
-#if 0
- _mesa_printf("attachment incomplete: %s\n", msg);
+#if DEBUG_FBO
+ _mesa_debug(NULL, "attachment incomplete: %s\n", msg);
#else
(void) msg;
#endif
@@ -317,6 +321,23 @@ att_incomplete(const char *msg)
/**
+ * For debug only.
+ */
+static void
+fbo_incomplete(const char *msg, int index)
+{
+#if DEBUG_FBO
+ _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
+#else
+ (void) msg;
+ (void) index;
+#endif
+}
+
+
+
+
+/**
* Test if an attachment point is complete and update its Complete field.
* \param format if GL_COLOR, this is a color attachment point,
* if GL_DEPTH, this is a depth component attachment point,
@@ -468,20 +489,6 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
/**
- * Helpful for debugging
- */
-static void
-fbo_incomplete(const char *msg, int index)
-{
- (void) msg;
- (void) index;
- /*
- _mesa_debug(NULL, "FBO Incomplete: %s [%d]\n", msg, index);
- */
-}
-
-
-/**
* Test if the given framebuffer object is complete and update its
* Status field with the results.
* Calls the ctx->Driver.ValidateFramebuffer() function to allow the
@@ -1953,13 +1960,13 @@ _mesa_GenerateMipmapEXT(GLenum target)
_mesa_lock_texture(ctx, texObj);
if (target == GL_TEXTURE_CUBE_MAP) {
- int face;
-
+ GLuint face;
for (face = 0; face < 6; face++)
ctx->Driver.GenerateMipmap(ctx,
GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + face,
texObj);
- } else {
+ }
+ else {
ctx->Driver.GenerateMipmap(ctx, target, texObj);
}
_mesa_unlock_texture(ctx, texObj);
diff --git a/src/mesa/main/mfeatures.h b/src/mesa/main/mfeatures.h
index e23cdb1f426..6318934c6bf 100644
--- a/src/mesa/main/mfeatures.h
+++ b/src/mesa/main/mfeatures.h
@@ -36,6 +36,38 @@
#define _HAVE_FULL_GL 1
#endif
+/* assert that a feature is disabled and should never be used */
+#define ASSERT_NO_FEATURE() ASSERT(0)
+
+/**
+ * A feature can be anything. But most of them share certain characteristics.
+ *
+ * When a feature defines driver entries, they can be initialized by
+ * _MESA_INIT_<FEATURE>_FUNCTIONS
+ *
+ * When a feature defines vtxfmt entries, they can be initialized and
+ * installed by
+ * _MESA_INIT_<FEATURE>_VTXFMT
+ * _mesa_install_<feature>_vtxfmt
+ *
+ * When a feature defines dispatch entries, they are initialized by
+ * _mesa_init_<feature>_dispatch
+ *
+ * When a feature has states, they are initialized and freed by
+ * _mesa_init_<feature>
+ * _mesa_free_<feature>_data
+ *
+ * Except for states, the others compile to no-op when a feature is disabled.
+ *
+ * The GLAPIENTRYs and helper functions defined by a feature should also
+ * compile to no-op when it is disabled. But to save typings and to catch
+ * bugs, some of them may be unavailable, or compile to ASSERT_NO_FEATURE()
+ * when the feature is disabled.
+ *
+ * A feature following the conventions may be used without knowing if it is
+ * enabled or not.
+ */
+
#define FEATURE_accum _HAVE_FULL_GL
#define FEATURE_attrib_stack _HAVE_FULL_GL
#define FEATURE_colortable _HAVE_FULL_GL
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 823c6dc29c6..d7bf7689f3c 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1834,7 +1834,6 @@ struct gl_vertex_program
struct gl_program Base; /**< base class */
GLboolean IsNVProgram; /**< is this a GL_NV_vertex_program program? */
GLboolean IsPositionInvariant;
- void *TnlData; /**< should probably use Base.DriverData */
};
@@ -2080,6 +2079,7 @@ struct gl_shader_state
GLboolean EmitContReturn; /**< Emit CONT/RET opcodes? */
GLboolean EmitCondCodes; /**< Use condition codes? */
GLboolean EmitComments; /**< Annotated instructions */
+ GLboolean EmitNVTempInitialization; /**< 0-fill NV temp registers */
void *MemPool;
GLbitfield Flags; /**< Mask of GLSL_x flags */
struct gl_sl_pragmas DefaultPragmas; /**< Default #pragma settings */
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index fcef6dfd422..3820ebd8894 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -36,13 +36,17 @@
#include "macros.h"
#include "pixel.h"
#include "mtypes.h"
+#include "glapi/dispatch.h"
+
+
+#if FEATURE_pixel_transfer
/**********************************************************************/
/***** glPixelZoom *****/
/**********************************************************************/
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor )
{
GET_CURRENT_CONTEXT(ctx);
@@ -163,7 +167,7 @@ validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack,
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
{
GET_CURRENT_CONTEXT(ctx);
@@ -205,7 +209,7 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
{
GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
@@ -261,7 +265,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
{
GLfloat fvalues[MAX_PIXEL_MAP_TABLE];
@@ -317,7 +321,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetPixelMapfv( GLenum map, GLfloat *values )
{
GET_CURRENT_CONTEXT(ctx);
@@ -362,7 +366,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetPixelMapuiv( GLenum map, GLuint *values )
{
GET_CURRENT_CONTEXT(ctx);
@@ -406,7 +410,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_GetPixelMapusv( GLenum map, GLushort *values )
{
GET_CURRENT_CONTEXT(ctx);
@@ -468,7 +472,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
* Implements glPixelTransfer[fi] whether called immediately or from a
* display list.
*/
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelTransferf( GLenum pname, GLfloat param )
{
GET_CURRENT_CONTEXT(ctx);
@@ -662,7 +666,7 @@ _mesa_PixelTransferf( GLenum pname, GLfloat param )
}
-void GLAPIENTRY
+static void GLAPIENTRY
_mesa_PixelTransferi( GLenum pname, GLint param )
{
_mesa_PixelTransferf( pname, (GLfloat) param );
@@ -756,6 +760,24 @@ void _mesa_update_pixel( GLcontext *ctx, GLuint new_state )
}
+void
+_mesa_init_pixel_dispatch(struct _glapi_table *disp)
+{
+ SET_GetPixelMapfv(disp, _mesa_GetPixelMapfv);
+ SET_GetPixelMapuiv(disp, _mesa_GetPixelMapuiv);
+ SET_GetPixelMapusv(disp, _mesa_GetPixelMapusv);
+ SET_PixelMapfv(disp, _mesa_PixelMapfv);
+ SET_PixelMapuiv(disp, _mesa_PixelMapuiv);
+ SET_PixelMapusv(disp, _mesa_PixelMapusv);
+ SET_PixelTransferf(disp, _mesa_PixelTransferf);
+ SET_PixelTransferi(disp, _mesa_PixelTransferi);
+ SET_PixelZoom(disp, _mesa_PixelZoom);
+}
+
+
+#endif /* FEATURE_pixel_transfer */
+
+
/**********************************************************************/
/***** Initialization *****/
/**********************************************************************/
diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h
index cb6c5262a39..f4d3f1efdb0 100644
--- a/src/mesa/main/pixel.h
+++ b/src/mesa/main/pixel.h
@@ -33,48 +33,35 @@
#define PIXEL_H
-#include "mtypes.h"
+#include "main/mtypes.h"
-/** \name API functions */
-/*@{*/
+#if FEATURE_pixel_transfer
-extern void GLAPIENTRY
-_mesa_GetPixelMapfv( GLenum map, GLfloat *values );
-
-extern void GLAPIENTRY
-_mesa_GetPixelMapuiv( GLenum map, GLuint *values );
-
-extern void GLAPIENTRY
-_mesa_GetPixelMapusv( GLenum map, GLushort *values );
-
-extern void GLAPIENTRY
-_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values );
-
-extern void GLAPIENTRY
-_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values );
-
-extern void GLAPIENTRY
-_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values );
+extern void
+_mesa_update_pixel( GLcontext *ctx, GLuint newstate );
-extern void GLAPIENTRY
-_mesa_PixelTransferf( GLenum pname, GLfloat param );
+extern void
+_mesa_init_pixel_dispatch( struct _glapi_table * disp );
-extern void GLAPIENTRY
-_mesa_PixelTransferi( GLenum pname, GLint param );
+#else /* FEATURE_pixel_transfer */
-extern void GLAPIENTRY
-_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor );
+static INLINE void
+_mesa_update_pixel(GLcontext *ctx, GLuint newstate)
+{
+}
-/*@}*/
+static INLINE void
+_mesa_init_pixel_dispatch(struct _glapi_table *disp)
+{
+}
+#endif /* FEATURE_pixel_transfer */
-extern void
-_mesa_update_pixel( GLcontext *ctx, GLuint newstate );
extern void
_mesa_init_pixel( GLcontext * ctx );
/*@}*/
-#endif
+#endif /* PIXEL_H */
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index 140a998df2e..f10e6b04b7c 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -40,9 +40,7 @@
#include "framebuffer.h"
#include "light.h"
#include "matrix.h"
-#if FEATURE_pixel_transfer
#include "pixel.h"
-#endif
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "state.h"
@@ -585,10 +583,8 @@ _mesa_update_state_locked( GLcontext *ctx )
if (new_state & (_NEW_STENCIL | _NEW_BUFFERS))
_mesa_update_stencil( ctx );
-#if FEATURE_pixel_transfer
if (new_state & _MESA_NEW_TRANSFER_STATE)
_mesa_update_pixel( ctx, new_state );
-#endif
if (new_state & _DD_NEW_SEPARATE_SPECULAR)
update_separate_specular( ctx );
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 2f3e47e69ec..d7e77e759e0 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -276,6 +276,7 @@ need_saturate( GLuint mode )
return GL_TRUE;
default:
assert(0);
+ return GL_FALSE;
}
}
diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c
index e3feb024c31..b3ecfc784e3 100644
--- a/src/mesa/main/texgen.c
+++ b/src/mesa/main/texgen.c
@@ -35,6 +35,7 @@
#include "main/enums.h"
#include "main/macros.h"
#include "main/texgen.h"
+#include "main/texstate.h"
#include "math/m_matrix.h"
@@ -79,7 +80,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texgen = get_texgen(texUnit, coord);
if (!texgen) {
@@ -231,7 +232,7 @@ _mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texgen = get_texgen(texUnit, coord);
if (!texgen) {
@@ -269,7 +270,7 @@ _mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texgen = get_texgen(texUnit, coord);
if (!texgen) {
@@ -307,7 +308,7 @@ _mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texgen = get_texgen(texUnit, coord);
if (!texgen) {
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 82283030409..465da6b0469 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -33,9 +33,8 @@
#include "glheader.h"
#include "bufferobj.h"
#include "context.h"
-#if FEATURE_convolve
#include "convolve.h"
-#endif
+#include "enums.h"
#include "fbobject.h"
#include "framebuffer.h"
#include "hash.h"
@@ -2075,6 +2074,23 @@ update_fbo_texture(GLcontext *ctx, struct gl_texture_object *texObj,
}
+/**
+ * If the texture object's GenerateMipmap flag is set and we've
+ * changed the texture base level image, regenerate the rest of the
+ * mipmap levels now.
+ */
+static INLINE void
+check_gen_mipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj, GLint level)
+{
+ ASSERT(target != GL_TEXTURE_CUBE_MAP);
+ if (texObj->GenerateMipmap && level == texObj->BaseLevel) {
+ ASSERT(ctx->Driver.GenerateMipmap);
+ ctx->Driver.GenerateMipmap(ctx, target, texObj);
+ }
+}
+
+
/** Debug helper: override the user-requested internal format */
static GLenum
override_internal_format(GLenum internalFormat, GLint width, GLint height)
@@ -2131,6 +2147,13 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexImage1D %s %d %s %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat), width, border,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
internalFormat = override_internal_format(internalFormat, width, 1);
#if FEATURE_convolve
@@ -2161,36 +2184,36 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, 1, 1,
+ border, internalFormat);
+
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage1D);
+ ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
+ width, border, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
- ASSERT(texImage->Data == NULL);
-
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, 1, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.TexImage1D);
-
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
- width, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
-
- update_fbo_texture(ctx, texObj, face, level);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_1D) {
@@ -2230,6 +2253,13 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexImage2D %s %d %s %d %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat), width, height,
+ border, _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
internalFormat = override_internal_format(internalFormat, width, height);
#if FEATURE_convolve
@@ -2269,35 +2299,35 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
-
- ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, postConvHeight, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.TexImage2D);
-
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
- width, height, border, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
-
- ASSERT(texImage->TexFormat);
-
- update_fbo_texture(ctx, texObj, face, level);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage2D);
+ ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
+ width, height, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
+
+ ASSERT(texImage->TexFormat);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_2D ||
@@ -2346,6 +2376,13 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexImage3D %s %d %s %d %d %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat), width, height,
+ depth, border, _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
internalFormat = override_internal_format(internalFormat, width, height);
if (target == GL_TEXTURE_3D ||
@@ -2372,35 +2409,35 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage3D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
-
- ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- width, height, depth,
- border, internalFormat);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
+ border, internalFormat);
- ASSERT(ctx->Driver.TexImage3D);
+ /* Give the texture to the driver. <pixels> may be null. */
+ ASSERT(ctx->Driver.TexImage3D);
+ ctx->Driver.TexImage3D(ctx, target, level, internalFormat,
+ width, height, depth, border, format, type,
+ pixels, &ctx->Unpack, texObj, texImage);
- /* Give the texture to the driver! <pixels> may be null! */
- (*ctx->Driver.TexImage3D)(ctx, target, level, internalFormat,
- width, height, depth, border, format, type,
- pixels, &ctx->Unpack, texObj, texImage);
+ ASSERT(texImage->TexFormat);
- ASSERT(texImage->TexFormat);
+ check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_3D ||
@@ -2455,6 +2492,12 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexSubImage1D %s %d %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ xoffset, width, _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
@@ -2480,23 +2523,24 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (subtexture_error_check2(ctx, 1, target, level, xoffset, 0, 0,
- postConvWidth, 1, 1, format, type, texImage)) {
- goto out; /* error was detected */
+ postConvWidth, 1, 1,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
- if (width == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage1D);
+ ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
+ format, type, pixels, &ctx->Unpack,
+ texObj, texImage);
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ check_gen_mipmap(ctx, target, texObj, level);
- ASSERT(ctx->Driver.TexSubImage1D);
- (*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
- format, type, pixels, &ctx->Unpack,
- texObj, texImage);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2515,6 +2559,13 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexSubImage2D %s %d %d %d %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ xoffset, yoffset, width, height,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
@@ -2533,30 +2584,31 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
if (subtexture_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
- postConvWidth, postConvHeight, 1, format, type,
- texImage)) {
- goto out; /* error was detected */
+ postConvWidth, postConvHeight, 1,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0 && height >= 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+
+ ASSERT(ctx->Driver.TexSubImage2D);
+ ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
+ width, height, format, type, pixels,
+ &ctx->Unpack, texObj, texImage);
- if (width == 0 || height == 0)
- goto out; /* no-op, not an error */
+ check_gen_mipmap(ctx, target, texObj, level);
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
-
- ASSERT(ctx->Driver.TexSubImage2D);
- (*ctx->Driver.TexSubImage2D)(ctx, target, level, xoffset, yoffset,
- width, height, format, type, pixels,
- &ctx->Unpack, texObj, texImage);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2575,6 +2627,13 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glTexSubImage3D %s %d %d %d %d %d %d %d %s %s %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ xoffset, yoffset, zoffset, width, height, depth,
+ _mesa_lookup_enum_by_nr(format),
+ _mesa_lookup_enum_by_nr(type), pixels);
+
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
@@ -2590,28 +2649,30 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (subtexture_error_check2(ctx, 3, target, level, xoffset, yoffset, zoffset,
- width, height, depth, format, type, texImage)) {
- goto out; /* error was detected */
+ if (subtexture_error_check2(ctx, 3, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, texImage)) {
+ /* error was recorded */
}
+ else if (width > 0 && height > 0 && height > 0) {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
- if (width == 0 || height == 0 || height == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage3D);
+ ctx->Driver.TexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ width, height, depth,
+ format, type, pixels,
+ &ctx->Unpack, texObj, texImage );
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
+ check_gen_mipmap(ctx, target, texObj, level);
- ASSERT(ctx->Driver.TexSubImage3D);
- (*ctx->Driver.TexSubImage3D)(ctx, target, level,
- xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels,
- &ctx->Unpack, texObj, texImage );
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2631,6 +2692,12 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCopyTexImage1D %s %d %s %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ x, y, width, border);
+
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
@@ -2646,38 +2713,39 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
- goto out;
}
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
+ ASSERT(texImage->Data == NULL);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
- border, internalFormat);
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage, postConvWidth, 1, 1,
+ border, internalFormat);
+ ASSERT(ctx->Driver.CopyTexImage1D);
+ ctx->Driver.CopyTexImage1D(ctx, target, level, internalFormat,
+ x, y, width, border);
- ASSERT(ctx->Driver.CopyTexImage1D);
- (*ctx->Driver.CopyTexImage1D)(ctx, target, level, internalFormat,
- x, y, width, border);
+ ASSERT(texImage->TexFormat);
- ASSERT(texImage->TexFormat);
+ check_gen_mipmap(ctx, target, texObj, level);
- update_fbo_texture(ctx, texObj, face, level);
+ update_fbo_texture(ctx, texObj, face, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2696,6 +2764,12 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCopyTexImage2D %s %d %s %d %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ x, y, width, height, border);
+
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
@@ -2719,33 +2793,34 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- goto out;
}
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
-
- ASSERT(texImage->Data == NULL);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+
+ ASSERT(texImage->Data == NULL);
+
+ clear_teximage_fields(texImage); /* not really needed, but helpful */
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ postConvWidth, postConvHeight, 1,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CopyTexImage2D);
+ ctx->Driver.CopyTexImage2D(ctx, target, level, internalFormat,
+ x, y, width, height, border);
- clear_teximage_fields(texImage); /* not really needed, but helpful */
- _mesa_init_teximage_fields(ctx, target, texImage,
- postConvWidth, postConvHeight, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CopyTexImage2D);
- (*ctx->Driver.CopyTexImage2D)(ctx, target, level, internalFormat,
- x, y, width, height, border);
-
- ASSERT(texImage->TexFormat);
+ ASSERT(texImage->TexFormat);
- update_fbo_texture(ctx, texObj, face, level);
+ check_gen_mipmap(ctx, target, texObj, level);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ update_fbo_texture(ctx, texObj, face, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2764,6 +2839,11 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCopyTexSubImage1D %s %d %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(target),
+ level, xoffset, x, y, width);
+
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
@@ -2785,23 +2865,25 @@ _mesa_CopyTexSubImage1D( GLenum target, GLint level,
if (copytexsubimage_error_check2(ctx, 1, target, level,
xoffset, 0, 0, postConvWidth, 1,
- texImage))
- goto out;
-
+ texImage)) {
+ /* error was recorded */
+ }
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage1D);
+ ctx->Driver.CopyTexSubImage1D(ctx, target, level,
+ xoffset, x, y, width);
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage1D);
- ctx->Driver.CopyTexSubImage1D(ctx, target, level,
- xoffset, x, y, width);
- }
+ check_gen_mipmap(ctx, target, texObj, level);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2819,6 +2901,11 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCopyTexSubImage2D %s %d %d %d %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(target),
+ level, xoffset, yoffset, x, y, width, height);
+
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
@@ -2839,24 +2926,29 @@ _mesa_CopyTexSubImage2D( GLenum target, GLint level,
}
#endif
- if (copytexsubimage_error_check2(ctx, 2, target, level, xoffset, yoffset, 0,
- postConvWidth, postConvHeight, texImage))
- goto out;
+ if (copytexsubimage_error_check2(ctx, 2, target, level,
+ xoffset, yoffset, 0,
+ postConvWidth, postConvHeight,
+ texImage)) {
+ /* error was recorded */
+ }
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage2D);
+ ctx->Driver.CopyTexSubImage2D(ctx, target, level, xoffset, yoffset,
+ x, y, width, height);
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage2D);
- ctx->Driver.CopyTexSubImage2D(ctx, target, level,
- xoffset, yoffset, x, y, width, height);
- }
+ check_gen_mipmap(ctx, target, texObj, level);
- ctx->NewState |= _NEW_TEXTURE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2874,6 +2966,11 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCopyTexSubImage3D %s %d %d %d %d %d %d %d %d\n",
+ _mesa_lookup_enum_by_nr(target),
+ level, xoffset, yoffset, zoffset, x, y, width, height);
+
if (ctx->NewState & NEW_COPY_TEX_STATE)
_mesa_update_state(ctx);
@@ -2896,25 +2993,28 @@ _mesa_CopyTexSubImage3D( GLenum target, GLint level,
if (copytexsubimage_error_check2(ctx, 3, target, level, xoffset, yoffset,
zoffset, postConvWidth, postConvHeight,
- texImage))
- goto out;
-
- /* If we have a border, xoffset=-1 is legal. Bias by border width */
- xoffset += texImage->Border;
- yoffset += texImage->Border;
- zoffset += texImage->Border;
-
- if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
- &width, &height)) {
- ASSERT(ctx->Driver.CopyTexSubImage3D);
- ctx->Driver.CopyTexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset,
- x, y, width, height);
+ texImage)) {
+ /* error was recored */
}
+ else {
+ /* If we have a border, xoffset=-1 is legal. Bias by border width */
+ xoffset += texImage->Border;
+ yoffset += texImage->Border;
+ zoffset += texImage->Border;
+
+ if (_mesa_clip_copytexsubimage(ctx, &xoffset, &yoffset, &x, &y,
+ &width, &height)) {
+ ASSERT(ctx->Driver.CopyTexSubImage3D);
+ ctx->Driver.CopyTexSubImage3D(ctx, target, level,
+ xoffset, yoffset, zoffset,
+ x, y, width, height);
- ctx->NewState |= _NEW_TEXTURE;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -3122,6 +3222,12 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCompressedTexImage1DARB %s %d %s %d %d %d %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, border, imageSize, data);
+
if (target == GL_TEXTURE_1D) {
/* non-proxy target */
struct gl_texture_unit *texUnit;
@@ -3142,28 +3248,29 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage1D");
- goto out;
}
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
- }
- ASSERT(texImage->Data == NULL);
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
- _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
- border, internalFormat);
+ _mesa_init_teximage_fields(ctx, target, texImage, width, 1, 1,
+ border, internalFormat);
- ASSERT(ctx->Driver.CompressedTexImage1D);
- (*ctx->Driver.CompressedTexImage1D)(ctx, target, level,
- internalFormat, width, border,
- imageSize, data,
- texObj, texImage);
+ ASSERT(ctx->Driver.CompressedTexImage1D);
+ ctx->Driver.CompressedTexImage1D(ctx, target, level,
+ internalFormat, width, border,
+ imageSize, data,
+ texObj, texImage);
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_1D) {
@@ -3216,6 +3323,12 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCompressedTexImage2DARB %s %d %s %d %d %d %d %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, border, imageSize, data);
+
if (target == GL_TEXTURE_2D ||
(ctx->Extensions.ARB_texture_cube_map &&
target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB &&
@@ -3239,28 +3352,29 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage2D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CompressedTexImage2D);
- (*ctx->Driver.CompressedTexImage2D)(ctx, target, level,
- internalFormat, width, height,
- border, imageSize, data,
- texObj, texImage);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage, width, height, 1,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CompressedTexImage2D);
+ ctx->Driver.CompressedTexImage2D(ctx, target, level,
+ internalFormat, width, height,
+ border, imageSize, data,
+ texObj, texImage);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_2D ||
@@ -3315,6 +3429,12 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE))
+ _mesa_debug(ctx, "glCompressedTexImage3DARB %s %d %s %d %d %d %d %d %p\n",
+ _mesa_lookup_enum_by_nr(target), level,
+ _mesa_lookup_enum_by_nr(internalFormat),
+ width, height, depth, border, imageSize, data);
+
if (target == GL_TEXTURE_3D) {
/* non-proxy target */
struct gl_texture_unit *texUnit;
@@ -3334,29 +3454,31 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
texImage = _mesa_get_tex_image(ctx, texObj, target, level);
if (!texImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage3D");
- goto out;
- }
-
- if (texImage->Data) {
- ctx->Driver.FreeTexImageData( ctx, texImage );
}
- ASSERT(texImage->Data == NULL);
-
- _mesa_init_teximage_fields(ctx, target, texImage, width, height, depth,
- border, internalFormat);
-
- ASSERT(ctx->Driver.CompressedTexImage3D);
- (*ctx->Driver.CompressedTexImage3D)(ctx, target, level,
- internalFormat,
- width, height, depth,
- border, imageSize, data,
- texObj, texImage);
-
- /* state update */
- texObj->_Complete = GL_FALSE;
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
+ else {
+ if (texImage->Data) {
+ ctx->Driver.FreeTexImageData( ctx, texImage );
+ }
+ ASSERT(texImage->Data == NULL);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ width, height, depth,
+ border, internalFormat);
+
+ ASSERT(ctx->Driver.CompressedTexImage3D);
+ ctx->Driver.CompressedTexImage3D(ctx, target, level,
+ internalFormat,
+ width, height, depth,
+ border, imageSize, data,
+ texObj, texImage);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ /* state update */
+ texObj->_Complete = GL_FALSE;
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
_mesa_unlock_texture(ctx, texObj);
}
else if (target == GL_PROXY_TEXTURE_3D) {
@@ -3422,6 +3544,7 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3430,26 +3553,25 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCompressedTexSubImage1D(format)");
- goto out;
}
+ else if ((width == 1 || width == 2) &&
+ (GLuint) width != texImage->Width) {
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glCompressedTexSubImage1D(width)");
+ }
+ else if (width > 0) {
+ if (ctx->Driver.CompressedTexSubImage1D) {
+ ctx->Driver.CompressedTexSubImage1D(ctx, target, level,
+ xoffset, width,
+ format, imageSize, data,
+ texObj, texImage);
+ }
- if ((width == 1 || width == 2) && (GLuint) width != texImage->Width) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage1D(width)");
- goto out;
- }
-
- if (width == 0)
- goto out; /* no-op, not an error */
+ check_gen_mipmap(ctx, target, texObj, level);
- if (ctx->Driver.CompressedTexSubImage1D) {
- (*ctx->Driver.CompressedTexSubImage1D)(ctx, target, level,
- xoffset, width,
- format, imageSize, data,
- texObj, texImage);
+ ctx->NewState |= _NEW_TEXTURE;
}
- ctx->NewState |= _NEW_TEXTURE;
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -3479,6 +3601,7 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3487,27 +3610,26 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCompressedTexSubImage2D(format)");
- goto out;
}
-
- if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
- ((height == 1 || height == 2) && (GLuint) height != texImage->Height)) {
+ else if (((width == 1 || width == 2)
+ && (GLuint) width != texImage->Width) ||
+ ((height == 1 || height == 2)
+ && (GLuint) height != texImage->Height)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage2D(size)");
- goto out;
}
-
- if (width == 0 || height == 0)
- goto out; /* no-op, not an error */
-
- if (ctx->Driver.CompressedTexSubImage2D) {
- (*ctx->Driver.CompressedTexSubImage2D)(ctx, target, level,
+ else if (width > 0 && height > 0) {
+ if (ctx->Driver.CompressedTexSubImage2D) {
+ ctx->Driver.CompressedTexSubImage2D(ctx, target, level,
xoffset, yoffset, width, height,
format, imageSize, data,
texObj, texImage);
+ }
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
}
- ctx->NewState |= _NEW_TEXTURE;
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -3536,6 +3658,7 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
_mesa_lock_texture(ctx, texObj);
{
texImage = _mesa_select_tex_image(ctx, texObj, target, level);
@@ -3544,29 +3667,29 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
if ((GLint) format != texImage->InternalFormat) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCompressedTexSubImage3D(format)");
- goto out;
}
-
- if (((width == 1 || width == 2) && (GLuint) width != texImage->Width) ||
- ((height == 1 || height == 2) && (GLuint) height != texImage->Height) ||
- ((depth == 1 || depth == 2) && (GLuint) depth != texImage->Depth)) {
+ else if (((width == 1 || width == 2)
+ && (GLuint) width != texImage->Width) ||
+ ((height == 1 || height == 2)
+ && (GLuint) height != texImage->Height) ||
+ ((depth == 1 || depth == 2)
+ && (GLuint) depth != texImage->Depth)) {
_mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage3D(size)");
- goto out;
}
-
- if (width == 0 || height == 0 || depth == 0)
- goto out; /* no-op, not an error */
-
- if (ctx->Driver.CompressedTexSubImage3D) {
- (*ctx->Driver.CompressedTexSubImage3D)(ctx, target, level,
+ else if (width > 0 && height > 0 && depth > 0) {
+ if (ctx->Driver.CompressedTexSubImage3D) {
+ ctx->Driver.CompressedTexSubImage3D(ctx, target, level,
xoffset, yoffset, zoffset,
width, height, depth,
format, imageSize, data,
texObj, texImage);
+ }
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
}
- ctx->NewState |= _NEW_TEXTURE;
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index d09c4392506..678845ece06 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -29,9 +29,7 @@
#include "mfeatures.h"
-#if FEATURE_colortable
#include "colortab.h"
-#endif
#include "context.h"
#include "enums.h"
#include "fbobject.h"
@@ -194,9 +192,7 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj )
*/
texObj->Target = 0x99;
-#if FEATURE_colortable
_mesa_free_colortable_data(&texObj->Palette);
-#endif
/* free the texture images */
for (face = 0; face < 6; face++) {
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index 05d144270ec..b2fbe2205ba 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -70,7 +70,7 @@ validate_texture_wrap_mode(GLcontext * ctx, GLenum target, GLenum wrap)
return GL_TRUE;
}
- _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)", wrap );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)", wrap );
return GL_FALSE;
}
@@ -210,7 +210,7 @@ set_tex_parameteri(GLcontext *ctx,
}
/* fall-through */
default:
- _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
params[0] );
}
return GL_FALSE;
@@ -225,7 +225,7 @@ set_tex_parameteri(GLcontext *ctx,
texObj->MagFilter = params[0];
return GL_TRUE;
default:
- _mesa_error( ctx, GL_INVALID_VALUE, "glTexParameter(param=0x%x)",
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexParameter(param=0x%x)",
params[0]);
}
return GL_FALSE;
diff --git a/src/mesa/main/texrender.c b/src/mesa/main/texrender.c
index cc74d58fbd1..53be83b05ce 100644
--- a/src/mesa/main/texrender.c
+++ b/src/mesa/main/texrender.c
@@ -398,6 +398,14 @@ texture_put_mono_values(GLcontext *ctx, struct gl_renderbuffer *rb,
static void
+store_nop(struct gl_texture_image *texImage,
+ GLint col, GLint row, GLint img,
+ const void *texel)
+{
+}
+
+
+static void
delete_texture_wrapper(struct gl_renderbuffer *rb)
{
ASSERT(rb->RefCount == 0);
@@ -462,7 +470,10 @@ update_wrapper(GLcontext *ctx, const struct gl_renderbuffer_attachment *att)
ASSERT(trb->TexImage);
trb->Store = trb->TexImage->TexFormat->StoreTexel;
- ASSERT(trb->Store);
+ if (!trb->Store) {
+ /* we'll never draw into some textures (compressed formats) */
+ trb->Store = store_nop;
+ }
if (att->Texture->Target == GL_TEXTURE_1D_ARRAY_EXT) {
trb->Yoffset = att->Zoffset;
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 861c5f37c4e..b9311d0ffc9 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -31,9 +31,7 @@
#include "glheader.h"
#include "mfeatures.h"
#include "colormac.h"
-#if FEATURE_colortable
#include "colortab.h"
-#endif
#include "context.h"
#include "enums.h"
#include "macros.h"
@@ -753,9 +751,7 @@ _mesa_init_texture(GLcontext *ctx)
ctx->Texture.CurrentUnit = 0; /* multitexture */
ctx->Texture._EnabledUnits = 0x0;
ctx->Texture.SharedPalette = GL_FALSE;
-#if FEATURE_colortable
_mesa_init_colortable(&ctx->Texture.Palette);
-#endif
for (u = 0; u < MAX_TEXTURE_UNITS; u++)
init_texture_unit(ctx, u);
@@ -796,10 +792,8 @@ _mesa_free_texture_data(GLcontext *ctx)
for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++)
ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]);
-#if FEATURE_colortable
for (u = 0; u < MAX_TEXTURE_IMAGE_UNITS; u++)
_mesa_free_colortable_data(&ctx->Texture.Unit[u].ColorTable);
-#endif
}
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index a22db628d3e..f553a898f9e 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -56,9 +56,7 @@
#include "bufferobj.h"
#include "colormac.h"
#include "context.h"
-#if FEATURE_convolve
#include "convolve.h"
-#endif
#include "image.h"
#include "macros.h"
#include "mipmap.h"
@@ -3302,32 +3300,9 @@ _mesa_set_fetch_functions(struct gl_texture_image *texImage, GLuint dims)
}
-/**
- * Choose the actual storage format for a new texture image.
- * Mainly, this is a wrapper for the driver's ChooseTextureFormat() function.
- * Also set some other texImage fields related to texture compression, etc.
- * \param ctx rendering context
- * \param texImage the gl_texture_image
- * \param dims texture dimensions (1, 2 or 3)
- * \param format the user-specified format parameter
- * \param type the user-specified type parameter
- * \param internalFormat the user-specified internal format hint
- */
static void
-choose_texture_format(GLcontext *ctx, struct gl_texture_image *texImage,
- GLuint dims,
- GLenum format, GLenum type, GLint internalFormat)
+compute_texture_size(GLcontext *ctx, struct gl_texture_image *texImage)
{
- ASSERT(dims == 1 || dims == 2 || dims == 3);
- ASSERT(ctx->Driver.ChooseTextureFormat);
-
- texImage->TexFormat
- = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
-
- ASSERT(texImage->TexFormat);
-
- _mesa_set_fetch_functions(texImage, dims);
-
if (texImage->TexFormat->TexelBytes == 0) {
/* must be a compressed format */
texImage->IsCompressed = GL_TRUE;
@@ -3365,7 +3340,12 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
GLint sizeInBytes;
(void) border;
- choose_texture_format(ctx, texImage, 1, format, type, internalFormat);
+ texImage->TexFormat
+ = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 1);
+ compute_texture_size(ctx, texImage);
/* allocate memory */
if (texImage->IsCompressed)
@@ -3403,11 +3383,6 @@ _mesa_store_teximage1d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3434,7 +3409,12 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
GLint texelBytes, sizeInBytes;
(void) border;
- choose_texture_format(ctx, texImage, 2, format, type, internalFormat);
+ texImage->TexFormat
+ = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 2);
+ compute_texture_size(ctx, texImage);
texelBytes = texImage->TexFormat->TexelBytes;
@@ -3481,11 +3461,6 @@ _mesa_store_teximage2d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3508,7 +3483,12 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
GLint texelBytes, sizeInBytes;
(void) border;
- choose_texture_format(ctx, texImage, 3, format, type, internalFormat);
+ texImage->TexFormat
+ = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, format, type);
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 3);
+ compute_texture_size(ctx, texImage);
texelBytes = texImage->TexFormat->TexelBytes;
@@ -3555,11 +3535,6 @@ _mesa_store_teximage3d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3601,11 +3576,6 @@ _mesa_store_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3654,11 +3624,6 @@ _mesa_store_texsubimage2d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3707,11 +3672,6 @@ _mesa_store_texsubimage3d(GLcontext *ctx, GLenum target, GLint level,
}
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, packing);
}
@@ -3762,7 +3722,12 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
ASSERT(texImage->Depth == 1);
ASSERT(texImage->Data == NULL); /* was freed in glCompressedTexImage2DARB */
- choose_texture_format(ctx, texImage, 2, 0, 0, internalFormat);
+ texImage->TexFormat
+ = ctx->Driver.ChooseTextureFormat(ctx, internalFormat, 0, 0);
+ ASSERT(texImage->TexFormat);
+
+ _mesa_set_fetch_functions(texImage, 2);
+ compute_texture_size(ctx, texImage);
/* allocate storage */
texImage->Data = _mesa_alloc_texmemory(imageSize);
@@ -3781,11 +3746,6 @@ _mesa_store_compressed_teximage2d(GLcontext *ctx, GLenum target, GLint level,
ASSERT(texImage->CompressedSize == (GLuint) imageSize);
MEMCPY(texImage->Data, data, imageSize);
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
@@ -3891,11 +3851,6 @@ _mesa_store_compressed_texsubimage2d(GLcontext *ctx, GLenum target,
src += srcRowStride;
}
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-
_mesa_unmap_teximage_pbo(ctx, &ctx->Unpack);
}
diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c
index d6469b17bea..471a7358a2f 100644
--- a/src/mesa/shader/nvprogram.c
+++ b/src/mesa/shader/nvprogram.c
@@ -509,7 +509,79 @@ _mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer)
*pointer = (GLvoid *) ctx->Array.ArrayObj->VertexAttrib[index].Ptr;
}
+void
+_mesa_emit_nv_temp_initialization(GLcontext *ctx,
+ struct gl_program *program)
+{
+ struct prog_instruction *inst;
+ int 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)
+{
+ int 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(program->NumTemporaries,
+ inst->SrcReg[0].Index + 1);
+ }
+ if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) {
+ program->NumTemporaries = MAX2(program->NumTemporaries,
+ inst->SrcReg[1].Index + 1);
+ }
+ if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) {
+ program->NumTemporaries = MAX2(program->NumTemporaries,
+ inst->SrcReg[2].Index + 1);
+ }
+ }
+}
/**
* Load/parse/compile a program.
diff --git a/src/mesa/shader/nvprogram.h b/src/mesa/shader/nvprogram.h
index bfac165b5ed..8ee59661bd0 100644
--- a/src/mesa/shader/nvprogram.h
+++ b/src/mesa/shader/nvprogram.h
@@ -103,5 +103,11 @@ 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
index f5e2df26708..8574016050c 100644
--- a/src/mesa/shader/nvvertparse.c
+++ b/src/mesa/shader/nvvertparse.c
@@ -44,6 +44,7 @@
#include "nvprogram.h"
#include "nvvertparse.h"
#include "prog_instruction.h"
+#include "prog_parameter.h"
#include "prog_print.h"
#include "program.h"
@@ -1345,6 +1346,9 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
if (Parse_Program(&parseState, instBuffer)) {
+ gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
+ int i;
+
/* successful parse! */
if (parseState.isStateProgram) {
@@ -1398,6 +1402,29 @@ _mesa_parse_nv_vertex_program(GLcontext *ctx, GLenum dstTarget,
_mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
_mesa_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! */
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index c8a762f8ff7..69b81e724a2 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -1555,17 +1555,12 @@ _mesa_execute_program(GLcontext * ctx,
case OPCODE_TXB: /* GL_ARB_fragment_program only */
/* Texel lookup with LOD bias */
{
- const GLuint unit = machine->Samplers[inst->TexSrcUnit];
- const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
GLfloat texcoord[4], color[4], lodBias;
fetch_vector4(&inst->SrcReg[0], machine, texcoord);
/* texcoord[3] is the bias to add to lambda */
- lodBias = texUnit->LodBias + texcoord[3];
- if (texUnit->_Current) {
- lodBias += texUnit->_Current->LodBias;
- }
+ lodBias = texcoord[3];
fetch_texel(ctx, machine, inst, texcoord, lodBias, color);
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index 39a221eeaba..1c687bc16cf 100644
--- a/src/mesa/shader/prog_instruction.h
+++ b/src/mesa/shader/prog_instruction.h
@@ -121,7 +121,6 @@
/*@{*/
#define SATURATE_OFF 0
#define SATURATE_ZERO_ONE 1
-#define SATURATE_PLUS_MINUS_ONE 2
/*@}*/
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index 6b9e73b2cbd..2f029b02e50 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -100,6 +100,7 @@ _mesa_free_parameter_list(struct gl_program_parameter_list *paramList)
* \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)
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 963478fccdb..532adf4d360 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -351,13 +351,6 @@ _mesa_delete_program(GLcontext *ctx, struct gl_program *prog)
_mesa_free_parameter_list(prog->Attributes);
}
- /* XXX this is a little ugly */
- if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
- struct gl_vertex_program *vprog = (struct gl_vertex_program *) prog;
- if (vprog->TnlData)
- _mesa_free(vprog->TnlData);
- }
-
_mesa_free(prog);
}
@@ -502,6 +495,7 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog)
= (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:
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
index c51b4d2f282..c0f50147bd9 100644
--- a/src/mesa/shader/program_parse.tab.c
+++ b/src/mesa/shader/program_parse.tab.c
@@ -789,28 +789,28 @@ static const yytype_uint16 yyrline[] =
517, 518, 519, 520, 521, 522, 523, 526, 538, 546,
563, 570, 589, 600, 620, 645, 654, 687, 694, 709,
759, 801, 812, 833, 843, 849, 880, 897, 897, 899,
- 906, 918, 919, 920, 923, 935, 947, 965, 976, 988,
- 990, 991, 992, 993, 996, 996, 996, 996, 997, 1000,
- 1004, 1009, 1016, 1023, 1030, 1053, 1076, 1077, 1078, 1079,
- 1080, 1081, 1084, 1102, 1106, 1112, 1116, 1120, 1124, 1133,
- 1142, 1146, 1151, 1157, 1168, 1168, 1169, 1171, 1175, 1179,
- 1183, 1189, 1189, 1191, 1207, 1230, 1233, 1244, 1250, 1256,
- 1257, 1264, 1270, 1276, 1284, 1290, 1296, 1304, 1310, 1316,
- 1324, 1325, 1328, 1329, 1330, 1331, 1332, 1333, 1334, 1335,
- 1336, 1337, 1338, 1341, 1350, 1354, 1358, 1364, 1373, 1377,
- 1381, 1390, 1394, 1400, 1406, 1413, 1418, 1426, 1436, 1438,
- 1446, 1452, 1456, 1460, 1466, 1477, 1486, 1490, 1495, 1499,
- 1503, 1507, 1513, 1520, 1524, 1530, 1538, 1549, 1556, 1560,
- 1566, 1576, 1587, 1591, 1609, 1618, 1621, 1627, 1631, 1635,
- 1641, 1652, 1657, 1662, 1667, 1672, 1677, 1685, 1688, 1693,
- 1706, 1714, 1725, 1733, 1733, 1735, 1735, 1737, 1747, 1752,
- 1759, 1769, 1778, 1783, 1790, 1800, 1810, 1822, 1822, 1823,
- 1823, 1825, 1835, 1843, 1853, 1861, 1869, 1878, 1889, 1893,
- 1899, 1900, 1901, 1904, 1904, 1907, 1942, 1946, 1946, 1949,
- 1955, 1963, 1976, 1985, 1994, 1998, 2007, 2016, 2027, 2034,
- 2039, 2048, 2060, 2063, 2072, 2083, 2084, 2085, 2088, 2089,
- 2090, 2093, 2094, 2097, 2098, 2101, 2102, 2105, 2116, 2127,
- 2138, 2159, 2160
+ 906, 918, 919, 920, 923, 937, 951, 969, 980, 992,
+ 994, 995, 996, 997, 1000, 1000, 1000, 1000, 1001, 1004,
+ 1008, 1013, 1020, 1027, 1034, 1057, 1080, 1081, 1082, 1083,
+ 1084, 1085, 1088, 1106, 1110, 1116, 1120, 1124, 1128, 1137,
+ 1146, 1150, 1155, 1161, 1172, 1172, 1173, 1175, 1179, 1183,
+ 1187, 1193, 1193, 1195, 1211, 1234, 1237, 1248, 1254, 1260,
+ 1261, 1268, 1274, 1280, 1288, 1294, 1300, 1308, 1314, 1320,
+ 1328, 1329, 1332, 1333, 1334, 1335, 1336, 1337, 1338, 1339,
+ 1340, 1341, 1342, 1345, 1354, 1358, 1362, 1368, 1377, 1381,
+ 1385, 1394, 1398, 1404, 1410, 1417, 1422, 1430, 1440, 1442,
+ 1450, 1456, 1460, 1464, 1470, 1481, 1490, 1494, 1499, 1503,
+ 1507, 1511, 1517, 1524, 1528, 1534, 1542, 1553, 1560, 1564,
+ 1570, 1580, 1591, 1595, 1613, 1622, 1625, 1631, 1635, 1639,
+ 1645, 1656, 1661, 1666, 1671, 1676, 1681, 1689, 1692, 1697,
+ 1710, 1718, 1729, 1737, 1737, 1739, 1739, 1741, 1751, 1756,
+ 1763, 1773, 1782, 1787, 1794, 1804, 1814, 1826, 1826, 1827,
+ 1827, 1829, 1839, 1847, 1857, 1865, 1873, 1882, 1893, 1897,
+ 1903, 1904, 1905, 1908, 1908, 1911, 1946, 1950, 1950, 1953,
+ 1959, 1967, 1980, 1989, 1998, 2002, 2011, 2020, 2031, 2038,
+ 2043, 2052, 2064, 2067, 2076, 2087, 2088, 2089, 2092, 2093,
+ 2094, 2097, 2098, 2101, 2102, 2105, 2106, 2109, 2120, 2131,
+ 2142, 2163, 2164
};
#endif
@@ -2971,8 +2971,10 @@ yyreduce:
#line 924 "program_parse.y"
{
if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) {
- yyerror(& (yylsp[(1) - (1)]), state,
- "relative address offset too large (positive)");
+ 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);
@@ -2983,11 +2985,13 @@ yyreduce:
case 75:
/* Line 1455 of yacc.c */
-#line 936 "program_parse.y"
+#line 938 "program_parse.y"
{
if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) {
- yyerror(& (yylsp[(1) - (1)]), state,
- "relative address offset too large (negative)");
+ 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);
@@ -2998,7 +3002,7 @@ yyreduce:
case 76:
/* Line 1455 of yacc.c */
-#line 948 "program_parse.y"
+#line 952 "program_parse.y"
{
struct asm_symbol *const s = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
@@ -3019,7 +3023,7 @@ yyreduce:
case 77:
/* Line 1455 of yacc.c */
-#line 966 "program_parse.y"
+#line 970 "program_parse.y"
{
if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
@@ -3033,7 +3037,7 @@ yyreduce:
case 78:
/* Line 1455 of yacc.c */
-#line 977 "program_parse.y"
+#line 981 "program_parse.y"
{
if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
yyerror(& (yylsp[(1) - (1)]), state,
@@ -3048,21 +3052,21 @@ yyreduce:
case 83:
/* Line 1455 of yacc.c */
-#line 993 "program_parse.y"
+#line 997 "program_parse.y"
{ (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
break;
case 88:
/* Line 1455 of yacc.c */
-#line 997 "program_parse.y"
+#line 1001 "program_parse.y"
{ (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
break;
case 89:
/* Line 1455 of yacc.c */
-#line 1001 "program_parse.y"
+#line 1005 "program_parse.y"
{
(yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
;}
@@ -3071,7 +3075,7 @@ yyreduce:
case 90:
/* Line 1455 of yacc.c */
-#line 1005 "program_parse.y"
+#line 1009 "program_parse.y"
{
(yyval.dst_reg) = (yyvsp[(2) - (3)].dst_reg);
;}
@@ -3080,7 +3084,7 @@ yyreduce:
case 91:
/* Line 1455 of yacc.c */
-#line 1009 "program_parse.y"
+#line 1013 "program_parse.y"
{
(yyval.dst_reg).CondMask = COND_TR;
(yyval.dst_reg).CondSwizzle = SWIZZLE_NOOP;
@@ -3091,7 +3095,7 @@ yyreduce:
case 92:
/* Line 1455 of yacc.c */
-#line 1017 "program_parse.y"
+#line 1021 "program_parse.y"
{
(yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
(yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
@@ -3101,7 +3105,7 @@ yyreduce:
case 93:
/* Line 1455 of yacc.c */
-#line 1024 "program_parse.y"
+#line 1028 "program_parse.y"
{
(yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
(yyval.dst_reg).CondSwizzle = (yyvsp[(2) - (2)].swiz_mask).swizzle;
@@ -3111,7 +3115,7 @@ yyreduce:
case 94:
/* Line 1455 of yacc.c */
-#line 1031 "program_parse.y"
+#line 1035 "program_parse.y"
{
const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
@@ -3137,7 +3141,7 @@ yyreduce:
case 95:
/* Line 1455 of yacc.c */
-#line 1054 "program_parse.y"
+#line 1058 "program_parse.y"
{
const int cond = _mesa_parse_cc((yyvsp[(1) - (1)].string));
if ((cond == 0) || ((yyvsp[(1) - (1)].string)[2] != '\0')) {
@@ -3163,7 +3167,7 @@ yyreduce:
case 102:
/* Line 1455 of yacc.c */
-#line 1085 "program_parse.y"
+#line 1089 "program_parse.y"
{
struct asm_symbol *const s =
declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
@@ -3184,7 +3188,7 @@ yyreduce:
case 103:
/* Line 1455 of yacc.c */
-#line 1103 "program_parse.y"
+#line 1107 "program_parse.y"
{
(yyval.attrib) = (yyvsp[(2) - (2)].attrib);
;}
@@ -3193,7 +3197,7 @@ yyreduce:
case 104:
/* Line 1455 of yacc.c */
-#line 1107 "program_parse.y"
+#line 1111 "program_parse.y"
{
(yyval.attrib) = (yyvsp[(2) - (2)].attrib);
;}
@@ -3202,7 +3206,7 @@ yyreduce:
case 105:
/* Line 1455 of yacc.c */
-#line 1113 "program_parse.y"
+#line 1117 "program_parse.y"
{
(yyval.attrib) = VERT_ATTRIB_POS;
;}
@@ -3211,7 +3215,7 @@ yyreduce:
case 106:
/* Line 1455 of yacc.c */
-#line 1117 "program_parse.y"
+#line 1121 "program_parse.y"
{
(yyval.attrib) = VERT_ATTRIB_WEIGHT;
;}
@@ -3220,7 +3224,7 @@ yyreduce:
case 107:
/* Line 1455 of yacc.c */
-#line 1121 "program_parse.y"
+#line 1125 "program_parse.y"
{
(yyval.attrib) = VERT_ATTRIB_NORMAL;
;}
@@ -3229,7 +3233,7 @@ yyreduce:
case 108:
/* Line 1455 of yacc.c */
-#line 1125 "program_parse.y"
+#line 1129 "program_parse.y"
{
if (!state->ctx->Extensions.EXT_secondary_color) {
yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported");
@@ -3243,7 +3247,7 @@ yyreduce:
case 109:
/* Line 1455 of yacc.c */
-#line 1134 "program_parse.y"
+#line 1138 "program_parse.y"
{
if (!state->ctx->Extensions.EXT_fog_coord) {
yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported");
@@ -3257,7 +3261,7 @@ yyreduce:
case 110:
/* Line 1455 of yacc.c */
-#line 1143 "program_parse.y"
+#line 1147 "program_parse.y"
{
(yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
;}
@@ -3266,7 +3270,7 @@ yyreduce:
case 111:
/* Line 1455 of yacc.c */
-#line 1147 "program_parse.y"
+#line 1151 "program_parse.y"
{
yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
YYERROR;
@@ -3276,7 +3280,7 @@ yyreduce:
case 112:
/* Line 1455 of yacc.c */
-#line 1152 "program_parse.y"
+#line 1156 "program_parse.y"
{
(yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
;}
@@ -3285,7 +3289,7 @@ yyreduce:
case 113:
/* Line 1455 of yacc.c */
-#line 1158 "program_parse.y"
+#line 1162 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
@@ -3299,7 +3303,7 @@ yyreduce:
case 117:
/* Line 1455 of yacc.c */
-#line 1172 "program_parse.y"
+#line 1176 "program_parse.y"
{
(yyval.attrib) = FRAG_ATTRIB_WPOS;
;}
@@ -3308,7 +3312,7 @@ yyreduce:
case 118:
/* Line 1455 of yacc.c */
-#line 1176 "program_parse.y"
+#line 1180 "program_parse.y"
{
(yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer);
;}
@@ -3317,7 +3321,7 @@ yyreduce:
case 119:
/* Line 1455 of yacc.c */
-#line 1180 "program_parse.y"
+#line 1184 "program_parse.y"
{
(yyval.attrib) = FRAG_ATTRIB_FOGC;
;}
@@ -3326,7 +3330,7 @@ yyreduce:
case 120:
/* Line 1455 of yacc.c */
-#line 1184 "program_parse.y"
+#line 1188 "program_parse.y"
{
(yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
;}
@@ -3335,7 +3339,7 @@ yyreduce:
case 123:
/* Line 1455 of yacc.c */
-#line 1192 "program_parse.y"
+#line 1196 "program_parse.y"
{
struct asm_symbol *const s =
declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
@@ -3354,7 +3358,7 @@ yyreduce:
case 124:
/* Line 1455 of yacc.c */
-#line 1208 "program_parse.y"
+#line 1212 "program_parse.y"
{
if (((yyvsp[(4) - (6)].integer) != 0) && ((unsigned) (yyvsp[(4) - (6)].integer) != (yyvsp[(6) - (6)].temp_sym).param_binding_length)) {
yyerror(& (yylsp[(4) - (6)]), state,
@@ -3379,7 +3383,7 @@ yyreduce:
case 125:
/* Line 1455 of yacc.c */
-#line 1230 "program_parse.y"
+#line 1234 "program_parse.y"
{
(yyval.integer) = 0;
;}
@@ -3388,7 +3392,7 @@ yyreduce:
case 126:
/* Line 1455 of yacc.c */
-#line 1234 "program_parse.y"
+#line 1238 "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");
@@ -3402,7 +3406,7 @@ yyreduce:
case 127:
/* Line 1455 of yacc.c */
-#line 1245 "program_parse.y"
+#line 1249 "program_parse.y"
{
(yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
;}
@@ -3411,7 +3415,7 @@ yyreduce:
case 128:
/* Line 1455 of yacc.c */
-#line 1251 "program_parse.y"
+#line 1255 "program_parse.y"
{
(yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
;}
@@ -3420,7 +3424,7 @@ yyreduce:
case 130:
/* Line 1455 of yacc.c */
-#line 1258 "program_parse.y"
+#line 1262 "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);
@@ -3430,7 +3434,7 @@ yyreduce:
case 131:
/* Line 1455 of yacc.c */
-#line 1265 "program_parse.y"
+#line 1269 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3441,7 +3445,7 @@ yyreduce:
case 132:
/* Line 1455 of yacc.c */
-#line 1271 "program_parse.y"
+#line 1275 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3452,7 +3456,7 @@ yyreduce:
case 133:
/* Line 1455 of yacc.c */
-#line 1277 "program_parse.y"
+#line 1281 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3463,7 +3467,7 @@ yyreduce:
case 134:
/* Line 1455 of yacc.c */
-#line 1285 "program_parse.y"
+#line 1289 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3474,7 +3478,7 @@ yyreduce:
case 135:
/* Line 1455 of yacc.c */
-#line 1291 "program_parse.y"
+#line 1295 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3485,7 +3489,7 @@ yyreduce:
case 136:
/* Line 1455 of yacc.c */
-#line 1297 "program_parse.y"
+#line 1301 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3496,7 +3500,7 @@ yyreduce:
case 137:
/* Line 1455 of yacc.c */
-#line 1305 "program_parse.y"
+#line 1309 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3507,7 +3511,7 @@ yyreduce:
case 138:
/* Line 1455 of yacc.c */
-#line 1311 "program_parse.y"
+#line 1315 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3518,7 +3522,7 @@ yyreduce:
case 139:
/* Line 1455 of yacc.c */
-#line 1317 "program_parse.y"
+#line 1321 "program_parse.y"
{
memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
(yyval.temp_sym).param_binding_begin = ~0;
@@ -3529,98 +3533,98 @@ yyreduce:
case 140:
/* Line 1455 of yacc.c */
-#line 1324 "program_parse.y"
+#line 1328 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;}
break;
case 141:
/* Line 1455 of yacc.c */
-#line 1325 "program_parse.y"
+#line 1329 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 142:
/* Line 1455 of yacc.c */
-#line 1328 "program_parse.y"
+#line 1332 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 143:
/* Line 1455 of yacc.c */
-#line 1329 "program_parse.y"
+#line 1333 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 144:
/* Line 1455 of yacc.c */
-#line 1330 "program_parse.y"
+#line 1334 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 145:
/* Line 1455 of yacc.c */
-#line 1331 "program_parse.y"
+#line 1335 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 146:
/* Line 1455 of yacc.c */
-#line 1332 "program_parse.y"
+#line 1336 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 147:
/* Line 1455 of yacc.c */
-#line 1333 "program_parse.y"
+#line 1337 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 148:
/* Line 1455 of yacc.c */
-#line 1334 "program_parse.y"
+#line 1338 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 149:
/* Line 1455 of yacc.c */
-#line 1335 "program_parse.y"
+#line 1339 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 150:
/* Line 1455 of yacc.c */
-#line 1336 "program_parse.y"
+#line 1340 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 151:
/* Line 1455 of yacc.c */
-#line 1337 "program_parse.y"
+#line 1341 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 152:
/* Line 1455 of yacc.c */
-#line 1338 "program_parse.y"
+#line 1342 "program_parse.y"
{ memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
break;
case 153:
/* Line 1455 of yacc.c */
-#line 1342 "program_parse.y"
+#line 1346 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_MATERIAL;
@@ -3632,7 +3636,7 @@ yyreduce:
case 154:
/* Line 1455 of yacc.c */
-#line 1351 "program_parse.y"
+#line 1355 "program_parse.y"
{
(yyval.integer) = (yyvsp[(1) - (1)].integer);
;}
@@ -3641,7 +3645,7 @@ yyreduce:
case 155:
/* Line 1455 of yacc.c */
-#line 1355 "program_parse.y"
+#line 1359 "program_parse.y"
{
(yyval.integer) = STATE_EMISSION;
;}
@@ -3650,7 +3654,7 @@ yyreduce:
case 156:
/* Line 1455 of yacc.c */
-#line 1359 "program_parse.y"
+#line 1363 "program_parse.y"
{
(yyval.integer) = STATE_SHININESS;
;}
@@ -3659,7 +3663,7 @@ yyreduce:
case 157:
/* Line 1455 of yacc.c */
-#line 1365 "program_parse.y"
+#line 1369 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_LIGHT;
@@ -3671,7 +3675,7 @@ yyreduce:
case 158:
/* Line 1455 of yacc.c */
-#line 1374 "program_parse.y"
+#line 1378 "program_parse.y"
{
(yyval.integer) = (yyvsp[(1) - (1)].integer);
;}
@@ -3680,7 +3684,7 @@ yyreduce:
case 159:
/* Line 1455 of yacc.c */
-#line 1378 "program_parse.y"
+#line 1382 "program_parse.y"
{
(yyval.integer) = STATE_POSITION;
;}
@@ -3689,7 +3693,7 @@ yyreduce:
case 160:
/* Line 1455 of yacc.c */
-#line 1382 "program_parse.y"
+#line 1386 "program_parse.y"
{
if (!state->ctx->Extensions.EXT_point_parameters) {
yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
@@ -3703,7 +3707,7 @@ yyreduce:
case 161:
/* Line 1455 of yacc.c */
-#line 1391 "program_parse.y"
+#line 1395 "program_parse.y"
{
(yyval.integer) = (yyvsp[(2) - (2)].integer);
;}
@@ -3712,7 +3716,7 @@ yyreduce:
case 162:
/* Line 1455 of yacc.c */
-#line 1395 "program_parse.y"
+#line 1399 "program_parse.y"
{
(yyval.integer) = STATE_HALF_VECTOR;
;}
@@ -3721,7 +3725,7 @@ yyreduce:
case 163:
/* Line 1455 of yacc.c */
-#line 1401 "program_parse.y"
+#line 1405 "program_parse.y"
{
(yyval.integer) = STATE_SPOT_DIRECTION;
;}
@@ -3730,7 +3734,7 @@ yyreduce:
case 164:
/* Line 1455 of yacc.c */
-#line 1407 "program_parse.y"
+#line 1411 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
(yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
@@ -3740,7 +3744,7 @@ yyreduce:
case 165:
/* Line 1455 of yacc.c */
-#line 1414 "program_parse.y"
+#line 1418 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
@@ -3750,7 +3754,7 @@ yyreduce:
case 166:
/* Line 1455 of yacc.c */
-#line 1419 "program_parse.y"
+#line 1423 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
@@ -3761,7 +3765,7 @@ yyreduce:
case 167:
/* Line 1455 of yacc.c */
-#line 1427 "program_parse.y"
+#line 1431 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_LIGHTPROD;
@@ -3774,7 +3778,7 @@ yyreduce:
case 169:
/* Line 1455 of yacc.c */
-#line 1439 "program_parse.y"
+#line 1443 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = (yyvsp[(3) - (3)].integer);
@@ -3785,7 +3789,7 @@ yyreduce:
case 170:
/* Line 1455 of yacc.c */
-#line 1447 "program_parse.y"
+#line 1451 "program_parse.y"
{
(yyval.integer) = STATE_TEXENV_COLOR;
;}
@@ -3794,7 +3798,7 @@ yyreduce:
case 171:
/* Line 1455 of yacc.c */
-#line 1453 "program_parse.y"
+#line 1457 "program_parse.y"
{
(yyval.integer) = STATE_AMBIENT;
;}
@@ -3803,7 +3807,7 @@ yyreduce:
case 172:
/* Line 1455 of yacc.c */
-#line 1457 "program_parse.y"
+#line 1461 "program_parse.y"
{
(yyval.integer) = STATE_DIFFUSE;
;}
@@ -3812,7 +3816,7 @@ yyreduce:
case 173:
/* Line 1455 of yacc.c */
-#line 1461 "program_parse.y"
+#line 1465 "program_parse.y"
{
(yyval.integer) = STATE_SPECULAR;
;}
@@ -3821,7 +3825,7 @@ yyreduce:
case 174:
/* Line 1455 of yacc.c */
-#line 1467 "program_parse.y"
+#line 1471 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
@@ -3835,7 +3839,7 @@ yyreduce:
case 175:
/* Line 1455 of yacc.c */
-#line 1478 "program_parse.y"
+#line 1482 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_TEXGEN;
@@ -3847,7 +3851,7 @@ yyreduce:
case 176:
/* Line 1455 of yacc.c */
-#line 1487 "program_parse.y"
+#line 1491 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_EYE_S;
;}
@@ -3856,7 +3860,7 @@ yyreduce:
case 177:
/* Line 1455 of yacc.c */
-#line 1491 "program_parse.y"
+#line 1495 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_OBJECT_S;
;}
@@ -3865,7 +3869,7 @@ yyreduce:
case 178:
/* Line 1455 of yacc.c */
-#line 1496 "program_parse.y"
+#line 1500 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
;}
@@ -3874,7 +3878,7 @@ yyreduce:
case 179:
/* Line 1455 of yacc.c */
-#line 1500 "program_parse.y"
+#line 1504 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
;}
@@ -3883,7 +3887,7 @@ yyreduce:
case 180:
/* Line 1455 of yacc.c */
-#line 1504 "program_parse.y"
+#line 1508 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
;}
@@ -3892,7 +3896,7 @@ yyreduce:
case 181:
/* Line 1455 of yacc.c */
-#line 1508 "program_parse.y"
+#line 1512 "program_parse.y"
{
(yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
;}
@@ -3901,7 +3905,7 @@ yyreduce:
case 182:
/* Line 1455 of yacc.c */
-#line 1514 "program_parse.y"
+#line 1518 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = (yyvsp[(2) - (2)].integer);
@@ -3911,7 +3915,7 @@ yyreduce:
case 183:
/* Line 1455 of yacc.c */
-#line 1521 "program_parse.y"
+#line 1525 "program_parse.y"
{
(yyval.integer) = STATE_FOG_COLOR;
;}
@@ -3920,7 +3924,7 @@ yyreduce:
case 184:
/* Line 1455 of yacc.c */
-#line 1525 "program_parse.y"
+#line 1529 "program_parse.y"
{
(yyval.integer) = STATE_FOG_PARAMS;
;}
@@ -3929,7 +3933,7 @@ yyreduce:
case 185:
/* Line 1455 of yacc.c */
-#line 1531 "program_parse.y"
+#line 1535 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_CLIPPLANE;
@@ -3940,7 +3944,7 @@ yyreduce:
case 186:
/* Line 1455 of yacc.c */
-#line 1539 "program_parse.y"
+#line 1543 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
@@ -3954,7 +3958,7 @@ yyreduce:
case 187:
/* Line 1455 of yacc.c */
-#line 1550 "program_parse.y"
+#line 1554 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = (yyvsp[(2) - (2)].integer);
@@ -3964,7 +3968,7 @@ yyreduce:
case 188:
/* Line 1455 of yacc.c */
-#line 1557 "program_parse.y"
+#line 1561 "program_parse.y"
{
(yyval.integer) = STATE_POINT_SIZE;
;}
@@ -3973,7 +3977,7 @@ yyreduce:
case 189:
/* Line 1455 of yacc.c */
-#line 1561 "program_parse.y"
+#line 1565 "program_parse.y"
{
(yyval.integer) = STATE_POINT_ATTENUATION;
;}
@@ -3982,7 +3986,7 @@ yyreduce:
case 190:
/* Line 1455 of yacc.c */
-#line 1567 "program_parse.y"
+#line 1571 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
(yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
@@ -3995,7 +3999,7 @@ yyreduce:
case 191:
/* Line 1455 of yacc.c */
-#line 1577 "program_parse.y"
+#line 1581 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
(yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
@@ -4008,7 +4012,7 @@ yyreduce:
case 192:
/* Line 1455 of yacc.c */
-#line 1587 "program_parse.y"
+#line 1591 "program_parse.y"
{
(yyval.state)[2] = 0;
(yyval.state)[3] = 3;
@@ -4018,7 +4022,7 @@ yyreduce:
case 193:
/* Line 1455 of yacc.c */
-#line 1592 "program_parse.y"
+#line 1596 "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).
@@ -4039,7 +4043,7 @@ yyreduce:
case 194:
/* Line 1455 of yacc.c */
-#line 1610 "program_parse.y"
+#line 1614 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
(yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
@@ -4050,7 +4054,7 @@ yyreduce:
case 195:
/* Line 1455 of yacc.c */
-#line 1618 "program_parse.y"
+#line 1622 "program_parse.y"
{
(yyval.integer) = 0;
;}
@@ -4059,7 +4063,7 @@ yyreduce:
case 196:
/* Line 1455 of yacc.c */
-#line 1622 "program_parse.y"
+#line 1626 "program_parse.y"
{
(yyval.integer) = (yyvsp[(1) - (1)].integer);
;}
@@ -4068,7 +4072,7 @@ yyreduce:
case 197:
/* Line 1455 of yacc.c */
-#line 1628 "program_parse.y"
+#line 1632 "program_parse.y"
{
(yyval.integer) = STATE_MATRIX_INVERSE;
;}
@@ -4077,7 +4081,7 @@ yyreduce:
case 198:
/* Line 1455 of yacc.c */
-#line 1632 "program_parse.y"
+#line 1636 "program_parse.y"
{
(yyval.integer) = STATE_MATRIX_TRANSPOSE;
;}
@@ -4086,7 +4090,7 @@ yyreduce:
case 199:
/* Line 1455 of yacc.c */
-#line 1636 "program_parse.y"
+#line 1640 "program_parse.y"
{
(yyval.integer) = STATE_MATRIX_INVTRANS;
;}
@@ -4095,7 +4099,7 @@ yyreduce:
case 200:
/* Line 1455 of yacc.c */
-#line 1642 "program_parse.y"
+#line 1646 "program_parse.y"
{
if ((yyvsp[(1) - (1)].integer) > 3) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
@@ -4109,7 +4113,7 @@ yyreduce:
case 201:
/* Line 1455 of yacc.c */
-#line 1653 "program_parse.y"
+#line 1657 "program_parse.y"
{
(yyval.state)[0] = STATE_MODELVIEW_MATRIX;
(yyval.state)[1] = (yyvsp[(2) - (2)].integer);
@@ -4119,7 +4123,7 @@ yyreduce:
case 202:
/* Line 1455 of yacc.c */
-#line 1658 "program_parse.y"
+#line 1662 "program_parse.y"
{
(yyval.state)[0] = STATE_PROJECTION_MATRIX;
(yyval.state)[1] = 0;
@@ -4129,7 +4133,7 @@ yyreduce:
case 203:
/* Line 1455 of yacc.c */
-#line 1663 "program_parse.y"
+#line 1667 "program_parse.y"
{
(yyval.state)[0] = STATE_MVP_MATRIX;
(yyval.state)[1] = 0;
@@ -4139,7 +4143,7 @@ yyreduce:
case 204:
/* Line 1455 of yacc.c */
-#line 1668 "program_parse.y"
+#line 1672 "program_parse.y"
{
(yyval.state)[0] = STATE_TEXTURE_MATRIX;
(yyval.state)[1] = (yyvsp[(2) - (2)].integer);
@@ -4149,7 +4153,7 @@ yyreduce:
case 205:
/* Line 1455 of yacc.c */
-#line 1673 "program_parse.y"
+#line 1677 "program_parse.y"
{
yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
YYERROR;
@@ -4159,7 +4163,7 @@ yyreduce:
case 206:
/* Line 1455 of yacc.c */
-#line 1678 "program_parse.y"
+#line 1682 "program_parse.y"
{
(yyval.state)[0] = STATE_PROGRAM_MATRIX;
(yyval.state)[1] = (yyvsp[(3) - (4)].integer);
@@ -4169,7 +4173,7 @@ yyreduce:
case 207:
/* Line 1455 of yacc.c */
-#line 1685 "program_parse.y"
+#line 1689 "program_parse.y"
{
(yyval.integer) = 0;
;}
@@ -4178,7 +4182,7 @@ yyreduce:
case 208:
/* Line 1455 of yacc.c */
-#line 1689 "program_parse.y"
+#line 1693 "program_parse.y"
{
(yyval.integer) = (yyvsp[(2) - (3)].integer);
;}
@@ -4187,7 +4191,7 @@ yyreduce:
case 209:
/* Line 1455 of yacc.c */
-#line 1694 "program_parse.y"
+#line 1698 "program_parse.y"
{
/* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
* zero is valid.
@@ -4204,7 +4208,7 @@ yyreduce:
case 210:
/* Line 1455 of yacc.c */
-#line 1707 "program_parse.y"
+#line 1711 "program_parse.y"
{
/* Since GL_ARB_matrix_palette isn't supported, just let any value
* through here. The error will be generated later.
@@ -4216,7 +4220,7 @@ yyreduce:
case 211:
/* Line 1455 of yacc.c */
-#line 1715 "program_parse.y"
+#line 1719 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
@@ -4230,7 +4234,7 @@ yyreduce:
case 212:
/* Line 1455 of yacc.c */
-#line 1726 "program_parse.y"
+#line 1730 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = STATE_DEPTH_RANGE;
@@ -4240,7 +4244,7 @@ yyreduce:
case 217:
/* Line 1455 of yacc.c */
-#line 1738 "program_parse.y"
+#line 1742 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = state->state_param_enum;
@@ -4253,7 +4257,7 @@ yyreduce:
case 218:
/* Line 1455 of yacc.c */
-#line 1748 "program_parse.y"
+#line 1752 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (1)].integer);
(yyval.state)[1] = (yyvsp[(1) - (1)].integer);
@@ -4263,7 +4267,7 @@ yyreduce:
case 219:
/* Line 1455 of yacc.c */
-#line 1753 "program_parse.y"
+#line 1757 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (3)].integer);
(yyval.state)[1] = (yyvsp[(3) - (3)].integer);
@@ -4273,7 +4277,7 @@ yyreduce:
case 220:
/* Line 1455 of yacc.c */
-#line 1760 "program_parse.y"
+#line 1764 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = state->state_param_enum;
@@ -4286,7 +4290,7 @@ yyreduce:
case 221:
/* Line 1455 of yacc.c */
-#line 1770 "program_parse.y"
+#line 1774 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = state->state_param_enum;
@@ -4299,7 +4303,7 @@ yyreduce:
case 222:
/* Line 1455 of yacc.c */
-#line 1779 "program_parse.y"
+#line 1783 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (1)].integer);
(yyval.state)[1] = (yyvsp[(1) - (1)].integer);
@@ -4309,7 +4313,7 @@ yyreduce:
case 223:
/* Line 1455 of yacc.c */
-#line 1784 "program_parse.y"
+#line 1788 "program_parse.y"
{
(yyval.state)[0] = (yyvsp[(1) - (3)].integer);
(yyval.state)[1] = (yyvsp[(3) - (3)].integer);
@@ -4319,7 +4323,7 @@ yyreduce:
case 224:
/* Line 1455 of yacc.c */
-#line 1791 "program_parse.y"
+#line 1795 "program_parse.y"
{
memset((yyval.state), 0, sizeof((yyval.state)));
(yyval.state)[0] = state->state_param_enum;
@@ -4332,7 +4336,7 @@ yyreduce:
case 225:
/* Line 1455 of yacc.c */
-#line 1801 "program_parse.y"
+#line 1805 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
@@ -4345,7 +4349,7 @@ yyreduce:
case 226:
/* Line 1455 of yacc.c */
-#line 1811 "program_parse.y"
+#line 1815 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
@@ -4358,7 +4362,7 @@ yyreduce:
case 231:
/* Line 1455 of yacc.c */
-#line 1826 "program_parse.y"
+#line 1830 "program_parse.y"
{
(yyval.vector).count = 4;
(yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
@@ -4371,7 +4375,7 @@ yyreduce:
case 232:
/* Line 1455 of yacc.c */
-#line 1836 "program_parse.y"
+#line 1840 "program_parse.y"
{
(yyval.vector).count = 1;
(yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
@@ -4384,7 +4388,7 @@ yyreduce:
case 233:
/* Line 1455 of yacc.c */
-#line 1844 "program_parse.y"
+#line 1848 "program_parse.y"
{
(yyval.vector).count = 1;
(yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer);
@@ -4397,7 +4401,7 @@ yyreduce:
case 234:
/* Line 1455 of yacc.c */
-#line 1854 "program_parse.y"
+#line 1858 "program_parse.y"
{
(yyval.vector).count = 4;
(yyval.vector).data[0] = (yyvsp[(2) - (3)].real);
@@ -4410,7 +4414,7 @@ yyreduce:
case 235:
/* Line 1455 of yacc.c */
-#line 1862 "program_parse.y"
+#line 1866 "program_parse.y"
{
(yyval.vector).count = 4;
(yyval.vector).data[0] = (yyvsp[(2) - (5)].real);
@@ -4423,7 +4427,7 @@ yyreduce:
case 236:
/* Line 1455 of yacc.c */
-#line 1871 "program_parse.y"
+#line 1875 "program_parse.y"
{
(yyval.vector).count = 4;
(yyval.vector).data[0] = (yyvsp[(2) - (7)].real);
@@ -4436,7 +4440,7 @@ yyreduce:
case 237:
/* Line 1455 of yacc.c */
-#line 1880 "program_parse.y"
+#line 1884 "program_parse.y"
{
(yyval.vector).count = 4;
(yyval.vector).data[0] = (yyvsp[(2) - (9)].real);
@@ -4449,7 +4453,7 @@ yyreduce:
case 238:
/* Line 1455 of yacc.c */
-#line 1890 "program_parse.y"
+#line 1894 "program_parse.y"
{
(yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
;}
@@ -4458,7 +4462,7 @@ yyreduce:
case 239:
/* Line 1455 of yacc.c */
-#line 1894 "program_parse.y"
+#line 1898 "program_parse.y"
{
(yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
;}
@@ -4467,35 +4471,35 @@ yyreduce:
case 240:
/* Line 1455 of yacc.c */
-#line 1899 "program_parse.y"
+#line 1903 "program_parse.y"
{ (yyval.negate) = FALSE; ;}
break;
case 241:
/* Line 1455 of yacc.c */
-#line 1900 "program_parse.y"
+#line 1904 "program_parse.y"
{ (yyval.negate) = TRUE; ;}
break;
case 242:
/* Line 1455 of yacc.c */
-#line 1901 "program_parse.y"
+#line 1905 "program_parse.y"
{ (yyval.negate) = FALSE; ;}
break;
case 243:
/* Line 1455 of yacc.c */
-#line 1904 "program_parse.y"
+#line 1908 "program_parse.y"
{ (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
break;
case 245:
/* Line 1455 of yacc.c */
-#line 1908 "program_parse.y"
+#line 1912 "program_parse.y"
{
/* NV_fragment_program_option defines the size qualifiers in a
* fairly broken way. "SHORT" or "LONG" can optionally be used
@@ -4534,7 +4538,7 @@ yyreduce:
case 246:
/* Line 1455 of yacc.c */
-#line 1942 "program_parse.y"
+#line 1946 "program_parse.y"
{
;}
break;
@@ -4542,14 +4546,14 @@ yyreduce:
case 247:
/* Line 1455 of yacc.c */
-#line 1946 "program_parse.y"
+#line 1950 "program_parse.y"
{ (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
break;
case 249:
/* Line 1455 of yacc.c */
-#line 1950 "program_parse.y"
+#line 1954 "program_parse.y"
{
if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
YYERROR;
@@ -4560,7 +4564,7 @@ yyreduce:
case 250:
/* Line 1455 of yacc.c */
-#line 1956 "program_parse.y"
+#line 1960 "program_parse.y"
{
if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
YYERROR;
@@ -4571,7 +4575,7 @@ yyreduce:
case 251:
/* Line 1455 of yacc.c */
-#line 1964 "program_parse.y"
+#line 1968 "program_parse.y"
{
struct asm_symbol *const s =
declare_variable(state, (yyvsp[(3) - (5)].string), at_output, & (yylsp[(3) - (5)]));
@@ -4587,7 +4591,7 @@ yyreduce:
case 252:
/* Line 1455 of yacc.c */
-#line 1977 "program_parse.y"
+#line 1981 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.result) = VERT_RESULT_HPOS;
@@ -4601,7 +4605,7 @@ yyreduce:
case 253:
/* Line 1455 of yacc.c */
-#line 1986 "program_parse.y"
+#line 1990 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.result) = VERT_RESULT_FOGC;
@@ -4615,7 +4619,7 @@ yyreduce:
case 254:
/* Line 1455 of yacc.c */
-#line 1995 "program_parse.y"
+#line 1999 "program_parse.y"
{
(yyval.result) = (yyvsp[(2) - (2)].result);
;}
@@ -4624,7 +4628,7 @@ yyreduce:
case 255:
/* Line 1455 of yacc.c */
-#line 1999 "program_parse.y"
+#line 2003 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.result) = VERT_RESULT_PSIZ;
@@ -4638,7 +4642,7 @@ yyreduce:
case 256:
/* Line 1455 of yacc.c */
-#line 2008 "program_parse.y"
+#line 2012 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer);
@@ -4652,7 +4656,7 @@ yyreduce:
case 257:
/* Line 1455 of yacc.c */
-#line 2017 "program_parse.y"
+#line 2021 "program_parse.y"
{
if (state->mode == ARB_fragment) {
(yyval.result) = FRAG_RESULT_DEPTH;
@@ -4666,7 +4670,7 @@ yyreduce:
case 258:
/* Line 1455 of yacc.c */
-#line 2028 "program_parse.y"
+#line 2032 "program_parse.y"
{
(yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
;}
@@ -4675,7 +4679,7 @@ yyreduce:
case 259:
/* Line 1455 of yacc.c */
-#line 2034 "program_parse.y"
+#line 2038 "program_parse.y"
{
(yyval.integer) = (state->mode == ARB_vertex)
? VERT_RESULT_COL0
@@ -4686,7 +4690,7 @@ yyreduce:
case 260:
/* Line 1455 of yacc.c */
-#line 2040 "program_parse.y"
+#line 2044 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.integer) = VERT_RESULT_COL0;
@@ -4700,7 +4704,7 @@ yyreduce:
case 261:
/* Line 1455 of yacc.c */
-#line 2049 "program_parse.y"
+#line 2053 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.integer) = VERT_RESULT_BFC0;
@@ -4714,7 +4718,7 @@ yyreduce:
case 262:
/* Line 1455 of yacc.c */
-#line 2060 "program_parse.y"
+#line 2064 "program_parse.y"
{
(yyval.integer) = 0;
;}
@@ -4723,7 +4727,7 @@ yyreduce:
case 263:
/* Line 1455 of yacc.c */
-#line 2064 "program_parse.y"
+#line 2068 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.integer) = 0;
@@ -4737,7 +4741,7 @@ yyreduce:
case 264:
/* Line 1455 of yacc.c */
-#line 2073 "program_parse.y"
+#line 2077 "program_parse.y"
{
if (state->mode == ARB_vertex) {
(yyval.integer) = 1;
@@ -4751,91 +4755,91 @@ yyreduce:
case 265:
/* Line 1455 of yacc.c */
-#line 2083 "program_parse.y"
+#line 2087 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 266:
/* Line 1455 of yacc.c */
-#line 2084 "program_parse.y"
+#line 2088 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 267:
/* Line 1455 of yacc.c */
-#line 2085 "program_parse.y"
+#line 2089 "program_parse.y"
{ (yyval.integer) = 1; ;}
break;
case 268:
/* Line 1455 of yacc.c */
-#line 2088 "program_parse.y"
+#line 2092 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 269:
/* Line 1455 of yacc.c */
-#line 2089 "program_parse.y"
+#line 2093 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 270:
/* Line 1455 of yacc.c */
-#line 2090 "program_parse.y"
+#line 2094 "program_parse.y"
{ (yyval.integer) = 1; ;}
break;
case 271:
/* Line 1455 of yacc.c */
-#line 2093 "program_parse.y"
+#line 2097 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 272:
/* Line 1455 of yacc.c */
-#line 2094 "program_parse.y"
+#line 2098 "program_parse.y"
{ (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
break;
case 273:
/* Line 1455 of yacc.c */
-#line 2097 "program_parse.y"
+#line 2101 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 274:
/* Line 1455 of yacc.c */
-#line 2098 "program_parse.y"
+#line 2102 "program_parse.y"
{ (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
break;
case 275:
/* Line 1455 of yacc.c */
-#line 2101 "program_parse.y"
+#line 2105 "program_parse.y"
{ (yyval.integer) = 0; ;}
break;
case 276:
/* Line 1455 of yacc.c */
-#line 2102 "program_parse.y"
+#line 2106 "program_parse.y"
{ (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
break;
case 277:
/* Line 1455 of yacc.c */
-#line 2106 "program_parse.y"
+#line 2110 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
@@ -4849,7 +4853,7 @@ yyreduce:
case 278:
/* Line 1455 of yacc.c */
-#line 2117 "program_parse.y"
+#line 2121 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
@@ -4863,7 +4867,7 @@ yyreduce:
case 279:
/* Line 1455 of yacc.c */
-#line 2128 "program_parse.y"
+#line 2132 "program_parse.y"
{
if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
@@ -4877,7 +4881,7 @@ yyreduce:
case 280:
/* Line 1455 of yacc.c */
-#line 2139 "program_parse.y"
+#line 2143 "program_parse.y"
{
struct asm_symbol *exist = (struct asm_symbol *)
_mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
@@ -4901,7 +4905,7 @@ yyreduce:
/* Line 1455 of yacc.c */
-#line 4905 "program_parse.tab.c"
+#line 4909 "program_parse.tab.c"
default: break;
}
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
@@ -5120,7 +5124,7 @@ yyreturn:
/* Line 1675 of yacc.c */
-#line 2163 "program_parse.y"
+#line 2167 "program_parse.y"
void
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
index f70ea92cb05..9703e8e670f 100644
--- a/src/mesa/shader/program_parse.y
+++ b/src/mesa/shader/program_parse.y
@@ -923,8 +923,10 @@ addrRegRelOffset: { $$ = 0; }
addrRegPosOffset: INTEGER
{
if (($1 < 0) || ($1 > 63)) {
- yyerror(& @1, state,
- "relative address offset too large (positive)");
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
YYERROR;
} else {
$$ = $1;
@@ -935,8 +937,10 @@ addrRegPosOffset: INTEGER
addrRegNegOffset: INTEGER
{
if (($1 < 0) || ($1 > 64)) {
- yyerror(& @1, state,
- "relative address offset too large (negative)");
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
YYERROR;
} else {
$$ = $1;
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 54a25dfaf07..178b7d0dbaf 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1474,6 +1474,21 @@ _mesa_link_program(GLcontext *ctx, GLuint program)
FLUSH_VERTICES(ctx, _NEW_PROGRAM);
_slang_link(ctx, program, shProg);
+
+ /* debug code */
+ if (0) {
+ GLuint i;
+
+ _mesa_printf("Link %u shaders in program %u: %s\n",
+ shProg->NumShaders, shProg->Name,
+ shProg->LinkStatus ? "Success" : "Failed");
+
+ for (i = 0; i < shProg->NumShaders; i++) {
+ _mesa_printf(" shader %u, type 0x%x\n",
+ shProg->Shaders[i]->Name,
+ shProg->Shaders[i]->Type);
+ }
+ }
}
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
index bef0f856534..e5809509c93 100644
--- a/src/mesa/shader/slang/slang_builtin.c
+++ b/src/mesa/shader/slang/slang_builtin.c
@@ -741,7 +741,7 @@ static const struct input_info vertInputs[] = {
{ "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, SWIZZLE_NOOP }
+ { NULL, 0, GL_NONE, SWIZZLE_NOOP }
};
/** Predefined fragment shader inputs */
@@ -754,7 +754,7 @@ static const struct input_info fragInputs[] = {
{ "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, SWIZZLE_NOOP }
+ { NULL, 0, GL_NONE, SWIZZLE_NOOP }
};
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 349f432deca..703af9f8740 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -2775,7 +2775,7 @@ _slang_gen_while(slang_assemble_ctx * A, slang_operation *oper)
* body code (child[1])
*/
slang_ir_node *loop, *breakIf, *body;
- GLboolean isConst, constTrue;
+ GLboolean isConst, constTrue = GL_FALSE;
if (!A->EmitContReturn) {
/* We don't want to emit CONT instructions. If this while-loop has
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index 169c07f8cea..8f2b40d5dfb 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -546,6 +546,32 @@ _slang_update_inputs_outputs(struct gl_program *prog)
+/**
+ * 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 = _mesa_strstr(source, "#version");
+ if (ver) {
+ verCount++;
+ if (verCount > 1) {
+ ver[0] = '/';
+ ver[1] = '/';
+ }
+ source += 8;
+ }
+ else {
+ break;
+ }
+ }
+}
+
/**
@@ -593,6 +619,8 @@ concat_shaders(struct gl_shader_program *shProg, GLenum shaderType)
_mesa_printf("---NEW CONCATENATED SHADER---:\n%s\n------------\n", source);
*/
+ remove_extra_version_directives(source);
+
newShader = CALLOC_STRUCT(gl_shader);
newShader->Type = shaderType;
newShader->Source = source;
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index fa2a6307a4b..7107538cee7 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -115,7 +115,6 @@ SWRAST_SOURCES = \
swrast/s_feedback.c \
swrast/s_fog.c \
swrast/s_fragprog.c \
- swrast/s_imaging.c \
swrast/s_lines.c \
swrast/s_logic.c \
swrast/s_masking.c \
@@ -125,7 +124,6 @@ SWRAST_SOURCES = \
swrast/s_stencil.c \
swrast/s_texcombine.c \
swrast/s_texfilter.c \
- swrast/s_texstore.c \
swrast/s_triangle.c \
swrast/s_zoom.c
diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S
index 50a20370349..aaa17e6a3b9 100644
--- a/src/mesa/sparc/glapi_sparc.S
+++ b/src/mesa/sparc/glapi_sparc.S
@@ -1362,6 +1362,7 @@ gl_dispatch_functions_start:
GL_STUB_ALIAS(glIsRenderbuffer, glIsRenderbufferEXT)
GL_STUB_ALIAS(glRenderbufferStorage, glRenderbufferStorageEXT)
GL_STUB_ALIAS(glFramebufferTextureLayer, glFramebufferTextureLayerEXT)
+ GL_STUB_ALIAS(glProvokingVertex, glProvokingVertexEXT)
.globl gl_dispatch_functions_end
HIDDEN(gl_dispatch_functions_end)
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index c741940bcf4..5626e25323e 100644
--- a/src/mesa/state_tracker/st_cb_blit.c
+++ b/src/mesa/state_tracker/st_cb_blit.c
@@ -39,6 +39,7 @@
#include "shader/prog_print.h"
#include "st_context.h"
+#include "st_texture.h"
#include "st_program.h"
#include "st_cb_blit.h"
#include "st_cb_fbo.h"
@@ -110,17 +111,50 @@ st_BlitFramebuffer(GLcontext *ctx,
}
if (mask & GL_COLOR_BUFFER_BIT) {
- struct st_renderbuffer *srcRb =
- st_renderbuffer(readFB->_ColorReadBuffer);
- struct st_renderbuffer *dstRb =
- st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
- struct pipe_surface *srcSurf = srcRb->surface;
- struct pipe_surface *dstSurf = dstRb->surface;
-
- util_blit_pixels(st->blit,
- srcSurf, srcX0, srcY0, srcX1, srcY1,
- dstSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter);
+ struct gl_renderbuffer_attachment *srcAtt =
+ &readFB->Attachment[readFB->_ColorReadBufferIndex];
+
+ if(srcAtt->Type == GL_TEXTURE) {
+ struct pipe_screen *screen = ctx->st->pipe->screen;
+ const struct st_texture_object *srcObj =
+ st_texture_object(srcAtt->Texture);
+ struct st_renderbuffer *dstRb =
+ st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
+ struct pipe_surface *srcSurf;
+ struct pipe_surface *dstSurf = dstRb->surface;
+
+ if (!srcObj->pt)
+ return;
+
+ srcSurf = screen->get_tex_surface(screen,
+ srcObj->pt,
+ srcAtt->CubeMapFace,
+ srcAtt->TextureLevel,
+ srcAtt->Zoffset,
+ PIPE_BUFFER_USAGE_GPU_READ);
+ if(!srcSurf)
+ return;
+
+ util_blit_pixels(st->blit,
+ srcSurf, srcX0, srcY0, srcX1, srcY1,
+ dstSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+
+ pipe_surface_reference(&srcSurf, NULL);
+ }
+ else {
+ struct st_renderbuffer *srcRb =
+ st_renderbuffer(readFB->_ColorReadBuffer);
+ struct st_renderbuffer *dstRb =
+ st_renderbuffer(drawFB->_ColorDrawBuffers[0]);
+ struct pipe_surface *srcSurf = srcRb->surface;
+ struct pipe_surface *dstSurf = dstRb->surface;
+
+ util_blit_pixels(st->blit,
+ srcSurf, srcX0, srcY0, srcX1, srcY1,
+ dstSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+ }
}
if (mask & depthStencil) {
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index a9cafbf8cdc..99f3ba678bb 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -98,7 +98,7 @@ is_passthrough_program(const struct gl_fragment_program *prog)
static struct st_fragment_program *
combined_drawpix_fragment_program(GLcontext *ctx)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct st_fragment_program *stfp;
if (st->pixel_xfer.program->serialNo == st->pixel_xfer.xfer_prog_sn
@@ -445,8 +445,8 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
GLfloat x1, GLfloat y1, const GLfloat *color,
GLboolean invertTex, GLfloat maxXcoord, GLfloat maxYcoord)
{
- struct st_context *st = ctx->st;
- struct pipe_context *pipe = ctx->st->pipe;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
GLfloat verts[4][3][4]; /* four verts, three attribs, XYZW */
/* setup vertex data */
@@ -540,9 +540,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
const GLfloat *color,
GLboolean invertTex)
{
- struct st_context *st = ctx->st;
- struct pipe_context *pipe = ctx->st->pipe;
- struct cso_context *cso = ctx->st->cso_context;
+ struct st_context *st = st_context(ctx);
+ struct pipe_context *pipe = st->pipe;
+ struct cso_context *cso = st->cso_context;
GLfloat x0, y0, x1, y1;
GLsizei maxSize;
@@ -652,7 +652,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *strb;
@@ -793,7 +793,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
{
struct st_fragment_program *stfp;
struct st_vertex_program *stvp;
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_surface *ps;
const GLfloat *color;
@@ -811,21 +811,21 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (format == GL_DEPTH_COMPONENT) {
ps = st->state.framebuffer.zsbuf;
- stfp = make_fragment_shader_z(ctx->st);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
+ stfp = make_fragment_shader_z(st);
+ stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
color = ctx->Current.RasterColor;
}
else {
ps = st->state.framebuffer.cbufs[0];
stfp = combined_drawpix_fragment_program(ctx);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
+ stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
color = NULL;
}
/* draw with textured quad */
{
struct pipe_texture *pt
- = make_texture(ctx->st, width, height, format, type, unpack, pixels);
+ = make_texture(st, width, height, format, type, unpack, pixels);
if (pt) {
draw_textured_quad(ctx, x, y, ctx->Current.RasterPos[2],
width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY,
@@ -942,7 +942,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLsizei width, GLsizei height,
GLint dstx, GLint dsty, GLenum type)
{
- struct st_context *st = ctx->st;
+ struct st_context *st = st_context(ctx);
struct pipe_context *pipe = st->pipe;
struct pipe_screen *screen = pipe->screen;
struct st_renderbuffer *rbRead;
@@ -995,14 +995,14 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
rbRead = st_get_color_read_renderbuffer(ctx);
color = NULL;
stfp = combined_drawpix_fragment_program(ctx);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_FALSE);
+ stvp = st_make_passthrough_vertex_shader(st, GL_FALSE);
}
else {
assert(type == GL_DEPTH);
rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer);
color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
- stfp = make_fragment_shader_z(ctx->st);
- stvp = st_make_passthrough_vertex_shader(ctx->st, GL_TRUE);
+ stfp = make_fragment_shader_z(st);
+ stvp = st_make_passthrough_vertex_shader(st, GL_TRUE);
}
srcFormat = rbRead->texture->format;
@@ -1059,7 +1059,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
assert(pth <= maxSize);
}
- pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
ptw, pth, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt)
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index a96602878e4..fe0a1214933 100644
--- a/src/mesa/state_tracker/st_cb_fbo.c
+++ b/src/mesa/state_tracker/st_cb_fbo.c
@@ -258,6 +258,7 @@ st_new_renderbuffer_fb(enum pipe_format format, int samples, boolean sw)
strb->Base.ClassID = 0x4242; /* just a unique value */
strb->Base.NumSamples = samples;
strb->format = format;
+ init_renderbuffer_bits(strb, format);
strb->software = sw;
switch (format) {
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4398ab28392..b2d5c39a3a0 100644
--- a/src/mesa/state_tracker/st_cb_program.c
+++ b/src/mesa/state_tracker/st_cb_program.c
@@ -45,6 +45,7 @@
#include "st_context.h"
#include "st_program.h"
#include "st_atom_shader.h"
+#include "st_mesa_to_tgsi.h"
#include "st_cb_program.h"
@@ -152,7 +153,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
}
if (stvp->state.tokens) {
- _mesa_free((void *) stvp->state.tokens);
+ st_free_tokens(stvp->state.tokens);
stvp->state.tokens = NULL;
}
}
@@ -167,7 +168,7 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog)
}
if (stfp->state.tokens) {
- _mesa_free((void *) stfp->state.tokens);
+ st_free_tokens(stfp->state.tokens);
stfp->state.tokens = NULL;
}
@@ -214,7 +215,7 @@ static void st_program_string_notify( GLcontext *ctx,
}
if (stfp->state.tokens) {
- _mesa_free((void *) stfp->state.tokens);
+ st_free_tokens(stfp->state.tokens);
stfp->state.tokens = NULL;
}
@@ -242,7 +243,7 @@ static void st_program_string_notify( GLcontext *ctx,
}
if (stvp->state.tokens) {
- _mesa_free((void *) stvp->state.tokens);
+ st_free_tokens(stvp->state.tokens);
stvp->state.tokens = NULL;
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index abaf9d2c353..3520c986b47 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -658,8 +658,10 @@ st_TexImage(GLcontext * ctx,
format, type,
pixels, unpack, "glTexImage");
}
- if (!pixels)
- return;
+
+ /* Note: we can't check for pixels==NULL until after we've allocated
+ * memory for the texture.
+ */
/* See if we can do texture compression with a blit/render.
*/
@@ -670,6 +672,9 @@ st_TexImage(GLcontext * ctx,
stImage->pt->format,
stImage->pt->target,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) {
+ if (!pixels)
+ goto done;
+
if (compress_with_blit(ctx, target, level, 0, 0, 0, width, height, depth,
format, type, pixels, unpack, texImage)) {
goto done;
@@ -711,6 +716,9 @@ st_TexImage(GLcontext * ctx,
return;
}
+ if (!pixels)
+ goto done;
+
DBG("Upload image %dx%dx%d row_len %x pitch %x\n",
width, height, depth, width * texelBytes, dstRowStride);
@@ -753,17 +761,13 @@ st_TexImage(GLcontext * ctx,
}
}
+done:
_mesa_unmap_teximage_pbo(ctx, unpack);
-done:
if (stImage->pt && texImage->Data) {
st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
-
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
}
@@ -1096,7 +1100,7 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
if (!texImage->Data) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage");
- return;
+ goto done;
}
src = (const GLubyte *) pixels;
@@ -1127,17 +1131,13 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
}
}
+done:
_mesa_unmap_teximage_pbo(ctx, packing);
-done:
if (stImage->pt) {
st_texture_image_unmap(ctx->st, stImage);
texImage->Data = NULL;
}
-
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
}
@@ -1601,10 +1601,6 @@ st_copy_texsubimage(GLcontext *ctx,
destX, destY, destZ,
srcX, srcY, width, height);
}
-
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
}
diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c
index 503a5f34a3f..c76bff91819 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -328,23 +328,29 @@ get_arrays_bounds(const struct st_vertex_program *vp,
const GLubyte **low, const GLubyte **high)
{
const GLubyte *low_addr = NULL;
+ const GLubyte *high_addr = NULL;
GLuint attr;
- GLint stride;
for (attr = 0; attr < vp->num_inputs; attr++) {
const GLuint mesaAttr = vp->index_to_input[attr];
+ const GLint stride = arrays[mesaAttr]->StrideB;
const GLubyte *start = arrays[mesaAttr]->Ptr;
- stride = arrays[mesaAttr]->StrideB;
+ const unsigned sz = (arrays[mesaAttr]->Size *
+ _mesa_sizeof_type(arrays[mesaAttr]->Type));
+ const GLubyte *end = start + (max_index * stride) + sz;
+
if (attr == 0) {
low_addr = start;
+ high_addr = end;
}
else {
low_addr = MIN2(low_addr, start);
+ high_addr = MAX2(high_addr, end);
}
}
*low = low_addr;
- *high = low_addr + (max_index + 1) * stride;
+ *high = high_addr;
}
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index ca32b2e573c..5c0d335d62d 100644
--- a/src/mesa/state_tracker/st_framebuffer.c
+++ b/src/mesa/state_tracker/st_framebuffer.c
@@ -66,7 +66,7 @@ st_create_framebuffer( const __GLcontextModes *visual,
else {
/* Only allocate front buffer right now if we're single buffered.
* If double-buffered, allocate front buffer on demand later.
- * See check_create_front_buffers().
+ * See check_create_front_buffers() and st_set_framebuffer_surface().
*/
struct gl_renderbuffer *rb
= st_new_renderbuffer_fb(colorFormat, samples, FALSE);
@@ -170,8 +170,20 @@ st_set_framebuffer_surface(struct st_framebuffer *stfb,
strb = st_renderbuffer(stfb->Base.Attachment[surfIndex].Renderbuffer);
- /* fail */
- if (!strb) return;
+ if (!strb) {
+ if (surfIndex == ST_SURFACE_FRONT_LEFT) {
+ /* Delayed creation when the window system supplies a fake front buffer */
+ struct st_renderbuffer *strb_back
+ = st_renderbuffer(stfb->Base.Attachment[ST_SURFACE_BACK_LEFT].Renderbuffer);
+ struct gl_renderbuffer *rb
+ = st_new_renderbuffer_fb(surf->format, strb_back->Base.NumSamples, FALSE);
+ _mesa_add_renderbuffer(&stfb->Base, BUFFER_FRONT_LEFT, rb);
+ strb = st_renderbuffer(rb);
+ } else {
+ /* fail */
+ return;
+ }
+ }
/* replace the renderbuffer's surface/texture pointers */
pipe_surface_reference( &strb->surface, surf );
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.c b/src/mesa/state_tracker/st_mesa_to_tgsi.c
index 2ab12d3cf3f..b0a1b529f1e 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -27,836 +27,648 @@
/*
* \author
- * Michal Krol
+ * Michal Krol,
+ * Keith Whitwell
*/
#include "pipe/p_compiler.h"
#include "pipe/p_shader_tokens.h"
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_build.h"
-#include "tgsi/tgsi_util.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_sanity.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_ureg.h"
#include "st_mesa_to_tgsi.h"
#include "shader/prog_instruction.h"
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
#include "util/u_debug.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+
+struct label {
+ unsigned branch_target;
+ unsigned token;
+};
+
+struct st_translate {
+ struct ureg_program *ureg;
+
+ struct ureg_dst temps[MAX_PROGRAM_TEMPS];
+ struct ureg_src *constants;
+ struct ureg_dst outputs[PIPE_MAX_SHADER_OUTPUTS];
+ struct ureg_src inputs[PIPE_MAX_SHADER_INPUTS];
+ struct ureg_dst address[1];
+ struct ureg_src samplers[PIPE_MAX_SAMPLERS];
+
+ const GLuint *inputMapping;
+ const GLuint *outputMapping;
+
+ /* For every instruction that contains a label (eg CALL), keep
+ * details so that we can go back afterwards and emit the correct
+ * tgsi instruction number for each label.
+ */
+ struct label *labels;
+ unsigned labels_size;
+ unsigned labels_count;
+
+ /* Keep a record of the tgsi instruction number that each mesa
+ * instruction starts at, will be used to fix up labels after
+ * translation.
+ */
+ unsigned *insn;
+ unsigned insn_size;
+ unsigned insn_count;
+
+ unsigned procType; /**< TGSI_PROCESSOR_VERTEX/FRAGMENT */
+
+ boolean error;
+};
+
+
+static unsigned *get_label( struct st_translate *t,
+ unsigned branch_target )
+{
+ unsigned i;
+
+ if (t->labels_count + 1 >= t->labels_size) {
+ unsigned old_size = t->labels_size;
+ t->labels_size = 1 << (util_logbase2(t->labels_size) + 1);
+ t->labels = REALLOC( t->labels,
+ old_size * sizeof t->labels[0],
+ t->labels_size * sizeof t->labels[0] );
+ if (t->labels == NULL) {
+ static unsigned dummy;
+ t->error = TRUE;
+ return &dummy;
+ }
+ }
+
+ i = t->labels_count++;
+ t->labels[i].branch_target = branch_target;
+ return &t->labels[i].token;
+}
+
+
+static void set_insn_start( struct st_translate *t,
+ unsigned start )
+{
+ if (t->insn_count + 1 >= t->insn_size) {
+ unsigned old_size = t->insn_size;
+ t->insn_size = 1 << (util_logbase2(t->insn_size) + 1);
+ t->insn = REALLOC( t->insn,
+ old_size * sizeof t->insn[0],
+ t->insn_size * sizeof t->insn[0] );
+ if (t->insn == NULL) {
+ t->error = TRUE;
+ return;
+ }
+ }
+
+ t->insn[t->insn_count++] = start;
+}
+
/*
* Map mesa register file to TGSI register file.
*/
-static GLuint
-map_register_file(
- gl_register_file file,
- GLuint index,
- const GLuint immediateMapping[],
- GLboolean indirectAccess )
+static struct ureg_dst
+dst_register( struct st_translate *t,
+ gl_register_file file,
+ GLuint index )
{
switch( file ) {
case PROGRAM_UNDEFINED:
- return TGSI_FILE_NULL;
+ return ureg_dst_undef();
+
case PROGRAM_TEMPORARY:
- return TGSI_FILE_TEMPORARY;
- /*case PROGRAM_LOCAL_PARAM:*/
- /*case PROGRAM_ENV_PARAM:*/
-
- /* Because of the longstanding problem with mesa arb shaders
- * where constants, immediates and state variables are all
- * bundled together as PROGRAM_STATE_VAR, we can't tell from the
- * mesa register file whether this is a CONSTANT or an
- * IMMEDIATE, hence we need all the other information.
- */
- case PROGRAM_STATE_VAR:
- case PROGRAM_NAMED_PARAM:
- case PROGRAM_UNIFORM:
- if (!indirectAccess && immediateMapping && immediateMapping[index] != ~0)
- return TGSI_FILE_IMMEDIATE;
- else
- return TGSI_FILE_CONSTANT;
- case PROGRAM_CONSTANT:
- if (indirectAccess)
- return TGSI_FILE_CONSTANT;
- assert(immediateMapping[index] != ~0);
- return TGSI_FILE_IMMEDIATE;
- case PROGRAM_INPUT:
- return TGSI_FILE_INPUT;
+ if (ureg_dst_is_undef(t->temps[index]))
+ t->temps[index] = ureg_DECL_temporary( t->ureg );
+
+ return t->temps[index];
+
case PROGRAM_OUTPUT:
- return TGSI_FILE_OUTPUT;
+ return t->outputs[t->outputMapping[index]];
+
case PROGRAM_ADDRESS:
- return TGSI_FILE_ADDRESS;
+ return t->address[index];
+
default:
assert( 0 );
- return TGSI_FILE_NULL;
+ return ureg_dst_undef();
}
}
-/**
- * Map mesa register file index to TGSI index.
- * Take special care when processing input and output indices.
- * \param file one of TGSI_FILE_x
- * \param index the mesa register file index
- * \param inputMapping maps Mesa input indexes to TGSI input indexes
- * \param outputMapping maps Mesa output indexes to TGSI output indexes
- */
-static GLuint
-map_register_file_index(
- GLuint procType,
- GLuint file,
- GLuint index,
- GLuint *swizzle,
- const GLuint inputMapping[],
- const GLuint outputMapping[],
- const GLuint immediateMapping[],
- GLboolean indirectAccess )
+
+static struct ureg_src
+src_register( struct st_translate *t,
+ gl_register_file file,
+ GLuint index )
{
switch( file ) {
- case TGSI_FILE_INPUT:
- /* inputs are mapped according to the user-defined map */
- return inputMapping[index];
+ case PROGRAM_UNDEFINED:
+ return ureg_src_undef();
- case TGSI_FILE_OUTPUT:
- return outputMapping[index];
+ case PROGRAM_TEMPORARY:
+ if (ureg_dst_is_undef(t->temps[index]))
+ t->temps[index] = ureg_DECL_temporary( t->ureg );
+ return ureg_src(t->temps[index]);
- case TGSI_FILE_IMMEDIATE:
- if (indirectAccess)
- return index;
- assert(immediateMapping[index] != ~0);
- return immediateMapping[index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_UNIFORM:
+ case PROGRAM_CONSTANT:
+ return t->constants[index];
+
+ case PROGRAM_INPUT:
+ return t->inputs[t->inputMapping[index]];
+
+ case PROGRAM_OUTPUT:
+ return ureg_src(t->outputs[t->outputMapping[index]]); /* not needed? */
+
+ case PROGRAM_ADDRESS:
+ return ureg_src(t->address[index]);
default:
- return index;
+ assert( 0 );
+ return ureg_src_undef();
}
}
-/*
+
+/**
* Map mesa texture target to TGSI texture target.
*/
-static GLuint
-map_texture_target(
- GLuint textarget,
- GLboolean shadow )
+static unsigned
+translate_texture_target( GLuint textarget,
+ GLboolean shadow )
{
- switch( textarget ) {
- case TEXTURE_1D_INDEX:
- if (shadow)
- return TGSI_TEXTURE_SHADOW1D;
- else
- return TGSI_TEXTURE_1D;
- case TEXTURE_2D_INDEX:
- if (shadow)
- return TGSI_TEXTURE_SHADOW2D;
- else
- return TGSI_TEXTURE_2D;
- case TEXTURE_3D_INDEX:
- return TGSI_TEXTURE_3D;
- case TEXTURE_CUBE_INDEX:
- return TGSI_TEXTURE_CUBE;
- case TEXTURE_RECT_INDEX:
- if (shadow)
- return TGSI_TEXTURE_SHADOWRECT;
- else
- return TGSI_TEXTURE_RECT;
- default:
- assert( 0 );
+ if (shadow) {
+ switch( textarget ) {
+ case TEXTURE_1D_INDEX: return TGSI_TEXTURE_SHADOW1D;
+ case TEXTURE_2D_INDEX: return TGSI_TEXTURE_SHADOW2D;
+ case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT;
+ default: break;
+ }
}
- return TGSI_TEXTURE_1D;
-}
-
-static GLuint
-convert_sat(
- GLuint sat )
-{
- switch( sat ) {
- case SATURATE_OFF:
- return TGSI_SAT_NONE;
- case SATURATE_ZERO_ONE:
- return TGSI_SAT_ZERO_ONE;
- case SATURATE_PLUS_MINUS_ONE:
- return TGSI_SAT_MINUS_PLUS_ONE;
+ switch( textarget ) {
+ case TEXTURE_1D_INDEX: return TGSI_TEXTURE_1D;
+ case TEXTURE_2D_INDEX: return TGSI_TEXTURE_2D;
+ case TEXTURE_3D_INDEX: return TGSI_TEXTURE_3D;
+ case TEXTURE_CUBE_INDEX: return TGSI_TEXTURE_CUBE;
+ case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_RECT;
default:
assert( 0 );
- return TGSI_SAT_NONE;
+ return TGSI_TEXTURE_1D;
}
}
-static GLuint
-convert_writemask(
- GLuint writemask )
+
+static struct ureg_dst
+translate_dst( struct st_translate *t,
+ const struct prog_dst_register *DstReg,
+ boolean saturate )
{
- assert( WRITEMASK_X == TGSI_WRITEMASK_X );
- assert( WRITEMASK_Y == TGSI_WRITEMASK_Y );
- assert( WRITEMASK_Z == TGSI_WRITEMASK_Z );
- assert( WRITEMASK_W == TGSI_WRITEMASK_W );
- assert( (writemask & ~TGSI_WRITEMASK_XYZW) == 0 );
+ struct ureg_dst dst = dst_register( t,
+ DstReg->File,
+ DstReg->Index );
- return writemask;
+ dst = ureg_writemask( dst,
+ DstReg->WriteMask );
+
+ if (saturate)
+ dst = ureg_saturate( dst );
+
+ if (DstReg->RelAddr)
+ dst = ureg_dst_indirect( dst, ureg_src(t->address[0]) );
+
+ return dst;
}
-static struct tgsi_full_immediate
-make_immediate(const float *value, uint size)
+
+static struct ureg_src
+translate_src( struct st_translate *t,
+ const struct prog_src_register *SrcReg )
{
- struct tgsi_full_immediate imm;
- unsigned i;
+ struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );
+
+ src = ureg_swizzle( src,
+ GET_SWZ( SrcReg->Swizzle, 0 ) & 0x3,
+ GET_SWZ( SrcReg->Swizzle, 1 ) & 0x3,
+ GET_SWZ( SrcReg->Swizzle, 2 ) & 0x3,
+ GET_SWZ( SrcReg->Swizzle, 3 ) & 0x3);
- imm = tgsi_default_full_immediate();
- imm.Immediate.NrTokens += size;
- imm.Immediate.DataType = TGSI_IMM_FLOAT32;
+ if (SrcReg->Negate == NEGATE_XYZW)
+ src = ureg_negate(src);
- for (i = 0; i < size; i++)
- imm.u[i].Float = value[i];
+ if (SrcReg->Abs)
+ src = ureg_abs(src);
- return imm;
+ if (SrcReg->RelAddr)
+ src = ureg_src_indirect( src, ureg_src(t->address[0]));
+
+ return src;
}
-static void
-compile_instruction(
- const struct prog_instruction *inst,
- struct tgsi_full_instruction *fullinst,
- const GLuint inputMapping[],
- const GLuint outputMapping[],
- const GLuint immediateMapping[],
- GLboolean indirectAccess,
- GLuint preamble_size,
- GLuint procType,
- GLboolean *insideSubroutine,
- GLint wposTemp)
+
+static struct ureg_src swizzle_4v( struct ureg_src src,
+ const unsigned *swz )
{
- GLuint i;
- struct tgsi_full_dst_register *fulldst;
- struct tgsi_full_src_register *fullsrc;
-
- *fullinst = tgsi_default_full_instruction();
-
- fullinst->Instruction.Saturate = convert_sat( inst->SaturateMode );
- fullinst->Instruction.NumDstRegs = _mesa_num_inst_dst_regs( inst->Opcode );
- fullinst->Instruction.NumSrcRegs = _mesa_num_inst_src_regs( inst->Opcode );
-
- fulldst = &fullinst->FullDstRegisters[0];
- fulldst->DstRegister.File = map_register_file( inst->DstReg.File, 0, NULL, GL_FALSE );
- fulldst->DstRegister.Index = map_register_file_index(
- procType,
- fulldst->DstRegister.File,
- inst->DstReg.Index,
- NULL,
- inputMapping,
- outputMapping,
- NULL,
- GL_FALSE );
- fulldst->DstRegister.WriteMask = convert_writemask( inst->DstReg.WriteMask );
- if (inst->DstReg.RelAddr) {
- fulldst->DstRegister.Indirect = 1;
- fulldst->DstRegisterInd.File = TGSI_FILE_ADDRESS;
- fulldst->DstRegisterInd.Index = 0;
+ return ureg_swizzle( src, swz[0], swz[1], swz[2], swz[3] );
+}
+
+
+/**
+ * Translate SWZ instructions into a single MAD. EG:
+ *
+ * SWZ dst, src.x-y10
+ *
+ * becomes:
+ *
+ * MAD dst {1,-1,0,0}, src.xyxx, {0,0,1,0}
+ */
+static void emit_swz( struct st_translate *t,
+ struct ureg_dst dst,
+ const struct prog_src_register *SrcReg )
+{
+ struct ureg_program *ureg = t->ureg;
+ struct ureg_src src = src_register( t, SrcReg->File, SrcReg->Index );
+
+ unsigned negate_mask = SrcReg->Negate;
+
+ unsigned one_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ONE) << 0 |
+ (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ONE) << 1 |
+ (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ONE) << 2 |
+ (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ONE) << 3);
+
+ unsigned zero_mask = ((GET_SWZ(SrcReg->Swizzle, 0) == SWIZZLE_ZERO) << 0 |
+ (GET_SWZ(SrcReg->Swizzle, 1) == SWIZZLE_ZERO) << 1 |
+ (GET_SWZ(SrcReg->Swizzle, 2) == SWIZZLE_ZERO) << 2 |
+ (GET_SWZ(SrcReg->Swizzle, 3) == SWIZZLE_ZERO) << 3);
+
+ unsigned negative_one_mask = one_mask & negate_mask;
+ unsigned positive_one_mask = one_mask & ~negate_mask;
+
+ struct ureg_src imm;
+ unsigned i;
+ unsigned mul_swizzle[4] = {0,0,0,0};
+ unsigned add_swizzle[4] = {0,0,0,0};
+ unsigned src_swizzle[4] = {0,0,0,0};
+ boolean need_add = FALSE;
+ boolean need_mul = FALSE;
+
+ if (dst.WriteMask == 0)
+ return;
+
+ /* Is this just a MOV?
+ */
+ if (zero_mask == 0 &&
+ one_mask == 0 &&
+ (negate_mask == 0 || negate_mask == TGSI_WRITEMASK_XYZW))
+ {
+ ureg_MOV( ureg, dst, translate_src( t, SrcReg ));
+ return;
}
- for (i = 0; i < fullinst->Instruction.NumSrcRegs; i++) {
- GLuint j;
- GLuint swizzle = inst->SrcReg[i].Swizzle;
+#define IMM_ZERO 0
+#define IMM_ONE 1
+#define IMM_NEG_ONE 2
- fullsrc = &fullinst->FullSrcRegisters[i];
+ imm = ureg_imm3f( ureg, 0, 1, -1 );
- if (procType == TGSI_PROCESSOR_FRAGMENT &&
- inst->SrcReg[i].File == PROGRAM_INPUT &&
- inst->SrcReg[i].Index == FRAG_ATTRIB_WPOS) {
- /* special case of INPUT[WPOS] */
- fullsrc->SrcRegister.File = TGSI_FILE_TEMPORARY;
- fullsrc->SrcRegister.Index = wposTemp;
- }
- else {
- /* any other src register */
- fullsrc->SrcRegister.File = map_register_file(
- inst->SrcReg[i].File,
- inst->SrcReg[i].Index,
- immediateMapping,
- indirectAccess );
- fullsrc->SrcRegister.Index = map_register_file_index(
- procType,
- fullsrc->SrcRegister.File,
- inst->SrcReg[i].Index,
- &swizzle,
- inputMapping,
- outputMapping,
- immediateMapping,
- indirectAccess );
- }
+ for (i = 0; i < 4; i++) {
+ unsigned bit = 1 << i;
- /* swizzle (ext swizzle also depends on negation) */
- {
- GLuint swz[4];
- GLboolean extended = (inst->SrcReg[i].Negate != NEGATE_NONE &&
- inst->SrcReg[i].Negate != NEGATE_XYZW);
- for( j = 0; j < 4; j++ ) {
- swz[j] = GET_SWZ( swizzle, j );
- if (swz[j] > SWIZZLE_W)
- extended = GL_TRUE;
+ if (dst.WriteMask & bit) {
+ if (positive_one_mask & bit) {
+ mul_swizzle[i] = IMM_ZERO;
+ add_swizzle[i] = IMM_ONE;
+ need_add = TRUE;
}
- if (extended) {
- for (j = 0; j < 4; j++) {
- tgsi_util_set_src_register_extswizzle(&fullsrc->SrcRegisterExtSwz,
- swz[j], j);
- }
+ else if (negative_one_mask & bit) {
+ mul_swizzle[i] = IMM_ZERO;
+ add_swizzle[i] = IMM_NEG_ONE;
+ need_add = TRUE;
+ }
+ else if (zero_mask & bit) {
+ mul_swizzle[i] = IMM_ZERO;
+ add_swizzle[i] = IMM_ZERO;
+ need_add = TRUE;
}
else {
- for (j = 0; j < 4; j++) {
- tgsi_util_set_src_register_swizzle(&fullsrc->SrcRegister,
- swz[j], j);
+ add_swizzle[i] = IMM_ZERO;
+ src_swizzle[i] = GET_SWZ(SrcReg->Swizzle, i);
+ need_mul = TRUE;
+ if (negate_mask & bit) {
+ mul_swizzle[i] = IMM_NEG_ONE;
+ }
+ else {
+ mul_swizzle[i] = IMM_ONE;
}
}
}
+ }
- if( inst->SrcReg[i].Negate == NEGATE_XYZW ) {
- fullsrc->SrcRegister.Negate = 1;
- }
- else if( inst->SrcReg[i].Negate != NEGATE_NONE ) {
- if( inst->SrcReg[i].Negate & NEGATE_X ) {
- fullsrc->SrcRegisterExtSwz.NegateX = 1;
- }
- if( inst->SrcReg[i].Negate & NEGATE_Y ) {
- fullsrc->SrcRegisterExtSwz.NegateY = 1;
- }
- if( inst->SrcReg[i].Negate & NEGATE_Z ) {
- fullsrc->SrcRegisterExtSwz.NegateZ = 1;
- }
- if( inst->SrcReg[i].Negate & NEGATE_W ) {
- fullsrc->SrcRegisterExtSwz.NegateW = 1;
- }
- }
+ if (need_mul && need_add) {
+ ureg_MAD( ureg,
+ dst,
+ swizzle_4v( src, src_swizzle ),
+ swizzle_4v( imm, mul_swizzle ),
+ swizzle_4v( imm, add_swizzle ) );
+ }
+ else if (need_mul) {
+ ureg_MUL( ureg,
+ dst,
+ swizzle_4v( src, src_swizzle ),
+ swizzle_4v( imm, mul_swizzle ) );
+ }
+ else if (need_add) {
+ ureg_MOV( ureg,
+ dst,
+ swizzle_4v( imm, add_swizzle ) );
+ }
+ else {
+ assert(0);
+ }
- if( inst->SrcReg[i].Abs ) {
- fullsrc->SrcRegisterExtMod.Absolute = 1;
- }
+#undef IMM_ZERO
+#undef IMM_ONE
+#undef IMM_NEG_ONE
+}
- if( inst->SrcReg[i].RelAddr ) {
- fullsrc->SrcRegister.Indirect = 1;
- fullsrc->SrcRegisterInd.File = TGSI_FILE_ADDRESS;
- fullsrc->SrcRegisterInd.Index = 0;
- }
- }
- switch( inst->Opcode ) {
+static unsigned
+translate_opcode( unsigned op )
+{
+ switch( op ) {
case OPCODE_ARL:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ARL;
- break;
+ return TGSI_OPCODE_ARL;
case OPCODE_ABS:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ABS;
- break;
+ return TGSI_OPCODE_ABS;
case OPCODE_ADD:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ADD;
- break;
+ return TGSI_OPCODE_ADD;
case OPCODE_BGNLOOP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_BGNLOOP;
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
- break;
+ return TGSI_OPCODE_BGNLOOP;
case OPCODE_BGNSUB:
- fullinst->Instruction.Opcode = TGSI_OPCODE_BGNSUB;
- *insideSubroutine = GL_TRUE;
- break;
+ return TGSI_OPCODE_BGNSUB;
case OPCODE_BRA:
- fullinst->Instruction.Opcode = TGSI_OPCODE_BRA;
- break;
+ return TGSI_OPCODE_BRA;
case OPCODE_BRK:
- fullinst->Instruction.Opcode = TGSI_OPCODE_BRK;
- break;
+ return TGSI_OPCODE_BRK;
case OPCODE_CAL:
- fullinst->Instruction.Opcode = TGSI_OPCODE_CAL;
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
- break;
+ return TGSI_OPCODE_CAL;
case OPCODE_CMP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_CMP;
- break;
+ return TGSI_OPCODE_CMP;
case OPCODE_CONT:
- fullinst->Instruction.Opcode = TGSI_OPCODE_CONT;
- break;
+ return TGSI_OPCODE_CONT;
case OPCODE_COS:
- fullinst->Instruction.Opcode = TGSI_OPCODE_COS;
- break;
+ return TGSI_OPCODE_COS;
case OPCODE_DDX:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DDX;
- break;
+ return TGSI_OPCODE_DDX;
case OPCODE_DDY:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DDY;
- break;
+ return TGSI_OPCODE_DDY;
case OPCODE_DP2:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP2;
- break;
+ return TGSI_OPCODE_DP2;
case OPCODE_DP2A:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP2A;
- break;
+ return TGSI_OPCODE_DP2A;
case OPCODE_DP3:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP3;
- break;
+ return TGSI_OPCODE_DP3;
case OPCODE_DP4:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DP4;
- break;
+ return TGSI_OPCODE_DP4;
case OPCODE_DPH:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DPH;
- break;
+ return TGSI_OPCODE_DPH;
case OPCODE_DST:
- fullinst->Instruction.Opcode = TGSI_OPCODE_DST;
- break;
+ return TGSI_OPCODE_DST;
case OPCODE_ELSE:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ELSE;
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
- break;
+ return TGSI_OPCODE_ELSE;
case OPCODE_ENDIF:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDIF;
- break;
+ return TGSI_OPCODE_ENDIF;
case OPCODE_ENDLOOP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDLOOP;
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
- break;
+ return TGSI_OPCODE_ENDLOOP;
case OPCODE_ENDSUB:
- fullinst->Instruction.Opcode = TGSI_OPCODE_ENDSUB;
- *insideSubroutine = GL_FALSE;
- break;
+ return TGSI_OPCODE_ENDSUB;
case OPCODE_EX2:
- fullinst->Instruction.Opcode = TGSI_OPCODE_EX2;
- break;
+ return TGSI_OPCODE_EX2;
case OPCODE_EXP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_EXP;
- break;
+ return TGSI_OPCODE_EXP;
case OPCODE_FLR:
- fullinst->Instruction.Opcode = TGSI_OPCODE_FLR;
- break;
+ return TGSI_OPCODE_FLR;
case OPCODE_FRC:
- fullinst->Instruction.Opcode = TGSI_OPCODE_FRC;
- break;
+ return TGSI_OPCODE_FRC;
case OPCODE_IF:
- fullinst->Instruction.Opcode = TGSI_OPCODE_IF;
- fullinst->InstructionExtLabel.Label = inst->BranchTarget + preamble_size;
- break;
+ return TGSI_OPCODE_IF;
case OPCODE_TRUNC:
- fullinst->Instruction.Opcode = TGSI_OPCODE_TRUNC;
- break;
+ return TGSI_OPCODE_TRUNC;
case OPCODE_KIL:
- /* conditional */
- fullinst->Instruction.Opcode = TGSI_OPCODE_KIL;
- break;
+ return TGSI_OPCODE_KIL;
case OPCODE_KIL_NV:
- /* predicated */
- assert(inst->DstReg.CondMask == COND_TR);
- fullinst->Instruction.Opcode = TGSI_OPCODE_KILP;
- break;
+ return TGSI_OPCODE_KILP;
case OPCODE_LG2:
- fullinst->Instruction.Opcode = TGSI_OPCODE_LG2;
- break;
+ return TGSI_OPCODE_LG2;
case OPCODE_LOG:
- fullinst->Instruction.Opcode = TGSI_OPCODE_LOG;
- break;
+ return TGSI_OPCODE_LOG;
case OPCODE_LIT:
- fullinst->Instruction.Opcode = TGSI_OPCODE_LIT;
- break;
+ return TGSI_OPCODE_LIT;
case OPCODE_LRP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_LRP;
- break;
+ return TGSI_OPCODE_LRP;
case OPCODE_MAD:
- fullinst->Instruction.Opcode = TGSI_OPCODE_MAD;
- break;
+ return TGSI_OPCODE_MAD;
case OPCODE_MAX:
- fullinst->Instruction.Opcode = TGSI_OPCODE_MAX;
- break;
+ return TGSI_OPCODE_MAX;
case OPCODE_MIN:
- fullinst->Instruction.Opcode = TGSI_OPCODE_MIN;
- break;
+ return TGSI_OPCODE_MIN;
case OPCODE_MOV:
- fullinst->Instruction.Opcode = TGSI_OPCODE_MOV;
- break;
+ return TGSI_OPCODE_MOV;
case OPCODE_MUL:
- fullinst->Instruction.Opcode = TGSI_OPCODE_MUL;
- break;
+ return TGSI_OPCODE_MUL;
case OPCODE_NOISE1:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE1;
- break;
+ return TGSI_OPCODE_NOISE1;
case OPCODE_NOISE2:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE2;
- break;
+ return TGSI_OPCODE_NOISE2;
case OPCODE_NOISE3:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE3;
- break;
+ return TGSI_OPCODE_NOISE3;
case OPCODE_NOISE4:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOISE4;
- break;
+ return TGSI_OPCODE_NOISE4;
case OPCODE_NOP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NOP;
- break;
+ return TGSI_OPCODE_NOP;
case OPCODE_NRM3:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NRM;
- break;
+ return TGSI_OPCODE_NRM;
case OPCODE_NRM4:
- fullinst->Instruction.Opcode = TGSI_OPCODE_NRM4;
- break;
+ return TGSI_OPCODE_NRM4;
case OPCODE_POW:
- fullinst->Instruction.Opcode = TGSI_OPCODE_POW;
- break;
+ return TGSI_OPCODE_POW;
case OPCODE_RCP:
- fullinst->Instruction.Opcode = TGSI_OPCODE_RCP;
- break;
+ return TGSI_OPCODE_RCP;
case OPCODE_RET:
- /* If RET is used inside main (not a real subroutine) we may want
- * to execute END instead of RET. TBD...
- */
- if (1 /* *insideSubroutine */) {
- fullinst->Instruction.Opcode = TGSI_OPCODE_RET;
- }
- else {
- /* inside main() pseudo-function */
- fullinst->Instruction.Opcode = TGSI_OPCODE_END;
- }
- break;
+ return TGSI_OPCODE_RET;
case OPCODE_RSQ:
- fullinst->Instruction.Opcode = TGSI_OPCODE_RSQ;
- break;
+ return TGSI_OPCODE_RSQ;
case OPCODE_SCS:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SCS;
- fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XY;
- break;
+ return TGSI_OPCODE_SCS;
case OPCODE_SEQ:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SEQ;
- break;
+ return TGSI_OPCODE_SEQ;
case OPCODE_SGE:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SGE;
- break;
+ return TGSI_OPCODE_SGE;
case OPCODE_SGT:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SGT;
- break;
+ return TGSI_OPCODE_SGT;
case OPCODE_SIN:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SIN;
- break;
+ return TGSI_OPCODE_SIN;
case OPCODE_SLE:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SLE;
- break;
+ return TGSI_OPCODE_SLE;
case OPCODE_SLT:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SLT;
- break;
+ return TGSI_OPCODE_SLT;
case OPCODE_SNE:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SNE;
- break;
+ return TGSI_OPCODE_SNE;
case OPCODE_SSG:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SSG;
- break;
+ return TGSI_OPCODE_SSG;
case OPCODE_SUB:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SUB;
- break;
+ return TGSI_OPCODE_SUB;
case OPCODE_SWZ:
- fullinst->Instruction.Opcode = TGSI_OPCODE_SWZ;
- break;
+ return TGSI_OPCODE_SWZ;
case OPCODE_TEX:
- /* ordinary texture lookup */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TEX;
- fullinst->Instruction.NumSrcRegs = 2;
- fullinst->InstructionExtTexture.Texture =
- map_texture_target( inst->TexSrcTarget, inst->TexShadow );
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
- break;
+ return TGSI_OPCODE_TEX;
case OPCODE_TXB:
- /* texture lookup with LOD bias */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXB;
- fullinst->Instruction.NumSrcRegs = 2;
- fullinst->InstructionExtTexture.Texture =
- map_texture_target( inst->TexSrcTarget, inst->TexShadow );
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
- break;
+ return TGSI_OPCODE_TXB;
case OPCODE_TXD:
- /* texture lookup with explicit partial derivatives */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXD;
- fullinst->Instruction.NumSrcRegs = 4;
- fullinst->InstructionExtTexture.Texture =
- map_texture_target( inst->TexSrcTarget, inst->TexShadow );
- /* src[0] = coord, src[1] = d[strq]/dx, src[2] = d[strq]/dy */
- fullinst->FullSrcRegisters[3].SrcRegister.File = TGSI_FILE_SAMPLER;
- fullinst->FullSrcRegisters[3].SrcRegister.Index = inst->TexSrcUnit;
- break;
+ return TGSI_OPCODE_TXD;
case OPCODE_TXL:
- /* texture lookup with explicit LOD */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXL;
- fullinst->Instruction.NumSrcRegs = 2;
- fullinst->InstructionExtTexture.Texture =
- map_texture_target( inst->TexSrcTarget, inst->TexShadow );
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
- break;
+ return TGSI_OPCODE_TXL;
case OPCODE_TXP:
- /* texture lookup with divide by Q component */
- /* convert to TEX w/ special flag for division */
- fullinst->Instruction.Opcode = TGSI_OPCODE_TXP;
- fullinst->Instruction.NumSrcRegs = 2;
- fullinst->InstructionExtTexture.Texture =
- map_texture_target( inst->TexSrcTarget, inst->TexShadow );
- fullinst->FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- fullinst->FullSrcRegisters[1].SrcRegister.Index = inst->TexSrcUnit;
- break;
+ return TGSI_OPCODE_TXP;
case OPCODE_XPD:
- fullinst->Instruction.Opcode = TGSI_OPCODE_XPD;
- fulldst->DstRegister.WriteMask &= TGSI_WRITEMASK_XYZ;
- break;
+ return TGSI_OPCODE_XPD;
case OPCODE_END:
- fullinst->Instruction.Opcode = TGSI_OPCODE_END;
- break;
+ return TGSI_OPCODE_END;
default:
assert( 0 );
+ return TGSI_OPCODE_NOP;
}
}
-/**
- * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
- */
-static struct tgsi_full_declaration
-make_input_decl(
- GLuint index,
- GLboolean interpolate_info,
- GLuint interpolate,
- GLuint usage_mask,
- GLboolean semantic_info,
- GLuint semantic_name,
- GLbitfield semantic_index,
- GLbitfield input_flags)
-{
- struct tgsi_full_declaration decl;
-
- assert(semantic_name < TGSI_SEMANTIC_COUNT);
-
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
- decl.Declaration.UsageMask = usage_mask;
- decl.Declaration.Semantic = semantic_info;
- decl.DeclarationRange.First = index;
- decl.DeclarationRange.Last = index;
- if (semantic_info) {
- decl.Semantic.SemanticName = semantic_name;
- decl.Semantic.SemanticIndex = semantic_index;
- }
- if (interpolate_info) {
- decl.Declaration.Interpolate = interpolate;
- }
- if (input_flags & PROG_PARAM_BIT_CENTROID)
- decl.Declaration.Centroid = 1;
- if (input_flags & PROG_PARAM_BIT_INVARIANT)
- decl.Declaration.Invariant = 1;
-
- return decl;
-}
-/**
- * \param usage_mask bitfield of TGSI_WRITEMASK_{XYZW} tokens
- */
-static struct tgsi_full_declaration
-make_output_decl(
- GLuint index,
- GLuint semantic_name,
- GLuint semantic_index,
- GLuint usage_mask,
- GLbitfield output_flags)
+static void
+compile_instruction(
+ struct st_translate *t,
+ const struct prog_instruction *inst )
{
- struct tgsi_full_declaration decl;
-
- assert(semantic_name < TGSI_SEMANTIC_COUNT);
-
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.UsageMask = usage_mask;
- decl.Declaration.Semantic = 1;
- decl.DeclarationRange.First = index;
- decl.DeclarationRange.Last = index;
- decl.Semantic.SemanticName = semantic_name;
- decl.Semantic.SemanticIndex = semantic_index;
- if (output_flags & PROG_PARAM_BIT_CENTROID)
- decl.Declaration.Centroid = 1;
- if (output_flags & PROG_PARAM_BIT_INVARIANT)
- decl.Declaration.Invariant = 1;
-
- return decl;
-}
-
+ struct ureg_program *ureg = t->ureg;
+ GLuint i;
+ struct ureg_dst dst[1];
+ struct ureg_src src[4];
+ unsigned num_dst;
+ unsigned num_src;
-static struct tgsi_full_declaration
-make_temp_decl(
- GLuint start_index,
- GLuint end_index )
-{
- struct tgsi_full_declaration decl;
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_TEMPORARY;
- decl.DeclarationRange.First = start_index;
- decl.DeclarationRange.Last = end_index;
- return decl;
-}
+ num_dst = _mesa_num_inst_dst_regs( inst->Opcode );
+ num_src = _mesa_num_inst_src_regs( inst->Opcode );
-static struct tgsi_full_declaration
-make_addr_decl(
- GLuint start_index,
- GLuint end_index )
-{
- struct tgsi_full_declaration decl;
+ if (num_dst)
+ dst[0] = translate_dst( t,
+ &inst->DstReg,
+ inst->SaturateMode );
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_ADDRESS;
- decl.DeclarationRange.First = start_index;
- decl.DeclarationRange.Last = end_index;
- return decl;
-}
+ for (i = 0; i < num_src; i++)
+ src[i] = translate_src( t, &inst->SrcReg[i] );
-static struct tgsi_full_declaration
-make_sampler_decl(GLuint index)
-{
- struct tgsi_full_declaration decl;
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.DeclarationRange.First = index;
- decl.DeclarationRange.Last = index;
- return decl;
-}
-
-/** Reference into a constant buffer */
-static struct tgsi_full_declaration
-make_constant_decl(GLuint first, GLuint last)
-{
- struct tgsi_full_declaration decl;
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_CONSTANT;
- decl.DeclarationRange.First = first;
- decl.DeclarationRange.Last = last;
- return decl;
-}
+ switch( inst->Opcode ) {
+ case OPCODE_SWZ:
+ emit_swz( t, dst[0], &inst->SrcReg[0] );
+ return;
+ case OPCODE_BGNLOOP:
+ case OPCODE_CAL:
+ case OPCODE_ELSE:
+ case OPCODE_ENDLOOP:
+ case OPCODE_IF:
+ assert(num_dst == 0);
+ ureg_label_insn( ureg,
+ translate_opcode( inst->Opcode ),
+ src, num_src,
+ get_label( t, inst->BranchTarget ));
+ return;
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ case OPCODE_TXD:
+ case OPCODE_TXL:
+ case OPCODE_TXP:
+ src[num_src++] = t->samplers[inst->TexSrcUnit];
+ ureg_tex_insn( ureg,
+ translate_opcode( inst->Opcode ),
+ dst, num_dst,
+ translate_texture_target( inst->TexSrcTarget,
+ inst->TexShadow ),
+ src, num_src );
+ return;
-/**
- * Find the temporaries which are used in the given program.
- */
-static void
-find_temporaries(const struct gl_program *program,
- GLboolean tempsUsed[MAX_PROGRAM_TEMPS])
-{
- GLuint i, j;
+ case OPCODE_SCS:
+ dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XY );
+ ureg_insn( ureg,
+ translate_opcode( inst->Opcode ),
+ dst, num_dst,
+ src, num_src );
+ break;
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++)
- tempsUsed[i] = GL_FALSE;
+ case OPCODE_XPD:
+ dst[0] = ureg_writemask(dst[0], TGSI_WRITEMASK_XYZ );
+ ureg_insn( ureg,
+ translate_opcode( inst->Opcode ),
+ dst, num_dst,
+ src, num_src );
+ break;
- for (i = 0; i < program->NumInstructions; i++) {
- const struct prog_instruction *inst = program->Instructions + i;
- const GLuint n = _mesa_num_inst_src_regs( inst->Opcode );
- for (j = 0; j < n; j++) {
- if (inst->SrcReg[j].File == PROGRAM_TEMPORARY)
- tempsUsed[inst->SrcReg[j].Index] = GL_TRUE;
- if (inst->DstReg.File == PROGRAM_TEMPORARY)
- tempsUsed[inst->DstReg.Index] = GL_TRUE;
- }
+ default:
+ ureg_insn( ureg,
+ translate_opcode( inst->Opcode ),
+ dst, num_dst,
+ src, num_src );
+ break;
}
}
/**
- * Find an unused temporary in the tempsUsed array.
+ * Emit the TGSI instructions for inverting the WPOS y coordinate.
*/
-static int
-find_free_temporary(GLboolean tempsUsed[MAX_PROGRAM_TEMPS])
-{
- int i;
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
- if (!tempsUsed[i]) {
- tempsUsed[i] = GL_TRUE;
- return i;
- }
- }
- return -1;
-}
-
-
-/** helper for building simple TGSI instruction, one src register */
-static void
-build_tgsi_instruction1(struct tgsi_full_instruction *inst,
- int opcode,
- int dstFile, int dstIndex, int writemask,
- int srcFile1, int srcIndex1)
-{
- *inst = tgsi_default_full_instruction();
-
- inst->Instruction.Opcode = opcode;
-
- inst->Instruction.NumDstRegs = 1;
- inst->FullDstRegisters[0].DstRegister.File = dstFile;
- inst->FullDstRegisters[0].DstRegister.Index = dstIndex;
- inst->FullDstRegisters[0].DstRegister.WriteMask = writemask;
-
- inst->Instruction.NumSrcRegs = 1;
- inst->FullSrcRegisters[0].SrcRegister.File = srcFile1;
- inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1;
-}
-
-
-/** helper for building simple TGSI instruction, two src registers */
static void
-build_tgsi_instruction2(struct tgsi_full_instruction *inst,
- int opcode,
- int dstFile, int dstIndex, int writemask,
- int srcFile1, int srcIndex1,
- int srcFile2, int srcIndex2)
+emit_inverted_wpos( struct st_translate *t,
+ const struct gl_program *program )
{
- *inst = tgsi_default_full_instruction();
-
- inst->Instruction.Opcode = opcode;
+ struct ureg_program *ureg = t->ureg;
- inst->Instruction.NumDstRegs = 1;
- inst->FullDstRegisters[0].DstRegister.File = dstFile;
- inst->FullDstRegisters[0].DstRegister.Index = dstIndex;
- inst->FullDstRegisters[0].DstRegister.WriteMask = writemask;
+ /* Fragment program uses fragment position input.
+ * Need to replace instances of INPUT[WPOS] with temp T
+ * where T = INPUT[WPOS] by y is inverted.
+ */
+ static const gl_state_index winSizeState[STATE_LENGTH]
+ = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 };
+
+ /* XXX: note we are modifying the incoming shader here! Need to
+ * do this before emitting the constant decls below, or this
+ * will be missed:
+ */
+ unsigned winHeightConst = _mesa_add_state_reference(program->Parameters,
+ winSizeState);
- inst->Instruction.NumSrcRegs = 2;
- inst->FullSrcRegisters[0].SrcRegister.File = srcFile1;
- inst->FullSrcRegisters[0].SrcRegister.Index = srcIndex1;
- inst->FullSrcRegisters[1].SrcRegister.File = srcFile2;
- inst->FullSrcRegisters[1].SrcRegister.Index = srcIndex2;
-}
+ struct ureg_src winsize = ureg_DECL_constant( ureg, winHeightConst );
+ struct ureg_dst wpos_temp = ureg_DECL_temporary( ureg );
+ struct ureg_src wpos_input = t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]];
+ /* MOV wpos_temp, input[wpos]
+ */
+ ureg_MOV( ureg, wpos_temp, wpos_input );
+ /* SUB wpos_temp.y, winsize_const, wpos_input
+ */
+ ureg_SUB( ureg,
+ ureg_writemask(wpos_temp, TGSI_WRITEMASK_Y ),
+ winsize,
+ wpos_input);
-/**
- * Emit the TGSI instructions for inverting the WPOS y coordinate.
- */
-static int
-emit_inverted_wpos(struct tgsi_token *tokens,
- int wpos_temp,
- int winsize_const,
- int wpos_input,
- struct tgsi_header *header, int maxTokens)
-{
- struct tgsi_full_instruction fullinst;
- int ti = 0;
-
- /* MOV wpos_temp.xzw, input[wpos]; */
- build_tgsi_instruction1(&fullinst,
- TGSI_OPCODE_MOV,
- TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_XZW,
- TGSI_FILE_INPUT, 0);
-
- ti += tgsi_build_full_instruction(&fullinst,
- &tokens[ti],
- header,
- maxTokens - ti);
-
- /* SUB wpos_temp.y, const[winsize_const] - input[wpos_input]; */
- build_tgsi_instruction2(&fullinst,
- TGSI_OPCODE_SUB,
- TGSI_FILE_TEMPORARY, wpos_temp, WRITEMASK_Y,
- TGSI_FILE_CONSTANT, winsize_const,
- TGSI_FILE_INPUT, wpos_input);
-
- ti += tgsi_build_full_instruction(&fullinst,
- &tokens[ti],
- header,
- maxTokens - ti);
-
- return ti;
+ /* Use wpos_temp as position input from here on:
+ */
+ t->inputs[t->inputMapping[FRAG_ATTRIB_WPOS]] = ureg_src(wpos_temp);
}
-
-
/**
* Translate Mesa program to TGSI format.
* \param program the program to translate
@@ -864,20 +676,19 @@ emit_inverted_wpos(struct tgsi_token *tokens,
* \param inputMapping maps Mesa fragment program inputs to TGSI generic
* input indexes
* \param inputSemanticName the TGSI_SEMANTIC flag for each input
- * \param inputSemanticIndex the semantic index (ex: which texcoord) for each input
+ * \param inputSemanticIndex the semantic index (ex: which texcoord) for
+ * each input
* \param interpMode the TGSI_INTERPOLATE_LINEAR/PERSP mode for each input
-
* \param numOutputs number of output registers used
* \param outputMapping maps Mesa fragment program outputs to TGSI
* generic outputs
* \param outputSemanticName the TGSI_SEMANTIC flag for each output
- * \param outputSemanticIndex the semantic index (ex: which texcoord) for each output
- * \param tokens array to store translated tokens in
- * \param maxTokens size of the tokens array
+ * \param outputSemanticIndex the semantic index (ex: which texcoord) for
+ * each output
*
- * \return number of tokens placed in 'tokens' buffer, or zero if error
+ * \return array of translated tokens, caller's responsibility to free
*/
-GLuint
+const struct tgsi_token *
st_translate_mesa_program(
GLcontext *ctx,
uint procType,
@@ -892,252 +703,124 @@ st_translate_mesa_program(
const GLuint outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[],
- const GLbitfield outputFlags[],
- struct tgsi_token *tokens,
- GLuint maxTokens )
+ const GLbitfield outputFlags[] )
{
- GLuint i;
- GLuint ti; /* token index */
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- GLuint preamble_size = 0;
- GLuint immediates[1000];
- GLuint numImmediates = 0;
- GLboolean insideSubroutine = GL_FALSE;
- GLboolean indirectAccess = GL_FALSE;
- GLboolean tempsUsed[MAX_PROGRAM_TEMPS + 1];
- GLint wposTemp = -1, winHeightConst = -1;
-
- assert(procType == TGSI_PROCESSOR_FRAGMENT ||
- procType == TGSI_PROCESSOR_VERTEX);
-
- find_temporaries(program, tempsUsed);
-
- if (procType == TGSI_PROCESSOR_FRAGMENT) {
- if (program->InputsRead & FRAG_BIT_WPOS) {
- /* Fragment program uses fragment position input.
- * Need to replace instances of INPUT[WPOS] with temp T
- * where T = INPUT[WPOS] by y is inverted.
- */
- static const gl_state_index winSizeState[STATE_LENGTH]
- = { STATE_INTERNAL, STATE_FB_SIZE, 0, 0, 0 };
- winHeightConst = _mesa_add_state_reference(program->Parameters,
- winSizeState);
- wposTemp = find_free_temporary(tempsUsed);
- }
- }
-
+ struct st_translate translate, *t;
+ struct ureg_program *ureg;
+ const struct tgsi_token *tokens = NULL;
+ unsigned i;
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
+ t = &translate;
+ memset(t, 0, sizeof *t);
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
+ t->procType = procType;
+ t->inputMapping = inputMapping;
+ t->outputMapping = outputMapping;
+ t->ureg = ureg_create( procType );
+ if (t->ureg == NULL)
+ return NULL;
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
+ ureg = t->ureg;
- ti = 3;
+ /*_mesa_print_program(program);*/
/*
* Declare input attributes.
*/
if (procType == TGSI_PROCESSOR_FRAGMENT) {
for (i = 0; i < numInputs; i++) {
- struct tgsi_full_declaration fulldecl;
- fulldecl = make_input_decl(i,
- GL_TRUE, interpMode[i],
- TGSI_WRITEMASK_XYZW,
- GL_TRUE, inputSemanticName[i],
- inputSemanticIndex[i],
- inputFlags[i]);
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+ t->inputs[i] = ureg_DECL_fs_input(ureg,
+ inputSemanticName[i],
+ inputSemanticIndex[i],
+ interpMode[i]);
}
- }
- else {
- /* vertex prog */
- /* XXX: this could probaby be merged with the clause above.
- * the only difference is the semantic tags.
- */
- for (i = 0; i < numInputs; i++) {
- struct tgsi_full_declaration fulldecl;
- fulldecl = make_input_decl(i,
- GL_FALSE, 0,
- TGSI_WRITEMASK_XYZW,
- GL_FALSE, 0, 0,
- inputFlags[i]);
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+
+ if (program->InputsRead & FRAG_BIT_WPOS) {
+ /* Must do this after setting up t->inputs, and before
+ * emitting constant references, below:
+ */
+ emit_inverted_wpos( t, program );
}
- }
- /*
- * Declare output attributes.
- */
- if (procType == TGSI_PROCESSOR_FRAGMENT) {
+ /*
+ * Declare output attributes.
+ */
for (i = 0; i < numOutputs; i++) {
- struct tgsi_full_declaration fulldecl;
switch (outputSemanticName[i]) {
case TGSI_SEMANTIC_POSITION:
- fulldecl = make_output_decl(i,
- TGSI_SEMANTIC_POSITION, /* Z / Depth */
- outputSemanticIndex[i],
- TGSI_WRITEMASK_Z,
- outputFlags[i]);
+ t->outputs[i] = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_POSITION, /* Z / Depth */
+ outputSemanticIndex[i] );
+
+ t->outputs[i] = ureg_writemask( t->outputs[i],
+ TGSI_WRITEMASK_Z );
break;
case TGSI_SEMANTIC_COLOR:
- fulldecl = make_output_decl(i,
- TGSI_SEMANTIC_COLOR,
- outputSemanticIndex[i],
- TGSI_WRITEMASK_XYZW,
- outputFlags[i]);
+ t->outputs[i] = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ outputSemanticIndex[i] );
break;
default:
assert(0);
return 0;
}
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
}
}
else {
- /* vertex prog */
- for (i = 0; i < numOutputs; i++) {
- struct tgsi_full_declaration fulldecl;
- fulldecl = make_output_decl(i,
- outputSemanticName[i],
- outputSemanticIndex[i],
- TGSI_WRITEMASK_XYZW,
- outputFlags[i]);
- ti += tgsi_build_full_declaration(&fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+ for (i = 0; i < numInputs; i++) {
+ t->inputs[i] = ureg_DECL_vs_input(ureg, i);
}
- }
- /* temporary decls */
- {
- GLboolean inside_range = GL_FALSE;
- GLuint start_range = 0;
-
- tempsUsed[MAX_PROGRAM_TEMPS] = GL_FALSE;
- for (i = 0; i < MAX_PROGRAM_TEMPS + 1; i++) {
- if (tempsUsed[i] && !inside_range) {
- inside_range = GL_TRUE;
- start_range = i;
- }
- else if (!tempsUsed[i] && inside_range) {
- struct tgsi_full_declaration fulldecl;
-
- inside_range = GL_FALSE;
- fulldecl = make_temp_decl( start_range, i - 1 );
- ti += tgsi_build_full_declaration(
- &fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
- }
+ for (i = 0; i < numOutputs; i++) {
+ t->outputs[i] = ureg_DECL_output( ureg,
+ outputSemanticName[i],
+ outputSemanticIndex[i] );
}
}
/* Declare address register.
- */
+ */
if (program->NumAddressRegs > 0) {
- struct tgsi_full_declaration fulldecl;
-
assert( program->NumAddressRegs == 1 );
-
- fulldecl = make_addr_decl( 0, 0 );
- ti += tgsi_build_full_declaration(
- &fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
-
- indirectAccess = GL_TRUE;
+ t->address[0] = ureg_DECL_address( ureg );
}
- /* immediates/literals */
- memset(immediates, ~0, sizeof(immediates));
- /* Emit immediates only when there is no address register in use.
- * FIXME: Be smarter and recognize param arrays -- indirect addressing is
- * only valid within the referenced array.
+ /* Emit constants and immediates. Mesa uses a single index space
+ * for these, so we put all the translated regs in t->constants.
*/
- if (program->Parameters && !indirectAccess) {
- for (i = 0; i < program->Parameters->NumParameters; i++) {
- if (program->Parameters->Parameters[i].Type == PROGRAM_CONSTANT) {
- struct tgsi_full_immediate fullimm;
-
- fullimm = make_immediate( program->Parameters->ParameterValues[i], 4 );
- ti += tgsi_build_full_immediate(
- &fullimm,
- &tokens[ti],
- header,
- maxTokens - ti );
- immediates[i] = numImmediates;
- numImmediates++;
- }
- }
- }
-
- /* constant buffer refs */
if (program->Parameters) {
- GLint start = -1, end = -1;
-
+
+ t->constants = CALLOC( program->Parameters->NumParameters,
+ sizeof t->constants[0] );
+ if (t->constants == NULL)
+ goto out;
+
for (i = 0; i < program->Parameters->NumParameters; i++) {
- GLboolean emit = (i == program->Parameters->NumParameters - 1);
- GLboolean matches;
-
switch (program->Parameters->Parameters[i].Type) {
case PROGRAM_ENV_PARAM:
case PROGRAM_STATE_VAR:
case PROGRAM_NAMED_PARAM:
case PROGRAM_UNIFORM:
- matches = GL_TRUE;
+ t->constants[i] = ureg_DECL_constant( ureg, i );
break;
+
+ /* Emit immediates only when there is no address register
+ * in use. FIXME: Be smarter and recognize param arrays:
+ * indirect addressing is only valid within the referenced
+ * array.
+ */
case PROGRAM_CONSTANT:
- matches = indirectAccess;
+ if (program->NumAddressRegs > 0)
+ t->constants[i] = ureg_DECL_constant( ureg, i );
+ else
+ t->constants[i] =
+ ureg_DECL_immediate( ureg,
+ program->Parameters->ParameterValues[i],
+ 4 );
break;
default:
- matches = GL_FALSE;
- }
-
- if (matches) {
- if (start == -1) {
- /* begin a sequence */
- start = i;
- end = i;
- }
- else {
- /* continue sequence */
- end = i;
- }
- }
- else {
- if (start != -1) {
- /* end of sequence */
- emit = GL_TRUE;
- }
- }
-
- if (emit && start >= 0) {
- struct tgsi_full_declaration fulldecl;
-
- fulldecl = make_constant_decl( start, end );
- ti += tgsi_build_full_declaration(
- &fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
- start = end = -1;
+ break;
}
}
}
@@ -1145,58 +828,55 @@ st_translate_mesa_program(
/* texture samplers */
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (program->SamplersUsed & (1 << i)) {
- struct tgsi_full_declaration fulldecl;
-
- fulldecl = make_sampler_decl( i );
- ti += tgsi_build_full_declaration(
- &fulldecl,
- &tokens[ti],
- header,
- maxTokens - ti );
+ t->samplers[i] = ureg_DECL_sampler( ureg, i );
}
}
- /* invert WPOS fragment input */
- if (wposTemp >= 0) {
- ti += emit_inverted_wpos(&tokens[ti], wposTemp, winHeightConst,
- inputMapping[FRAG_ATTRIB_WPOS],
- header, maxTokens - ti);
- preamble_size = 2; /* two instructions added */
+ /* Emit each instruction in turn:
+ */
+ for (i = 0; i < program->NumInstructions; i++) {
+ set_insn_start( t, ureg_get_instruction_number( ureg ));
+ compile_instruction( t, &program->Instructions[i] );
}
- for (i = 0; i < program->NumInstructions; i++) {
- struct tgsi_full_instruction fullinst;
-
- compile_instruction(
- &program->Instructions[i],
- &fullinst,
- inputMapping,
- outputMapping,
- immediates,
- indirectAccess,
- preamble_size,
- procType,
- &insideSubroutine,
- wposTemp);
-
- ti += tgsi_build_full_instruction(
- &fullinst,
- &tokens[ti],
- header,
- maxTokens - ti );
+ /* Fix up all emitted labels:
+ */
+ for (i = 0; i < t->labels_count; i++) {
+ ureg_fixup_label( ureg,
+ t->labels[i].token,
+ t->insn[t->labels[i].branch_target] );
}
-#if DEBUG
- if(!tgsi_sanity_check(tokens)) {
- debug_printf("Due to sanity check failure(s) above the following shader program is invalid:\n");
- debug_printf("\nOriginal program:\n%s", program->String);
- debug_printf("\nMesa program:\n");
+ tokens = ureg_get_tokens( ureg, NULL );
+ ureg_destroy( ureg );
+
+out:
+ FREE(t->insn);
+ FREE(t->labels);
+ FREE(t->constants);
+
+ if (t->error) {
+ debug_printf("%s: translate error flag set\n", __FUNCTION__);
+ FREE((void *)tokens);
+ tokens = NULL;
+ }
+
+ if (!tokens) {
+ debug_printf("%s: failed to translate Mesa program:\n", __FUNCTION__);
_mesa_print_program(program);
- debug_printf("\nTGSI program:\n");
- tgsi_dump(tokens, 0);
assert(0);
}
-#endif
- return ti;
+ return tokens;
+}
+
+
+/**
+ * Tokens cannot be free with _mesa_free otherwise the builtin gallium
+ * malloc debugging will get confused.
+ */
+void
+st_free_tokens(const struct tgsi_token *tokens)
+{
+ FREE((void *)tokens);
}
diff --git a/src/mesa/state_tracker/st_mesa_to_tgsi.h b/src/mesa/state_tracker/st_mesa_to_tgsi.h
index b465b3bddcf..c0d1ff59e1f 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.h
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.h
@@ -39,7 +39,7 @@ extern "C" {
struct tgsi_token;
struct gl_program;
-GLuint
+const struct tgsi_token *
st_translate_mesa_program(
GLcontext *ctx,
uint procType,
@@ -54,9 +54,10 @@ st_translate_mesa_program(
const GLuint outputMapping[],
const ubyte outputSemanticName[],
const ubyte outputSemanticIndex[],
- const GLbitfield outputFlags[],
- struct tgsi_token *tokens,
- GLuint maxTokens );
+ const GLbitfield outputFlags[] );
+
+void
+st_free_tokens(const struct tgsi_token *tokens);
#if defined __cplusplus
diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c
index d2da20ae424..927f60cc7e9 100644
--- a/src/mesa/state_tracker/st_program.c
+++ b/src/mesa/state_tracker/st_program.c
@@ -49,9 +49,6 @@
#include "cso_cache/cso_context.h"
-#define ST_MAX_SHADER_TOKENS (8 * 1024)
-
-
#define TGSI_DEBUG 0
@@ -70,12 +67,9 @@ st_translate_vertex_program(struct st_context *st,
const ubyte *outputSemanticIndex)
{
struct pipe_context *pipe = st->pipe;
- struct tgsi_token *tokens;
GLuint defaultOutputMapping[VERT_RESULT_MAX];
- struct pipe_shader_state vs;
GLuint attr, i;
GLuint num_generic = 0;
- GLuint num_tokens;
ubyte vs_input_semantic_name[PIPE_MAX_SHADER_INPUTS];
ubyte vs_input_semantic_index[PIPE_MAX_SHADER_INPUTS];
@@ -88,14 +82,7 @@ st_translate_vertex_program(struct st_context *st,
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
- tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
- if(!tokens) {
- /* FIXME: propagate error to the caller */
- assert(0);
- return;
- }
-
- memset(&vs, 0, sizeof(vs));
+// memset(&vs, 0, sizeof(vs));
memset(input_flags, 0, sizeof(input_flags));
memset(output_flags, 0, sizeof(output_flags));
@@ -330,7 +317,7 @@ st_translate_vertex_program(struct st_context *st,
/* free old shader state, if any */
if (stvp->state.tokens) {
- _mesa_free((void *) stvp->state.tokens);
+ st_free_tokens(stvp->state.tokens);
stvp->state.tokens = NULL;
}
if (stvp->driver_shader) {
@@ -338,43 +325,32 @@ st_translate_vertex_program(struct st_context *st,
stvp->driver_shader = NULL;
}
- /* XXX: fix static allocation of tokens:
- */
- num_tokens = st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_VERTEX,
- &stvp->Base.Base,
- /* inputs */
- vs_num_inputs,
- stvp->input_to_index,
- vs_input_semantic_name,
- vs_input_semantic_index,
- NULL,
- input_flags,
- /* outputs */
- vs_num_outputs,
- outputMapping,
- vs_output_semantic_name,
- vs_output_semantic_index,
- output_flags,
- /* tokenized result */
- tokens, ST_MAX_SHADER_TOKENS);
-
- assert(num_tokens < ST_MAX_SHADER_TOKENS);
-
- vs.tokens = (struct tgsi_token *)
- _mesa_realloc(tokens,
- ST_MAX_SHADER_TOKENS * sizeof *tokens,
- num_tokens * sizeof *tokens);
+ stvp->state.tokens =
+ st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_VERTEX,
+ &stvp->Base.Base,
+ /* inputs */
+ vs_num_inputs,
+ stvp->input_to_index,
+ vs_input_semantic_name,
+ vs_input_semantic_index,
+ NULL,
+ input_flags,
+ /* outputs */
+ vs_num_outputs,
+ outputMapping,
+ vs_output_semantic_name,
+ vs_output_semantic_index,
+ output_flags );
stvp->num_inputs = vs_num_inputs;
- stvp->state = vs; /* struct copy */
- stvp->driver_shader = pipe->create_vs_state(pipe, &vs);
+ stvp->driver_shader = pipe->create_vs_state(pipe, &stvp->state);
if (0)
_mesa_print_program(&stvp->Base.Base);
if (TGSI_DEBUG)
- tgsi_dump( vs.tokens, 0 );
+ tgsi_dump( stvp->state.tokens, 0 );
}
@@ -383,7 +359,6 @@ st_translate_vertex_program(struct st_context *st,
* Translate a Mesa fragment shader into a TGSI shader.
* \param inputMapping to map fragment program input registers to TGSI
* input slots
- * \param tokensOut destination for TGSI tokens
* \return pointer to cached pipe_shader object.
*/
void
@@ -392,16 +367,13 @@ st_translate_fragment_program(struct st_context *st,
const GLuint inputMapping[])
{
struct pipe_context *pipe = st->pipe;
- struct tgsi_token *tokens;
GLuint outputMapping[FRAG_RESULT_MAX];
GLuint defaultInputMapping[FRAG_ATTRIB_MAX];
- struct pipe_shader_state fs;
GLuint interpMode[16]; /* XXX size? */
GLuint attr;
const GLbitfield inputsRead = stfp->Base.Base.InputsRead;
GLuint vslot = 0;
GLuint num_generic = 0;
- GLuint num_tokens;
uint fs_num_inputs = 0;
@@ -412,14 +384,7 @@ st_translate_fragment_program(struct st_context *st,
GLbitfield input_flags[MAX_PROGRAM_INPUTS];
GLbitfield output_flags[MAX_PROGRAM_OUTPUTS];
- tokens = (struct tgsi_token *)MALLOC(ST_MAX_SHADER_TOKENS * sizeof *tokens);
- if(!tokens) {
- /* FIXME: propagate error to the caller */
- assert(0);
- return;
- }
-
- memset(&fs, 0, sizeof(fs));
+// memset(&fs, 0, sizeof(fs));
memset(input_flags, 0, sizeof(input_flags));
memset(output_flags, 0, sizeof(output_flags));
@@ -541,42 +506,31 @@ st_translate_fragment_program(struct st_context *st,
if (!inputMapping)
inputMapping = defaultInputMapping;
- /* XXX: fix static allocation of tokens:
- */
- num_tokens = st_translate_mesa_program(st->ctx,
- TGSI_PROCESSOR_FRAGMENT,
- &stfp->Base.Base,
- /* inputs */
- fs_num_inputs,
- inputMapping,
- stfp->input_semantic_name,
- stfp->input_semantic_index,
- interpMode,
- input_flags,
- /* outputs */
- fs_num_outputs,
- outputMapping,
- fs_output_semantic_name,
- fs_output_semantic_index,
- output_flags,
- /* tokenized result */
- tokens, ST_MAX_SHADER_TOKENS);
-
- assert(num_tokens < ST_MAX_SHADER_TOKENS);
-
- fs.tokens = (struct tgsi_token *)
- _mesa_realloc(tokens,
- ST_MAX_SHADER_TOKENS * sizeof *tokens,
- num_tokens * sizeof *tokens);
-
- stfp->state = fs; /* struct copy */
- stfp->driver_shader = pipe->create_fs_state(pipe, &fs);
+ stfp->state.tokens =
+ st_translate_mesa_program(st->ctx,
+ TGSI_PROCESSOR_FRAGMENT,
+ &stfp->Base.Base,
+ /* inputs */
+ fs_num_inputs,
+ inputMapping,
+ stfp->input_semantic_name,
+ stfp->input_semantic_index,
+ interpMode,
+ input_flags,
+ /* outputs */
+ fs_num_outputs,
+ outputMapping,
+ fs_output_semantic_name,
+ fs_output_semantic_index,
+ output_flags );
+
+ stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state);
if (0)
_mesa_print_program(&stfp->Base.Base);
if (TGSI_DEBUG)
- tgsi_dump( fs.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
+ tgsi_dump( stfp->state.tokens, 0/*TGSI_DUMP_VERBOSE*/ );
}
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index 613a91b0ecd..77a77f0bcbb 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -89,6 +89,8 @@ fetch_texel_lod( GLcontext *ctx, const GLfloat texcoord[4], GLfloat lambda,
* Fetch a texel with the given partial derivatives to compute a level
* of detail in the mipmap.
* Called via machine->FetchTexelDeriv()
+ * \param lodBias the lod bias which may be specified by a TXB instruction,
+ * otherwise zero.
*/
static void
fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
@@ -96,7 +98,8 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
GLfloat lodBias, GLuint unit, GLfloat color[4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
- const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+ const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ const struct gl_texture_object *texObj = texUnit->_Current;
if (texObj) {
const struct gl_texture_image *texImg =
@@ -108,10 +111,12 @@ fetch_texel_deriv( GLcontext *ctx, const GLfloat texcoord[4],
lambda = _swrast_compute_lambda(texdx[0], texdy[0], /* ds/dx, ds/dy */
texdx[1], texdy[1], /* dt/dx, dt/dy */
- texdx[3], texdy[2], /* dq/dx, dq/dy */
+ texdx[3], texdy[3], /* dq/dx, dq/dy */
texW, texH,
texcoord[0], texcoord[1], texcoord[3],
- 1.0F / texcoord[3]) + lodBias;
+ 1.0F / texcoord[3]);
+
+ lambda += lodBias + texUnit->LodBias + texObj->LodBias;
lambda = CLAMP(lambda, texObj->MinLod, texObj->MaxLod);
diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c
deleted file mode 100644
index 3578b713f61..00000000000
--- a/src/mesa/swrast/s_imaging.c
+++ /dev/null
@@ -1,196 +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.
- */
-
-/* KW: Moved these here to remove knowledge of swrast from core mesa.
- * Should probably pull the entire software implementation of these
- * extensions into either swrast or a sister module.
- */
-
-#include "main/glheader.h"
-#include "main/colortab.h"
-#include "main/convolve.h"
-#include "s_context.h"
-#include "s_span.h"
-
-
-void
-_swrast_CopyColorTable( GLcontext *ctx,
- GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width)
-{
- GLchan data[MAX_WIDTH][4];
- struct gl_buffer_object *bufferSave;
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- /* no readbuffer - OK */
- return;
- }
-
- if (width > MAX_WIDTH)
- width = MAX_WIDTH;
-
- swrast_render_start(ctx);
-
- /* read the data from framebuffer */
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, x, y, CHAN_TYPE, data );
-
- swrast_render_finish(ctx);
-
- /* save PBO binding */
- bufferSave = ctx->Unpack.BufferObj;
- ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj;
-
- _mesa_ColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
-
- /* restore PBO binding */
- ctx->Unpack.BufferObj = bufferSave;
-}
-
-
-void
-_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width)
-{
- GLchan data[MAX_WIDTH][4];
- struct gl_buffer_object *bufferSave;
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- /* no readbuffer - OK */
- return;
- }
-
- if (width > MAX_WIDTH)
- width = MAX_WIDTH;
-
- swrast_render_start(ctx);
-
- /* read the data from framebuffer */
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, x, y, CHAN_TYPE, data );
-
- swrast_render_finish(ctx);
-
- /* save PBO binding */
- bufferSave = ctx->Unpack.BufferObj;
- ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj;
-
- _mesa_ColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
-
- /* restore PBO binding */
- ctx->Unpack.BufferObj = bufferSave;
-}
-
-
-void
-_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width)
-{
- GLchan rgba[MAX_CONVOLUTION_WIDTH][4];
- struct gl_buffer_object *bufferSave;
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- /* no readbuffer - OK */
- return;
- }
-
- swrast_render_start(ctx);
-
- /* read the data from framebuffer */
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, x, y, CHAN_TYPE, rgba );
-
- swrast_render_finish(ctx);
-
- /* save PBO binding */
- bufferSave = ctx->Unpack.BufferObj;
- ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj;
-
- /* store as convolution filter */
- _mesa_ConvolutionFilter1D(target, internalFormat, width,
- GL_RGBA, CHAN_TYPE, rgba);
-
- /* restore PBO binding */
- ctx->Unpack.BufferObj = bufferSave;
-}
-
-
-void
-_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height)
-{
- struct gl_pixelstore_attrib packSave;
- GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
- GLint i;
- struct gl_buffer_object *bufferSave;
-
- if (!ctx->ReadBuffer->_ColorReadBuffer) {
- /* no readbuffer - OK */
- return;
- }
-
- swrast_render_start(ctx);
-
- /* read pixels from framebuffer */
- for (i = 0; i < height; i++) {
- _swrast_read_rgba_span( ctx, ctx->ReadBuffer->_ColorReadBuffer,
- width, x, y + i, CHAN_TYPE, rgba[i] );
- }
-
- swrast_render_finish(ctx);
-
- /*
- * HACK: save & restore context state so we can store this as a
- * convolution filter via the GL api. Doesn't call any callbacks
- * hanging off ctx->Unpack statechanges.
- */
-
- packSave = ctx->Unpack; /* save pixel packing params */
-
- ctx->Unpack.Alignment = 1;
- ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH;
- ctx->Unpack.SkipPixels = 0;
- ctx->Unpack.SkipRows = 0;
- ctx->Unpack.ImageHeight = 0;
- ctx->Unpack.SkipImages = 0;
- ctx->Unpack.SwapBytes = GL_FALSE;
- ctx->Unpack.LsbFirst = GL_FALSE;
- ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj;
- ctx->NewState |= _NEW_PACKUNPACK;
-
- /* save PBO binding */
- bufferSave = ctx->Unpack.BufferObj;
- ctx->Unpack.BufferObj = ctx->Shared->NullBufferObj;
-
- _mesa_ConvolutionFilter2D(target, internalFormat, width, height,
- GL_RGBA, CHAN_TYPE, rgba);
-
- /* restore PBO binding */
- ctx->Unpack.BufferObj = bufferSave;
-
- ctx->Unpack = packSave; /* restore pixel packing params */
- ctx->NewState |= _NEW_PACKUNPACK;
-}
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index 6b1f9346475..004d4e05ae5 100644
--- a/src/mesa/swrast/s_texfilter.c
+++ b/src/mesa/swrast/s_texfilter.c
@@ -1862,7 +1862,7 @@ choose_cube_face(const struct gl_texture_object *texObj,
GLuint face;
GLfloat sc, tc, ma;
- if (arx > ary && arx > arz) {
+ if (arx >= ary && arx >= arz) {
if (rx >= 0.0F) {
face = FACE_POS_X;
sc = -rz;
@@ -1876,7 +1876,7 @@ choose_cube_face(const struct gl_texture_object *texObj,
ma = arx;
}
}
- else if (ary > arx && ary > arz) {
+ else if (ary >= arx && ary >= arz) {
if (ry >= 0.0F) {
face = FACE_POS_Y;
sc = rx;
@@ -1905,8 +1905,12 @@ choose_cube_face(const struct gl_texture_object *texObj,
}
}
- newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;
- newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;
+ {
+ const float ima = 1.0F / ma;
+ newCoord[0] = ( sc * ima + 1.0F ) * 0.5F;
+ newCoord[1] = ( tc * ima + 1.0F ) * 0.5F;
+ }
+
return (const struct gl_texture_image **) texObj->Image[face];
}
diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c
deleted file mode 100644
index f9ff9ad6a42..00000000000
--- a/src/mesa/swrast/s_texstore.c
+++ /dev/null
@@ -1,601 +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.
- */
-
-/*
- * Authors:
- * Brian Paul
- */
-
-
-/*
- * The functions in this file are mostly related to software texture fallbacks.
- * This includes texture image transfer/packing and texel fetching.
- * Hardware drivers will likely override most of this.
- */
-
-
-
-#include "main/glheader.h"
-#include "main/imports.h"
-#include "main/colormac.h"
-#include "main/context.h"
-#include "main/convolve.h"
-#include "main/image.h"
-#include "main/macros.h"
-#include "main/mipmap.h"
-#include "main/texformat.h"
-#include "main/teximage.h"
-#include "main/texstore.h"
-
-#include "s_context.h"
-#include "s_depth.h"
-#include "s_span.h"
-
-
-/**
- * Read an RGBA image from the frame buffer.
- * This is used by glCopyTex[Sub]Image[12]D().
- * \param x window source x
- * \param y window source y
- * \param width image width
- * \param height image height
- * \param type datatype for returned GL_RGBA image
- * \return pointer to image
- */
-static GLvoid *
-read_color_image( GLcontext *ctx, GLint x, GLint y, GLenum type,
- GLsizei width, GLsizei height )
-{
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_ColorReadBuffer;
- const GLint pixelSize = _mesa_bytes_per_pixel(GL_RGBA, type);
- const GLint stride = width * pixelSize;
- GLint row;
- GLubyte *image, *dst;
-
- image = (GLubyte *) _mesa_malloc(width * height * pixelSize);
- if (!image)
- return NULL;
-
- swrast_render_start(ctx);
-
- dst = image;
- for (row = 0; row < height; row++) {
- _swrast_read_rgba_span(ctx, rb, width, x, y + row, type, dst);
- dst += stride;
- }
-
- swrast_render_finish(ctx);
-
- return image;
-}
-
-
-/**
- * As above, but read data from depth buffer. Returned as GLuints.
- * \sa read_color_image
- */
-static GLuint *
-read_depth_image( GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height )
-{
- struct gl_renderbuffer *rb = ctx->ReadBuffer->_DepthBuffer;
- GLuint *image, *dst;
- GLint i;
-
- image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
- if (!image)
- return NULL;
-
- swrast_render_start(ctx);
-
- dst = image;
- for (i = 0; i < height; i++) {
- _swrast_read_depth_span_uint(ctx, rb, width, x, y + i, dst);
- dst += width;
- }
-
- swrast_render_finish(ctx);
-
- return image;
-}
-
-
-/**
- * As above, but read data from depth+stencil buffers.
- */
-static GLuint *
-read_depth_stencil_image(GLcontext *ctx, GLint x, GLint y,
- GLsizei width, GLsizei height)
-{
- struct gl_renderbuffer *depthRb = ctx->ReadBuffer->_DepthBuffer;
- struct gl_renderbuffer *stencilRb = ctx->ReadBuffer->_StencilBuffer;
- GLuint *image, *dst;
- GLint i;
-
- ASSERT(depthRb);
- ASSERT(stencilRb);
-
- image = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint));
- if (!image)
- return NULL;
-
- swrast_render_start(ctx);
-
- /* read from depth buffer */
- dst = image;
- if (depthRb->DataType == GL_UNSIGNED_INT) {
- for (i = 0; i < height; i++) {
- _swrast_get_row(ctx, depthRb, width, x, y + i, dst, sizeof(GLuint));
- dst += width;
- }
- }
- else {
- GLushort z16[MAX_WIDTH];
- ASSERT(depthRb->DataType == GL_UNSIGNED_SHORT);
- for (i = 0; i < height; i++) {
- GLint j;
- _swrast_get_row(ctx, depthRb, width, x, y + i, z16, sizeof(GLushort));
- /* convert GLushorts to GLuints */
- for (j = 0; j < width; j++) {
- dst[j] = z16[j];
- }
- dst += width;
- }
- }
-
- /* put depth values into bits 0xffffff00 */
- if (ctx->ReadBuffer->Visual.depthBits == 24) {
- GLint j;
- for (j = 0; j < width * height; j++) {
- image[j] <<= 8;
- }
- }
- else if (ctx->ReadBuffer->Visual.depthBits == 16) {
- GLint j;
- for (j = 0; j < width * height; j++) {
- image[j] = (image[j] << 16) | (image[j] & 0xff00);
- }
- }
- else {
- /* this handles arbitrary depthBits >= 12 */
- const GLint rShift = ctx->ReadBuffer->Visual.depthBits;
- const GLint lShift = 32 - rShift;
- GLint j;
- for (j = 0; j < width * height; j++) {
- GLuint z = (image[j] << lShift);
- image[j] = z | (z >> rShift);
- }
- }
-
- /* read stencil values and interleave into image array */
- dst = image;
- for (i = 0; i < height; i++) {
- GLstencil stencil[MAX_WIDTH];
- GLint j;
- ASSERT(8 * sizeof(GLstencil) == stencilRb->StencilBits);
- _swrast_get_row(ctx, stencilRb, width, x, y + i,
- stencil, sizeof(GLstencil));
- for (j = 0; j < width; j++) {
- dst[j] = (dst[j] & 0xffffff00) | (stencil[j] & 0xff);
- }
- dst += width;
- }
-
- swrast_render_finish(ctx);
-
- return image;
-}
-
-
-static GLboolean
-is_depth_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH_COMPONENT:
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-static GLboolean
-is_depth_stencil_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH_STENCIL_EXT:
- case GL_DEPTH24_STENCIL8_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/*
- * Fallback for Driver.CopyTexImage1D().
- */
-void
-_swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border )
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- ASSERT(texObj);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(texImage);
-
- ASSERT(ctx->Driver.TexImage1D);
-
- if (is_depth_format(internalFormat)) {
- /* read depth image from framebuffer */
- GLuint *image = read_depth_image(ctx, x, y, width, 1);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
- return;
- }
- /* call glTexImage1D to redefine the texture */
- ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
- width, border,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else if (is_depth_stencil_format(internalFormat)) {
- /* read depth/stencil image from framebuffer */
- GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
- return;
- }
- /* call glTexImage1D to redefine the texture */
- ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
- width, border,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- image, &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else {
- /* read RGBA image from framebuffer */
- const GLenum format = GL_RGBA;
- const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;
- GLvoid *image = read_color_image(ctx, x, y, type, width, 1);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
- return;
- }
- /* call glTexImage1D to redefine the texture */
- ctx->Driver.TexImage1D(ctx, target, level, internalFormat,
- width, border, format, type, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
-
-
-/**
- * Fallback for Driver.CopyTexImage2D().
- *
- * We implement CopyTexImage by reading the image from the framebuffer
- * then passing it to the ctx->Driver.TexImage2D() function.
- *
- * Device drivers should try to implement direct framebuffer->texture copies.
- */
-void
-_swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border )
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- ASSERT(texObj);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(texImage);
-
- ASSERT(ctx->Driver.TexImage2D);
-
- if (is_depth_format(internalFormat)) {
- /* read depth image from framebuffer */
- GLuint *image = read_depth_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- return;
- }
- /* call glTexImage2D to redefine the texture */
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else if (is_depth_stencil_format(internalFormat)) {
- GLuint *image = read_depth_stencil_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- return;
- }
- /* call glTexImage2D to redefine the texture */
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- image, &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else {
- /* read RGBA image from framebuffer */
- const GLenum format = GL_RGBA;
- const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;
- GLvoid *image = read_color_image(ctx, x, y, type, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
- return;
- }
- /* call glTexImage2D to redefine the texture */
- ctx->Driver.TexImage2D(ctx, target, level, internalFormat,
- width, height, border, format, type, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
-
-
-/*
- * Fallback for Driver.CopyTexSubImage1D().
- */
-void
-_swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width )
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- ASSERT(texObj);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(texImage);
-
- ASSERT(ctx->Driver.TexImage1D);
-
- if (texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
- /* read depth image from framebuffer */
- GLuint *image = read_depth_image(ctx, x, y, width, 1);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
- return;
- }
-
- /* call glTexSubImage1D to redefine the texture */
- ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
- /* read depth/stencil image from framebuffer */
- GLuint *image = read_depth_stencil_image(ctx, x, y, width, 1);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
- return;
- }
- /* call glTexImage1D to redefine the texture */
- ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- image, &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else {
- /* read RGBA image from framebuffer */
- const GLenum format = GL_RGBA;
- const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;
- GLvoid *image = read_color_image(ctx, x, y, type, width, 1);
- if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
- return;
- }
- /* now call glTexSubImage1D to do the real work */
- ctx->Driver.TexSubImage1D(ctx, target, level, xoffset, width,
- format, type, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
-
-
-/**
- * Fallback for Driver.CopyTexSubImage2D().
- *
- * Read the image from the framebuffer then hand it
- * off to ctx->Driver.TexSubImage2D().
- */
-void
-_swrast_copy_texsubimage2d( GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- ASSERT(texObj);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(texImage);
-
- ASSERT(ctx->Driver.TexImage2D);
-
- if (texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
- /* read depth image from framebuffer */
- GLuint *image = read_depth_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
- return;
- }
- /* call glTexImage2D to redefine the texture */
- ctx->Driver.TexSubImage2D(ctx, target, level,
- xoffset, yoffset, width, height,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
- /* read depth/stencil image from framebuffer */
- GLuint *image = read_depth_stencil_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
- return;
- }
- /* call glTexImage2D to redefine the texture */
- ctx->Driver.TexSubImage2D(ctx, target, level,
- xoffset, yoffset, width, height,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- image, &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else {
- /* read RGBA image from framebuffer */
- const GLenum format = GL_RGBA;
- const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;
- GLvoid *image = read_color_image(ctx, x, y, type, width, height);
- if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
- return;
- }
- /* now call glTexSubImage2D to do the real work */
- ctx->Driver.TexSubImage2D(ctx, target, level,
- xoffset, yoffset, width, height,
- format, type, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
-
-
-/*
- * Fallback for Driver.CopyTexSubImage3D().
- */
-void
-_swrast_copy_texsubimage3d( GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height )
-{
- struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- ASSERT(texObj);
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- ASSERT(texImage);
-
- ASSERT(ctx->Driver.TexImage3D);
-
- if (texImage->_BaseFormat == GL_DEPTH_COMPONENT) {
- /* read depth image from framebuffer */
- GLuint *image = read_depth_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
- return;
- }
- /* call glTexImage3D to redefine the texture */
- ctx->Driver.TexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset, width, height, 1,
- GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else if (texImage->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
- /* read depth/stencil image from framebuffer */
- GLuint *image = read_depth_stencil_image(ctx, x, y, width, height);
- if (!image) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
- return;
- }
- /* call glTexImage3D to redefine the texture */
- ctx->Driver.TexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset, width, height, 1,
- GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT,
- image, &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
- else {
- /* read RGBA image from framebuffer */
- const GLenum format = GL_RGBA;
- const GLenum type = ctx->ReadBuffer->_ColorReadBuffer->DataType;
- GLvoid *image = read_color_image(ctx, x, y, type, width, height);
- if (!image) {
- _mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
- return;
- }
- /* now call glTexSubImage3D to do the real work */
- ctx->Driver.TexSubImage3D(ctx, target, level,
- xoffset, yoffset, zoffset, width, height, 1,
- format, type, image,
- &ctx->DefaultPacking, texObj, texImage);
- _mesa_free(image);
- }
-
- /* GL_SGIS_generate_mipmap */
- if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
- ctx->Driver.GenerateMipmap(ctx, target, texObj);
- }
-}
diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h
index c319ca62f9c..c183b315b67 100644
--- a/src/mesa/swrast/swrast.h
+++ b/src/mesa/swrast/swrast.h
@@ -207,60 +207,6 @@ extern void
_swrast_print_vertex( GLcontext *ctx, const SWvertex *v );
-/*
- * Imaging fallbacks (a better solution should be found, perhaps
- * moving all the imaging fallback code to a new module)
- */
-extern void
-_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width,
- GLsizei height);
-extern void
-_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width);
-extern void
-_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
- GLint x, GLint y, GLsizei width);
-extern void
-_swrast_CopyColorTable( GLcontext *ctx,
- GLenum target, GLenum internalformat,
- GLint x, GLint y, GLsizei width);
-
-
-/*
- * Texture fallbacks. Could also live in a new module
- * with the rest of the texture store fallbacks?
- */
-extern void
-_swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLint border);
-
-extern void
-_swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level,
- GLenum internalFormat,
- GLint x, GLint y, GLsizei width, GLsizei height,
- GLint border);
-
-
-extern void
-_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
- GLint xoffset, GLint x, GLint y, GLsizei width);
-
-extern void
-_swrast_copy_texsubimage2d(GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height);
-
-extern void
-_swrast_copy_texsubimage3d(GLcontext *ctx,
- GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height);
-
extern void
_swrast_eject_texture_images(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index b9550d6106c..774cffc451b 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -672,29 +672,69 @@ vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
const GLvoid *indices,
GLint basevertex)
{
+ static GLuint warnCount = 0;
GET_CURRENT_CONTEXT(ctx);
if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
type, indices, basevertex ))
return;
+ /* NOTE: It's important that 'end' is a reasonable value.
+ * in _tnl_draw_prims(), we use end to determine how many vertices
+ * to transform. If it's too large, we can unnecessarily split prims
+ * or we can read/write out of memory in several different places!
+ */
+
if (end >= ctx->Array.ArrayObj->_MaxElement) {
/* the max element is out of bounds of one or more enabled arrays */
- _mesa_warning(ctx, "glDraw[Range]Elements{,BaseVertex}(start %u, end %u, "
- "count %d, type 0x%x, indices=%p, base=%d)\n"
- "\tindex=%u is out of bounds (max=%u) "
- "Element Buffer %u (size %d)",
- start, end, count, type, indices, end, basevertex,
- ctx->Array.ArrayObj->_MaxElement - 1,
- ctx->Array.ElementArrayBufferObj->Name,
- ctx->Array.ElementArrayBufferObj->Size);
+ warnCount++;
+
+ if (warnCount < 10) {
+ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, count %d, "
+ "type 0x%x, indices=%p)\n"
+ "\tend is out of bounds (max=%u) "
+ "Element Buffer %u (size %d)\n"
+ "\tThis should probably be fixed in the application.",
+ start, end, count, type, indices,
+ ctx->Array.ArrayObj->_MaxElement - 1,
+ ctx->Array.ElementArrayBufferObj->Name,
+ ctx->Array.ElementArrayBufferObj->Size);
+ }
if (0)
dump_element_buffer(ctx, type);
if (0)
_mesa_print_arrays(ctx);
- return;
+
+#ifdef DEBUG
+ /* 'end' was out of bounds, but now let's check the actual array
+ * indexes to see if any of them are out of bounds. If so, warn
+ * and skip the draw to avoid potential segfault, etc.
+ */
+ {
+ GLuint max = _mesa_max_buffer_index(ctx, count, type, indices,
+ ctx->Array.ElementArrayBufferObj);
+ if (max >= ctx->Array.ArrayObj->_MaxElement) {
+ if (warnCount < 10) {
+ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, "
+ "count %d, type 0x%x, indices=%p)\n"
+ "\tindex=%u is out of bounds (max=%u) "
+ "Element Buffer %u (size %d)\n"
+ "\tSkipping the glDrawRangeElements() call",
+ start, end, count, type, indices, max,
+ ctx->Array.ArrayObj->_MaxElement - 1,
+ ctx->Array.ElementArrayBufferObj->Name,
+ ctx->Array.ElementArrayBufferObj->Size);
+ }
+ return;
+ }
+ /* XXX we could also find the min index and compare to 'start'
+ * to see if start is correct. But it's more likely to get the
+ * upper bound wrong.
+ */
+ }
+#endif
}
else if (0) {
_mesa_printf("glDraw[Range]Elements{,BaseVertex}"
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index 799a25fc1cb..55a82ee369e 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -127,7 +127,10 @@ void vbo_rebase_prims( GLcontext *ctx,
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
- if (ib && ctx->Extensions.ARB_draw_elements_base_vertex) {
+ /* XXX this path is disabled for now.
+ * There's rendering corruption in some apps when it's enabled.
+ */
+ if (0 && ib && ctx->Extensions.ARB_draw_elements_base_vertex) {
/* If we can just tell the hardware or the TNL to interpret our
* indices with a different base, do so.
*/
diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S
index 907deb4d2fc..72d0532906a 100644
--- a/src/mesa/x86-64/glapi_x86-64.S
+++ b/src/mesa/x86-64/glapi_x86-64.S
@@ -30393,6 +30393,7 @@ GL_PREFIX(_dispatch_stub_794):
.globl GL_PREFIX(RenderbufferStorage) ; .set GL_PREFIX(RenderbufferStorage), GL_PREFIX(RenderbufferStorageEXT)
.globl GL_PREFIX(BlitFramebuffer) ; .set GL_PREFIX(BlitFramebuffer), GL_PREFIX(_dispatch_stub_783)
.globl GL_PREFIX(FramebufferTextureLayer) ; .set GL_PREFIX(FramebufferTextureLayer), GL_PREFIX(FramebufferTextureLayerEXT)
+ .globl GL_PREFIX(ProvokingVertex) ; .set GL_PREFIX(ProvokingVertex), GL_PREFIX(ProvokingVertexEXT)
#if defined(GLX_USE_TLS) && defined(__linux__)
.section ".note.ABI-tag", "a"
diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S
index 5f12b4fb6a0..12c77f434ec 100644
--- a/src/mesa/x86/glapi_x86.S
+++ b/src/mesa/x86/glapi_x86.S
@@ -1316,6 +1316,7 @@ GLNAME(gl_dispatch_functions_start):
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(FramebufferTextureLayer, _gloffset_FramebufferTextureLayerEXT, FramebufferTextureLayer@20, FramebufferTextureLayerEXT, FramebufferTextureLayerEXT@20)
+ GL_STUB_ALIAS(ProvokingVertex, _gloffset_ProvokingVertexEXT, ProvokingVertex@4, ProvokingVertexEXT, ProvokingVertexEXT@4)
GLOBL GLNAME(gl_dispatch_functions_end)
HIDDEN(GLNAME(gl_dispatch_functions_end))
diff --git a/src/xvmc/context.c b/src/xvmc/context.c
index 273f6580292..9c2b6648bb5 100644
--- a/src/xvmc/context.c
+++ b/src/xvmc/context.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/extensions/XvMClib.h>
+#include <X11/Xlibint.h>
#include <pipe/p_context.h>
#include <vl_display.h>
#include <vl_screen.h>
@@ -137,6 +138,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i
struct vlScreen *vl_scrn;
struct vlContext *vl_ctx;
struct pipe_context *pipe;
+ Display *dpy = display;
assert(display);
@@ -176,6 +178,7 @@ Status XvMCCreateContext(Display *display, XvPortID port, int surface_type_id, i
context->port = port;
context->privData = vl_ctx;
+ SyncHandle();
return Success;
}
diff --git a/src/xvmc/subpicture.c b/src/xvmc/subpicture.c
index c8f70c90d0c..09e9c98e6af 100644
--- a/src/xvmc/subpicture.c
+++ b/src/xvmc/subpicture.c
@@ -2,6 +2,7 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xvlib.h>
#include <X11/extensions/XvMC.h>
+#include <X11/Xlibint.h>
Status XvMCCreateSubpicture
(
@@ -13,6 +14,7 @@ Status XvMCCreateSubpicture
int xvimage_id
)
{
+ Display *dpy = display;
assert(display);
if (!context)
@@ -38,7 +40,8 @@ Status XvMCCreateSubpicture
subpicture->component_order[2] = 0;
subpicture->component_order[3] = 0;
/* TODO: subpicture->privData = ;*/
-
+
+ SyncHandle();
return Success;
}
diff --git a/src/xvmc/surface.c b/src/xvmc/surface.c
index 7c5f45bd346..fea351b84f0 100644
--- a/src/xvmc/surface.c
+++ b/src/xvmc/surface.c
@@ -1,6 +1,7 @@
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/extensions/XvMC.h>
+#include <X11/Xlibint.h>
#include <vl_display.h>
#include <vl_screen.h>
#include <vl_context.h>
@@ -61,6 +62,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
{
struct vlContext *vl_ctx;
struct vlSurface *vl_sfc;
+ Display *dpy = display;
assert(display);
@@ -90,6 +92,7 @@ Status XvMCCreateSurface(Display *display, XvMCContext *context, XvMCSurface *su
surface->height = context->height;
surface->privData = vl_sfc;
+ SyncHandle();
return Success;
}
diff --git a/windows/VC7/mesa/mesa/mesa.vcproj b/windows/VC7/mesa/mesa/mesa.vcproj
index 4d5d4c744b6..4d7df741702 100644
--- a/windows/VC7/mesa/mesa/mesa.vcproj
+++ b/windows/VC7/mesa/mesa/mesa.vcproj
@@ -416,9 +416,6 @@
RelativePath="..\..\..\..\src\mesa\swrast\s_fragprog.c">
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_imaging.c">
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_lines.c">
</File>
<File
@@ -446,9 +443,6 @@
RelativePath="..\..\..\..\src\mesa\swrast\s_texfilter.c">
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_texstore.c">
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_triangle.c">
</File>
<File
diff --git a/windows/VC8/mesa/mesa/mesa.vcproj b/windows/VC8/mesa/mesa/mesa.vcproj
index 068da1612d4..f15c4435f61 100644
--- a/windows/VC8/mesa/mesa/mesa.vcproj
+++ b/windows/VC8/mesa/mesa/mesa.vcproj
@@ -783,10 +783,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_imaging.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_lines.c"
>
</File>
@@ -823,10 +819,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_texstore.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_triangle.c"
>
</File>