summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile19
-rw-r--r--SConstruct6
-rwxr-xr-xbin/mklib1
-rw-r--r--common.py6
-rw-r--r--configs/default5
-rw-r--r--configs/linux-llvm19
-rw-r--r--configure.ac23
-rw-r--r--docs/contents.html2
-rw-r--r--docs/dispatch.html2
-rw-r--r--docs/download.html10
-rw-r--r--docs/faq.html13
-rw-r--r--docs/news.html7
-rw-r--r--docs/precompiled.html12
-rw-r--r--docs/relnotes-7.5.1.html72
-rw-r--r--docs/relnotes-7.5.2.html56
-rw-r--r--docs/relnotes-7.5.html10
-rw-r--r--docs/relnotes-7.6.html29
-rw-r--r--docs/relnotes-7.7.html54
-rw-r--r--docs/relnotes.html3
-rw-r--r--include/EGL/eglplatform.h3
-rw-r--r--include/GL/gl.h15
-rw-r--r--include/GL/glext.h566
-rw-r--r--include/GL/glxext.h18
-rw-r--r--include/GL/wglext.h19
-rw-r--r--progs/SConscript1
-rw-r--r--progs/demos/.gitignore1
-rw-r--r--progs/demos/copypix.c22
-rw-r--r--progs/demos/cubemap.c59
-rw-r--r--progs/demos/fbotexture.c28
-rw-r--r--progs/demos/lodbias.c4
-rw-r--r--progs/egl/.gitignore1
-rw-r--r--progs/egl/Makefile94
-rw-r--r--progs/egl/demo3.c2
-rw-r--r--progs/egl/xeglbindtex.c474
-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/.gitignore1
-rw-r--r--progs/glsl/Makefile173
-rw-r--r--progs/glsl/brick.c14
-rw-r--r--progs/glsl/brick.shtest8
-rw-r--r--progs/glsl/bump.c14
-rw-r--r--progs/glsl/convolutions.c1
-rw-r--r--progs/glsl/deriv.c1
-rw-r--r--progs/glsl/fragcoord.c1
-rw-r--r--progs/glsl/identity.c1
-rw-r--r--progs/glsl/mandelbrot.c12
-rw-r--r--progs/glsl/mandelbrot.shtest13
-rw-r--r--progs/glsl/multinoise.c1
-rw-r--r--progs/glsl/multitex.c15
-rw-r--r--progs/glsl/multitex.shtest6
-rw-r--r--progs/glsl/noise.c8
-rw-r--r--progs/glsl/noise2.c1
-rw-r--r--progs/glsl/pointcoord.c1
-rw-r--r--progs/glsl/samplers.c16
-rw-r--r--progs/glsl/shadow_sampler.c1
-rw-r--r--progs/glsl/shtest.c709
-rw-r--r--progs/glsl/texaaline.c21
-rw-r--r--progs/glsl/texdemo1.c11
-rw-r--r--progs/glsl/toyball.c28
-rw-r--r--progs/glsl/toyball.shtest17
-rw-r--r--progs/glsl/trirast.c1
-rw-r--r--progs/glsl/twoside.c1
-rw-r--r--progs/glsl/vert-or-frag-only.c1
-rw-r--r--progs/glsl/vert-tex.c2
-rw-r--r--progs/openvg/demos/Makefile2
-rw-r--r--progs/openvg/trivial/Makefile2
-rw-r--r--progs/perf/Makefile53
-rw-r--r--progs/perf/SConscript30
-rw-r--r--progs/perf/common.c133
-rw-r--r--progs/perf/common.h (renamed from src/gallium/state_trackers/glx/xlib/fakeglx.h)29
-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/glmain.c267
-rw-r--r--progs/perf/glmain.h68
-rw-r--r--progs/perf/swapbuffers.c161
-rw-r--r--progs/perf/teximage.c331
-rw-r--r--progs/perf/vbo.c245
-rw-r--r--progs/perf/vertexrate.c276
-rw-r--r--progs/samples/select.c6
-rw-r--r--progs/tests/SConscript1
-rw-r--r--progs/tests/fbotest1.c2
-rw-r--r--progs/tests/floattex.c4
-rw-r--r--progs/tests/getprocaddress.c3280
-rw-r--r--progs/tests/getprocaddress.py2
-rw-r--r--progs/tests/getteximage.c136
-rw-r--r--progs/tests/texcmp.c2
-rw-r--r--progs/tests/texcompsub.c22
-rw-r--r--progs/tests/texwrap.c18
-rw-r--r--progs/tests/zreaddraw.c85
-rw-r--r--progs/trivial/.gitignore15
-rw-r--r--progs/trivial/Makefile8
-rw-r--r--progs/util/glutskel.c64
-rw-r--r--progs/util/shaderutil.c200
-rw-r--r--progs/util/shaderutil.h35
-rw-r--r--progs/vp/arl-static.txt2
-rw-r--r--progs/vp/arl-unused.txt2
-rw-r--r--progs/vp/vp-tris.c6
-rw-r--r--progs/xdemos/.gitignore1
-rw-r--r--progs/xdemos/Makefile1
-rw-r--r--progs/xdemos/glxcontexts.c3
-rw-r--r--progs/xdemos/glxgears.c13
-rw-r--r--progs/xdemos/glxswapcontrol.c5
-rw-r--r--progs/xdemos/multictx.c585
-rw-r--r--scons/dxsdk.py15
-rw-r--r--scons/gallium.py9
-rw-r--r--scons/llvm.py78
-rw-r--r--scons/udis86.py42
-rw-r--r--scons/winddk.py45
-rw-r--r--src/egl/drivers/demo/demo.c106
-rw-r--r--src/egl/drivers/dri/Makefile1
-rw-r--r--src/egl/drivers/dri/egldri.c4
-rw-r--r--src/egl/drivers/glx/egl_glx.c412
-rw-r--r--src/egl/drivers/xdri/Makefile15
-rw-r--r--src/egl/drivers/xdri/driinit.c67
-rw-r--r--src/egl/drivers/xdri/driinit.h9
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c1054
-rw-r--r--src/egl/drivers/xdri/glxinit.c626
-rw-r--r--src/egl/drivers/xdri/glxinit.h14
-rw-r--r--src/egl/main/Makefile10
-rw-r--r--src/egl/main/eglapi.c673
-rw-r--r--src/egl/main/eglapi.h74
-rw-r--r--src/egl/main/eglcompiler.h33
-rw-r--r--src/egl/main/eglconfig.c20
-rw-r--r--src/egl/main/eglconfig.h8
-rw-r--r--src/egl/main/eglconfigutil.c2
-rw-r--r--src/egl/main/eglcontext.c152
-rw-r--r--src/egl/main/eglcontext.h27
-rw-r--r--src/egl/main/eglcurrent.c125
-rw-r--r--src/egl/main/eglcurrent.h8
-rw-r--r--src/egl/main/egldisplay.c275
-rw-r--r--src/egl/main/egldisplay.h230
-rw-r--r--src/egl/main/egldriver.c341
-rw-r--r--src/egl/main/egldriver.h46
-rw-r--r--src/egl/main/eglglobals.c69
-rw-r--r--src/egl/main/eglglobals.h21
-rw-r--r--src/egl/main/eglhash.c347
-rw-r--r--src/egl/main/eglhash.h39
-rw-r--r--src/egl/main/eglmisc.c60
-rw-r--r--src/egl/main/eglmisc.h6
-rw-r--r--src/egl/main/eglmode.c37
-rw-r--r--src/egl/main/eglmode.h10
-rw-r--r--src/egl/main/eglmutex.h52
-rw-r--r--src/egl/main/eglscreen.c109
-rw-r--r--src/egl/main/eglscreen.h24
-rw-r--r--src/egl/main/eglsurface.c137
-rw-r--r--src/egl/main/eglsurface.h54
-rw-r--r--src/egl/main/egltypedefs.h2
-rw-r--r--src/egl/main/eglx.c100
-rw-r--r--src/egl/main/eglx.h12
-rw-r--r--src/gallium/Makefile.template6
-rw-r--r--src/gallium/SConscript1
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c78
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c48
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c2
-rw-r--r--src/gallium/auxiliary/gallivm/instructionssoa.cpp4
-rw-r--r--src/gallium/auxiliary/gallivm/tgsitollvm.cpp78
-rw-r--r--src/gallium/auxiliary/tgsi/Makefile1
-rw-r--r--src/gallium/auxiliary/tgsi/SConscript1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt48
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c41
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump_c.c5
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c198
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.h29
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c247
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.h14
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h172
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h1
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c32
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c35
-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.c99
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c3
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c1077
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h619
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_util.h4
-rw-r--r--src/gallium/auxiliary/util/.gitignore2
-rw-r--r--src/gallium/auxiliary/util/Makefile10
-rw-r--r--src/gallium/auxiliary/util/SConscript22
-rw-r--r--src/gallium/auxiliary/util/u_blit.c137
-rw-r--r--src/gallium/auxiliary/util/u_blit.h11
-rw-r--r--src/gallium/auxiliary/util/u_debug.h16
-rw-r--r--src/gallium/auxiliary/util/u_debug_dump.c189
-rw-r--r--src/gallium/auxiliary/util/u_debug_dump.h65
-rw-r--r--src/gallium/auxiliary/util/u_fifo.h94
-rw-r--r--src/gallium/auxiliary/util/u_format.c46
-rw-r--r--src/gallium/auxiliary/util/u_format.csv99
-rw-r--r--src/gallium/auxiliary/util/u_format.h138
-rw-r--r--src/gallium/auxiliary/util/u_format_access.py498
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py141
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_table.py144
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c14
-rw-r--r--src/gallium/auxiliary/util/u_math.h93
-rw-r--r--src/gallium/auxiliary/util/u_memory.h8
-rw-r--r--src/gallium/auxiliary/util/u_mm.c22
-rw-r--r--src/gallium/auxiliary/util/u_mm.h2
-rw-r--r--src/gallium/auxiliary/util/u_network.c6
-rw-r--r--src/gallium/auxiliary/util/u_network.h2
-rw-r--r--src/gallium/auxiliary/util/u_rect.c8
-rw-r--r--src/gallium/auxiliary/util/u_rect.h4
-rw-r--r--src/gallium/auxiliary/util/u_simple_screen.c30
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c316
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.h4
-rw-r--r--src/gallium/auxiliary/util/u_stream_stdc.c2
-rw-r--r--src/gallium/auxiliary/util/u_surface.h17
-rw-r--r--src/gallium/auxiliary/util/u_tile.c256
-rw-r--r--src/gallium/auxiliary/util/u_time.c12
-rw-r--r--src/gallium/auxiliary/util/u_time.h11
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.c3
-rw-r--r--src/gallium/auxiliary/util/u_upload_mgr.c8
-rw-r--r--src/gallium/drivers/cell/common.h2
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fp.c10
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c4
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c13
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c50
-rw-r--r--src/gallium/drivers/i915simple/Makefile1
-rw-r--r--src/gallium/drivers/i915simple/SConscript1
-rw-r--r--src/gallium/drivers/i915simple/i915_batch.h89
-rw-r--r--src/gallium/drivers/i915simple/i915_blit.c80
-rw-r--r--src/gallium/drivers/i915simple/i915_blit.h32
-rw-r--r--src/gallium/drivers/i915simple/i915_buffer.c136
-rw-r--r--src/gallium/drivers/i915simple/i915_buffer.h31
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c181
-rw-r--r--src/gallium/drivers/i915simple/i915_context.h23
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_debug.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_flush.c10
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_emit.c1
-rw-r--r--src/gallium/drivers/i915simple/i915_prim_vbuf.c320
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c189
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.h24
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c84
-rw-r--r--src/gallium/drivers/i915simple/i915_state_emit.c164
-rw-r--r--src/gallium/drivers/i915simple/i915_state_sampler.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_surface.c4
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c707
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.h11
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h143
-rw-r--r--src/gallium/drivers/i915simple/intel_batchbuffer.h87
-rw-r--r--src/gallium/drivers/i915simple/intel_winsys.h230
-rw-r--r--src/gallium/drivers/i965simple/brw_screen.c4
-rw-r--r--src/gallium/drivers/i965simple/brw_surface.c4
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_wm_glsl.c6
-rw-r--r--src/gallium/drivers/identity/id_context.c2
-rw-r--r--src/gallium/drivers/identity/id_drm.c92
-rw-r--r--src/gallium/drivers/identity/id_screen.c2
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile57
-rw-r--r--src/gallium/drivers/llvmpipe/README149
-rw-r--r--src/gallium/drivers/llvmpipe/SConscript84
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.c64
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_alpha.h54
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.c1177
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_arit.h191
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend.h107
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c356
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c108
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c298
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.c369
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_const.h108
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_conv.c702
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_conv.h73
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_debug.c125
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_debug.h64
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.c216
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_depth.h63
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_flow.c493
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_flow.h129
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format.h119
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format_aos.c303
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_format_soa.c208
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.c377
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_interp.h99
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_intr.c192
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_intr.h102
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.c394
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_logic.h72
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_sample.h135
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c416
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_struct.c72
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_struct.h75
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.c239
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_swizzle.h91
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi.h84
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c1484
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.c182
-rw-r--r--src/gallium/drivers/llvmpipe/lp_bld_type.h175
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.c150
-rw-r--r--src/gallium/drivers/llvmpipe/lp_buffer.h55
-rw-r--r--src/gallium/drivers/llvmpipe/lp_clear.c81
-rw-r--r--src/gallium/drivers/llvmpipe/lp_clear.h43
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.c295
-rw-r--r--src/gallium/drivers/llvmpipe/lp_context.h155
-rw-r--r--src/gallium/drivers/llvmpipe/lp_draw_arrays.c192
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.c98
-rw-r--r--src/gallium/drivers/llvmpipe/lp_flush.h37
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c173
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.h135
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_setup.c190
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_setup.h85
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_vbuf.c607
-rw-r--r--src/gallium/drivers/llvmpipe/lp_prim_vbuf.h38
-rw-r--r--src/gallium/drivers/llvmpipe/lp_quad.h114
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.c111
-rw-r--r--src/gallium/drivers/llvmpipe/lp_query.h39
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c238
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.h (renamed from src/gallium/state_trackers/wgl/shared/stw_public.h)72
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.c1483
-rw-r--r--src/gallium/drivers/llvmpipe/lp_setup.h53
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state.h230
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_blend.c114
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_clip.c79
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_derived.c277
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c762
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_rasterizer.c62
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_sampler.c127
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_surface.c106
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vertex.c73
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_vs.c96
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.c50
-rw-r--r--src/gallium/drivers/llvmpipe/lp_surface.h42
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test.h128
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_blend.c881
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_conv.c427
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_format.c272
-rw-r--r--src/gallium/drivers/llvmpipe/lp_test_main.c384
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_cache.c304
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_cache.h151
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample.h101
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_c.c1713
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c196
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.c429
-rw-r--r--src/gallium/drivers/llvmpipe/lp_texture.h90
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.c302
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_cache.h106
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.c931
-rw-r--r--src/gallium/drivers/llvmpipe/lp_tile_soa.h81
-rw-r--r--src/gallium/drivers/llvmpipe/lp_winsys.h128
-rwxr-xr-xsrc/gallium/drivers/llvmpipe/sp2lp.sh34
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c9
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.h11
-rw-r--r--src/gallium/drivers/nv04/nv04_screen.c2
-rw-r--r--src/gallium/drivers/nv04/nv04_surface_2d.c106
-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.c4
-rw-r--r--src/gallium/drivers/nv40/nv40_screen.c2
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c22
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h9
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c52
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c1478
-rw-r--r--src/gallium/drivers/nv50/nv50_program.h35
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c59
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c27
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c114
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c20
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c47
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h71
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c82
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c201
-rw-r--r--src/gallium/drivers/r300/Makefile18
-rw-r--r--src/gallium/drivers/r300/r300_chipset.c11
-rw-r--r--src/gallium/drivers/r300/r300_chipset.h4
-rw-r--r--src/gallium/drivers/r300/r300_context.c31
-rw-r--r--src/gallium/drivers/r300/r300_context.h174
-rw-r--r--src/gallium/drivers/r300/r300_cs.h19
-rw-r--r--src/gallium/drivers/r300/r300_debug.c214
-rw-r--r--src/gallium/drivers/r300/r300_debug.h211
-rw-r--r--src/gallium/drivers/r300/r300_emit.c351
-rw-r--r--src/gallium/drivers/r300/r300_emit.h22
-rw-r--r--src/gallium/drivers/r300/r300_fs.c163
-rw-r--r--src/gallium/drivers/r300/r300_fs.h15
-rw-r--r--src/gallium/drivers/r300/r300_fs_inlines.h158
-rw-r--r--src/gallium/drivers/r300/r300_query.c78
-rw-r--r--src/gallium/drivers/r300/r300_query.h7
-rw-r--r--src/gallium/drivers/r300/r300_reg.h4
-rw-r--r--src/gallium/drivers/r300/r300_render.c70
-rw-r--r--src/gallium/drivers/r300/r300_screen.c13
-rw-r--r--src/gallium/drivers/r300/r300_state.c46
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c52
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.h6
-rw-r--r--src/gallium/drivers/r300/r300_state_inlines.h19
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c21
-rw-r--r--src/gallium/drivers/r300/r300_surface.c50
-rw-r--r--src/gallium/drivers/r300/r300_surface.h6
-rw-r--r--src/gallium/drivers/r300/r300_texture.c57
-rw-r--r--src/gallium/drivers/r300/r300_texture.h4
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c335
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.h41
-rw-r--r--src/gallium/drivers/r300/r300_vs.c519
-rw-r--r--src/gallium/drivers/r300/r300_vs.h137
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h3
-rw-r--r--src/gallium/drivers/r300/r3xx_fs.c100
-rw-r--r--src/gallium/drivers/r300/r3xx_fs.h50
-rw-r--r--src/gallium/drivers/r300/r5xx_fs.c540
-rw-r--r--src/gallium/drivers/r300/r5xx_fs.h106
-rw-r--r--src/gallium/drivers/softpipe/sp_clear.c6
-rw-r--r--src/gallium/drivers/softpipe/sp_clear.h1
-rw-r--r--src/gallium/drivers/softpipe/sp_context.c27
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state_derived.c21
-rw-r--r--src/gallium/drivers/softpipe/sp_tex_sample.c4
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c46
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.h3
-rw-r--r--src/gallium/drivers/trace/tr_context.c6
-rw-r--r--src/gallium/drivers/trace/tr_drm.c89
-rw-r--r--src/gallium/drivers/trace/tr_dump.c2
-rw-r--r--src/gallium/drivers/trace/tr_screen.c3
-rw-r--r--src/gallium/include/pipe/internal/p_winsys_screen.h1
-rw-r--r--src/gallium/include/pipe/p_compiler.h4
-rw-r--r--src/gallium/include/pipe/p_config.h3
-rw-r--r--src/gallium/include/pipe/p_context.h17
-rw-r--r--src/gallium/include/pipe/p_defines.h8
-rw-r--r--src/gallium/include/pipe/p_inlines.h35
-rw-r--r--src/gallium/include/pipe/p_screen.h1
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h175
-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/include/state_tracker/drm_api.h29
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c10
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c182
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h12
-rw-r--r--src/gallium/state_trackers/dri/dri_extensions.c2
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c133
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h6
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c28
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c116
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.c100
-rw-r--r--src/gallium/state_trackers/egl/egl_tracker.h44
-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/glx/xlib/Makefile9
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript10
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c (renamed from src/gallium/state_trackers/glx/xlib/fakeglx.c)661
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_getproc.c214
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_usefont.c (renamed from src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c)22
-rw-r--r--src/gallium/state_trackers/glx/xlib/glxapi.c1254
-rw-r--r--src/gallium/state_trackers/glx/xlib/glxapi.h213
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.c42
-rw-r--r--src/gallium/state_trackers/glx/xlib/xm_api.h2
-rwxr-xr-xsrc/gallium/state_trackers/python/retrace/parse.py2
-rw-r--r--src/gallium/state_trackers/vega/asm_filters.h4
-rw-r--r--src/gallium/state_trackers/vega/path.c2
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.c14
-rw-r--r--src/gallium/state_trackers/vega/vg_tracker.h7
-rw-r--r--src/gallium/state_trackers/wgl/SConscript25
-rw-r--r--src/gallium/state_trackers/wgl/shared/stw_context.c382
-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)33
-rw-r--r--src/gallium/state_trackers/wgl/stw_device.h (renamed from src/gallium/state_trackers/wgl/shared/stw_device.h)5
-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)18
-rw-r--r--src/gallium/state_trackers/wgl/stw_framebuffer.h (renamed from src/gallium/state_trackers/wgl/shared/stw_framebuffer.h)0
-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)0
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.c (renamed from src/gallium/state_trackers/wgl/shared/stw_pixelformat.c)60
-rw-r--r--src/gallium/state_trackers/wgl/stw_pixelformat.h (renamed from src/gallium/state_trackers/wgl/shared/stw_pixelformat.h)7
-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)0
-rw-r--r--src/gallium/state_trackers/xorg/SConscript27
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.c1052
-rw-r--r--src/gallium/state_trackers/xorg/xorg_composite.h17
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c71
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c329
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c146
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c573
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h53
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.c484
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa_tgsi.h43
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c4
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h23
-rw-r--r--src/gallium/state_trackers/xorg/xorg_winsys.h2
-rw-r--r--src/gallium/winsys/drm/Makefile.template4
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript8
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/gem/Makefile8
-rw-r--r--src/gallium/winsys/drm/intel/gem/SConscript8
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.c37
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_api.h18
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c139
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h55
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c120
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.h31
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c369
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h108
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_fence.h34
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_api.c203
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c229
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c148
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_fence.c81
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h78
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/xorg/intel_xorg.c12
-rw-r--r--src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c127
-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/drm/radeon/core/radeon_buffer.c17
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h5
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c73
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h8
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c94
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h20
-rw-r--r--src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c12
-rw-r--r--src/gallium/winsys/egl_xlib/Makefile2
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c408
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c1
-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.c284
-rw-r--r--src/gallium/winsys/gdi/gdi_softpipe_winsys.c3
-rw-r--r--src/gallium/winsys/xlib/Makefile1
-rw-r--r--src/gallium/winsys/xlib/SConscript10
-rw-r--r--src/gallium/winsys/xlib/xlib.c10
-rw-r--r--src/gallium/winsys/xlib/xlib.h1
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_screen.c3
-rw-r--r--src/gallium/winsys/xlib/xlib_llvmpipe.c464
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c2
-rw-r--r--src/glut/glx/win32_winproc.c5
-rw-r--r--src/glx/x11/dri2.c550
-rw-r--r--src/glx/x11/dri2.h58
-rw-r--r--src/glx/x11/dri2_glx.c719
-rw-r--r--src/glx/x11/dri_common.c443
-rw-r--r--src/glx/x11/dri_glx.c1067
-rw-r--r--src/glx/x11/drisw_glx.c2
-rw-r--r--src/glx/x11/glx_pbuffer.c45
-rw-r--r--src/glx/x11/glx_query.c46
-rw-r--r--src/glx/x11/glxclient.h428
-rw-r--r--src/glx/x11/glxcmds.c3659
-rw-r--r--src/glx/x11/glxcurrent.c69
-rw-r--r--src/glx/x11/glxext.c74
-rw-r--r--src/glx/x11/glxextensions.c24
-rw-r--r--src/glx/x11/glxhash.c11
-rw-r--r--src/glx/x11/indirect_size.c4
-rw-r--r--src/glx/x11/indirect_vertex_array.c78
-rw-r--r--src/glx/x11/single2.c156
-rw-r--r--src/mesa/SConscript7
-rw-r--r--src/mesa/drivers/common/driverfuncs.c27
-rw-r--r--src/mesa/drivers/common/meta.c2471
-rw-r--r--src/mesa/drivers/common/meta.h114
-rw-r--r--src/mesa/drivers/dri/common/.gitignore1
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.c243
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.h22
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c2
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h1492
-rw-r--r--src/mesa/drivers/dri/fb/fb_egl.c4
-rw-r--r--src/mesa/drivers/dri/ffb/ffb_tex.c18
-rw-r--r--src/mesa/drivers/dri/i915/Makefile1
-rw-r--r--src/mesa/drivers/dri/i915/i830_context.h8
-rw-r--r--src/mesa/drivers/dri/i915/i830_reg.h3
-rw-r--r--src/mesa/drivers/dri/i915/i830_state.c32
-rw-r--r--src/mesa/drivers/dri/i915/i830_vtbl.c27
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.c8
-rw-r--r--src/mesa/drivers/dri/i915/i915_context.h12
-rw-r--r--src/mesa/drivers/dri/i915/i915_reg.h4
-rw-r--r--src/mesa/drivers/dri/i915/i915_state.c186
-rw-r--r--src/mesa/drivers/dri/i915/i915_vtbl.c24
l---------src/mesa/drivers/dri/i915/intel_syncobj.c1
-rw-r--r--src/mesa/drivers/dri/i965/Makefile2
-rw-r--r--src/mesa/drivers/dri/i965/brw_cc.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.h3
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_line.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_point.c4
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_state.c11
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_tri.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_unfilled.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_util.c48
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h24
-rw-r--r--src/mesa/drivers/dri/i965/brw_curbe.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h4
-rw-r--r--src/mesa/drivers/dri/i965/brw_disasm.c903
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.c69
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c149
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_emit.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_state.c5
-rw-r--r--src/mesa/drivers/dri/i965/brw_misc_state.c1
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf_state.c21
-rw-r--r--src/mesa/drivers/dri/i965/brw_state.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_state_upload.c15
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h19
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c23
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c120
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h10
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c169
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c171
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c272
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_iz.c3
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass0.c33
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_pass1.c6
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_sampler_state.c44
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_state.c7
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_surface_state.c13
l---------src/mesa/drivers/dri/i965/intel_syncobj.c1
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c10
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c46
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.h6
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.c263
-rw-r--r--src/mesa/drivers/dri/intel/intel_buffer_objects.h6
-rw-r--r--src/mesa/drivers/dri/intel/intel_chipset.h4
-rw-r--r--src/mesa/drivers/dri/intel/intel_clear.c35
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c51
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h17
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c15
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c71
-rw-r--r--src/mesa/drivers/dri/intel/intel_generatemipmap.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_bitmap.c35
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_copy.c173
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_draw.c173
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_read.c11
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c38
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c12
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c59
-rw-r--r--src/mesa/drivers/dri/intel/intel_syncobj.c132
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_copy.c25
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_image.c17
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c70
-rw-r--r--src/mesa/drivers/dri/r200/Makefile12
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c177
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c66
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.h22
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.c10
-rw-r--r--src/mesa/drivers/dri/r200/r200_ioctl.h19
-rw-r--r--src/mesa/drivers/dri/r200/r200_pixel.c40
-rw-r--r--src/mesa/drivers/dri/r200/r200_sanity.c4
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.c93
-rw-r--r--src/mesa/drivers/dri/r200/r200_state.h4
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c503
-rw-r--r--src/mesa/drivers/dri/r200/r200_swtcl.c57
-rw-r--r--src/mesa/drivers/dri/r200/r200_tcl.c91
-rw-r--r--src/mesa/drivers/dri/r200/r200_tex.c8
-rw-r--r--src/mesa/drivers/dri/r200/r200_texstate.c12
-rw-r--r--src/mesa/drivers/dri/r200/r200_vertprog.c14
l---------src/mesa/drivers/dri/r200/radeon_debug.c1
l---------src/mesa/drivers/dri/r200/radeon_debug.h1
l---------src/mesa/drivers/dri/r200/radeon_queryobj.c1
l---------src/mesa/drivers/dri/r200/radeon_queryobj.h1
-rw-r--r--src/mesa/drivers/dri/r300/Makefile31
-rw-r--r--src/mesa/drivers/dri/r300/compiler/Makefile75
-rw-r--r--src/mesa/drivers/dri/r300/compiler/memory_pool.c95
-rw-r--r--src/mesa/drivers/dri/r300/compiler/memory_pool.h49
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog.c416
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog.h49
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c (renamed from src/mesa/drivers/dri/r300/r300_fragprog_emit.c)210
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c (renamed from src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c)20
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.h (renamed from src/mesa/drivers/dri/r300/r300_fragprog_swizzle.h)0
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c149
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c656
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c177
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog.c (renamed from src/mesa/drivers/dri/r300/r500_fragprog.c)249
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog.h (renamed from src/mesa/drivers/dri/r300/r500_fragprog.h)11
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c (renamed from src/mesa/drivers/dri/r300/r500_fragprog_emit.c)82
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_code.c170
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_code.h207
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.c262
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_compiler.h108
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.c (renamed from src/mesa/drivers/dri/r300/radeon_nqssadce.c)141
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.h (renamed from src/mesa/drivers/dri/r300/radeon_nqssadce.h)12
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program.c210
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program.h (renamed from src/mesa/drivers/dri/r300/radeon_program.h)44
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c (renamed from src/mesa/drivers/dri/r300/radeon_program_alu.c)464
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h (renamed from src/mesa/drivers/dri/r300/radeon_program_alu.h)21
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c (renamed from src/mesa/drivers/dri/r300/radeon_program_pair.c)316
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h (renamed from src/mesa/drivers/dri/r300/radeon_program_pair.h)37
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.c433
-rw-r--r--src/mesa/drivers/dri/r300/r300_cmdbuf.h6
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c136
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h210
-rw-r--r--src/mesa/drivers/dri/r300/r300_draw.c531
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.c35
-rw-r--r--src/mesa/drivers/dri/r300/r300_emit.h4
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.c451
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog.h111
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.c370
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.h4
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c119
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h38
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c225
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c11
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c301
-rw-r--r--src/mesa/drivers/dri/r300/r300_swtcl.c82
-rw-r--r--src/mesa/drivers/dri/r300/r300_tex.c8
-rw-r--r--src/mesa/drivers/dri/r300/r300_texstate.c3
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c1609
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.h32
l---------src/mesa/drivers/dri/r300/radeon_buffer_objects.c1
l---------src/mesa/drivers/dri/r300/radeon_buffer_objects.h1
-rw-r--r--src/mesa/drivers/dri/r300/radeon_context.h14
l---------src/mesa/drivers/dri/r300/radeon_debug.c1
l---------src/mesa/drivers/dri/r300/radeon_debug.h1
-rw-r--r--src/mesa/drivers/dri/r300/radeon_program.c128
l---------src/mesa/drivers/dri/r300/radeon_queryobj.c1
l---------src/mesa/drivers/dri/r300/radeon_queryobj.h1
-rw-r--r--src/mesa/drivers/dri/r600/Makefile14
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.c209
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.h39
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c81
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.h146
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.c77
-rw-r--r--src/mesa/drivers/dri/r600/r600_reg_auto_r6xx.h2
-rw-r--r--src/mesa/drivers/dri/r600/r600_tex.c85
-rw-r--r--src/mesa/drivers/dri/r600/r600_texstate.c619
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c416
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.h10
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c1453
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.h83
-rw-r--r--src/mesa/drivers/dri/r600/r700_clear.c12
-rw-r--r--src/mesa/drivers/dri/r600/r700_debug.c35
-rw-r--r--src/mesa/drivers/dri/r600/r700_debug.h60
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.c191
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.h11
-rw-r--r--src/mesa/drivers/dri/r600/r700_ioctl.c27
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c44
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c998
-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_shaderinst.c14
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.c509
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.h8
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.c415
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.h53
l---------src/mesa/drivers/dri/r600/radeon_buffer_objects.c1
l---------src/mesa/drivers/dri/r600/radeon_buffer_objects.h1
l---------src/mesa/drivers/dri/r600/radeon_debug.c1
l---------src/mesa/drivers/dri/r600/radeon_debug.h1
l---------src/mesa/drivers/dri/r600/radeon_queryobj.c1
l---------src/mesa/drivers/dri/r600/radeon_queryobj.h1
-rw-r--r--src/mesa/drivers/dri/radeon/Makefile12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_drm.h54
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c144
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.h4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_buffer_objects.c229
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_buffer_objects.h52
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h15
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cmdbuf.h14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c351
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c254
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h98
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.c44
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_context.h12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_drm.h9
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.c3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_legacy.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_debug.c107
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_debug.h170
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c278
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.h14
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c30
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.c25
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_ioctl.h12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lighting.c6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.c55
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_lock.h12
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_arrays.c10
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c38
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h5
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_queryobj.c235
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_queryobj.h55
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_sanity.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c188
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c355
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.c59
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state.h2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c290
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_swtcl.c77
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tcl.c89
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_tex.c11
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texstate.c18
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c63
-rw-r--r--src/mesa/drivers/dri/radeon/server/radeon_reg.h5
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_state.c5
-rw-r--r--src/mesa/drivers/dri/s3v/s3v_tex.c11
-rw-r--r--src/mesa/drivers/dri/savage/savage_xmesa.c13
-rw-r--r--src/mesa/drivers/dri/savage/savagecontext.h1
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c12
-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.def19
-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.c11
-rw-r--r--src/mesa/drivers/x11/xm_dd.c30
-rw-r--r--src/mesa/drivers/x11/xmesaP.h4
-rw-r--r--src/mesa/glapi/ARB_depth_clamp.xml12
-rw-r--r--src/mesa/glapi/ARB_draw_elements_base_vertex.xml40
-rw-r--r--src/mesa/glapi/ARB_seamless_cube_map.xml12
-rw-r--r--src/mesa/glapi/ARB_sync.xml82
-rw-r--r--src/mesa/glapi/EXT_framebuffer_object.xml38
-rw-r--r--src/mesa/glapi/EXT_provoking_vertex.xml13
-rw-r--r--src/mesa/glapi/EXT_texture_array.xml41
-rw-r--r--src/mesa/glapi/Makefile3
-rw-r--r--src/mesa/glapi/dispatch.h528
-rw-r--r--src/mesa/glapi/extension_helper.py2
-rw-r--r--src/mesa/glapi/gl_API.xml67
-rw-r--r--src/mesa/glapi/gl_x86-64_asm.py2
-rw-r--r--src/mesa/glapi/gl_x86_asm.py2
-rw-r--r--src/mesa/glapi/glapi.c42
-rw-r--r--src/mesa/glapi/glapi.h4
-rw-r--r--src/mesa/glapi/glapioffsets.h458
-rw-r--r--src/mesa/glapi/glapitable.h442
-rw-r--r--src/mesa/glapi/glapitemp.h308
-rw-r--r--src/mesa/glapi/glprocs.h1194
-rw-r--r--src/mesa/glapi/glthread.c51
-rw-r--r--src/mesa/glapi/glthread.h44
-rw-r--r--src/mesa/glapi/mesadef.py18
-rw-r--r--src/mesa/main/api_arrayelt.c3
-rw-r--r--src/mesa/main/api_exec.c16
-rw-r--r--src/mesa/main/api_noop.c93
-rw-r--r--src/mesa/main/api_noop.h11
-rw-r--r--src/mesa/main/api_validate.c92
-rw-r--r--src/mesa/main/api_validate.h10
-rw-r--r--src/mesa/main/attrib.c153
-rw-r--r--src/mesa/main/bufferobj.c301
-rw-r--r--src/mesa/main/bufferobj.h61
-rw-r--r--src/mesa/main/colortab.c82
-rw-r--r--src/mesa/main/compiler.h8
-rw-r--r--src/mesa/main/config.h65
-rw-r--r--src/mesa/main/context.c113
-rw-r--r--src/mesa/main/context.h6
-rw-r--r--src/mesa/main/convolve.c195
-rw-r--r--src/mesa/main/dd.h43
-rw-r--r--src/mesa/main/debug.c97
-rw-r--r--src/mesa/main/dlist.c980
-rw-r--r--src/mesa/main/drawpix.c188
-rw-r--r--src/mesa/main/enable.c24
-rw-r--r--src/mesa/main/enums.c6232
-rw-r--r--src/mesa/main/execmem.c7
-rw-r--r--src/mesa/main/extensions.c13
-rw-r--r--src/mesa/main/fbobject.c65
-rw-r--r--src/mesa/main/ffvertex_prog.c7
-rw-r--r--src/mesa/main/fog.c2
-rw-r--r--src/mesa/main/framebuffer.c26
-rw-r--r--src/mesa/main/get.c1882
-rw-r--r--src/mesa/main/get.h3
-rw-r--r--src/mesa/main/get_gen.py40
-rw-r--r--src/mesa/main/getstring.c1
-rw-r--r--src/mesa/main/histogram.c63
-rw-r--r--src/mesa/main/image.c483
-rw-r--r--src/mesa/main/image.h34
-rw-r--r--src/mesa/main/imports.c85
-rw-r--r--src/mesa/main/imports.h4
-rw-r--r--src/mesa/main/light.c8
-rw-r--r--src/mesa/main/macros.h3
-rw-r--r--src/mesa/main/mfeatures.h1
-rw-r--r--src/mesa/main/mtypes.h50
-rw-r--r--src/mesa/main/pixel.c239
-rw-r--r--src/mesa/main/polygon.c75
-rw-r--r--src/mesa/main/readpix.c55
-rw-r--r--src/mesa/main/shared.c21
-rw-r--r--src/mesa/main/simple_list.h5
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/syncobj.c409
-rw-r--r--src/mesa/main/syncobj.h70
-rw-r--r--src/mesa/main/texenv.c69
-rw-r--r--src/mesa/main/texenvprogram.c284
-rw-r--r--src/mesa/main/texgen.c9
-rw-r--r--src/mesa/main/texgetimage.c233
-rw-r--r--src/mesa/main/texgetimage.h9
-rw-r--r--src/mesa/main/teximage.c1335
-rw-r--r--src/mesa/main/teximage.h16
-rw-r--r--src/mesa/main/texobj.c56
-rw-r--r--src/mesa/main/texobj.h8
-rw-r--r--src/mesa/main/texparam.c64
-rw-r--r--src/mesa/main/texstate.c9
-rw-r--r--src/mesa/main/texstate.h18
-rw-r--r--src/mesa/main/texstore.c99
-rw-r--r--src/mesa/main/varray.c59
-rw-r--r--src/mesa/main/varray.h21
-rw-r--r--src/mesa/main/version.h6
-rw-r--r--src/mesa/main/viewport.c4
-rw-r--r--src/mesa/main/vtxfmt.c4
-rw-r--r--src/mesa/main/vtxfmt_tmp.h53
-rw-r--r--src/mesa/math/m_clip_tmp.h44
-rw-r--r--src/mesa/math/m_debug_clip.c31
-rw-r--r--src/mesa/math/m_xform.h6
-rw-r--r--src/mesa/shader/.gitignore1
-rw-r--r--src/mesa/shader/Makefile7
-rw-r--r--src/mesa/shader/arbprogparse.c3981
-rw-r--r--src/mesa/shader/arbprogram.c3
-rw-r--r--src/mesa/shader/arbprogram.syn2824
-rw-r--r--src/mesa/shader/arbprogram_syn.h1350
-rw-r--r--src/mesa/shader/hash_table.c163
-rw-r--r--src/mesa/shader/hash_table.h117
-rw-r--r--src/mesa/shader/lex.yy.c3578
-rw-r--r--src/mesa/shader/prog_execute.c5
-rw-r--r--src/mesa/shader/prog_instruction.h10
-rw-r--r--src/mesa/shader/prog_parameter.c28
-rw-r--r--src/mesa/shader/prog_parameter.h3
-rw-r--r--src/mesa/shader/prog_parameter_layout.c217
-rw-r--r--src/mesa/shader/prog_parameter_layout.h42
-rw-r--r--src/mesa/shader/prog_print.c85
-rw-r--r--src/mesa/shader/prog_print.h11
-rw-r--r--src/mesa/shader/program.c7
-rw-r--r--src/mesa/shader/program_lexer.l493
-rw-r--r--src/mesa/shader/program_parse.tab.c5253
-rw-r--r--src/mesa/shader/program_parse.tab.h207
-rw-r--r--src/mesa/shader/program_parse.y2383
-rw-r--r--src/mesa/shader/program_parse_extra.c117
-rw-r--r--src/mesa/shader/program_parser.h266
-rw-r--r--src/mesa/shader/programopt.c1
-rw-r--r--src/mesa/shader/shader_api.c198
-rw-r--r--src/mesa/shader/shader_api.h8
-rw-r--r--src/mesa/shader/slang/slang_builtin.c185
-rw-r--r--src/mesa/shader/slang/slang_builtin.h14
-rw-r--r--src/mesa/shader/slang/slang_codegen.c104
-rw-r--r--src/mesa/shader/slang/slang_link.c64
-rw-r--r--src/mesa/shader/symbol_table.c350
-rw-r--r--src/mesa/shader/symbol_table.h55
-rw-r--r--src/mesa/sources.mak15
-rw-r--r--src/mesa/sparc/clip.S3
-rw-r--r--src/mesa/sparc/glapi_sparc.S151
-rw-r--r--src/mesa/sparc/sparc.c6
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c17
-rw-r--r--src/mesa/state_tracker/st_cb_bitmap.c83
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c147
-rw-r--r--src/mesa/state_tracker/st_cb_bufferobjects.c19
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c24
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c120
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c54
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c12
-rw-r--r--src/mesa/state_tracker/st_cb_program.c9
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c2
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c6
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c129
-rw-r--r--src/mesa/state_tracker/st_draw.c5
-rw-r--r--src/mesa/state_tracker/st_draw.h2
-rw-r--r--src/mesa/state_tracker/st_draw_feedback.c4
-rw-r--r--src/mesa/state_tracker/st_extensions.c4
-rw-r--r--src/mesa/state_tracker/st_format.c4
-rw-r--r--src/mesa/state_tracker/st_framebuffer.c18
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.c1517
-rw-r--r--src/mesa/state_tracker/st_mesa_to_tgsi.h9
-rw-r--r--src/mesa/state_tracker/st_program.c172
-rw-r--r--src/mesa/state_tracker/st_public.h4
-rw-r--r--src/mesa/state_tracker/st_texture.c110
-rw-r--r--src/mesa/state_tracker/st_texture.h5
-rw-r--r--src/mesa/swrast/s_bitmap.c4
-rw-r--r--src/mesa/swrast/s_blit.c189
-rw-r--r--src/mesa/swrast/s_context.c3
-rw-r--r--src/mesa/swrast/s_depth.c27
-rw-r--r--src/mesa/swrast/s_depth.h2
-rw-r--r--src/mesa/swrast/s_drawpix.c67
-rw-r--r--src/mesa/swrast/s_feedback.c4
-rw-r--r--src/mesa/swrast/s_fragprog.c5
-rw-r--r--src/mesa/swrast/s_imaging.c196
-rw-r--r--src/mesa/swrast/s_points.c28
-rw-r--r--src/mesa/swrast/s_readpix.c4
-rw-r--r--src/mesa/swrast/s_span.c3
-rw-r--r--src/mesa/swrast/s_stencil.c9
-rw-r--r--src/mesa/swrast/s_texfilter.c4
-rw-r--r--src/mesa/swrast/s_texstore.c601
-rw-r--r--src/mesa/swrast/s_triangle.c12
-rw-r--r--src/mesa/swrast/swrast.h54
-rw-r--r--src/mesa/tnl/t_context.c2
-rw-r--r--src/mesa/tnl/t_context.h4
-rw-r--r--src/mesa/tnl/t_draw.c76
-rw-r--r--src/mesa/tnl/t_rasterpos.c25
-rw-r--r--src/mesa/tnl/t_vb_program.c11
-rw-r--r--src/mesa/tnl/t_vb_vertex.c24
-rw-r--r--src/mesa/tnl/tnl.h10
-rw-r--r--src/mesa/vbo/vbo.h7
-rw-r--r--src/mesa/vbo/vbo_exec_api.c21
-rw-r--r--src/mesa/vbo/vbo_exec_array.c450
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c20
-rw-r--r--src/mesa/vbo/vbo_rebase.c19
-rw-r--r--src/mesa/vbo/vbo_save_api.c43
-rw-r--r--src/mesa/vbo/vbo_save_draw.c1
-rw-r--r--src/mesa/vbo/vbo_split.c8
-rw-r--r--src/mesa/vbo/vbo_split_copy.c64
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c3
-rw-r--r--src/mesa/x86-64/glapi_x86-64.S2607
-rw-r--r--src/mesa/x86/Makefile2
-rw-r--r--src/mesa/x86/glapi_x86.S153
-rw-r--r--src/mesa/x86/x86_xform.c9
-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.vcproj60
-rw-r--r--windows/VC8/mesa/osmesa/osmesa.vcproj4
1005 files changed, 101433 insertions, 45184 deletions
diff --git a/Makefile b/Makefile
index 146c52093b..ea00e811b7 100644
--- a/Makefile
+++ b/Makefile
@@ -182,7 +182,7 @@ ultrix-gcc:
# Rules for making release tarballs
-VERSION=7.6-devel
+VERSION=7.7-devel
DIRECTORY = Mesa-$(VERSION)
LIB_NAME = MesaLib-$(VERSION)
DEMO_NAME = MesaDemos-$(VERSION)
@@ -237,7 +237,8 @@ MAIN_FILES = \
$(DIRECTORY)/src/mesa/glapi/*.[chS] \
$(DIRECTORY)/src/mesa/math/*.[ch] \
$(DIRECTORY)/src/mesa/math/descrip.mms \
- $(DIRECTORY)/src/mesa/shader/*.[ch] \
+ $(DIRECTORY)/src/mesa/shader/*.[chly] \
+ $(DIRECTORY)/src/mesa/shader/Makefile \
$(DIRECTORY)/src/mesa/shader/descrip.mms \
$(DIRECTORY)/src/mesa/shader/grammar/*.[ch] \
$(DIRECTORY)/src/mesa/shader/slang/*.[ch] \
@@ -324,6 +325,7 @@ GALLIUM_FILES = \
$(DIRECTORY)/src/gallium/*/*/SConscript \
$(DIRECTORY)/src/gallium/*/*/*.[ch] \
$(DIRECTORY)/src/gallium/*/*/*.py \
+ $(DIRECTORY)/src/gallium/*/*/*.csv \
$(DIRECTORY)/src/gallium/*/*/*/Makefile \
$(DIRECTORY)/src/gallium/*/*/*/SConscript \
$(DIRECTORY)/src/gallium/*/*/*/*.[ch] \
@@ -345,7 +347,9 @@ DRI_FILES = \
$(DIRECTORY)/src/mesa/drivers/dri/common/xmlpool/*.[ch] \
$(DIRECTORY)/src/mesa/drivers/dri/common/xmlpool/*.po \
$(DIRECTORY)/src/mesa/drivers/dri/*/*.[chS] \
+ $(DIRECTORY)/src/mesa/drivers/dri/*/*/*.[chS] \
$(DIRECTORY)/src/mesa/drivers/dri/*/Makefile \
+ $(DIRECTORY)/src/mesa/drivers/dri/*/*/Makefile \
$(DIRECTORY)/src/mesa/drivers/dri/*/Doxyfile \
$(DIRECTORY)/src/mesa/drivers/dri/*/server/*.[ch]
@@ -388,7 +392,17 @@ GLW_FILES = \
$(DIRECTORY)/src/glw/glw.pc.in \
$(DIRECTORY)/src/glw/depend
+GLEW_FILES = \
+ $(DIRECTORY)/include/GL/glew.h \
+ $(DIRECTORY)/include/GL/glxew.h \
+ $(DIRECTORY)/include/GL/wglew.h \
+ $(DIRECTORY)/src/glew/*.c \
+ $(DIRECTORY)/src/glew/Makefile \
+ $(DIRECTORY)/src/glew/SConscript \
+ $(DIRECTORY)/src/glew/LICENSE.txt
+
DEMO_FILES = \
+ $(GLEW_FILES) \
$(DIRECTORY)/progs/beos/*.cpp \
$(DIRECTORY)/progs/beos/Makefile \
$(DIRECTORY)/progs/images/*.rgb \
@@ -415,6 +429,7 @@ DEMO_FILES = \
$(DIRECTORY)/progs/glsl/*.c \
$(DIRECTORY)/progs/glsl/*.frag \
$(DIRECTORY)/progs/glsl/*.vert \
+ $(DIRECTORY)/progs/glsl/*.shtest \
$(DIRECTORY)/progs/windml/Makefile.ugl \
$(DIRECTORY)/progs/windml/*.c \
$(DIRECTORY)/progs/windml/*.bmp \
diff --git a/SConstruct b/SConstruct
index 4a0fb94deb..e9baab0947 100644
--- a/SConstruct
+++ b/SConstruct
@@ -32,7 +32,7 @@ import common
default_statetrackers = 'mesa'
if common.default_platform in ('linux', 'freebsd', 'darwin'):
- default_drivers = 'softpipe,failover,i915simple,trace,identity'
+ default_drivers = 'softpipe,failover,i915simple,trace,identity,llvmpipe'
default_winsys = 'xlib'
elif common.default_platform in ('winddk',):
default_drivers = 'softpipe,i915simple,trace,identity'
@@ -44,9 +44,9 @@ else:
opts = Variables('config.py')
common.AddOptions(opts)
opts.Add(ListVariable('statetrackers', 'state trackers to build', default_statetrackers,
- ['mesa', 'python']))
+ ['mesa', 'python', 'xorg']))
opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers,
- ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity']))
+ ['softpipe', 'failover', 'i915simple', 'i965simple', 'cell', 'trace', 'r300', 'identity', 'llvmpipe']))
opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys,
['xlib', 'intel', 'gdi', 'radeon']))
diff --git a/bin/mklib b/bin/mklib
index 2444945006..db97087c0a 100755
--- a/bin/mklib
+++ b/bin/mklib
@@ -971,5 +971,6 @@ esac
#
if [ ${INSTALLDIR} != "." ] ; then
echo "mklib: Installing" ${FINAL_LIBS} "in" ${INSTALLDIR}
+ test -d ${INSTALLDIR} || mkdir -p ${INSTALLDIR}
mv ${FINAL_LIBS} ${INSTALLDIR}/
fi
diff --git a/common.py b/common.py
index a687efc86f..3b6bf52c03 100644
--- a/common.py
+++ b/common.py
@@ -33,9 +33,9 @@ else:
default_machine = _platform.machine()
default_machine = _machine_map.get(default_machine, 'generic')
-if default_platform in ('linux', 'freebsd', 'darwin'):
+if default_platform in ('linux', 'freebsd'):
default_dri = 'yes'
-elif default_platform in ('winddk', 'windows', 'wince'):
+elif default_platform in ('winddk', 'windows', 'wince', 'darwin'):
default_dri = 'no'
else:
default_dri = 'no'
@@ -59,7 +59,7 @@ def AddOptions(opts):
opts.Add(EnumOption('machine', 'use machine-specific assembly code', default_machine,
allowed_values=('generic', 'ppc', 'x86', 'x86_64')))
opts.Add(EnumOption('platform', 'target platform', default_platform,
- allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince')))
+ allowed_values=('linux', 'cell', 'windows', 'winddk', 'wince', 'darwin')))
opts.Add(EnumOption('toolchain', 'compiler toolchain', 'default',
allowed_values=('default', 'crossmingw', 'winsdk', 'winddk')))
opts.Add(BoolOption('llvm', 'use LLVM', 'no'))
diff --git a/configs/default b/configs/default
index 60638d739d..cb3ca1046f 100644
--- a/configs/default
+++ b/configs/default
@@ -9,7 +9,7 @@ CONFIG_NAME = default
# Version info
MESA_MAJOR=7
-MESA_MINOR=6
+MESA_MINOR=7
MESA_TINY=0
MESA_VERSION = $(MESA_MAJOR).$(MESA_MINOR).$(MESA_TINY)
@@ -23,6 +23,7 @@ HOST_CC = $(CC)
CFLAGS = -O
CXXFLAGS = -O
LDFLAGS =
+HOST_CFLAGS = $(CFLAGS)
GLU_CFLAGS =
# Compiler for building demos/tests/etc
@@ -105,7 +106,7 @@ GALLIUM_STATE_TRACKERS_DIRS = glx
# Library dependencies
#EXTRA_LIB_PATH ?=
GL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread
-EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -lX11 -ldl -lpthread
+EGL_LIB_DEPS = $(EXTRA_LIB_PATH) -ldl -lpthread
OSMESA_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB)
GLU_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GL_LIB) -lm
GLUT_LIB_DEPS = $(EXTRA_LIB_PATH) -L$(TOP)/$(LIB_DIR) -l$(GLU_LIB) -l$(GL_LIB) -lX11 -lXmu -lXi -lm
diff --git a/configs/linux-llvm b/configs/linux-llvm
index e7ecd826d5..19b53cc546 100644
--- a/configs/linux-llvm
+++ b/configs/linux-llvm
@@ -1,14 +1,21 @@
# -*-makefile-*-
# Configuration for Linux and LLVM with debugging info
+# Builds the llvmpipe gallium driver
include $(TOP)/configs/linux
CONFIG_NAME = linux-llvm
-GALLIUM_AUXILIARY_DIRS += gallivm
+#GALLIUM_AUXILIARY_DIRS += gallivm
+
+# Add llvmpipe driver
+GALLIUM_DRIVERS_DIRS += llvmpipe
OPT_FLAGS = -g -ansi -pedantic
-DEFINES += -DDEBUG -DDEBUG_MATH -DMESA_LLVM=1
+DEFINES += -DDEBUG -DDEBUG_MATH -DGALLIUM_LLVMPIPE -DHAVE_UDIS86
+
+# override -std=c99
+CFLAGS += -std=gnu99
LLVM_VERSION := $(shell llvm-config --version)
@@ -17,14 +24,14 @@ ifeq ($(LLVM_VERSION),)
MESA_LLVM=0
else
MESA_LLVM=1
- $(info Using LLVM version: $(LLVM_VERSION))
+# $(info Using LLVM version: $(LLVM_VERSION))
endif
ifeq ($(MESA_LLVM),1)
# LLVM_CFLAGS=`llvm-config --cflags`
LLVM_CXXFLAGS=`llvm-config --cxxflags backend bitreader engine ipo interpreter instrumentation` -Wno-long-long
- LLVM_LDFLAGS=`llvm-config --ldflags backend bitreader engine ipo interpreter instrumentation`
- LLVM_LIBS=`llvm-config --libs backend bitreader engine ipo interpreter instrumentation`
+ LLVM_LDFLAGS = $(shell llvm-config --ldflags backend bitreader engine ipo interpreter instrumentation)
+ LLVM_LIBS = $(shell llvm-config --libs backend bitreader engine ipo interpreter instrumentation)
MKLIB_OPTIONS=-cplusplus
else
LLVM_CFLAGS=
@@ -32,4 +39,4 @@ else
endif
LD = g++
-GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++
+GL_LIB_DEPS = $(LLVM_LDFLAGS) $(LLVM_LIBS) $(EXTRA_LIB_PATH) -lX11 -lXext -lm -lpthread -lstdc++ -ludis86
diff --git a/configure.ac b/configure.ac
index 9b65d96b39..2881bb6bc2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -126,6 +126,7 @@ AC_ARG_ENABLE([32-bit],
if test "x$enable_32bit" = xyes; then
if test "x$GCC" = xyes; then
CFLAGS="$CFLAGS -m32"
+ ARCH_FLAGS="$ARCH_FLAGS -m32"
fi
if test "x$GXX" = xyes; then
CXXFLAGS="$CXXFLAGS -m32"
@@ -1147,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"
;;
@@ -1159,6 +1165,21 @@ AC_ARG_WITH([xorg-driver-dir],
[XORG_DRIVER_INSTALL_DIR="${libdir}/xorg/modules/drivers"])
AC_SUBST([XORG_DRIVER_INSTALL_DIR])
+AC_ARG_WITH([max-width],
+ [AS_HELP_STRING([--with-max-width=N],
+ [Maximum framebuffer width (4096)])],
+ [DEFINES="${DEFINES} -DMAX_WIDTH=${withval}";
+ AS_IF([test "${withval}" -gt "4096"],
+ [AC_MSG_WARN([Large framebuffer: see s_tritemp.h comments.])])]
+)
+AC_ARG_WITH([max-height],
+ [AS_HELP_STRING([--with-max-height=N],
+ [Maximum framebuffer height (4096)])],
+ [DEFINES="${DEFINES} -DMAX_HEIGHT=${withval}";
+ AS_IF([test "${withval}" -gt "4096"],
+ [AC_MSG_WARN([Large framebuffer: see s_tritemp.h comments.])])]
+)
+
dnl
dnl Gallium Intel configuration
dnl
@@ -1186,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/contents.html b/docs/contents.html
index 1dca3a228d..d15e6c1e33 100644
--- a/docs/contents.html
+++ b/docs/contents.html
@@ -39,7 +39,6 @@ a:visited {
<ul>
<li><a href="download.html" target="MainFrame">Downloading / Unpacking</a>
<li><a href="install.html" target="MainFrame">Compiling / Installing</a>
-<li><a href="glu.html" target="MainFrame">SGI's GLU</a>
<li><a href="precompiled.html" target="MainFrame">Precompiled Libraries</a>
</ul>
@@ -68,6 +67,7 @@ a:visited {
<li><a href="repository.html" target="MainFrame">Source Code Repository</a>
<li><a href="memory.html" target="MainFrame">DRI Memory Management</a>
<li><a href="shading.html" target="MainFrame">Shading Language</a>
+<li><a href="glu.html" target="MainFrame">SGI's GLU</a>
<li><a href="utilities.html" target="MainFrame">Utilities</a>
<li><a href="helpwanted.html" target="MainFrame">Help Wanted</a>
<li><a href="devinfo.html" target="MainFrame">Development Notes</a>
diff --git a/docs/dispatch.html b/docs/dispatch.html
index b9ea8822e6..bcab74c707 100644
--- a/docs/dispatch.html
+++ b/docs/dispatch.html
@@ -198,7 +198,7 @@ few preprocessor defines.</p>
<ul>
<li>If <tt>GLX_USE_TLS</tt> is defined, method #4 is used.</li>
<li>If <tt>PTHREADS</tt> is defined, method #3 is used.</li>
-<li>If any of <tt>PTHREADS</tt>, <tt>USE_XTHREADS</tt>,
+<li>If any of <tt>PTHREADS</tt>,
<tt>SOLARIS_THREADS</tt>, <tt>WIN32_THREADS</tt>, or <tt>BEOS_THREADS</tt>
is defined, method #2 is used.</li>
<li>If none of the preceeding are defined, method #1 is used.</li>
diff --git a/docs/download.html b/docs/download.html
index cf1cc21d37..3cb9423dd9 100644
--- a/docs/download.html
+++ b/docs/download.html
@@ -9,14 +9,14 @@
<H1>Downloading</H1>
<p>
-Primary download site:
-<a href="http://sourceforge.net/project/showfiles.php?group_id=3"
-target="_parent">SourceForge</a>
+Primary Mesa download site:
+<a href="ftp://ftp.freedesktop.org/pub/mesa/"
+target="_parent">freedesktop.org</a> (FTP)
</p>
<p>
-When a new release is coming, release candidates (betas) can be found
-<a href="http://www.mesa3d.org/beta/">here</a>.
+When a new release is coming, release candidates (betas) may be found
+<a href="ftp://ftp.freedesktop.org/pub/mesa/beta/" target="_parent">here</a>.
</p>
diff --git a/docs/faq.html b/docs/faq.html
index 11b5d43255..65e279aac5 100644
--- a/docs/faq.html
+++ b/docs/faq.html
@@ -316,6 +316,19 @@ Basically, applying a translation of (0.375, 0.375, 0.0) to your coordinates
will fix the problem.
</p>
+<h2>3.6 How can I change the maximum framebuffer size in Mesa's
+<tt>swrast</tt> backend?</h2>
+<p>
+These can be overridden by using the <tt>--with-max-width</tt> and
+<tt>--with-max-height</tt> options. The two need not be equal.
+</p><p>
+Do note that Mesa uses these values to size some internal buffers,
+so increasing these sizes will cause Mesa to require additional
+memory. Furthermore, increasing these limits beyond <tt>4096</tt>
+may introduce rasterization artifacts; see the leading comments in
+<tt>src/mesa/swrast/s_tritemp.h</tt>.
+</p>
+
<br>
<br>
diff --git a/docs/news.html b/docs/news.html
index 712ecedc10..07ad42ed49 100644
--- a/docs/news.html
+++ b/docs/news.html
@@ -11,6 +11,13 @@
<H1>News</H1>
+<h2>September 3, 2009</h2>
+<p>
+<a href="relnotes-7.5.1.html">Mesa 7.5.1</a> is released.
+This is a bug-fix release which fixes bugs found in version 7.5.
+</p>
+
+
<h2>July 17, 2009</h2>
<p>
<a href="relnotes-7.5.html">Mesa 7.5</a> is released.
diff --git a/docs/precompiled.html b/docs/precompiled.html
index 166d33d828..50cb2af60d 100644
--- a/docs/precompiled.html
+++ b/docs/precompiled.html
@@ -9,17 +9,11 @@
<H1>Precompiled Libraries</H1>
<p>
-In general, precompiled libraries are not available.
-However, people occasionally prepare packages of precompiled libraries
-for some systems.
+In general, precompiled Mesa libraries are not available.
</p>
-
-<H2>Mesa-6.0 for Solaris</H2>
-
<p>
-Steve Christensen has submitted precompiled Mesa-6.0 libraries for
-Solaris at <a href="http://sunfreeware.com/" target="_parent">
-sunfreeware.com</a>.
+However, some Linux distros (such as Ubuntu) seem to closely track
+Mesa and often have the latest Mesa release available as an update.
</p>
</BODY>
diff --git a/docs/relnotes-7.5.1.html b/docs/relnotes-7.5.1.html
new file mode 100644
index 0000000000..1a4f608b7c
--- /dev/null
+++ b/docs/relnotes-7.5.1.html
@@ -0,0 +1,72 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.5.1 Release Notes, 3 September 2009</H1>
+
+<p>
+Mesa 7.5.1 is a bug-fix release fixing issues found since the 7.5 release.
+</p>
+<p>
+The main new feature of Mesa 7.5.x is the
+<a href="http://wiki.freedesktop.org/wiki/Software/gallium"
+target="_parent">Gallium3D</a> infrastructure.
+</p>
+<p>
+Mesa 7.5.1 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+d7269e93bc7484430637d54ced250876 MesaLib-7.5.1.tar.gz
+877d6a4b24efc2b1d02aa553f262cba8 MesaLib-7.5.1.tar.bz2
+23f4fb757a05c8396425681234ae20e5 MesaLib-7.5.1.zip
+5af4bd113652108f5cec5113dad813f2 MesaDemos-7.5.1.tar.gz
+785402e3b9f0e335538fcc6bf19f6987 MesaDemos-7.5.1.tar.bz2
+950058cc6d6106e9c7d5876a03789fe9 MesaDemos-7.5.1.zip
+cb52ce2c93389c2711cbe8d857ec5303 MesaGLUT-7.5.1.tar.gz
+e3a9892e056d625c5353617a7c5b7e9c MesaGLUT-7.5.1.tar.bz2
+da1de364df148c94b4994006191a1e69 MesaGLUT-7.5.1.zip
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<li>Added configure --with-max-width=W, --with-max-height=H options to specify
+ max framebuffer, viewport size.
+</ul>
+
+
+<h2>Bug fixes</h2>
+<ul>
+<li>Added missing GLEW library to MesaDemos tarballs.
+<li>Fixed swapbuffers jerkiness in Doom3/etc in Intel drivers.
+<li>Fixed front buffer rendering bug in Intel drivers.
+<li>Fixed minor GLX memory leaks.
+<li>Fixed some texture env / fragment program state bugs.
+<li>Fixed some Gallium glBlitFramebuffer() bugs
+<li>Empty glBegin/glEnd() pair could cause divide by zero (bug 23489)
+<li>Fixed Gallium glBitmap() Z position bug
+<li>Setting arrays of sampler uniforms did not work
+<li>Selection/Feedback mode didn't handle polygon culling correctly (bug 16866)
+<li>Fixed 32/64-bit cross compilation issue in gen_matypes.c
+<li>Fixed glXCreateGLXPixmap() for direct rendering.
+<li>Fixed Gallium glCopyPixels(GL_STENCIL_INDEX) mispositioned image bug.
+</ul>
+
+
+</body>
+</html>
diff --git a/docs/relnotes-7.5.2.html b/docs/relnotes-7.5.2.html
new file mode 100644
index 0000000000..b638c0517d
--- /dev/null
+++ b/docs/relnotes-7.5.2.html
@@ -0,0 +1,56 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.5.2 Release Notes, (date tbd)</H1>
+
+<p>
+Mesa 7.5.2 is a bug-fix release fixing issues found since the 7.5.1 release.
+</p>
+<p>
+The main new feature of Mesa 7.5.x is the
+<a href="http://wiki.freedesktop.org/wiki/Software/gallium"
+target="_parent">Gallium3D</a> infrastructure.
+</p>
+<p>
+Mesa 7.5.2 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+tbd
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<li>Detect B43 chipset in Intel driver
+</ul>
+
+
+<h2>Bug fixes</h2>
+<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>
+
+
+</body>
+</html>
diff --git a/docs/relnotes-7.5.html b/docs/relnotes-7.5.html
index 8bcacd62e1..56deca6a86 100644
--- a/docs/relnotes-7.5.html
+++ b/docs/relnotes-7.5.html
@@ -40,7 +40,15 @@ If you're especially concerned with stability you should probably look for
<h2>MD5 checksums</h2>
<pre>
-tbd
+553fd956e544727f30fbe249619b6286 MesaLib-7.5.tar.gz
+459f332551f6ebb86f384d21dd15e1f0 MesaLib-7.5.tar.bz2
+8c02c0e17a9025250d20424ae32f5163 MesaLib-7.5.zip
+a188da2886fa5496ea0c2cda602b2eeb MesaDemos-7.5.tar.gz
+398ee8801814a00e47f6c2314e3dfddc MesaDemos-7.5.tar.bz2
+15a0c8ae013c54335a26335e1a98d609 MesaDemos-7.5.zip
+81010147def5a644ba14f9bbb7a49a2a MesaGLUT-7.5.tar.gz
+baa7a1e850b6e39bae58868fd0684004 MesaGLUT-7.5.tar.bz2
+265228418e4423fa328f2f5b7970cf08 MesaGLUT-7.5.zip
</pre>
diff --git a/docs/relnotes-7.6.html b/docs/relnotes-7.6.html
index 1e7ccf88bf..aaa36188d9 100644
--- a/docs/relnotes-7.6.html
+++ b/docs/relnotes-7.6.html
@@ -36,16 +36,33 @@ tbd
<ul>
<li><a href="openvg.html">OpenVG</a> front-end (state tracker for Gallium).
This was written by Zack Rusin at Tungsten Graphics.
-<li>GL_APPLE_vertex_array_object for Gallium drivers and Intel DRI drivers.
-<li>GL_ARB_vertex_array_object for Gallium drivers, software drivers and
- Intel DRI drivers.
-<li>GL_ARB_copy_buffer extension (supported in Gallium and swrast drivers)
-<LI>GL_ARB_map_buffer_range extension (supported in Gallium and software drivers)
-<li>GL_EXT_provoking_vertex extension (supported in Gallium and software drivers)
+<li>GL_ARB_vertex_array_object and GL_APPLE_vertex_array_object extensions
+ (supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
+<li>GL_ARB_copy_buffer extension
+ (supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
+<li>GL_ARB_map_buffer_range extension
+ (supported in Gallium drivers, Intel DRI drivers, and software drivers)</li>
+<li>GL_ARB_seamless_cube_map extension
+ (supported in software drivers and i965 drivers)</li>
+<li>GL_ARB_vertex_array_bgra (ARB synonym for GL_EXT_vertex_array_bgra)</li>
+<li>GL_ARB_sync (supported in software drivers and Intel DRI drivers)</li>
+<li>GL_EXT_provoking_vertex extension (supported in Gallium, i915, i965, and software drivers)
<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
+<li>Rewritten assembler for GL_ARB_vertex_program /
+ 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
new file mode 100644
index 0000000000..ca6ec55b60
--- /dev/null
+++ b/docs/relnotes-7.7.html
@@ -0,0 +1,54 @@
+<HTML>
+
+<TITLE>Mesa Release Notes</TITLE>
+
+<head><link rel="stylesheet" type="text/css" href="mesa.css"></head>
+
+<BODY>
+
+<body bgcolor="#eeeeee">
+
+<H1>Mesa 7.7 Release Notes / date TBD</H1>
+
+<p>
+Mesa 7.7 is a new development release.
+People who are concerned with stability and reliability should stick
+with a previous release or wait for Mesa 7.7.1.
+</p>
+<p>
+Mesa 7.7 implements the OpenGL 2.1 API, but the version reported by
+glGetString(GL_VERSION) depends on the particular driver being used.
+Some drivers don't support all the features required in OpenGL 2.1.
+</p>
+<p>
+See the <a href="install.html">Compiling/Installing page</a> for prerequisites
+for DRI hardware acceleration.
+</p>
+
+
+<h2>MD5 checksums</h2>
+<pre>
+tbd
+</pre>
+
+
+<h2>New features</h2>
+<ul>
+<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>
+
+
+<h2>Bug fixes</h2>
+<ul>
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+</ul>
+
+</body>
+</html>
diff --git a/docs/relnotes.html b/docs/relnotes.html
index 35a4c7385f..7a87f58a82 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -13,7 +13,10 @@ The release notes summarize what's new or changed in each Mesa release.
</p>
<UL>
+<LI><A HREF="relnotes-7.7.html">7.7 release notes</A>
<LI><A HREF="relnotes-7.6.html">7.6 release notes</A>
+<LI><A HREF="relnotes-7.5.2.html">7.5.2 release notes</A>
+<LI><A HREF="relnotes-7.5.1.html">7.5.1 release notes</A>
<LI><A HREF="relnotes-7.5.html">7.5 release notes</A>
<LI><A HREF="relnotes-7.4.4.html">7.4.4 release notes</A>
<LI><A HREF="relnotes-7.4.3.html">7.4.3 release notes</A>
diff --git a/include/EGL/eglplatform.h b/include/EGL/eglplatform.h
index 83e89cd704..9e83b60003 100644
--- a/include/EGL/eglplatform.h
+++ b/include/EGL/eglplatform.h
@@ -69,7 +69,8 @@ typedef HWND NativeWindowType;
typedef HBITMAP NativePixmapType;
/** END Added for Windows **/
-#elif defined(__gnu_linux__) || defined(__FreeBSD__) || defined(__sun)
+#elif defined(__gnu_linux__) || defined(__FreeBSD__) || defined(__sun) || defined(__APPLE__)
+
/** BEGIN Added for X (Mesa) **/
#ifndef EGLAPI
diff --git a/include/GL/gl.h b/include/GL/gl.h
index 05362b9776..5f8bc2b708 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/include/GL/glext.h b/include/GL/glext.h
index 5429287d3f..24e6c5dc80 100644
--- a/include/GL/glext.h
+++ b/include/GL/glext.h
@@ -29,9 +29,9 @@ extern "C" {
*/
/* Header file version number, required by OpenGL ABI for Linux */
-/* glext.h last updated $Date: 2009-05-05 15:27:42 -0700 (Tue, 05 May 2009) $ */
+/* glext.h last updated $Date: 2009-08-03 02:13:51 -0700 (Mon, 03 Aug 2009) $ */
/* Current version at http://www.opengl.org/registry/ */
-#define GL_GLEXT_VERSION 52
+#define GL_GLEXT_VERSION 54
/* Function declaration macros - to move into glplatform.h */
@@ -510,6 +510,8 @@ extern "C" {
#define GL_CLIP_DISTANCE3 0x3003
#define GL_CLIP_DISTANCE4 0x3004
#define GL_CLIP_DISTANCE5 0x3005
+#define GL_CLIP_DISTANCE6 0x3006
+#define GL_CLIP_DISTANCE7 0x3007
#define GL_MAX_CLIP_DISTANCES 0x0D32
#define GL_MAJOR_VERSION 0x821B
#define GL_MINOR_VERSION 0x821C
@@ -600,6 +602,9 @@ extern "C" {
#define GL_QUERY_NO_WAIT 0x8E14
#define GL_QUERY_BY_REGION_WAIT 0x8E15
#define GL_QUERY_BY_REGION_NO_WAIT 0x8E16
+#define GL_BUFFER_ACCESS_FLAGS 0x911F
+#define GL_BUFFER_MAP_LENGTH 0x9120
+#define GL_BUFFER_MAP_OFFSET 0x9121
/* Reuse tokens from ARB_depth_buffer_float */
/* reuse GL_DEPTH_COMPONENT32F */
/* reuse GL_DEPTH32F_STENCIL8 */
@@ -804,6 +809,84 @@ extern "C" {
/* reuse GL_INVALID_INDEX */
#endif
+#ifndef GL_VERSION_3_2
+#define GL_CONTEXT_CORE_PROFILE_BIT 0x00000001
+#define GL_CONTEXT_COMPATIBILITY_PROFILE_BIT 0x00000002
+#define GL_LINES_ADJACENCY 0x000A
+#define GL_LINE_STRIP_ADJACENCY 0x000B
+#define GL_TRIANGLES_ADJACENCY 0x000C
+#define GL_TRIANGLE_STRIP_ADJACENCY 0x000D
+#define GL_PROGRAM_POINT_SIZE 0x8642
+#define GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS 0x8C29
+#define GL_FRAMEBUFFER_ATTACHMENT_LAYERED 0x8DA7
+#define GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS 0x8DA8
+#define GL_GEOMETRY_SHADER 0x8DD9
+#define GL_GEOMETRY_VERTICES_OUT 0x8916
+#define GL_GEOMETRY_INPUT_TYPE 0x8917
+#define GL_GEOMETRY_OUTPUT_TYPE 0x8918
+#define GL_MAX_GEOMETRY_UNIFORM_COMPONENTS 0x8DDF
+#define GL_MAX_GEOMETRY_OUTPUT_VERTICES 0x8DE0
+#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS 0x8DE1
+#define GL_MAX_VERTEX_OUTPUT_COMPONENTS 0x9122
+#define GL_MAX_GEOMETRY_INPUT_COMPONENTS 0x9123
+#define GL_MAX_GEOMETRY_OUTPUT_COMPONENTS 0x9124
+#define GL_MAX_FRAGMENT_INPUT_COMPONENTS 0x9125
+#define GL_CONTEXT_PROFILE_MASK 0x9126
+/* reuse GL_MAX_VARYING_COMPONENTS */
+/* reuse GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
+/* Reuse tokens from ARB_depth_clamp */
+/* reuse GL_DEPTH_CLAMP */
+/* Would reuse tokens from ARB_draw_elements_base_vertex, but it has none */
+/* Would reuse tokens from ARB_fragment_coord_conventions, but it has none */
+/* Reuse tokens from ARB_provoking_vertex */
+/* reuse GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION */
+/* reuse GL_FIRST_VERTEX_CONVENTION */
+/* reuse GL_LAST_VERTEX_CONVENTION */
+/* reuse GL_PROVOKING_VERTEX */
+/* Reuse tokens from ARB_seamless_cube_map */
+/* reuse GL_TEXTURE_CUBE_MAP_SEAMLESS */
+/* Reuse tokens from ARB_sync */
+/* reuse GL_MAX_SERVER_WAIT_TIMEOUT */
+/* reuse GL_OBJECT_TYPE */
+/* reuse GL_SYNC_CONDITION */
+/* reuse GL_SYNC_STATUS */
+/* reuse GL_SYNC_FLAGS */
+/* reuse GL_SYNC_FENCE */
+/* reuse GL_SYNC_GPU_COMMANDS_COMPLETE */
+/* reuse GL_UNSIGNALED */
+/* reuse GL_SIGNALED */
+/* reuse GL_ALREADY_SIGNALED */
+/* reuse GL_TIMEOUT_EXPIRED */
+/* reuse GL_CONDITION_SATISFIED */
+/* reuse GL_WAIT_FAILED */
+/* reuse GL_TIMEOUT_IGNORED */
+/* reuse GL_SYNC_FLUSH_COMMANDS_BIT */
+/* reuse GL_TIMEOUT_IGNORED */
+/* Reuse tokens from ARB_texture_multisample */
+/* reuse GL_SAMPLE_POSITION */
+/* reuse GL_SAMPLE_MASK */
+/* reuse GL_SAMPLE_MASK_VALUE */
+/* reuse GL_MAX_SAMPLE_MASK_WORDS */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE */
+/* reuse GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_TEXTURE_SAMPLES */
+/* reuse GL_TEXTURE_FIXED_SAMPLE_LOCATIONS */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE */
+/* reuse GL_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY */
+/* reuse GL_MAX_COLOR_TEXTURE_SAMPLES */
+/* reuse GL_MAX_DEPTH_TEXTURE_SAMPLES */
+/* reuse GL_MAX_INTEGER_SAMPLES */
+/* Don't need to reuse tokens from ARB_vertex_array_bgra since they're already in 1.2 core */
+#endif
+
#ifndef GL_ARB_multitexture
#define GL_TEXTURE0_ARB 0x84C0
#define GL_TEXTURE1_ARB 0x84C1
@@ -1530,6 +1613,100 @@ extern "C" {
#ifndef GL_ARB_shader_texture_lod
#endif
+#ifndef GL_ARB_depth_clamp
+#define GL_DEPTH_CLAMP 0x864F
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION 0x8E4C
+#define GL_FIRST_VERTEX_CONVENTION 0x8E4D
+#define GL_LAST_VERTEX_CONVENTION 0x8E4E
+#define GL_PROVOKING_VERTEX 0x8E4F
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_MAX_SERVER_WAIT_TIMEOUT 0x9111
+#define GL_OBJECT_TYPE 0x9112
+#define GL_SYNC_CONDITION 0x9113
+#define GL_SYNC_STATUS 0x9114
+#define GL_SYNC_FLAGS 0x9115
+#define GL_SYNC_FENCE 0x9116
+#define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117
+#define GL_UNSIGNALED 0x9118
+#define GL_SIGNALED 0x9119
+#define GL_ALREADY_SIGNALED 0x911A
+#define GL_TIMEOUT_EXPIRED 0x911B
+#define GL_CONDITION_SATISFIED 0x911C
+#define GL_WAIT_FAILED 0x911D
+#define GL_SYNC_FLUSH_COMMANDS_BIT 0x00000001
+#define GL_TIMEOUT_IGNORED 0xFFFFFFFFFFFFFFFFull
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_SAMPLE_POSITION 0x8E50
+#define GL_SAMPLE_MASK 0x8E51
+#define GL_SAMPLE_MASK_VALUE 0x8E52
+#define GL_MAX_SAMPLE_MASK_WORDS 0x8E59
+#define GL_TEXTURE_2D_MULTISAMPLE 0x9100
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE 0x9101
+#define GL_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9102
+#define GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY 0x9103
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE 0x9104
+#define GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY 0x9105
+#define GL_TEXTURE_SAMPLES 0x9106
+#define GL_TEXTURE_FIXED_SAMPLE_LOCATIONS 0x9107
+#define GL_SAMPLER_2D_MULTISAMPLE 0x9108
+#define GL_INT_SAMPLER_2D_MULTISAMPLE 0x9109
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE 0x910A
+#define GL_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910B
+#define GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910C
+#define GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY 0x910D
+#define GL_MAX_COLOR_TEXTURE_SAMPLES 0x910E
+#define GL_MAX_DEPTH_TEXTURE_SAMPLES 0x910F
+#define GL_MAX_INTEGER_SAMPLES 0x9110
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+/* reuse GL_BGRA */
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_SAMPLE_SHADING 0x8C36
+#define GL_MIN_SAMPLE_SHADING_VALUE 0x8C37
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_TEXTURE_CUBE_MAP_ARRAY 0x9009
+#define GL_TEXTURE_BINDING_CUBE_MAP_ARRAY 0x900A
+#define GL_PROXY_TEXTURE_CUBE_MAP_ARRAY 0x900B
+#define GL_SAMPLER_CUBE_MAP_ARRAY 0x900C
+#define GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW 0x900D
+#define GL_INT_SAMPLER_CUBE_MAP_ARRAY 0x900E
+#define GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY 0x900F
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5E
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET 0x8E5F
+#define GL_MAX_PROGRAM_TEXTURE_GATHER_COMPONENTS 0x8F9F
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#endif
+
#ifndef GL_EXT_abgr
#define GL_ABGR_EXT 0x8000
#endif
@@ -3996,11 +4173,11 @@ extern "C" {
#define GL_SAMPLE_MASK_VALUE_NV 0x8E52
#define GL_TEXTURE_BINDING_RENDERBUFFER_NV 0x8E53
#define GL_TEXTURE_RENDERBUFFER_DATA_STORE_BINDING_NV 0x8E54
-#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
#define GL_TEXTURE_RENDERBUFFER_NV 0x8E55
#define GL_SAMPLER_RENDERBUFFER_NV 0x8E56
#define GL_INT_SAMPLER_RENDERBUFFER_NV 0x8E57
#define GL_UNSIGNED_INT_SAMPLER_RENDERBUFFER_NV 0x8E58
+#define GL_MAX_SAMPLE_MASK_WORDS_NV 0x8E59
#endif
#ifndef GL_NV_transform_feedback2
@@ -4046,6 +4223,94 @@ extern "C" {
#define GL_PROVOKING_VERTEX_EXT 0x8E4F
#endif
+#ifndef GL_EXT_texture_snorm
+#define GL_ALPHA_SNORM 0x9010
+#define GL_LUMINANCE_SNORM 0x9011
+#define GL_LUMINANCE_ALPHA_SNORM 0x9012
+#define GL_INTENSITY_SNORM 0x9013
+#define GL_ALPHA8_SNORM 0x9014
+#define GL_LUMINANCE8_SNORM 0x9015
+#define GL_LUMINANCE8_ALPHA8_SNORM 0x9016
+#define GL_INTENSITY8_SNORM 0x9017
+#define GL_ALPHA16_SNORM 0x9018
+#define GL_LUMINANCE16_SNORM 0x9019
+#define GL_LUMINANCE16_ALPHA16_SNORM 0x901A
+#define GL_INTENSITY16_SNORM 0x901B
+/* reuse GL_R_SNORM */
+/* reuse GL_RG_SNORM */
+/* reuse GL_RGB_SNORM */
+/* reuse GL_RGBA_SNORM */
+/* reuse GL_R8_SNORM */
+/* reuse GL_RG8_SNORM */
+/* reuse GL_RGB8_SNORM */
+/* reuse GL_RGBA8_SNORM */
+/* reuse GL_R16_SNORM */
+/* reuse GL_RG16_SNORM */
+/* reuse GL_RGB16_SNORM */
+/* reuse GL_RGBA16_SNORM */
+/* reuse GL_SIGNED_NORMALIZED */
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_TEXTURE_RANGE_LENGTH_APPLE 0x85B7
+#define GL_TEXTURE_RANGE_POINTER_APPLE 0x85B8
+#define GL_TEXTURE_STORAGE_HINT_APPLE 0x85BC
+#define GL_STORAGE_PRIVATE_APPLE 0x85BD
+/* reuse GL_STORAGE_CACHED_APPLE */
+/* reuse GL_STORAGE_SHARED_APPLE */
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_HALF_APPLE 0x140B
+#define GL_RGBA_FLOAT32_APPLE 0x8814
+#define GL_RGB_FLOAT32_APPLE 0x8815
+#define GL_ALPHA_FLOAT32_APPLE 0x8816
+#define GL_INTENSITY_FLOAT32_APPLE 0x8817
+#define GL_LUMINANCE_FLOAT32_APPLE 0x8818
+#define GL_LUMINANCE_ALPHA_FLOAT32_APPLE 0x8819
+#define GL_RGBA_FLOAT16_APPLE 0x881A
+#define GL_RGB_FLOAT16_APPLE 0x881B
+#define GL_ALPHA_FLOAT16_APPLE 0x881C
+#define GL_INTENSITY_FLOAT16_APPLE 0x881D
+#define GL_LUMINANCE_FLOAT16_APPLE 0x881E
+#define GL_LUMINANCE_ALPHA_FLOAT16_APPLE 0x881F
+#define GL_COLOR_FLOAT_APPLE 0x8A0F
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_VERTEX_ATTRIB_MAP1_APPLE 0x8A00
+#define GL_VERTEX_ATTRIB_MAP2_APPLE 0x8A01
+#define GL_VERTEX_ATTRIB_MAP1_SIZE_APPLE 0x8A02
+#define GL_VERTEX_ATTRIB_MAP1_COEFF_APPLE 0x8A03
+#define GL_VERTEX_ATTRIB_MAP1_ORDER_APPLE 0x8A04
+#define GL_VERTEX_ATTRIB_MAP1_DOMAIN_APPLE 0x8A05
+#define GL_VERTEX_ATTRIB_MAP2_SIZE_APPLE 0x8A06
+#define GL_VERTEX_ATTRIB_MAP2_COEFF_APPLE 0x8A07
+#define GL_VERTEX_ATTRIB_MAP2_ORDER_APPLE 0x8A08
+#define GL_VERTEX_ATTRIB_MAP2_DOMAIN_APPLE 0x8A09
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_AUX_DEPTH_STENCIL_APPLE 0x8A14
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_BUFFER_OBJECT_APPLE 0x85B3
+#define GL_RELEASED_APPLE 0x8A19
+#define GL_VOLATILE_APPLE 0x8A1A
+#define GL_RETAINED_APPLE 0x8A1B
+#define GL_UNDEFINED_APPLE 0x8A1C
+#define GL_PURGEABLE_APPLE 0x8A1D
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_PACK_ROW_BYTES_APPLE 0x8A15
+#define GL_UNPACK_ROW_BYTES_APPLE 0x8A16
+#endif
+
/*************************************************************/
@@ -4125,6 +4390,12 @@ typedef int64_t GLint64EXT;
typedef uint64_t GLuint64EXT;
#endif
+#ifndef ARB_sync
+typedef int64_t GLint64;
+typedef uint64_t GLuint64;
+typedef struct __GLsync *GLsync;
+#endif
+
#ifndef GL_VERSION_1_2
#define GL_VERSION_1_2 1
#ifdef GL_GLEXT_PROTOTYPES
@@ -4698,6 +4969,26 @@ GLAPI void APIENTRY glEndConditionalRender (void);
GLAPI void APIENTRY glVertexAttribIPointer (GLuint, GLint, GLenum, GLsizei, const GLvoid *);
GLAPI void APIENTRY glGetVertexAttribIiv (GLuint, GLenum, GLint *);
GLAPI void APIENTRY glGetVertexAttribIuiv (GLuint, GLenum, GLuint *);
+GLAPI void APIENTRY glVertexAttribI1i (GLuint, GLint);
+GLAPI void APIENTRY glVertexAttribI2i (GLuint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI3i (GLuint, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI4i (GLuint, GLint, GLint, GLint, GLint);
+GLAPI void APIENTRY glVertexAttribI1ui (GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI2ui (GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI3ui (GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI4ui (GLuint, GLuint, GLuint, GLuint, GLuint);
+GLAPI void APIENTRY glVertexAttribI1iv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI2iv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI3iv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI4iv (GLuint, const GLint *);
+GLAPI void APIENTRY glVertexAttribI1uiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI2uiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI3uiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI4uiv (GLuint, const GLuint *);
+GLAPI void APIENTRY glVertexAttribI4bv (GLuint, const GLbyte *);
+GLAPI void APIENTRY glVertexAttribI4sv (GLuint, const GLshort *);
+GLAPI void APIENTRY glVertexAttribI4ubv (GLuint, const GLubyte *);
+GLAPI void APIENTRY glVertexAttribI4usv (GLuint, const GLushort *);
GLAPI void APIENTRY glGetUniformuiv (GLuint, GLint, GLuint *);
GLAPI void APIENTRY glBindFragDataLocation (GLuint, GLuint, const GLchar *);
GLAPI GLint APIENTRY glGetFragDataLocation (GLuint, const GLchar *);
@@ -4737,52 +5028,6 @@ typedef void (APIENTRYP PFNGLENDCONDITIONALRENDERPROC) (void);
typedef void (APIENTRYP PFNGLVERTEXATTRIBIPOINTERPROC) (GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid *pointer);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIIVPROC) (GLuint index, GLenum pname, GLint *params);
typedef void (APIENTRYP PFNGLGETVERTEXATTRIBIUIVPROC) (GLuint index, GLenum pname, GLuint *params);
-typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
-typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
-typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
-typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
-typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
-typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
-typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
-typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
-typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
-typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
-typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
-typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
-typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
-typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
-typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
-typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
-typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
-typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
-typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
-typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
-#endif
-
-#ifndef GL_VERSION_3_0_DEPRECATED
-#define GL_VERSION_3_0_DEPRECATED 1
-#ifdef GL_GLEXT_PROTOTYPES
-GLAPI void APIENTRY glVertexAttribI1i (GLuint, GLint);
-GLAPI void APIENTRY glVertexAttribI2i (GLuint, GLint, GLint);
-GLAPI void APIENTRY glVertexAttribI3i (GLuint, GLint, GLint, GLint);
-GLAPI void APIENTRY glVertexAttribI4i (GLuint, GLint, GLint, GLint, GLint);
-GLAPI void APIENTRY glVertexAttribI1ui (GLuint, GLuint);
-GLAPI void APIENTRY glVertexAttribI2ui (GLuint, GLuint, GLuint);
-GLAPI void APIENTRY glVertexAttribI3ui (GLuint, GLuint, GLuint, GLuint);
-GLAPI void APIENTRY glVertexAttribI4ui (GLuint, GLuint, GLuint, GLuint, GLuint);
-GLAPI void APIENTRY glVertexAttribI1iv (GLuint, const GLint *);
-GLAPI void APIENTRY glVertexAttribI2iv (GLuint, const GLint *);
-GLAPI void APIENTRY glVertexAttribI3iv (GLuint, const GLint *);
-GLAPI void APIENTRY glVertexAttribI4iv (GLuint, const GLint *);
-GLAPI void APIENTRY glVertexAttribI1uiv (GLuint, const GLuint *);
-GLAPI void APIENTRY glVertexAttribI2uiv (GLuint, const GLuint *);
-GLAPI void APIENTRY glVertexAttribI3uiv (GLuint, const GLuint *);
-GLAPI void APIENTRY glVertexAttribI4uiv (GLuint, const GLuint *);
-GLAPI void APIENTRY glVertexAttribI4bv (GLuint, const GLbyte *);
-GLAPI void APIENTRY glVertexAttribI4sv (GLuint, const GLshort *);
-GLAPI void APIENTRY glVertexAttribI4ubv (GLuint, const GLubyte *);
-GLAPI void APIENTRY glVertexAttribI4usv (GLuint, const GLushort *);
-#endif /* GL_GLEXT_PROTOTYPES */
typedef void (APIENTRYP PFNGLVERTEXATTRIBI1IPROC) (GLuint index, GLint x);
typedef void (APIENTRYP PFNGLVERTEXATTRIBI2IPROC) (GLuint index, GLint x, GLint y);
typedef void (APIENTRYP PFNGLVERTEXATTRIBI3IPROC) (GLuint index, GLint x, GLint y, GLint z);
@@ -4803,6 +5048,26 @@ typedef void (APIENTRYP PFNGLVERTEXATTRIBI4BVPROC) (GLuint index, const GLbyte *
typedef void (APIENTRYP PFNGLVERTEXATTRIBI4SVPROC) (GLuint index, const GLshort *v);
typedef void (APIENTRYP PFNGLVERTEXATTRIBI4UBVPROC) (GLuint index, const GLubyte *v);
typedef void (APIENTRYP PFNGLVERTEXATTRIBI4USVPROC) (GLuint index, const GLushort *v);
+typedef void (APIENTRYP PFNGLGETUNIFORMUIVPROC) (GLuint program, GLint location, GLuint *params);
+typedef void (APIENTRYP PFNGLBINDFRAGDATALOCATIONPROC) (GLuint program, GLuint color, const GLchar *name);
+typedef GLint (APIENTRYP PFNGLGETFRAGDATALOCATIONPROC) (GLuint program, const GLchar *name);
+typedef void (APIENTRYP PFNGLUNIFORM1UIPROC) (GLint location, GLuint v0);
+typedef void (APIENTRYP PFNGLUNIFORM2UIPROC) (GLint location, GLuint v0, GLuint v1);
+typedef void (APIENTRYP PFNGLUNIFORM3UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2);
+typedef void (APIENTRYP PFNGLUNIFORM4UIPROC) (GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3);
+typedef void (APIENTRYP PFNGLUNIFORM1UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM2UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM3UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLUNIFORM4UIVPROC) (GLint location, GLsizei count, const GLuint *value);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, const GLint *params);
+typedef void (APIENTRYP PFNGLTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, const GLuint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIIVPROC) (GLenum target, GLenum pname, GLint *params);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERIUIVPROC) (GLenum target, GLenum pname, GLuint *params);
+typedef void (APIENTRYP PFNGLCLEARBUFFERIVPROC) (GLenum buffer, GLint drawbuffer, const GLint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERUIVPROC) (GLenum buffer, GLint drawbuffer, const GLuint *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFVPROC) (GLenum buffer, GLint drawbuffer, const GLfloat *value);
+typedef void (APIENTRYP PFNGLCLEARBUFFERFIPROC) (GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
+typedef const GLubyte * (APIENTRYP PFNGLGETSTRINGIPROC) (GLenum name, GLuint index);
#endif
#ifndef GL_VERSION_3_1
@@ -4822,6 +5087,27 @@ typedef void (APIENTRYP PFNGLTEXBUFFERPROC) (GLenum target, GLenum internalforma
typedef void (APIENTRYP PFNGLPRIMITIVERESTARTINDEXPROC) (GLuint index);
#endif
+#ifndef GL_VERSION_3_2
+#define GL_VERSION_3_2 1
+/* OpenGL 3.2 also reuses entry points from these extensions: */
+/* ARB_draw_elements_base_vertex */
+/* ARB_provoking_vertex */
+/* ARB_sync */
+/* ARB_texture_multisample */
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glGetInteger64i_v (GLenum, GLuint, GLint64 *);
+GLAPI void APIENTRY glGetBufferParameteri64v (GLenum, GLenum, GLint64 *);
+GLAPI void APIENTRY glProgramParameteri (GLuint, GLenum, GLint);
+GLAPI void APIENTRY glFramebufferTexture (GLenum, GLenum, GLuint, GLint);
+GLAPI void APIENTRY glFramebufferTextureFace (GLenum, GLenum, GLuint, GLint, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLGETINTEGER64I_VPROC) (GLenum target, GLuint index, GLint64 *data);
+typedef void (APIENTRYP PFNGLGETBUFFERPARAMETERI64VPROC) (GLenum target, GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLPROGRAMPARAMETERIPROC) (GLuint program, GLenum pname, GLint value);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level);
+typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTUREFACEPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLenum face);
+#endif
+
#ifndef GL_ARB_multitexture
#define GL_ARB_multitexture 1
#ifdef GL_GLEXT_PROTOTYPES
@@ -5567,6 +5853,112 @@ typedef void (APIENTRYP PFNGLCOPYBUFFERSUBDATAPROC) (GLenum readTarget, GLenum w
#define GL_ARB_shader_texture_lod 1
#endif
+#ifndef GL_ARB_depth_clamp
+#define GL_ARB_depth_clamp 1
+#endif
+
+#ifndef GL_ARB_draw_elements_base_vertex
+#define GL_ARB_draw_elements_base_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glDrawElementsBaseVertex (GLenum, GLsizei, GLenum, const GLvoid *, GLint);
+GLAPI void APIENTRY glDrawRangeElementsBaseVertex (GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint);
+GLAPI void APIENTRY glDrawElementsInstancedBaseVertex (GLenum, GLsizei, GLenum, const GLvoid *, GLsizei, GLint);
+GLAPI void APIENTRY glMultiDrawElementsBaseVertex (GLenum, const GLsizei *, GLenum, const GLvoid* *, GLsizei, const GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex);
+typedef void (APIENTRYP PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) (GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei primcount, GLint basevertex);
+typedef void (APIENTRYP PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) (GLenum mode, const GLsizei *count, GLenum type, const GLvoid* *indices, GLsizei primcount, const GLint *basevertex);
+#endif
+
+#ifndef GL_ARB_fragment_coord_conventions
+#define GL_ARB_fragment_coord_conventions 1
+#endif
+
+#ifndef GL_ARB_provoking_vertex
+#define GL_ARB_provoking_vertex 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glProvokingVertex (GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLPROVOKINGVERTEXPROC) (GLenum mode);
+#endif
+
+#ifndef GL_ARB_seamless_cube_map
+#define GL_ARB_seamless_cube_map 1
+#endif
+
+#ifndef GL_ARB_sync
+#define GL_ARB_sync 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLsync APIENTRY glFenceSync (GLenum, GLbitfield);
+GLAPI GLboolean APIENTRY glIsSync (GLsync);
+GLAPI void APIENTRY glDeleteSync (GLsync);
+GLAPI GLenum APIENTRY glClientWaitSync (GLsync, GLbitfield, GLuint64);
+GLAPI void APIENTRY glWaitSync (GLsync, GLbitfield, GLuint64);
+GLAPI void APIENTRY glGetInteger64v (GLenum, GLint64 *);
+GLAPI void APIENTRY glGetSynciv (GLsync, GLenum, GLsizei, GLsizei *, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLsync (APIENTRYP PFNGLFENCESYNCPROC) (GLenum condition, GLbitfield flags);
+typedef GLboolean (APIENTRYP PFNGLISSYNCPROC) (GLsync sync);
+typedef void (APIENTRYP PFNGLDELETESYNCPROC) (GLsync sync);
+typedef GLenum (APIENTRYP PFNGLCLIENTWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLWAITSYNCPROC) (GLsync sync, GLbitfield flags, GLuint64 timeout);
+typedef void (APIENTRYP PFNGLGETINTEGER64VPROC) (GLenum pname, GLint64 *params);
+typedef void (APIENTRYP PFNGLGETSYNCIVPROC) (GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values);
+#endif
+
+#ifndef GL_ARB_texture_multisample
+#define GL_ARB_texture_multisample 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTexImage2DMultisample (GLenum, GLsizei, GLint, GLsizei, GLsizei, GLboolean);
+GLAPI void APIENTRY glTexImage3DMultisample (GLenum, GLsizei, GLint, GLsizei, GLsizei, GLsizei, GLboolean);
+GLAPI void APIENTRY glGetMultisamplefv (GLenum, GLuint, GLfloat *);
+GLAPI void APIENTRY glSampleMaski (GLuint, GLbitfield);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXIMAGE2DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLTEXIMAGE3DMULTISAMPLEPROC) (GLenum target, GLsizei samples, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations);
+typedef void (APIENTRYP PFNGLGETMULTISAMPLEFVPROC) (GLenum pname, GLuint index, GLfloat *val);
+typedef void (APIENTRYP PFNGLSAMPLEMASKIPROC) (GLuint index, GLbitfield mask);
+#endif
+
+#ifndef GL_ARB_vertex_array_bgra
+#define GL_ARB_vertex_array_bgra 1
+#endif
+
+#ifndef GL_ARB_draw_buffers_blend
+#define GL_ARB_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendEquationi (GLuint, GLenum);
+GLAPI void APIENTRY glBlendEquationSeparatei (GLuint, GLenum, GLenum);
+GLAPI void APIENTRY glBlendFunci (GLuint, GLenum, GLenum);
+GLAPI void APIENTRY glBlendFuncSeparatei (GLuint, GLenum, GLenum, GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDEQUATIONIPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEIPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+typedef void (APIENTRYP PFNGLBLENDFUNCIPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEIPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+#endif
+
+#ifndef GL_ARB_sample_shading
+#define GL_ARB_sample_shading 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glMinSampleShading (GLclampf);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLMINSAMPLESHADINGPROC) (GLclampf value);
+#endif
+
+#ifndef GL_ARB_texture_cube_map_array
+#define GL_ARB_texture_cube_map_array 1
+#endif
+
+#ifndef GL_ARB_texture_gather
+#define GL_ARB_texture_gather 1
+#endif
+
+#ifndef GL_ARB_texture_query_lod
+#define GL_ARB_texture_query_lod 1
+#endif
+
#ifndef GL_EXT_abgr
#define GL_EXT_abgr 1
#endif
@@ -8204,7 +8596,7 @@ GLAPI void APIENTRY glTransformFeedbackAttribsNV (GLuint, const GLint *, GLenum)
GLAPI void APIENTRY glBindBufferRangeNV (GLenum, GLuint, GLuint, GLintptr, GLsizeiptr);
GLAPI void APIENTRY glBindBufferOffsetNV (GLenum, GLuint, GLuint, GLintptr);
GLAPI void APIENTRY glBindBufferBaseNV (GLenum, GLuint, GLuint);
-GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLint *, GLenum);
+GLAPI void APIENTRY glTransformFeedbackVaryingsNV (GLuint, GLsizei, const GLchar* *, GLenum);
GLAPI void APIENTRY glActiveVaryingNV (GLuint, const GLchar *);
GLAPI GLint APIENTRY glGetVaryingLocationNV (GLuint, const GLchar *);
GLAPI void APIENTRY glGetActiveVaryingNV (GLuint, GLuint, GLsizei, GLsizei *, GLsizei *, GLenum *, GLchar *);
@@ -8216,7 +8608,7 @@ typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKATTRIBSNVPROC) (GLuint count, cons
typedef void (APIENTRYP PFNGLBINDBUFFERRANGENVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size);
typedef void (APIENTRYP PFNGLBINDBUFFEROFFSETNVPROC) (GLenum target, GLuint index, GLuint buffer, GLintptr offset);
typedef void (APIENTRYP PFNGLBINDBUFFERBASENVPROC) (GLenum target, GLuint index, GLuint buffer);
-typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLint *locations, GLenum bufferMode);
+typedef void (APIENTRYP PFNGLTRANSFORMFEEDBACKVARYINGSNVPROC) (GLuint program, GLsizei count, const GLchar* *varyings, GLenum bufferMode);
typedef void (APIENTRYP PFNGLACTIVEVARYINGNVPROC) (GLuint program, const GLchar *name);
typedef GLint (APIENTRYP PFNGLGETVARYINGLOCATIONNVPROC) (GLuint program, const GLchar *name);
typedef void (APIENTRYP PFNGLGETACTIVEVARYINGNVPROC) (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name);
@@ -8781,6 +9173,78 @@ GLAPI void APIENTRY glProvokingVertexEXT (GLenum);
typedef void (APIENTRYP PFNGLPROVOKINGVERTEXEXTPROC) (GLenum mode);
#endif
+#ifndef GL_EXT_texture_snorm
+#define GL_EXT_texture_snorm 1
+#endif
+
+#ifndef GL_AMD_draw_buffers_blend
+#define GL_AMD_draw_buffers_blend 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glBlendFuncIndexedAMD (GLuint, GLenum, GLenum);
+GLAPI void APIENTRY glBlendFuncSeparateIndexedAMD (GLuint, GLenum, GLenum, GLenum, GLenum);
+GLAPI void APIENTRY glBlendEquationIndexedAMD (GLuint, GLenum);
+GLAPI void APIENTRY glBlendEquationSeparateIndexedAMD (GLuint, GLenum, GLenum);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLBLENDFUNCINDEXEDAMDPROC) (GLuint buf, GLenum src, GLenum dst);
+typedef void (APIENTRYP PFNGLBLENDFUNCSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONINDEXEDAMDPROC) (GLuint buf, GLenum mode);
+typedef void (APIENTRYP PFNGLBLENDEQUATIONSEPARATEINDEXEDAMDPROC) (GLuint buf, GLenum modeRGB, GLenum modeAlpha);
+#endif
+
+#ifndef GL_APPLE_texture_range
+#define GL_APPLE_texture_range 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glTextureRangeAPPLE (GLenum, GLsizei, const GLvoid *);
+GLAPI void APIENTRY glGetTexParameterPointervAPPLE (GLenum, GLenum, GLvoid* *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLTEXTURERANGEAPPLEPROC) (GLenum target, GLsizei length, const GLvoid *pointer);
+typedef void (APIENTRYP PFNGLGETTEXPARAMETERPOINTERVAPPLEPROC) (GLenum target, GLenum pname, GLvoid* *params);
+#endif
+
+#ifndef GL_APPLE_float_pixels
+#define GL_APPLE_float_pixels 1
+#endif
+
+#ifndef GL_APPLE_vertex_program_evaluators
+#define GL_APPLE_vertex_program_evaluators 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI void APIENTRY glEnableVertexAttribAPPLE (GLuint, GLenum);
+GLAPI void APIENTRY glDisableVertexAttribAPPLE (GLuint, GLenum);
+GLAPI GLboolean APIENTRY glIsVertexAttribEnabledAPPLE (GLuint, GLenum);
+GLAPI void APIENTRY glMapVertexAttrib1dAPPLE (GLuint, GLuint, GLdouble, GLdouble, GLint, GLint, const GLdouble *);
+GLAPI void APIENTRY glMapVertexAttrib1fAPPLE (GLuint, GLuint, GLfloat, GLfloat, GLint, GLint, const GLfloat *);
+GLAPI void APIENTRY glMapVertexAttrib2dAPPLE (GLuint, GLuint, GLdouble, GLdouble, GLint, GLint, GLdouble, GLdouble, GLint, GLint, const GLdouble *);
+GLAPI void APIENTRY glMapVertexAttrib2fAPPLE (GLuint, GLuint, GLfloat, GLfloat, GLint, GLint, GLfloat, GLfloat, GLint, GLint, const GLfloat *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef void (APIENTRYP PFNGLENABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLDISABLEVERTEXATTRIBAPPLEPROC) (GLuint index, GLenum pname);
+typedef GLboolean (APIENTRYP PFNGLISVERTEXATTRIBENABLEDAPPLEPROC) (GLuint index, GLenum pname);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB1FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2DAPPLEPROC) (GLuint index, GLuint size, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points);
+typedef void (APIENTRYP PFNGLMAPVERTEXATTRIB2FAPPLEPROC) (GLuint index, GLuint size, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points);
+#endif
+
+#ifndef GL_APPLE_aux_depth_stencil
+#define GL_APPLE_aux_depth_stencil 1
+#endif
+
+#ifndef GL_APPLE_object_purgeable
+#define GL_APPLE_object_purgeable 1
+#ifdef GL_GLEXT_PROTOTYPES
+GLAPI GLenum APIENTRY glObjectPurgeableAPPLE (GLenum, GLuint, GLenum);
+GLAPI GLenum APIENTRY glObjectUnpurgeableAPPLE (GLenum, GLuint, GLenum);
+GLAPI void APIENTRY glGetObjectParameterivAPPLE (GLenum, GLuint, GLenum, GLint *);
+#endif /* GL_GLEXT_PROTOTYPES */
+typedef GLenum (APIENTRYP PFNGLOBJECTPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef GLenum (APIENTRYP PFNGLOBJECTUNPURGEABLEAPPLEPROC) (GLenum objectType, GLuint name, GLenum option);
+typedef void (APIENTRYP PFNGLGETOBJECTPARAMETERIVAPPLEPROC) (GLenum objectType, GLuint name, GLenum pname, GLint *params);
+#endif
+
+#ifndef GL_APPLE_row_bytes
+#define GL_APPLE_row_bytes 1
+#endif
+
#ifdef __cplusplus
}
diff --git a/include/GL/glxext.h b/include/GL/glxext.h
index 536fb25a76..eac09f94fa 100644
--- a/include/GL/glxext.h
+++ b/include/GL/glxext.h
@@ -6,7 +6,7 @@ extern "C" {
#endif
/*
-** Copyright (c) 2007 The Khronos Group Inc.
+** Copyright (c) 2007-2009 The Khronos Group Inc.
**
** Permission is hereby granted, free of charge, to any person obtaining a
** copy of this software and/or associated documentation files (the
@@ -28,6 +28,8 @@ extern "C" {
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
*/
+/* Function declaration macros - to move into glplatform.h */
+
#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__)
#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
@@ -46,9 +48,9 @@ extern "C" {
/*************************************************************/
/* Header file version number, required by OpenGL ABI for Linux */
-/* glxext.h last updated 2008/10/22 */
+/* glxext.h last updated 2009/08/03 */
/* Current version at http://www.opengl.org/registry/ */
-#define GLX_GLXEXT_VERSION 21
+#define GLX_GLXEXT_VERSION 23
#ifndef GLX_VERSION_1_3
#define GLX_WINDOW_BIT 0x00000001
@@ -135,6 +137,12 @@ extern "C" {
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#endif
+#ifndef GLX_ARB_create_context_profile
+#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
+#endif
+
#ifndef GLX_SGIS_multisample
#define GLX_SAMPLE_BUFFERS_SGIS 100000
#define GLX_SAMPLES_SGIS 100001
@@ -518,6 +526,10 @@ extern GLXContext glXCreateContextAttribsARB (Display *, GLXFBConfig, GLXContext
typedef GLXContext ( * PFNGLXCREATECONTEXTATTRIBSARBPROC) (Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list);
#endif
+#ifndef GLX_ARB_create_context_profile
+#define GLX_ARB_create_context_profile 1
+#endif
+
#ifndef GLX_SGIS_multisample
#define GLX_SGIS_multisample 1
#endif
diff --git a/include/GL/wglext.h b/include/GL/wglext.h
index 3c492dd634..1f096fb919 100644
--- a/include/GL/wglext.h
+++ b/include/GL/wglext.h
@@ -48,9 +48,9 @@ extern "C" {
/*************************************************************/
/* Header file version number */
-/* wglext.h last updated 2009/03/03 */
+/* wglext.h last updated 2009/08/03 */
/* Current version at http://www.opengl.org/registry/ */
-#define WGL_WGLEXT_VERSION 12
+#define WGL_WGLEXT_VERSION 15
#ifndef WGL_ARB_buffer_region
#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001
@@ -176,8 +176,8 @@ extern "C" {
#endif
#ifndef WGL_ARB_create_context
-#define WGL_CONTEXT_DEBUG_BIT_ARB 0x0001
-#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x0002
+#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001
+#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092
#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093
@@ -185,6 +185,13 @@ extern "C" {
#define ERROR_INVALID_VERSION_ARB 0x2095
#endif
+#ifndef WGL_ARB_create_context_profile
+#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126
+#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
+#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002
+#define ERROR_INVALID_PROFILE_ARB 0x2096
+#endif
+
#ifndef WGL_EXT_make_current_read
#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043
#endif
@@ -497,6 +504,10 @@ extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *);
typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList);
#endif
+#ifndef WGL_ARB_create_context_profile
+#define WGL_ARB_create_context_profile 1
+#endif
+
#ifndef WGL_EXT_display_color_table
#define WGL_EXT_display_color_table 1
#ifdef WGL_WGLEXT_PROTOTYPES
diff --git a/progs/SConscript b/progs/SConscript
index 620dd30e69..66eaf9e541 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/.gitignore b/progs/demos/.gitignore
index f3c7091bcc..5dd974b63d 100644
--- a/progs/demos/.gitignore
+++ b/progs/demos/.gitignore
@@ -63,3 +63,4 @@ tunnel2
vao_demo
Windows
winpos
+*.rgb
diff --git a/progs/demos/copypix.c b/progs/demos/copypix.c
index 51435acfa0..a13339ea62 100644
--- a/progs/demos/copypix.c
+++ b/progs/demos/copypix.c
@@ -26,6 +26,7 @@ static int Scissor = 0;
static float Xzoom, Yzoom;
static GLboolean DrawFront = GL_FALSE;
static GLboolean Dither = GL_TRUE;
+static GLboolean Invert = GL_FALSE;
static void Reset( void )
@@ -59,6 +60,15 @@ static void Display( void )
if (Scissor)
glEnable(GL_SCISSOR_TEST);
+ if (Invert) {
+ glPixelTransferf(GL_RED_SCALE, -1.0);
+ glPixelTransferf(GL_GREEN_SCALE, -1.0);
+ glPixelTransferf(GL_BLUE_SCALE, -1.0);
+ glPixelTransferf(GL_RED_BIAS, 1.0);
+ glPixelTransferf(GL_GREEN_BIAS, 1.0);
+ glPixelTransferf(GL_BLUE_BIAS, 1.0);
+ }
+
/* draw copy */
glPixelZoom(Xzoom, Yzoom);
glWindowPos2iARB(Xpos, Ypos);
@@ -67,6 +77,15 @@ static void Display( void )
glDisable(GL_SCISSOR_TEST);
+ if (Invert) {
+ glPixelTransferf(GL_RED_SCALE, 1.0);
+ glPixelTransferf(GL_GREEN_SCALE, 1.0);
+ glPixelTransferf(GL_BLUE_SCALE, 1.0);
+ glPixelTransferf(GL_RED_BIAS, 0.0);
+ glPixelTransferf(GL_GREEN_BIAS, 0.0);
+ glPixelTransferf(GL_BLUE_BIAS, 0.0);
+ }
+
if (DrawFront)
glFinish();
else
@@ -105,6 +124,9 @@ static void Key( unsigned char key, int x, int y )
else
glDisable(GL_DITHER);
break;
+ case 'i':
+ Invert = !Invert;
+ break;
case 's':
Scissor = !Scissor;
break;
diff --git a/progs/demos/cubemap.c b/progs/demos/cubemap.c
index 0a3e10dac0..20332b1d96 100644
--- a/progs/demos/cubemap.c
+++ b/progs/demos/cubemap.c
@@ -43,6 +43,9 @@
#include "GL/glut.h"
#include "readtex.h"
+#ifndef GL_TEXTURE_CUBE_MAP_SEAMLESS
+#define GL_TEXTURE_CUBE_MAP_SEAMLESS 0x884F
+#endif
static GLfloat Xrot = 0, Yrot = 0;
static GLfloat EyeDist = 10;
@@ -53,6 +56,9 @@ static GLint FrameParity = 0;
static GLenum FilterIndex = 0;
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;
@@ -93,7 +99,9 @@ static struct {
-#define eps1 0.99
+/* The effects of GL_ARB_seamless_cube_map don't show up unless eps1 is 1.0.
+ */
+#define eps1 1.0 /*0.99*/
#define br 20.0 /* box radius */
static const GLfloat tex_coords[] = {
@@ -233,6 +241,13 @@ static void draw( void )
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_MAG_FILTER,
FilterModes[FilterIndex].mag_mode);
+ if (supportSeamless) {
+ if (seamless) {
+ glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ } else {
+ glDisable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
+ }
+ }
wrap = ClampModes[ClampIndex].mode;
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_S, wrap);
glTexParameteri(GL_TEXTURE_CUBE_MAP_ARB, GL_TEXTURE_WRAP_T, wrap);
@@ -337,6 +352,11 @@ static void key(unsigned char k, int x, int y)
mode = !mode;
set_mode(mode);
break;
+ case 's':
+ seamless = ! seamless;
+ printf("Seamless cube map filtering is %sabled\n",
+ (seamless) ? "en" : "dis" );
+ break;
case 'v':
use_vertex_arrays = ! use_vertex_arrays;
printf( "Vertex arrays are %sabled\n",
@@ -518,25 +538,32 @@ static void load_envmaps(void)
static void init( GLboolean useImageFiles )
{
/* check for extensions */
- {
- char *exten = (char *) glGetString(GL_EXTENSIONS);
- if (!strstr(exten, "GL_ARB_texture_cube_map")) {
- printf("Sorry, this demo requires GL_ARB_texture_cube_map\n");
- exit(0);
- }
+ if (!GLEW_ARB_texture_cube_map) {
+ printf("Sorry, this demo requires GL_ARB_texture_cube_map\n");
+ exit(0);
+ }
- /* Needed for glGenerateMipmapEXT / auto mipmapping
- */
- if (strstr(exten, "GL_EXT_framebuffer_object")) {
- supportFBO = GL_TRUE;
- }
- else if (!strstr(exten, "GL_SGIS_generate_mipmap")) {
- printf("Sorry, this demo requires GL_EXT_framebuffer_object or GL_SGIS_generate_mipmap\n");
- exit(0);
- }
+ /* Needed for glGenerateMipmapEXT / auto mipmapping
+ */
+ supportFBO = GLEW_EXT_framebuffer_object;
+
+ if (!supportFBO && !GLEW_SGIS_generate_mipmap) {
+ printf("Sorry, this demo requires GL_EXT_framebuffer_object or "
+ "GL_SGIS_generate_mipmap\n");
+ exit(0);
}
+
+ /* GLEW doesn't know about this extension yet, so use the old GLUT function
+ * to check for availability.
+ */
+ supportSeamless = glutExtensionSupported("GL_ARB_seamless_cube_map");
+
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/fbotexture.c b/progs/demos/fbotexture.c
index 3b36f755a0..56482663dc 100644
--- a/progs/demos/fbotexture.c
+++ b/progs/demos/fbotexture.c
@@ -498,7 +498,7 @@ SetupFunctionPointers(void)
* Make FBO to render into given texture.
*/
static GLuint
-MakeFBO_RenderTexture(GLuint TexObj)
+MakeFBO_RenderTexture(GLuint texObj)
{
GLuint fb;
GLint sizeFudge = 0;
@@ -507,7 +507,7 @@ MakeFBO_RenderTexture(GLuint TexObj)
glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, fb);
/* Render color to texture */
glFramebufferTexture2D_func(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- TexTarget, TexObj, TextureLevel);
+ TexTarget, texObj, TextureLevel);
if (Use_ARB_fbo) {
/* use a smaller depth buffer to see what happens */
@@ -541,7 +541,7 @@ MakeFBO_RenderTexture(GLuint TexObj)
/* queries */
{
- GLint bits, w, h;
+ GLint bits, w, h, name;
glBindRenderbuffer_func(GL_RENDERBUFFER_EXT, DepthRB);
glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
@@ -559,8 +559,28 @@ MakeFBO_RenderTexture(GLuint TexObj)
glGetRenderbufferParameteriv_func(GL_RENDERBUFFER_EXT,
GL_RENDERBUFFER_STENCIL_SIZE_EXT, &bits);
printf("Stencil renderbuffer size = %d bits\n", bits);
- }
+ glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+ GL_COLOR_ATTACHMENT0,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+ &name);
+ printf("Render to texture name: %d\n", texObj);
+ printf("Color attachment[0] name: %d\n", name);
+ assert(texObj == name);
+
+ glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+ GL_STENCIL_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+ &name);
+ printf("Stencil attachment name: %d\n", name);
+
+ glGetFramebufferAttachmentParameteriv_func(GL_FRAMEBUFFER_EXT,
+ GL_DEPTH_ATTACHMENT,
+ GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT,
+ &name);
+ printf("Depth attachment name: %d\n", name);
+
+ }
/* bind the regular framebuffer */
glBindFramebuffer_func(GL_FRAMEBUFFER_EXT, 0);
diff --git a/progs/demos/lodbias.c b/progs/demos/lodbias.c
index 30b1ed13d5..8d39bd605a 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/egl/.gitignore b/progs/egl/.gitignore
index f417aefb93..7a13d4686a 100644
--- a/progs/egl/.gitignore
+++ b/progs/egl/.gitignore
@@ -6,6 +6,7 @@ eglinfo
eglscreen
egltri
peglgears
+xeglbindtex
xeglgears
xeglthreads
xegl_tri
diff --git a/progs/egl/Makefile b/progs/egl/Makefile
index d3c32d46f7..ff9a858c56 100644
--- a/progs/egl/Makefile
+++ b/progs/egl/Makefile
@@ -7,6 +7,9 @@ include $(TOP)/configs/current
INCLUDE_DIRS = -I$(TOP)/include
HEADERS = $(TOP)/include/GLES/egl.h
+LIB_DEP = $(TOP)/$(LIB_DIR)/libEGL.so
+
+LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGL
PROGRAMS = \
demo1 \
@@ -17,6 +20,7 @@ PROGRAMS = \
eglgears \
eglscreen \
peglgears \
+ xeglbindtex \
xeglgears \
xeglthreads \
xegl_tri
@@ -29,84 +33,42 @@ PROGRAMS = \
default: $(PROGRAMS)
+demo1: demo1.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-demo1: demo1.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) demo1.o -L$(TOP)/$(LIB_DIR) -lEGL $(LIBDRM_LIB) -o $@
-
-demo1.o: demo1.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include demo1.c
-
-
-demo2: demo2.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) demo2.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-demo2.o: demo2.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include demo2.c
-
-
-demo3: demo3.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) demo3.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-demo3.o: demo3.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include demo3.c
-
-
-egltri: egltri.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) egltri.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) -o $@
-
-egltri.o: egltri.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include egltri.c
+demo2: demo2.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
+demo3: demo3.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-eglinfo: eglinfo.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) eglinfo.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) -o $@
+egltri: egltri.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-eglinfo.o: eglinfo.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include eglinfo.c
+eglinfo: eglinfo.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
+eglgears: eglgears.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-eglgears: eglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) eglgears.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+eglscreen: eglscreen.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-eglgears.o: eglgears.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include eglgears.c
+peglgears: peglgears.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) $(LIBDRM_LIB)
-eglscreen: eglscreen.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) $(LDFLAGS) eglscreen.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+xeglbindtex: xeglbindtex.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11
-eglscreen.o: eglscreen.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include eglscreen.c
+xeglgears: xeglgears.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11
-peglgears: peglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) peglgears.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-peglgears.o: peglgears.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include peglgears.c
-
-
-xeglgears: xeglgears.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) xeglgears.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-xeglgears.o: xeglgears.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include xeglgears.c
-
-
-xeglthreads: xeglthreads.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) xeglthreads.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-xeglthreads.o: xeglthreads.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include xeglthreads.c
-
-
-xegl_tri: xegl_tri.o $(TOP)/$(LIB_DIR)/libEGL.so
- $(CC) $(CFLAGS) xegl_tri.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
-
-xegl_tri.o: xegl_tri.c $(HEADERS)
- $(CC) -c $(CFLAGS) -I$(TOP)/include xegl_tri.c
+xeglthreads: xeglthreads.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11
+xegl_tri: xegl_tri.o $(HEADERS) $(LIB_DEP)
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LIBS) -lX11
clean:
-rm -f *.o *~
- -rm -f *.so
-rm -f $(PROGRAMS)
-
diff --git a/progs/egl/demo3.c b/progs/egl/demo3.c
index a6096a257e..daab62d173 100644
--- a/progs/egl/demo3.c
+++ b/progs/egl/demo3.c
@@ -551,7 +551,7 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height)
}
}
-#include "../src/egl/main/egldisplay.h"
+#include "../../src/egl/main/egldisplay.h"
typedef struct fb_display
{
diff --git a/progs/egl/xeglbindtex.c b/progs/egl/xeglbindtex.c
new file mode 100644
index 0000000000..fdd9fe2b87
--- /dev/null
+++ b/progs/egl/xeglbindtex.c
@@ -0,0 +1,474 @@
+/*
+ * Simple demo for eglBindTexImage. Based on xegl_tri.c by
+ *
+ * Copyright (C) 2008 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * The spec says that eglBindTexImage supports only OpenGL ES context, but this
+ * demo uses OpenGL context. Keep in mind that this is non-standard.
+ */
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/keysym.h>
+#include <GL/gl.h>
+#include <EGL/egl.h>
+
+static EGLDisplay dpy;
+static EGLContext ctx_win, ctx_pbuf;
+static EGLSurface surf_win, surf_pbuf;
+static GLuint tex_pbuf;
+
+static GLfloat view_rotx = 0.0, view_roty = 0.0, view_rotz = 0.0;
+static GLboolean blend = GL_TRUE;
+static GLuint color_flow;
+
+static void
+make_pbuffer(int width, int height)
+{
+ static const EGLint config_attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE,
+ EGL_NONE
+ };
+ EGLint pbuf_attribs[] = {
+ EGL_WIDTH, width,
+ EGL_HEIGHT, height,
+ EGL_TEXTURE_FORMAT, EGL_TEXTURE_RGB,
+ EGL_TEXTURE_TARGET, EGL_TEXTURE_2D,
+ EGL_NONE
+ };
+ EGLConfig config;
+ EGLint num_configs;
+
+ if (!eglChooseConfig(dpy, config_attribs, &config, 1, &num_configs)) {
+ printf("Error: couldn't get an EGL visual config for pbuffer\n");
+ exit(1);
+ }
+
+ eglBindAPI(EGL_OPENGL_API);
+ ctx_pbuf = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL );
+ surf_pbuf = eglCreatePbufferSurface(dpy, config, pbuf_attribs);
+ if (surf_pbuf == EGL_NO_SURFACE) {
+ printf("failed to allocate pbuffer\n");
+ exit(1);
+ }
+
+ glGenTextures(1, &tex_pbuf);
+}
+
+static void
+use_pbuffer(void)
+{
+ static int initialized;
+
+ eglMakeCurrent(dpy, surf_pbuf, surf_pbuf, ctx_pbuf);
+ if (!initialized) {
+ EGLint width, height;
+ GLfloat ar;
+
+ initialized = 1;
+
+ eglQuerySurface(dpy, surf_pbuf, EGL_WIDTH, &width);
+ eglQuerySurface(dpy, surf_pbuf, EGL_WIDTH, &height);
+ ar = (GLfloat) width / (GLfloat) height;
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 1.0, 10.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+
+ /* y-inverted */
+ glScalef(1.0, -1.0, 1.0);
+
+ glTranslatef(0.0, 0.0, -5.0);
+
+ glClearColor(0.2, 0.2, 0.2, 0.0);
+ }
+}
+
+static void
+make_window(Display *x_dpy, const char *name,
+ int x, int y, int width, int height,
+ Window *winRet)
+{
+ static const EGLint attribs[] = {
+ EGL_RED_SIZE, 8,
+ EGL_GREEN_SIZE, 8,
+ EGL_BLUE_SIZE, 8,
+ EGL_ALPHA_SIZE, 8,
+ EGL_DEPTH_SIZE, 8,
+ EGL_NONE
+ };
+
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ XVisualInfo *visInfo, visTemplate;
+ int num_visuals;
+ EGLConfig config;
+ EGLint num_configs, vid;
+
+ scrnum = DefaultScreen( x_dpy );
+ root = RootWindow( x_dpy, scrnum );
+
+ if (!eglChooseConfig(dpy, attribs, &config, 1, &num_configs)) {
+ printf("Error: couldn't get an EGL visual config\n");
+ exit(1);
+ }
+
+ if (!eglGetConfigAttrib(dpy, config, EGL_NATIVE_VISUAL_ID, &vid)) {
+ printf("Error: eglGetConfigAttrib() failed\n");
+ exit(1);
+ }
+
+ /* The X window visual must match the EGL config */
+ visTemplate.visualid = vid;
+ visInfo = XGetVisualInfo(x_dpy, VisualIDMask, &visTemplate, &num_visuals);
+ if (!visInfo) {
+ printf("Error: couldn't get X visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( x_dpy, root, visInfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ attr.override_redirect = 0;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect;
+
+ win = XCreateWindow( x_dpy, root, 0, 0, width, height,
+ 0, visInfo->depth, InputOutput,
+ visInfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(x_dpy, win, &sizehints);
+ XSetStandardProperties(x_dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ eglBindAPI(EGL_OPENGL_API);
+ ctx_win = eglCreateContext(dpy, config, EGL_NO_CONTEXT, NULL );
+ if (!ctx_win) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ surf_win = eglCreateWindowSurface(dpy, config, win, NULL);
+
+ XFree(visInfo);
+
+ *winRet = win;
+}
+
+static void
+use_window(void)
+{
+ static int initialized;
+
+ eglMakeCurrent(dpy, surf_win, surf_win, ctx_win);
+ if (!initialized) {
+ initialized = 1;
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, tex_pbuf);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+}
+
+static void
+draw_triangle(void)
+{
+ static const GLfloat verts[3][2] = {
+ { -3, -3 },
+ { 3, -3 },
+ { 0, 3 }
+ };
+ GLfloat colors[3][3] = {
+ { 1, 0, 0 },
+ { 0, 1, 0 },
+ { 0, 0, 1 }
+ };
+ GLint i;
+
+ /* flow the color */
+ for (i = 0; i < 3; i++) {
+ GLint first = (i + color_flow / 256) % 3;
+ GLint second = (first + 1) % 3;
+ GLint third = (second + 1) % 3;
+ GLfloat c = (color_flow % 256) / 256.0f;
+
+ c = c * c * c;
+ colors[i][first] = 1.0f - c;
+ colors[i][second] = c;
+ colors[i][third] = 0.0f;
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glColorPointer(3, GL_FLOAT, 0, colors);
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+}
+
+static void
+draw_textured_cube(void)
+{
+ static const GLfloat verts[][2] = {
+ { -4, -4 },
+ { 4, -4 },
+ { 4, 4 },
+ { -4, 4 }
+ };
+ static const GLfloat colors[][4] = {
+ { 1, 1, 1, 0.5 },
+ { 1, 1, 1, 0.5 },
+ { 1, 1, 1, 0.5 },
+ { 1, 1, 1, 0.5 }
+ };
+ static const GLfloat texs[][2] = {
+ { 0, 0 },
+ { 1, 0 },
+ { 1, 1 },
+ { 0, 1 }
+ };
+ static const GLfloat xforms[6][4] = {
+ { 0, 0, 1, 0 },
+ { 90, 0, 1, 0 },
+ { 180, 0, 1, 0 },
+ { 270, 0, 1, 0 },
+ { 90, 1, 0, 0 },
+ { -90, 1, 0, 0 }
+ };
+ GLint i;
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ if (blend) {
+ glDisable(GL_DEPTH_TEST);
+ glEnable(GL_BLEND);
+ } else {
+ glEnable(GL_DEPTH_TEST);
+ glDisable(GL_BLEND);
+ }
+
+ glVertexPointer(2, GL_FLOAT, 0, verts);
+ glColorPointer(4, GL_FLOAT, 0, colors);
+ glTexCoordPointer(2, GL_FLOAT, 0, texs);
+
+ glEnableClientState(GL_VERTEX_ARRAY);
+ glEnableClientState(GL_COLOR_ARRAY);
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+
+ for (i = 0; i < 6; i++) {
+ glPushMatrix();
+ glRotatef(xforms[i][0], xforms[i][1], xforms[i][2], xforms[i][3]);
+ glTranslatef(0, 0, 4.1);
+ glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ glPopMatrix();
+ }
+
+ glDisableClientState(GL_VERTEX_ARRAY);
+ glDisableClientState(GL_COLOR_ARRAY);
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY);
+}
+
+static void
+draw(void)
+{
+ use_pbuffer();
+ draw_triangle();
+
+ use_window();
+
+ eglBindTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1, 0, 0);
+ glRotatef(view_roty, 0, 1, 0);
+ glRotatef(view_rotz, 0, 0, 1);
+
+ draw_textured_cube();
+
+ glPopMatrix();
+
+ eglReleaseTexImage(dpy, surf_pbuf, EGL_BACK_BUFFER);
+}
+
+/* new window size or exposure */
+static void
+reshape(int width, int height)
+{
+ GLfloat ar = (GLfloat) width / (GLfloat) height;
+
+ use_window();
+
+ glViewport(0, 0, (GLint) width, (GLint) height);
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-ar, ar, -1, 1, 5.0, 60.0);
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -40.0);
+}
+
+static void
+event_loop(Display *x_dpy, Window win)
+{
+ while (1) {
+ int redraw = 1;
+
+ if (XPending(x_dpy) > 0) {
+ XEvent event;
+ XNextEvent(x_dpy, &event);
+
+ switch (event.type) {
+ case Expose:
+ redraw = 1;
+ break;
+ case ConfigureNotify:
+ reshape(event.xconfigure.width, event.xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event.xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else if (code == XK_b) {
+ blend = !blend;
+ }
+ else {
+ r = XLookupString(&event.xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return;
+ }
+ }
+ }
+ redraw = 1;
+ break;
+ default:
+ ; /*no-op*/
+ }
+ }
+
+ if (redraw) {
+ view_rotx += 1.0;
+ view_roty += 2.0;
+ view_rotz += 1.5;
+ color_flow += 20;
+ draw();
+ eglSwapBuffers(dpy, surf_win);
+ }
+ }
+}
+
+int
+main(int argc, char *argv[])
+{
+ const int winWidth = 300, winHeight = 300;
+ Display *x_dpy;
+ Window win;
+ char *dpyName = NULL;
+ EGLint egl_major, egl_minor;
+ const char *s;
+
+ x_dpy = XOpenDisplay(dpyName);
+ if (!x_dpy) {
+ printf("Error: couldn't open display %s\n",
+ dpyName ? dpyName : getenv("DISPLAY"));
+ return -1;
+ }
+
+ dpy = eglGetDisplay(x_dpy);
+ if (!dpy) {
+ printf("Error: eglGetDisplay() failed\n");
+ return -1;
+ }
+
+ if (!eglInitialize(dpy, &egl_major, &egl_minor)) {
+ printf("Error: eglInitialize() failed\n");
+ return -1;
+ }
+
+ s = eglQueryString(dpy, EGL_VERSION);
+ printf("EGL_VERSION = %s\n", s);
+
+ make_window(x_dpy, "color flow", 0, 0, winWidth, winHeight, &win);
+ make_pbuffer(winWidth, winHeight);
+
+ XMapWindow(x_dpy, win);
+
+ reshape(winWidth, winHeight);
+ event_loop(x_dpy, win);
+
+ glDeleteTextures(1, &tex_pbuf);
+
+ eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglTerminate(dpy);
+
+ XDestroyWindow(x_dpy, win);
+ XCloseDisplay(x_dpy);
+
+ return 0;
+}
diff --git a/progs/fp/add-sat.txt b/progs/fp/add-sat.txt
new file mode 100644
index 0000000000..2253efb085
--- /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 0000000000..5f04e9c76e
--- /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 0000000000..cf7d359e78
--- /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/.gitignore b/progs/glsl/.gitignore
index 39d90c23ac..986775bac2 100644
--- a/progs/glsl/.gitignore
+++ b/progs/glsl/.gitignore
@@ -22,6 +22,7 @@ samplers_array
shaderutil.c
shaderutil.h
shadow_sampler
+shtest
skinning
texaaline
texdemo1
diff --git a/progs/glsl/Makefile b/progs/glsl/Makefile
index eedd866c95..8928c833c0 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -10,11 +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)
+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
+# using : to avoid APP_CC pointing to CC loop
+CC := $(APP_CC)
+CFLAGS := -I$(INCDIR) $(CFLAGS)
+LDLIBS = $(LIBS)
-DEMO_SOURCES = \
+PROG_SOURCES = \
array.c \
bitmap.c \
brick.c \
@@ -32,7 +36,9 @@ DEMO_SOURCES = \
pointcoord.c \
points.c \
samplers.c \
+ samplers_array.c \
shadow_sampler.c \
+ shtest.c \
skinning.c \
texaaline.c \
texdemo1.c \
@@ -52,28 +58,16 @@ UTIL_SOURCES = \
readtex.c
UTIL_OBJS = $(UTIL_SOURCES:.c=.o)
-
-
-PROGS = $(DEMO_SOURCES:%.c=%)
-
-
-
-##### RULES #####
-
-# make .o file from .c file:
-.c.o:
- $(APP_CC) -c -I$(INCDIR) $(CFLAGS) $< -o $@
-
-
-# make executable from .o files
-.o:
- $(APP_CC) $(INCLUDES) $(CFLAGS) $(LDFLAGS) $< $(UTIL_OBJS) $(LIBS) -o $@
-
+PROG_OBJS = $(PROG_SOURCES:.c=.o)
+PROGS = $(PROG_SOURCES:%.c=%)
##### TARGETS #####
default: $(PROGS)
+$(PROG_OBJS): $(UTIL_HEADERS)
+
+$(PROGS): $(UTIL_OBJS)
clean:
-rm -f $(PROGS)
@@ -83,9 +77,11 @@ clean:
-rm -f readtex.*
-
##### Extra dependencies
+samplers_array.o: samplers.c
+ $(APP_CC) $(CFLAGS) -DSAMPLERS_ARRAY $< -c -o $@
+
extfuncs.h: $(TOP)/progs/util/extfuncs.h
cp $< .
@@ -101,138 +97,3 @@ shaderutil.c: $(TOP)/progs/util/shaderutil.c
shaderutil.h: $(TOP)/progs/util/shaderutil.h
cp $< .
-
-
-array.o: $(UTIL_HEADERS)
-
-array: array.o $(UTIL_OBJS)
-
-
-bitmap.o: $(UTIL_HEADERS)
-
-bitmap: bitmap.o $(UTIL_OBJS)
-
-
-brick.o: $(UTIL_HEADERS)
-
-brick: brick.o $(UTIL_OBJS)
-
-
-bump.o: $(UTIL_HEADERS)
-
-bump: bump.o $(UTIL_OBJS)
-
-
-convolutions.o: $(UTIL_HEADERS)
-
-convolutions: convolutions.o $(UTIL_OBJS)
-
-
-deriv.o: deriv.c $(UTIL_HEADERS)
-
-deriv: deriv.o $(UTIL_OBJS)
-
-
-identity.o: $(UTIL_HEADERS)
-
-identity: identity.o $(UTIL_OBJS)
-
-
-fragcoord.o: $(UTIL_HEADERS)
-
-fragcoord: fragcoord.o $(UTIL_OBJS)
-
-
-linktest.o: $(UTIL_HEADERS)
-
-linktest: linktest.o $(UTIL_OBJS)
-
-
-mandelbrot.o: $(UTIL_HEADERS)
-
-mandelbrot: mandelbrot.o $(UTIL_OBJS)
-
-
-multinoise.o: $(UTIL_HEADERS)
-
-multinoise: multinoise.o $(UTIL_OBJS)
-
-
-multitex.o: $(UTIL_HEADERS)
-
-multitex: multitex.o $(UTIL_OBJS)
-
-
-noise.o: $(UTIL_HEADERS)
-
-noise: noise.o $(UTIL_OBJS)
-
-
-noise2.o: $(UTIL_HEADERS)
-
-noise2: noise2.o $(UTIL_OBJS)
-
-
-points.o: $(UTIL_HEADERS)
-
-points: points.o $(UTIL_OBJS)
-
-
-pointcoord.o: $(UTIL_HEADERS)
-
-pointcoord: pointcoord.o $(UTIL_OBJS)
-
-
-samplers.o: $(UTIL_HEADERS)
-
-samplers: samplers.o $(UTIL_OBJS)
-
-
-samplers_array.o: $(UTIL_HEADERS)
-
-samplers_array: samplers_array.o $(UTIL_OBJS)
-
-
-shadow_sampler.o: $(UTIL_HEADERS)
-
-shadow_sampler: shadow_sampler.o $(UTIL_OBJS)
-
-
-skinning.o: $(UTIL_HEADERS)
-
-skinning: skinning.o $(UTIL_OBJS)
-
-
-texaaline.o: $(UTIL_HEADERS)
-
-texaaline: texaaline.o $(UTIL_OBJS)
-
-
-texdemo1.o: $(UTIL_HEADERS)
-
-texdemo1: texdemo1.o $(UTIL_OBJS)
-
-
-toyball.o: $(UTIL_HEADERS)
-
-toyball: toyball.o $(UTIL_OBJS)
-
-
-twoside.o: $(UTIL_HEADERS)
-
-twoside: twoside.o $(UTIL_OBJS)
-
-
-trirast.o: $(UTIL_HEADERS)
-
-trirast: trirast.o $(UTIL_OBJS)
-
-
-vert-or-frag-only.o: $(UTIL_HEADERS)
-
-vert-or-frag-only: vert-or-frag-only.o $(UTIL_OBJS)
-
-
-vert-tex.o: $(UTIL_HEADERS)
-
-vert-tex: vert-tex.o $(UTIL_OBJS)
diff --git a/progs/glsl/brick.c b/progs/glsl/brick.c
index 1d08b231e7..20417aa462 100644
--- a/progs/glsl/brick.c
+++ b/progs/glsl/brick.c
@@ -24,12 +24,12 @@ static GLuint program;
static struct uniform_info Uniforms[] = {
/* vert */
- { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
+ { "LightPosition", 1, GL_FLOAT_VEC3, { 0.1, 0.1, 9.0, 0}, -1 },
/* frag */
- { "BrickColor", 3, GL_FLOAT, { 0.8, 0.2, 0.2, 0 }, -1 },
- { "MortarColor", 3, GL_FLOAT, { 0.6, 0.6, 0.6, 0 }, -1 },
- { "BrickSize", 2, GL_FLOAT, { 1.0, 0.3, 0, 0 }, -1 },
- { "BrickPct", 2, GL_FLOAT, { 0.9, 0.8, 0, 0 }, -1 },
+ { "BrickColor", 1, GL_FLOAT_VEC3, { 0.8, 0.2, 0.2, 0 }, -1 },
+ { "MortarColor", 1, GL_FLOAT_VEC3, { 0.6, 0.6, 0.6, 0 }, -1 },
+ { "BrickSize", 1, GL_FLOAT_VEC2, { 1.0, 0.3, 0, 0 }, -1 },
+ { "BrickPct", 1, GL_FLOAT_VEC2, { 0.9, 0.8, 0, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -148,7 +148,8 @@ Init(void)
glUseProgram(program);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
+ PrintUniforms(Uniforms);
assert(glGetError() == 0);
@@ -183,7 +184,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/brick.shtest b/progs/glsl/brick.shtest
new file mode 100644
index 0000000000..8a2152692e
--- /dev/null
+++ b/progs/glsl/brick.shtest
@@ -0,0 +1,8 @@
+vs CH06-brick.vert
+fs CH06-brick.frag
+uniform LightPosition GL_FLOAT_VEC3 0.1 0.1 9.0
+uniform BrickColor GL_FLOAT_VEC3 0.8 0.2 0.2
+uniform MortarColor GL_FLOAT_VEC3 0.6 0.6 0.6
+uniform BrickSize GL_FLOAT_VEC2 1.0 0.3
+uniform BrickPct GL_FLOAT_VEC2 0.9 0.8
+
diff --git a/progs/glsl/bump.c b/progs/glsl/bump.c
index ddb986abcb..87669aec73 100644
--- a/progs/glsl/bump.c
+++ b/progs/glsl/bump.c
@@ -24,11 +24,11 @@ static GLuint program;
static struct uniform_info Uniforms[] = {
- { "LightPosition", 3, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
- { "SurfaceColor", 3, GL_FLOAT, { 0.8, 0.8, 0.2, 0 }, -1 },
- { "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
- { "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
- { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
+ { "LightPosition", 1, GL_FLOAT_VEC3, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
+ { "SurfaceColor", 1, GL_FLOAT_VEC3, { 0.8, 0.8, 0.2, 0 }, -1 },
+ { "BumpDensity", 1, GL_FLOAT, { 10.0, 0, 0, 0 }, -1 },
+ { "BumpSize", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
+ { "SpecularFactor", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -242,7 +242,8 @@ Init(void)
CheckError(__LINE__);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
+ PrintUniforms(Uniforms);
CheckError(__LINE__);
@@ -280,7 +281,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/convolutions.c b/progs/glsl/convolutions.c
index 22ce7edcdc..c2fb76e1aa 100644
--- a/progs/glsl/convolutions.c
+++ b/progs/glsl/convolutions.c
@@ -448,7 +448,6 @@ int main(int argc, char **argv)
{
glutInit(&argc, argv);
- glutInitWindowPosition(0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_ALPHA | GLUT_DOUBLE);
diff --git a/progs/glsl/deriv.c b/progs/glsl/deriv.c
index 9cf1e40e3e..265a515715 100644
--- a/progs/glsl/deriv.c
+++ b/progs/glsl/deriv.c
@@ -220,7 +220,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(200, 200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/fragcoord.c b/progs/glsl/fragcoord.c
index 9f56a038c9..3dfcec87a5 100644
--- a/progs/glsl/fragcoord.c
+++ b/progs/glsl/fragcoord.c
@@ -166,7 +166,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/identity.c b/progs/glsl/identity.c
index a772ccd716..526e9b82c1 100644
--- a/progs/glsl/identity.c
+++ b/progs/glsl/identity.c
@@ -187,7 +187,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(200, 200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/mandelbrot.c b/progs/glsl/mandelbrot.c
index 38dffc3e74..b05ef37fae 100644
--- a/progs/glsl/mandelbrot.c
+++ b/progs/glsl/mandelbrot.c
@@ -25,7 +25,7 @@ static GLuint program;
static struct uniform_info Uniforms[] = {
/* vert */
- { "LightPosition", 3, GL_FLOAT, { 0.1, 0.1, 9.0, 0}, -1 },
+ { "LightPosition", 1, GL_FLOAT_VEC3, { 0.1, 0.1, 9.0, 0}, -1 },
{ "SpecularContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
{ "DiffuseContribution", 1, GL_FLOAT, { 0.5, 0, 0, 0 }, -1 },
{ "Shininess", 1, GL_FLOAT, { 20.0, 0, 0, 0 }, -1 },
@@ -34,9 +34,9 @@ static struct uniform_info Uniforms[] = {
{ "Zoom", 1, GL_FLOAT, { 0.125, 0, 0, 0 }, -1 },
{ "Xcenter", 1, GL_FLOAT, { -1.5, 0, 0, 0 }, -1 },
{ "Ycenter", 1, GL_FLOAT, { .005, 0, 0, 0 }, -1 },
- { "InnerColor", 3, GL_FLOAT, { 1, 0, 0, 0 }, -1 },
- { "OuterColor1", 3, GL_FLOAT, { 0, 1, 0, 0 }, -1 },
- { "OuterColor2", 3, GL_FLOAT, { 0, 0, 1, 0 }, -1 },
+ { "InnerColor", 1, GL_FLOAT_VEC3, { 1, 0, 0, 0 }, -1 },
+ { "OuterColor1", 1, GL_FLOAT_VEC3, { 0, 1, 0, 0 }, -1 },
+ { "OuterColor2", 1, GL_FLOAT_VEC3, { 0, 0, 1, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -159,7 +159,8 @@ Init(void)
glUseProgram(program);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
+ PrintUniforms(Uniforms);
uZoom = glGetUniformLocation(program, "Zoom");
uXcenter = glGetUniformLocation(program, "Xcenter");
@@ -198,7 +199,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/mandelbrot.shtest b/progs/glsl/mandelbrot.shtest
new file mode 100644
index 0000000000..4f4e5c747e
--- /dev/null
+++ b/progs/glsl/mandelbrot.shtest
@@ -0,0 +1,13 @@
+vs CH18-mandel.vert
+fs CH18-mandel.frag
+uniform LightPosition GL_FLOAT_VEC3 0.1 0.1 9.0
+uniform SpecularContribution GL_FLOAT 0.5
+uniform DiffuseContribution GL_FLOAT 0.5
+uniform Shininess GL_FLOAT 20.0
+uniform Iterations GL_FLOAT 12
+uniform Zoom GL_FLOAT 0.125
+uniform Xcenter GL_FLOAT -1.5
+uniform Ycenter GL_FLOAT .005
+uniform InnerColor GL_FLOAT_VEC3 1 0 0
+uniform OuterColor1 GL_FLOAT_VEC3 0 1 0
+uniform OuterColor2 GL_FLOAT_VEC3 0 0 1
diff --git a/progs/glsl/multinoise.c b/progs/glsl/multinoise.c
index 0afe230801..0d4026e29c 100644
--- a/progs/glsl/multinoise.c
+++ b/progs/glsl/multinoise.c
@@ -262,7 +262,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/multitex.c b/progs/glsl/multitex.c
index 5e971716ad..bf46fd5210 100644
--- a/progs/glsl/multitex.c
+++ b/progs/glsl/multitex.c
@@ -59,8 +59,8 @@ static GLint VertCoord_attr = -1, TexCoord0_attr = -1, TexCoord1_attr = -1;
/* value[0] = tex unit */
static struct uniform_info Uniforms[] = {
- { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
- { "tex2", 1, GL_INT, { 1, 0, 0, 0 }, -1 },
+ { "tex1", 1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
+ { "tex2", 1, GL_SAMPLER_2D, { 1, 0, 0, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -134,7 +134,7 @@ DrawPolygonArray(void)
if (VertCoord_attr >= 0) {
glVertexAttribPointer(VertCoord_attr, 2, GL_FLOAT, GL_FALSE,
- 0, VertCoords);
+ 0, vertPtr);
glEnableVertexAttribArray(VertCoord_attr);
}
else {
@@ -143,11 +143,11 @@ DrawPolygonArray(void)
}
glVertexAttribPointer(TexCoord0_attr, 2, GL_FLOAT, GL_FALSE,
- 0, Tex0Coords);
+ 0, tex0Ptr);
glEnableVertexAttribArray(TexCoord0_attr);
glVertexAttribPointer(TexCoord1_attr, 2, GL_FLOAT, GL_FALSE,
- 0, Tex1Coords);
+ 0, tex1Ptr);
glEnableVertexAttribArray(TexCoord1_attr);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
@@ -328,7 +328,10 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
glUseProgram(program);
- InitUniforms(program, uniforms);
+ SetUniformValues(program, uniforms);
+ PrintUniforms(Uniforms);
+
+ assert(ValidateShaderProgram(program));
VertCoord_attr = glGetAttribLocation(program, "VertCoord");
if (VertCoord_attr > 0) {
diff --git a/progs/glsl/multitex.shtest b/progs/glsl/multitex.shtest
new file mode 100644
index 0000000000..4b7c3fd4a5
--- /dev/null
+++ b/progs/glsl/multitex.shtest
@@ -0,0 +1,6 @@
+vs multitex.vert
+fs multitex.frag
+texture 0 2D ../images/tile.rgb
+texture 1 2D ../images/tree2.rgba
+uniform tex1 GL_SAMPLER_2D 0
+uniform tex2 GL_SAMPLER_2D 1
diff --git a/progs/glsl/noise.c b/progs/glsl/noise.c
index 59f594e78b..fdab263ea6 100644
--- a/progs/glsl/noise.c
+++ b/progs/glsl/noise.c
@@ -35,8 +35,8 @@ static const char *FragShaderText =
static struct uniform_info Uniforms[] = {
- { "Scale", 4, GL_FLOAT, { 0.5, 0.4, 0.0, 0}, -1 },
- { "Bias", 4, GL_FLOAT, { 0.5, 0.3, 0.0, 0}, -1 },
+ { "Scale", 1, GL_FLOAT_VEC4, { 0.5, 0.4, 0.0, 0}, -1 },
+ { "Bias", 1, GL_FLOAT_VEC4, { 0.5, 0.3, 0.0, 0}, -1 },
{ "Slice", 1, GL_FLOAT, { 0.5, 0, 0, 0}, -1 },
END_OF_UNIFORMS
};
@@ -179,7 +179,8 @@ Init(void)
glUseProgram(program);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
+ PrintUniforms(Uniforms);
assert(glGetError() == 0);
@@ -199,7 +200,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/noise2.c b/progs/glsl/noise2.c
index e972b62673..7a28f09947 100644
--- a/progs/glsl/noise2.c
+++ b/progs/glsl/noise2.c
@@ -186,7 +186,6 @@ static void Init (void)
int main (int argc, char *argv[])
{
glutInit (&argc, argv);
- glutInitWindowPosition ( 0, 0);
glutInitWindowSize (200, 200);
glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow (argv[0]);
diff --git a/progs/glsl/pointcoord.c b/progs/glsl/pointcoord.c
index 27b73a05de..5dced6fac3 100644
--- a/progs/glsl/pointcoord.c
+++ b/progs/glsl/pointcoord.c
@@ -187,7 +187,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/samplers.c b/progs/glsl/samplers.c
index 113e5bbeff..87dad5d857 100644
--- a/progs/glsl/samplers.c
+++ b/progs/glsl/samplers.c
@@ -211,10 +211,18 @@ InitTextures(void)
for (y = 0; y < stripeSize; y++) {
for (x = 0; x < size; x++) {
GLint k = 4 * ((ypos + y) * size + x);
- texImage[k + 0] = intensity;
- texImage[k + 1] = intensity;
- texImage[k + 2] = 0;
- texImage[k + 3] = 255;
+ if (x < size / 2) {
+ texImage[k + 0] = intensity;
+ texImage[k + 1] = intensity;
+ texImage[k + 2] = 0;
+ texImage[k + 3] = 255;
+ }
+ else {
+ texImage[k + 0] = 255 - intensity;
+ texImage[k + 1] = 0;
+ texImage[k + 2] = 0;
+ texImage[k + 3] = 255;
+ }
}
}
diff --git a/progs/glsl/shadow_sampler.c b/progs/glsl/shadow_sampler.c
index 0a4d04dd8c..0adc9d88ba 100644
--- a/progs/glsl/shadow_sampler.c
+++ b/progs/glsl/shadow_sampler.c
@@ -321,7 +321,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 300);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/shtest.c b/progs/glsl/shtest.c
new file mode 100644
index 0000000000..628a7dd5b9
--- /dev/null
+++ b/progs/glsl/shtest.c
@@ -0,0 +1,709 @@
+/*
+ * Simple shader test harness.
+ * Brian Paul
+ * 13 Aug 2009
+ *
+ * Usage:
+ * shtest --vs vertShaderFile --fs fragShaderFile
+ *
+ * In this case the given vertex/frag shaders are read and compiled.
+ * Random values are assigned to the uniforms.
+ *
+ * or:
+ * shtest configFile
+ *
+ * In this case a config file is read that specifies the file names
+ * of the shaders plus initial values for uniforms.
+ *
+ * Example config file:
+ *
+ * vs shader.vert
+ * fs shader.frag
+ * uniform pi 3.14159
+ * uniform v1 1.0 0.5 0.2 0.3
+ * texture 0 2D texture0.rgb
+ * texture 1 CUBE texture1.rgb
+ * texture 2 RECT texture2.rgb
+ *
+ */
+
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <GL/glew.h>
+#include <GL/glu.h>
+#include <GL/glut.h>
+#include "shaderutil.h"
+#include "readtex.h"
+
+
+typedef enum
+{
+ SPHERE,
+ CUBE,
+ NUM_SHAPES
+} shape;
+
+
+static char *FragShaderFile = NULL;
+static char *VertShaderFile = NULL;
+static char *ConfigFile = NULL;
+
+/* program/shader objects */
+static GLuint fragShader;
+static GLuint vertShader;
+static GLuint Program;
+
+
+#define MAX_UNIFORMS 100
+static struct uniform_info Uniforms[MAX_UNIFORMS];
+static GLuint NumUniforms = 0;
+
+
+#define MAX_ATTRIBS 100
+static struct attrib_info Attribs[MAX_ATTRIBS];
+static GLuint NumAttribs = 0;
+
+
+/**
+ * Config file info.
+ */
+struct config_file
+{
+ struct name_value
+ {
+ char name[100];
+ float value[4];
+ int type;
+ } uniforms[100];
+
+ int num_uniforms;
+};
+
+
+static GLint win = 0;
+static GLboolean Anim = GL_FALSE;
+static GLfloat TexRot = 0.0;
+static GLfloat xRot = 0.0f, yRot = 0.0f, zRot = 0.0f;
+static shape Object = SPHERE;
+
+
+static float
+RandomFloat(float min, float max)
+{
+ int k = rand() % 10000;
+ float x = min + (max - min) * k / 10000.0;
+ return x;
+}
+
+
+/** Set new random values for uniforms */
+static void
+RandomUniformValues(void)
+{
+ GLuint i;
+ for (i = 0; i < NumUniforms; i++) {
+ switch (Uniforms[i].type) {
+ case GL_FLOAT:
+ Uniforms[i].value[0] = RandomFloat(0.0, 1.0);
+ break;
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
+ /* don't change sampler values - random values are bad */
+ break;
+ default:
+ Uniforms[i].value[0] = RandomFloat(-1.0, 2.0);
+ Uniforms[i].value[1] = RandomFloat(-1.0, 2.0);
+ Uniforms[i].value[2] = RandomFloat(-1.0, 2.0);
+ Uniforms[i].value[3] = RandomFloat(-1.0, 2.0);
+ }
+ }
+}
+
+
+static void
+Idle(void)
+{
+ yRot += 2.0;
+ if (yRot > 360.0)
+ yRot -= 360.0;
+ glutPostRedisplay();
+}
+
+
+
+static void
+SquareVertex(GLfloat s, GLfloat t, GLfloat size)
+{
+ GLfloat x = -size + s * 2.0 * size;
+ GLfloat y = -size + t * 2.0 * size;
+ GLuint i;
+
+ glMultiTexCoord2f(GL_TEXTURE0, s, t);
+ glMultiTexCoord2f(GL_TEXTURE1, s, t);
+ glMultiTexCoord2f(GL_TEXTURE2, s, t);
+ glMultiTexCoord2f(GL_TEXTURE3, s, t);
+
+ /* assign (s,t) to the generic attributes */
+ for (i = 0; i < NumAttribs; i++) {
+ if (Attribs[i].location >= 0) {
+ glVertexAttrib2f(Attribs[i].location, s, t);
+ }
+ }
+
+ glVertex2f(x, y);
+}
+
+
+/*
+ * Draw a square, specifying normal and tangent vectors.
+ */
+static void
+Square(GLfloat size)
+{
+ GLint tangentAttrib = 1;
+ glNormal3f(0, 0, 1);
+ glVertexAttrib3f(tangentAttrib, 1, 0, 0);
+ glBegin(GL_POLYGON);
+#if 1
+ SquareVertex(0, 0, size);
+ SquareVertex(1, 0, size);
+ SquareVertex(1, 1, size);
+ SquareVertex(0, 1, size);
+#else
+ glTexCoord2f(0, 0); glVertex2f(-size, -size);
+ glTexCoord2f(1, 0); glVertex2f( size, -size);
+ glTexCoord2f(1, 1); glVertex2f( size, size);
+ glTexCoord2f(0, 1); glVertex2f(-size, size);
+#endif
+ glEnd();
+}
+
+
+static void
+Cube(GLfloat size)
+{
+ /* +X */
+ glPushMatrix();
+ glRotatef(90, 0, 1, 0);
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+
+ /* -X */
+ glPushMatrix();
+ glRotatef(-90, 0, 1, 0);
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+
+ /* +Y */
+ glPushMatrix();
+ glRotatef(90, 1, 0, 0);
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+
+ /* -Y */
+ glPushMatrix();
+ glRotatef(-90, 1, 0, 0);
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+
+
+ /* +Z */
+ glPushMatrix();
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+
+ /* -Z */
+ glPushMatrix();
+ glRotatef(180, 0, 1, 0);
+ glTranslatef(0, 0, size);
+ Square(size);
+ glPopMatrix();
+}
+
+
+static void
+Sphere(GLfloat radius, GLint slices, GLint stacks)
+{
+ static GLUquadricObj *q = NULL;
+
+ if (!q) {
+ q = gluNewQuadric();
+ gluQuadricDrawStyle(q, GLU_FILL);
+ gluQuadricNormals(q, GLU_SMOOTH);
+ gluQuadricTexture(q, GL_TRUE);
+ }
+
+ gluSphere(q, radius, slices, stacks);
+}
+
+
+static void
+Redisplay(void)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(xRot, 1.0f, 0.0f, 0.0f);
+ glRotatef(yRot, 0.0f, 1.0f, 0.0f);
+ glRotatef(zRot, 0.0f, 0.0f, 1.0f);
+
+ glMatrixMode(GL_TEXTURE);
+ glLoadIdentity();
+ glRotatef(TexRot, 0.0f, 1.0f, 0.0f);
+ glMatrixMode(GL_MODELVIEW);
+
+ if (Object == SPHERE) {
+ Sphere(2.5, 20, 10);
+ }
+ else if (Object == CUBE) {
+ Cube(2.0);
+ }
+
+ glPopMatrix();
+
+ glutSwapBuffers();
+}
+
+
+static void
+Reshape(int width, int 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.0f, 0.0f, -15.0f);
+}
+
+
+static void
+CleanUp(void)
+{
+ glDeleteShader(fragShader);
+ glDeleteShader(vertShader);
+ glDeleteProgram(Program);
+ glutDestroyWindow(win);
+}
+
+
+static void
+Key(unsigned char key, int x, int y)
+{
+ const GLfloat step = 2.0;
+ (void) x;
+ (void) y;
+
+ switch(key) {
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'z':
+ zRot += step;
+ break;
+ case 'Z':
+ zRot -= step;
+ break;
+ case 'o':
+ Object = (Object + 1) % NUM_SHAPES;
+ break;
+ case 'r':
+ RandomUniformValues();
+ SetUniformValues(Program, Uniforms);
+ PrintUniforms(Uniforms);
+ break;
+ case 27:
+ CleanUp();
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+
+static void
+SpecialKey(int key, int x, int y)
+{
+ const GLfloat step = 2.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();
+}
+
+
+static void
+InitUniforms(const struct config_file *conf,
+ struct uniform_info uniforms[])
+{
+ int i;
+
+ for (i = 0; i < conf->num_uniforms; i++) {
+ int j;
+ for (j = 0; uniforms[j].name; j++) {
+ if (strcmp(uniforms[j].name, conf->uniforms[i].name) == 0) {
+ uniforms[j].type = conf->uniforms[i].type;
+ uniforms[j].value[0] = conf->uniforms[i].value[0];
+ uniforms[j].value[1] = conf->uniforms[i].value[1];
+ uniforms[j].value[2] = conf->uniforms[i].value[2];
+ uniforms[j].value[3] = conf->uniforms[i].value[3];
+ }
+ }
+ }
+}
+
+
+static void
+LoadTexture(GLint unit, GLenum target, const char *texFileName)
+{
+ GLint imgWidth, imgHeight;
+ GLenum imgFormat;
+ GLubyte *image = NULL;
+ GLuint tex;
+ GLenum filter = GL_LINEAR;
+ GLenum objTarget;
+
+ image = LoadRGBImage(texFileName, &imgWidth, &imgHeight, &imgFormat);
+ if (!image) {
+ printf("Couldn't read %s\n", texFileName);
+ exit(1);
+ }
+
+ printf("Load Texture: unit %d, target 0x%x: %s %d x %d\n",
+ unit, target, texFileName, imgWidth, imgHeight);
+
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
+ objTarget = GL_TEXTURE_CUBE_MAP;
+ }
+ else {
+ objTarget = target;
+ }
+
+ glActiveTexture(GL_TEXTURE0 + unit);
+ glGenTextures(1, &tex);
+ glBindTexture(objTarget, tex);
+
+ if (target == GL_TEXTURE_3D) {
+ /* depth=1 */
+ gluBuild3DMipmaps(target, 4, imgWidth, imgHeight, 1,
+ imgFormat, GL_UNSIGNED_BYTE, image);
+ }
+ else if (target == GL_TEXTURE_1D) {
+ gluBuild1DMipmaps(target, 4, imgWidth,
+ imgFormat, GL_UNSIGNED_BYTE, image);
+ }
+ else {
+ gluBuild2DMipmaps(target, 4, imgWidth, imgHeight,
+ imgFormat, GL_UNSIGNED_BYTE, image);
+ }
+
+ free(image);
+
+ glTexParameteri(objTarget, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(objTarget, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(objTarget, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(objTarget, GL_TEXTURE_MAG_FILTER, filter);
+}
+
+
+static GLenum
+TypeFromName(const char *n)
+{
+ static const struct {
+ const char *name;
+ GLenum type;
+ } types[] = {
+ { "GL_FLOAT", GL_FLOAT },
+ { "GL_FLOAT_VEC2", GL_FLOAT_VEC2 },
+ { "GL_FLOAT_VEC3", GL_FLOAT_VEC3 },
+ { "GL_FLOAT_VEC4", GL_FLOAT_VEC4 },
+ { "GL_INT", GL_INT },
+ { "GL_INT_VEC2", GL_INT_VEC2 },
+ { "GL_INT_VEC3", GL_INT_VEC3 },
+ { "GL_INT_VEC4", GL_INT_VEC4 },
+ { "GL_SAMPLER_1D", GL_SAMPLER_1D },
+ { "GL_SAMPLER_2D", GL_SAMPLER_2D },
+ { "GL_SAMPLER_3D", GL_SAMPLER_3D },
+ { "GL_SAMPLER_CUBE", GL_SAMPLER_CUBE },
+ { "GL_SAMPLER_2D_RECT", GL_SAMPLER_2D_RECT_ARB },
+ { NULL, 0 }
+ };
+ GLuint i;
+
+ for (i = 0; types[i].name; i++) {
+ if (strcmp(types[i].name, n) == 0)
+ return types[i].type;
+ }
+ abort();
+ return GL_NONE;
+}
+
+
+
+/**
+ * Read a config file.
+ */
+static void
+ReadConfigFile(const char *filename, struct config_file *conf)
+{
+ char line[1000];
+ FILE *f;
+
+ f = fopen(filename, "r");
+ if (!f) {
+ fprintf(stderr, "Unable to open config file %s\n", filename);
+ exit(1);
+ }
+
+ conf->num_uniforms = 0;
+
+ /* ugly but functional parser */
+ while (!feof(f)) {
+ fgets(line, sizeof(line), f);
+ if (!feof(f) && line[0]) {
+ if (strncmp(line, "vs ", 3) == 0) {
+ VertShaderFile = strdup(line + 3);
+ VertShaderFile[strlen(VertShaderFile) - 1] = 0;
+ }
+ else if (strncmp(line, "fs ", 3) == 0) {
+ FragShaderFile = strdup(line + 3);
+ FragShaderFile[strlen(FragShaderFile) - 1] = 0;
+ }
+ else if (strncmp(line, "texture ", 8) == 0) {
+ char target[100], texFileName[100];
+ int unit, k;
+ k = sscanf(line + 8, "%d %s %s", &unit, target, texFileName);
+ assert(k == 3 || k == 8);
+ if (strcmp(target, "CUBE") == 0) {
+ char texFileNames[6][100];
+ k = sscanf(line + 8, "%d %s %s %s %s %s %s %s",
+ &unit, target,
+ texFileNames[0],
+ texFileNames[1],
+ texFileNames[2],
+ texFileNames[3],
+ texFileNames[4],
+ texFileNames[5]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_X, texFileNames[0]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, texFileNames[1]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, texFileNames[2]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, texFileNames[3]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, texFileNames[4]);
+ LoadTexture(unit, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, texFileNames[5]);
+ }
+ else if (!strcmp(target, "2D")) {
+ LoadTexture(unit, GL_TEXTURE_2D, texFileName);
+ }
+ else if (!strcmp(target, "3D")) {
+ LoadTexture(unit, GL_TEXTURE_3D, texFileName);
+ }
+ else if (!strcmp(target, "RECT")) {
+ LoadTexture(unit, GL_TEXTURE_RECTANGLE_ARB, texFileName);
+ }
+ else {
+ printf("Bad texture target: %s\n", target);
+ exit(1);
+ }
+ }
+ else if (strncmp(line, "uniform ", 8) == 0) {
+ char name[1000], typeName[100];
+ int k;
+ float v1 = 0.0F, v2 = 0.0F, v3 = 0.0F, v4 = 0.0F;
+ GLenum type;
+
+ k = sscanf(line + 8, "%s %s %f %f %f %f", name, typeName,
+ &v1, &v2, &v3, &v4);
+
+ type = TypeFromName(typeName);
+
+ strcpy(conf->uniforms[conf->num_uniforms].name, name);
+ conf->uniforms[conf->num_uniforms].value[0] = v1;
+ conf->uniforms[conf->num_uniforms].value[1] = v2;
+ conf->uniforms[conf->num_uniforms].value[2] = v3;
+ conf->uniforms[conf->num_uniforms].value[3] = v4;
+ conf->uniforms[conf->num_uniforms].type = type;
+ conf->num_uniforms++;
+ }
+ else {
+ if (strlen(line) > 1) {
+ fprintf(stderr, "syntax error in: %s\n", line);
+ break;
+ }
+ }
+ }
+ }
+
+ fclose(f);
+}
+
+
+static void
+Init(void)
+{
+ GLdouble vertTime, fragTime, linkTime;
+ struct config_file config;
+
+ memset(&config, 0, sizeof(config));
+
+ if (ConfigFile)
+ ReadConfigFile(ConfigFile, &config);
+
+ if (!VertShaderFile) {
+ fprintf(stderr, "Error: no vertex shader\n");
+ exit(1);
+ }
+
+ if (!FragShaderFile) {
+ fprintf(stderr, "Error: no fragment shader\n");
+ exit(1);
+ }
+
+ if (!ShadersSupported())
+ exit(1);
+
+ vertShader = CompileShaderFile(GL_VERTEX_SHADER, VertShaderFile);
+ vertTime = GetShaderCompileTime();
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragShaderFile);
+ fragTime = GetShaderCompileTime();
+
+ Program = LinkShaders(vertShader, fragShader);
+ linkTime = GetShaderLinkTime();
+
+ printf("Read vert shader %s\n", VertShaderFile);
+ printf("Read frag shader %s\n", FragShaderFile);
+
+ printf("Time to compile vertex shader: %fs\n", vertTime);
+ printf("Time to compile fragment shader: %fs\n", fragTime);
+ printf("Time to link shaders: %fs\n", linkTime);
+
+ assert(ValidateShaderProgram(Program));
+
+ glUseProgram(Program);
+
+ NumUniforms = GetUniforms(Program, Uniforms);
+ if (config.num_uniforms) {
+ InitUniforms(&config, Uniforms);
+ }
+ else {
+ RandomUniformValues();
+ }
+ SetUniformValues(Program, Uniforms);
+ PrintUniforms(Uniforms);
+
+ NumAttribs = GetAttribs(Program, Attribs);
+ PrintAttribs(Attribs);
+
+ //assert(glGetError() == 0);
+
+ glClearColor(0.4f, 0.4f, 0.8f, 0.0f);
+
+ glEnable(GL_DEPTH_TEST);
+
+ glColor3f(1, 0, 0);
+}
+
+
+static void
+Keys(void)
+{
+ printf("Keyboard:\n");
+ printf(" a Animation toggle\n");
+ printf(" r Randomize uniform values\n");
+ printf(" o Change object\n");
+ printf(" arrows Rotate object\n");
+ printf(" ESC Exit\n");
+}
+
+
+static void
+Usage(void)
+{
+ printf("Usage:\n");
+ printf(" shtest config.shtest\n");
+ printf(" Run w/ given config file.\n");
+ printf(" shtest --vs vertShader --fs fragShader\n");
+ printf(" Load/compile given shaders.\n");
+}
+
+
+static void
+ParseOptions(int argc, char *argv[])
+{
+ int i;
+
+ if (argc == 1) {
+ Usage();
+ exit(1);
+ }
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "--fs") == 0) {
+ FragShaderFile = argv[i+1];
+ i++;
+ }
+ else if (strcmp(argv[i], "--vs") == 0) {
+ VertShaderFile = argv[i+1];
+ i++;
+ }
+ else {
+ /* assume the arg is a config file */
+ ConfigFile = argv[i];
+ break;
+ }
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ glutInitWindowSize(400, 400);
+ glutInit(&argc, argv);
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
+ win = glutCreateWindow(argv[0]);
+ glewInit();
+ glutReshapeFunc(Reshape);
+ glutKeyboardFunc(Key);
+ glutSpecialFunc(SpecialKey);
+ glutDisplayFunc(Redisplay);
+ ParseOptions(argc, argv);
+ Init();
+ Keys();
+ glutMainLoop();
+ return 0;
+}
+
diff --git a/progs/glsl/texaaline.c b/progs/glsl/texaaline.c
index 1f566c86a6..7a5ac405bb 100644
--- a/progs/glsl/texaaline.c
+++ b/progs/glsl/texaaline.c
@@ -103,6 +103,8 @@ static float Sin(float a)
static void
Redisplay(void)
{
+ float cx = 0.5 * WinWidth, cy = 0.5 * WinHeight;
+ float len = 0.5 * WinWidth - 20.0;
int i;
glClear(GL_COLOR_BUFFER_BIT);
@@ -114,20 +116,20 @@ Redisplay(void)
for (i = 0; i < 360; i+=5) {
float v0[2], v1[2];
- v0[0] = 150 + 40 * Cos(i);
- v0[1] = 150 + 40 * Sin(i);
- v1[0] = 150 + 130 * Cos(i);
- v1[1] = 150 + 130 * Sin(i);
+ v0[0] = cx + 40 * Cos(i);
+ v0[1] = cy + 40 * Sin(i);
+ v1[0] = cx + len * Cos(i);
+ v1[1] = cy + len * Sin(i);
QuadLine(v0, v1, Width);
}
{
float v0[2], v1[2], x;
for (x = 0; x < 1.0; x += 0.2) {
- v0[0] = 150 + x;
- v0[1] = 150 + x * 40 - 20;
- v1[0] = 150 + x + 5.0;
- v1[1] = 150 + x * 40 - 20;
+ v0[0] = cx + x;
+ v0[1] = cy + x * 40 - 20;
+ v1[0] = cx + x + 5.0;
+ v1[1] = cy + x * 40 - 20;
QuadLine(v0, v1, Width);
}
}
@@ -142,6 +144,8 @@ Redisplay(void)
static void
Reshape(int width, int height)
{
+ WinWidth = width;
+ WinHeight = height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -351,7 +355,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/texdemo1.c b/progs/glsl/texdemo1.c
index d55f9e7dd9..5b1913a722 100644
--- a/progs/glsl/texdemo1.c
+++ b/progs/glsl/texdemo1.c
@@ -53,14 +53,14 @@ static int win = 0;
static struct uniform_info ReflectUniforms[] = {
- { "cubeTex", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
- { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 },
+ { "cubeTex", 1, GL_SAMPLER_CUBE, { 0, 0, 0, 0 }, -1 },
+ { "lightPos", 1, GL_FLOAT_VEC3, { 10, 10, 20, 0 }, -1 },
END_OF_UNIFORMS
};
static struct uniform_info SimpleUniforms[] = {
- { "tex2d", 1, GL_INT, { 1, 0, 0, 0 }, -1 },
- { "lightPos", 3, GL_FLOAT, { 10, 10, 20, 0 }, -1 },
+ { "tex2d", 1, GL_SAMPLER_2D, { 1, 0, 0, 0 }, -1 },
+ { "lightPos", 1, GL_FLOAT_VEC3, { 10, 10, 20, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -382,7 +382,8 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
glUseProgram(program);
- InitUniforms(program, uniforms);
+ SetUniformValues(program, uniforms);
+ PrintUniforms(uniforms);
return program;
}
diff --git a/progs/glsl/toyball.c b/progs/glsl/toyball.c
index 7fe27aebfe..c502f24077 100644
--- a/progs/glsl/toyball.c
+++ b/progs/glsl/toyball.c
@@ -24,18 +24,18 @@ static GLuint program;
static struct uniform_info Uniforms[] = {
- { "LightDir", 4, GL_FLOAT, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
- { "HVector", 4, GL_FLOAT, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 },
- { "BallCenter", 4, GL_FLOAT, { 0.0, 0.0, 0.0, 1.0 }, -1 },
- { "SpecularColor", 4, GL_FLOAT, { 0.4, 0.4, 0.4, 60.0 }, -1 },
- { "Red", 4, GL_FLOAT, { 0.6, 0.0, 0.0, 1.0 }, -1 },
- { "Blue", 4, GL_FLOAT, { 0.0, 0.3, 0.6, 1.0 }, -1 },
- { "Yellow", 4, GL_FLOAT, { 0.6, 0.5, 0.0, 1.0 }, -1 },
- { "HalfSpace0", 4, GL_FLOAT, { 1.0, 0.0, 0.0, 0.2 }, -1 },
- { "HalfSpace1", 4, GL_FLOAT, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 },
- { "HalfSpace2", 4, GL_FLOAT, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 },
- { "HalfSpace3", 4, GL_FLOAT, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 },
- { "HalfSpace4", 4, GL_FLOAT, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 },
+ { "LightDir", 1, GL_FLOAT_VEC4, { 0.57737, 0.57735, 0.57735, 0.0 }, -1 },
+ { "HVector", 1, GL_FLOAT_VEC4, { 0.32506, 0.32506, 0.88808, 0.0 }, -1 },
+ { "BallCenter", 1, GL_FLOAT_VEC4, { 0.0, 0.0, 0.0, 1.0 }, -1 },
+ { "SpecularColor", 1, GL_FLOAT_VEC4, { 0.4, 0.4, 0.4, 60.0 }, -1 },
+ { "Red", 1, GL_FLOAT_VEC4, { 0.6, 0.0, 0.0, 1.0 }, -1 },
+ { "Blue", 1, GL_FLOAT_VEC4, { 0.0, 0.3, 0.6, 1.0 }, -1 },
+ { "Yellow", 1, GL_FLOAT_VEC4, { 0.6, 0.5, 0.0, 1.0 }, -1 },
+ { "HalfSpace0", 1, GL_FLOAT_VEC4, { 1.0, 0.0, 0.0, 0.2 }, -1 },
+ { "HalfSpace1", 1, GL_FLOAT_VEC4, { 0.309016994, 0.951056516, 0.0, 0.2 }, -1 },
+ { "HalfSpace2", 1, GL_FLOAT_VEC4, { -0.809016994, 0.587785252, 0.0, 0.2 }, -1 },
+ { "HalfSpace3", 1, GL_FLOAT_VEC4, { -0.809016994, -0.587785252, 0.0, 0.2 }, -1 },
+ { "HalfSpace4", 1, GL_FLOAT_VEC4, { 0.309116994, -0.951056516, 0.0, 0.2 }, -1 },
{ "InOrOutInit", 1, GL_FLOAT, { -3.0, 0, 0, 0 }, -1 },
{ "StripeWidth", 1, GL_FLOAT, { 0.3, 0, 0, 0 }, -1 },
{ "FWidth", 1, GL_FLOAT, { 0.005, 0, 0, 0 }, -1 },
@@ -173,7 +173,8 @@ Init(void)
glUseProgram(program);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
+ PrintUniforms(Uniforms);
assert(glGetError() == 0);
@@ -204,7 +205,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 400);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/toyball.shtest b/progs/glsl/toyball.shtest
new file mode 100644
index 0000000000..887663abd3
--- /dev/null
+++ b/progs/glsl/toyball.shtest
@@ -0,0 +1,17 @@
+vs CH11-toyball.vert
+fs CH11-toyball.frag
+uniform LightDir GL_FLOAT_VEC4 0.57737 0.57735 0.57735 0.0
+uniform HVector GL_FLOAT_VEC4 0.32506 0.32506 0.88808 0.0
+uniform BallCenter GL_FLOAT_VEC4 0.0 0.0 0.0 1.0
+uniform SpecularColor GL_FLOAT_VEC4 0.4 0.4 0.4 60.0
+uniform Red GL_FLOAT_VEC4 0.6 0.0 0.0 1.0
+uniform Blue GL_FLOAT_VEC4 0.0 0.3 0.6 1.0
+uniform Yellow GL_FLOAT_VEC4 0.6 0.5 0.0 1.0
+uniform HalfSpace0 GL_FLOAT_VEC4 1.0 0.0 0.0 0.2
+uniform HalfSpace1 GL_FLOAT_VEC4 .309016994 0.951056516 0.0 0.2
+uniform HalfSpace2 GL_FLOAT_VEC4 -0.809016994 0.587785252 0.0 0.2
+uniform HalfSpace3 GL_FLOAT_VEC4 -0.809016994 -0.587785252 0.0 0.2
+uniform HalfSpace4 GL_FLOAT_VEC4 .309116994 -0.951056516 0.0 0.2
+uniform InOrOutInit GL_FLOAT -3.0
+uniform StripeWidth GL_FLOAT 0.3
+uniform FWidth GL_FLOAT .005
diff --git a/progs/glsl/trirast.c b/progs/glsl/trirast.c
index f7546f25a2..53bd91ef97 100644
--- a/progs/glsl/trirast.c
+++ b/progs/glsl/trirast.c
@@ -239,7 +239,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/twoside.c b/progs/glsl/twoside.c
index b6c1b477dd..a57484f96c 100644
--- a/progs/glsl/twoside.c
+++ b/progs/glsl/twoside.c
@@ -285,7 +285,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE);
win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/vert-or-frag-only.c b/progs/glsl/vert-or-frag-only.c
index 81fcab8c5b..148991ca83 100644
--- a/progs/glsl/vert-or-frag-only.c
+++ b/progs/glsl/vert-or-frag-only.c
@@ -173,7 +173,6 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition( 0, 0);
glutInitWindowSize(400, 200);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Win = glutCreateWindow(argv[0]);
diff --git a/progs/glsl/vert-tex.c b/progs/glsl/vert-tex.c
index e791a5759a..4c8bfa587a 100644
--- a/progs/glsl/vert-tex.c
+++ b/progs/glsl/vert-tex.c
@@ -43,7 +43,7 @@ static GLfloat xRot = -70.0f, yRot = 0.0f, zRot = 0.0f;
/* value[0] = tex unit */
static struct uniform_info Uniforms[] = {
- { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
+ { "tex1", 1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
END_OF_UNIFORMS
};
diff --git a/progs/openvg/demos/Makefile b/progs/openvg/demos/Makefile
index 6e15342c7f..89b0ce441b 100644
--- a/progs/openvg/demos/Makefile
+++ b/progs/openvg/demos/Makefile
@@ -3,7 +3,7 @@
TOP = ../../..
include $(TOP)/configs/current
-VG_LIBS=-lm -pthread -lEGL -lOpenVG
+VG_LIBS=-lm -pthread -lX11 -lEGL -lOpenVG
INCLUDE_DIRS = -I$(TOP)/include
PROGRAMS = \
diff --git a/progs/openvg/trivial/Makefile b/progs/openvg/trivial/Makefile
index 362360e596..fcb3484377 100644
--- a/progs/openvg/trivial/Makefile
+++ b/progs/openvg/trivial/Makefile
@@ -5,7 +5,7 @@ TOP = ../../../
include $(TOP)/configs/current
INCLUDES = -I. -I$(TOP)/include
-LIBS=-L$(TOP)/$(LIB_DIR) -lm -lEGL -lOpenVG -lpthread
+LIBS=-L$(TOP)/$(LIB_DIR) -lm -lX11 -lEGL -lOpenVG -lpthread
CFLAGS += $(INCLUDES)
HEADERS=eglcommon.h
diff --git a/progs/perf/Makefile b/progs/perf/Makefile
new file mode 100644
index 0000000000..f078082685
--- /dev/null
+++ b/progs/perf/Makefile
@@ -0,0 +1,53 @@
+# 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 \
+ 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 0000000000..acd6564e14
--- /dev/null
+++ b/progs/perf/SConscript
@@ -0,0 +1,30 @@
+Import('env')
+
+if not env['GLUT']:
+ Return()
+
+env = env.Clone()
+
+env.Prepend(LIBS = ['$GLUT_LIB'])
+
+progs = [
+ 'copytex',
+ 'drawoverhead',
+ 'fbobind',
+ 'fill',
+ 'teximage',
+ 'swapbuffers',
+ '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 0000000000..722f4b7b45
--- /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/src/gallium/state_trackers/glx/xlib/fakeglx.h b/progs/perf/common.h
index e5fd960072..6ea17402b5 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx.h
+++ b/progs/perf/common.h
@@ -1,9 +1,5 @@
-
/*
- * Mesa 3-D graphics library
- * Version: 3.5
- *
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -18,24 +14,31 @@
* THE SOFTWARE IS PROVIDED "AS 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
+ * 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 FAKEGLX_H
-#define FAKEGLX_H
+#ifndef COMMON_H
+#define COMMON_H
+
+
+#include <stddef.h> /* for offsetof() */
+
+typedef void (*PerfRateFunc)(unsigned count);
-#include <X11/Xlib.h>
-struct _glxapi_table;
+extern double
+PerfMeasureRate(PerfRateFunc f);
-extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void);
+const char *
+PerfHumanFloat( double d );
-extern void Fake_glXUseXFont( Font font, int first, int count, int listbase );
+extern void
+perf_printf(const char *format, ...);
-#endif
+#endif /* COMMON_H */
diff --git a/progs/perf/copytex.c b/progs/perf/copytex.c
new file mode 100644
index 0000000000..f7a6b8aec3
--- /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 0000000000..f75c9bb74e
--- /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 0000000000..fb52a93a2f
--- /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 0000000000..279f2b5f18
--- /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/glmain.c b/progs/perf/glmain.c
new file mode 100644
index 0000000000..a167be042e
--- /dev/null
+++ b/progs/perf/glmain.c
@@ -0,0 +1,267 @@
+/*
+ * 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[1] != '.') {
+ fprintf(stderr, "Error: GL version 2.x 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);
+ 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 0000000000..d9bcd5f4e2
--- /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/swapbuffers.c b/progs/perf/swapbuffers.c
new file mode 100644
index 0000000000..63c7fc06f9
--- /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 0000000000..a3005d0bef
--- /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 0000000000..a9d4102de9
--- /dev/null
+++ b/progs/perf/vbo.c
@@ -0,0 +1,245 @@
+/*
+ * 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);
+ 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 0000000000..b5355525d0
--- /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/samples/select.c b/progs/samples/select.c
index 2c8f333bfa..31ed93b9e0 100644
--- a/progs/samples/select.c
+++ b/progs/samples/select.c
@@ -92,6 +92,12 @@ static void Init(void)
numObjects = 10;
InitObjects(numObjects);
glGetIntegerv(GL_VIEWPORT, vp);
+
+#if 0 /* debug - test culling */
+ glCullFace(GL_BACK);
+ glFrontFace(GL_CW);
+ glEnable(GL_CULL_FACE);
+#endif
}
static void Reshape(int width, int height)
diff --git a/progs/tests/SConscript b/progs/tests/SConscript
index b17fa90593..bb6a1d2b8a 100644
--- a/progs/tests/SConscript
+++ b/progs/tests/SConscript
@@ -72,6 +72,7 @@ progs = [
'fogcoord',
'fptest1',
'fptexture',
+ 'getteximage',
'glutfx',
'interleave',
'invert',
diff --git a/progs/tests/fbotest1.c b/progs/tests/fbotest1.c
index 8dac21494e..0cd7f95c35 100644
--- a/progs/tests/fbotest1.c
+++ b/progs/tests/fbotest1.c
@@ -127,7 +127,7 @@ Init( void )
if (!glutExtensionSupported("GL_EXT_framebuffer_object")) {
printf("GL_EXT_framebuffer_object not found!\n");
- /*exit(0);*/
+ exit(0);
}
printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
diff --git a/progs/tests/floattex.c b/progs/tests/floattex.c
index ad14cacdcb..39302ce3af 100644
--- a/progs/tests/floattex.c
+++ b/progs/tests/floattex.c
@@ -33,7 +33,7 @@ static const char *VertShaderText =
"} \n";
static struct uniform_info Uniforms[] = {
- { "tex1", 1, GL_INT, { 0, 0, 0, 0 }, -1 },
+ { "tex1", 1, GL_SAMPLER_2D, { 0, 0, 0, 0 }, -1 },
END_OF_UNIFORMS
};
@@ -189,7 +189,7 @@ CreateProgram(void)
glUseProgram_func(program);
- InitUniforms(program, Uniforms);
+ SetUniformValues(program, Uniforms);
return program;
}
diff --git a/progs/tests/getprocaddress.c b/progs/tests/getprocaddress.c
index ca66025d2d..a09ea58e1d 100644
--- a/progs/tests/getprocaddress.c
+++ b/progs/tests/getprocaddress.c
@@ -39,13 +39,2600 @@ typedef void (*generic_func)();
#define EQUAL(X, Y) (fabs((X) - (Y)) < 0.001)
-/**
+/* This macro simplifies the task of querying an extension function
+ * pointer and checking to see whether it resolved.
+ */
+#define DECLARE_GLFUNC_PTR(name,type) \
+ type name = (type) glXGetProcAddressARB((const GLubyte *) "gl" #name)
+
+/********************************************************************
+ * Generic helper functions used by the test functions.
+ */
+
+static void CheckGLError(int line, const char *file, const char *function)
+{
+ int errorCode;
+ glFinish();
+ errorCode = glGetError();
+ if (errorCode == GL_NO_ERROR) return;
+ while (errorCode != GL_NO_ERROR) {
+ fprintf(stderr, "OpenGL error 0x%x (%s) at line %d of file %s in function %s()\n",
+ errorCode,
+ errorCode == GL_INVALID_VALUE? "GL_INVALID_VALUE":
+ errorCode == GL_INVALID_ENUM? "GL_INVALID_ENUM":
+ errorCode == GL_INVALID_OPERATION? "GL_INVALID_OPERATION":
+ errorCode == GL_STACK_OVERFLOW? "GL_STACK_OVERFLOW":
+ errorCode == GL_STACK_UNDERFLOW? "GL_STACK_UNDERFLOW":
+ errorCode == GL_OUT_OF_MEMORY? "GL_OUT_OF_MEMORY":
+ "unknown",
+ line, file, function);
+ errorCode = glGetError();
+ }
+ fflush(stderr);
+}
+
+static GLboolean
+compare_bytes(const char *errorLabel, GLuint expectedSize,
+ const GLubyte *expectedData, GLuint actualSize, const GLubyte *actualData)
+{
+ int i;
+
+ if (expectedSize == actualSize &&
+ memcmp(expectedData, actualData, actualSize) == 0) {
+ /* All is well */
+ return GL_TRUE;
+ }
+
+ /* Trouble; we don't match. Print out why. */
+ fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
+ for (i = 0; i <= 1; i++) {
+ const GLubyte *ptr;
+ int size;
+ char *label;
+ int j;
+
+ switch(i) {
+ case 0:
+ label = "expected";
+ size = expectedSize;
+ ptr = expectedData;
+ break;
+ case 1:
+ label = " actual";
+ size = actualSize;
+ ptr = actualData;
+ break;
+ }
+
+ fprintf(stderr, " %s: size %d: {", label, size);
+ for (j = 0; j < size; j++) {
+ fprintf(stderr, "%s0x%02x", j > 0 ? ", " : "", ptr[j]);
+ }
+ fprintf(stderr, "}\n");
+ }
+
+ /* We fail if the data is unexpected. */
+ return GL_FALSE;
+}
+
+
+static GLboolean
+compare_ints(const char *errorLabel, GLuint expectedSize,
+ const GLint *expectedData, GLuint actualSize, const GLint *actualData)
+{
+ int i;
+
+ if (expectedSize == actualSize &&
+ memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
+ /* All is well */
+ return GL_TRUE;
+ }
+
+ /* Trouble; we don't match. Print out why. */
+ fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
+ for (i = 0; i <= 1; i++) {
+ const GLint *ptr;
+ int size;
+ char *label;
+ int j;
+
+ switch(i) {
+ case 0:
+ label = "expected";
+ size = expectedSize;
+ ptr = expectedData;
+ break;
+ case 1:
+ label = " actual";
+ size = actualSize;
+ ptr = actualData;
+ break;
+ }
+
+ fprintf(stderr, " %s: size %d: {", label, size);
+ for (j = 0; j < size; j++) {
+ fprintf(stderr, "%s%d", j > 0 ? ", " : "", ptr[j]);
+ }
+ fprintf(stderr, "}\n");
+ }
+
+ /* We fail if the data is unexpected. */
+ return GL_FALSE;
+}
+
+#define MAX_CONVERTED_VALUES 4
+static GLboolean
+compare_shorts_to_ints(const char *errorLabel, GLuint expectedSize,
+ const GLshort *expectedData, GLuint actualSize, const GLint *actualData)
+{
+ int i;
+ GLint convertedValues[MAX_CONVERTED_VALUES];
+
+ if (expectedSize > MAX_CONVERTED_VALUES) {
+ fprintf(stderr, "%s: too much data [need %d values, have %d values]\n",
+ errorLabel, expectedSize, MAX_CONVERTED_VALUES);
+ return GL_FALSE;
+ }
+
+ for (i = 0; i < expectedSize; i++) {
+ convertedValues[i] = (GLint) expectedData[i];
+ }
+
+ return compare_ints(errorLabel, expectedSize, convertedValues,
+ actualSize, actualData);
+}
+
+static GLboolean
+compare_floats(const char *errorLabel, GLuint expectedSize,
+ const GLfloat *expectedData, GLuint actualSize, const GLfloat *actualData)
+{
+ int i;
+
+ if (expectedSize == actualSize &&
+ memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
+ /* All is well */
+ return GL_TRUE;
+ }
+
+ /* Trouble; we don't match. Print out why. */
+ fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
+ for (i = 0; i <= 1; i++) {
+ const GLfloat *ptr;
+ int size;
+ char *label;
+ int j;
+
+ switch(i) {
+ case 0:
+ label = "expected";
+ size = expectedSize;
+ ptr = expectedData;
+ break;
+ case 1:
+ label = " actual";
+ size = actualSize;
+ ptr = actualData;
+ break;
+ }
+
+ fprintf(stderr, " %s: size %d: {", label, size);
+ for (j = 0; j < size; j++) {
+ fprintf(stderr, "%s%f", j > 0 ? ", " : "", ptr[j]);
+ }
+ fprintf(stderr, "}\n");
+ }
+
+ /* We fail if the data is unexpected. */
+ return GL_FALSE;
+}
+
+static GLboolean
+compare_doubles(const char *errorLabel, GLuint expectedSize,
+ const GLdouble *expectedData, GLuint actualSize, const GLdouble *actualData)
+{
+ int i;
+
+ if (expectedSize == actualSize ||
+ memcmp(expectedData, actualData, actualSize*sizeof(*expectedData)) == 0) {
+ /* All is well */
+ return GL_TRUE;
+ }
+
+ /* Trouble; we don't match. Print out why. */
+ fprintf(stderr, "%s: actual data is not as expected\n", errorLabel);
+ for (i = 0; i <= 1; i++) {
+ const GLdouble *ptr;
+ int size;
+ char *label;
+ int j;
+
+ switch(i) {
+ case 0:
+ label = "expected";
+ size = expectedSize;
+ ptr = expectedData;
+ break;
+ case 1:
+ label = " actual";
+ size = actualSize;
+ ptr = actualData;
+ break;
+ }
+
+ fprintf(stderr, " %s: size %d: {", label, size);
+ for (j = 0; j < size; j++) {
+ fprintf(stderr, "%s%f", j > 0 ? ", " : "", ptr[j]);
+ }
+ fprintf(stderr, "}\n");
+ }
+
+ /* We fail if the data is unexpected. */
+ return GL_FALSE;
+}
+
+/********************************************************************
+ * Functions to assist with GL_ARB_texture_compressiong testing
+ */
+
+static GLboolean
+check_texture_format_supported(GLenum format)
+{
+ GLint numFormats;
+ GLint *formats;
+ register int i;
+
+ glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB, &numFormats);
+ formats = malloc(numFormats * sizeof(GLint));
+ if (formats == NULL) {
+ fprintf(stderr, "check_texture_format_supported: could not allocate memory for %d GLints\n",
+ numFormats);
+ return GL_FALSE;
+ }
+
+ memset(formats, 0, numFormats * sizeof(GLint));
+ glGetIntegerv(GL_COMPRESSED_TEXTURE_FORMATS_ARB, formats);
+
+ for (i = 0; i < numFormats; i++) {
+ if (formats[i] == format) {
+ free(formats);
+ return GL_TRUE;
+ }
+ }
+
+ /* We didn't find the format we were looking for. Give an error. */
+#define FORMAT_NAME(x) (\
+ x == GL_COMPRESSED_RGB_FXT1_3DFX ? "GL_COMPRESSED_RGB_FXT1_3DFX" : \
+ x == GL_COMPRESSED_RGBA_FXT1_3DFX ? "GL_COMPRESSED_RGBA_FXT1_3DFX" : \
+ x == GL_COMPRESSED_RGB_S3TC_DXT1_EXT ? "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" : \
+ x == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" : \
+ x == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT" : \
+ x == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT ? "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT" : \
+ x == GL_RGB_S3TC ? "GL_RGB_S3TC" : \
+ x == GL_RGB4_S3TC ? "GL_RGB4_S3TC" : \
+ x == GL_RGBA_S3TC ? "GL_RGBA_S3TC" : \
+ x == GL_RGBA4_S3TC ? "GL_RGBA4_S3TC" : \
+ "unknown")
+ fprintf(stderr, "check_texture_format_supported: unsupported format 0x%04x [%s]\n",
+ format, FORMAT_NAME(format));
+ fprintf(stderr, "supported formats:");
+ for (i = 0; i < numFormats; i++) {
+ fprintf(stderr, " 0x%04x [%s]", formats[i], FORMAT_NAME(formats[i]));
+ }
+ fprintf(stderr, "\n");
+ return GL_FALSE;
+}
+
+/* This helper function compresses an RGBA texture and compares it
+ * against the expected compressed data. It returns GL_TRUE if all
+ * went as expected, or GL_FALSE in the case of error.
+ */
+static GLboolean
+check_texture_compression(const char *message, GLenum dimension,
+ GLint width, GLint height, GLint depth, const GLubyte *texture,
+ int expectedCompressedSize, const GLubyte *expectedCompressedData)
+{
+ /* These are the data we query about the texture. */
+ GLint isCompressed;
+ GLenum compressedFormat;
+ GLint compressedSize;
+ GLubyte *compressedData;
+
+ /* We need this function pointer to operate. */
+ DECLARE_GLFUNC_PTR(GetCompressedTexImageARB, PFNGLGETCOMPRESSEDTEXIMAGEARBPROC);
+ if (GetCompressedTexImageARB == NULL) {
+ fprintf(stderr,
+ "%s: could not query GetCompressedTexImageARB function pointer\n",
+ message);
+ return GL_FALSE;
+ }
+
+ /* Verify that we actually have the GL_COMPRESSED_RGBA_S3TC_DXT3_EXT format available. */
+ if (!check_texture_format_supported(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)) {
+ return GL_FALSE;
+ }
+
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ /* Set up the base image, requesting that the GL library compress it. */
+ switch(dimension) {
+ case GL_TEXTURE_1D:
+ glTexImage1D(GL_TEXTURE_1D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ width, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texture);
+ break;
+ case GL_TEXTURE_2D:
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ width, height, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texture);
+ break;
+ case GL_TEXTURE_3D:
+ glTexImage3D(GL_TEXTURE_3D, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ width, height, depth, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, texture);
+ break;
+ default:
+ fprintf(stderr, "%s: unknown dimension 0x%04x.\n", message, dimension);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Make sure the texture is compressed, and pull it out if it is. */
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_ARB,
+ &isCompressed);
+ if (!isCompressed) {
+ fprintf(stderr, "%s: could not compress GL_COMPRESSED_RGBA_S3TC_DXT3_EXT texture\n",
+ message);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_INTERNAL_FORMAT,
+ (GLint *)&compressedFormat);
+ if (compressedFormat != GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
+ fprintf(stderr, "%s: got internal format 0x%04x, expected GL_COMPRESSED_RGBA_S3TC_DXT3_EXT [0x%04x]\n",
+ __FUNCTION__, compressedFormat, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &compressedSize);
+ compressedData = malloc(compressedSize);
+ if (compressedData == NULL) {
+ fprintf(stderr, "%s: could not malloc %d bytes for compressed texture\n",
+ message, compressedSize);
+ return GL_FALSE;
+ }
+ memset(compressedData, 0, compressedSize);
+ (*GetCompressedTexImageARB)(dimension, 0, compressedData);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Compare it to the expected compressed data. The compare_bytes()
+ * call will print out diagnostics in the case of failure.
+ */
+ if (!compare_bytes(message,
+ expectedCompressedSize, expectedCompressedData,
+ compressedSize, compressedData)) {
+
+ free(compressedData);
+ return GL_FALSE;
+ }
+
+ /* All done. Free our allocated data and return success. */
+ free(compressedData);
+ return GL_TRUE;
+}
+
+/* We'll use one function to exercise 1D, 2D, and 3D textures. */
+
+/* The test function for compressed 3D texture images requires several
+ * different function pointers that have to be queried. This function
+ * gets all the function pointers it needs itself, and so is suitable for
+ * use to test any and all of the incorporated functions.
+ */
+
+static GLboolean
+exercise_CompressedTextures(GLenum dimension)
+{
+ /* Set up a basic (uncompressed) texture. We're doing a blue/yellow
+ * checkerboard. The 8x4/32-pixel board is well-suited to S3TC
+ * compression, which works on 4x4 blocks of pixels.
+ */
+#define B 0,0,255,255
+#define Y 255,255,0,255
+#define TEXTURE_WIDTH 16
+#define TEXTURE_HEIGHT 4
+#define TEXTURE_DEPTH 1
+ static GLubyte texture[TEXTURE_WIDTH*TEXTURE_HEIGHT*TEXTURE_DEPTH*4] = {
+ B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y,
+ B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y,
+ Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B,
+ Y, Y, B, B, Y, Y, B, B, Y, Y, B, B, Y, Y, B, B,
+ };
+#undef B
+#undef Y
+ GLubyte uncompressedTexture[TEXTURE_WIDTH*TEXTURE_HEIGHT*TEXTURE_DEPTH*4];
+
+ /* We'll use this as a texture subimage. */
+#define R 255,0,0,255
+#define G 0,255,0,255
+#define SUBTEXTURE_WIDTH 4
+#define SUBTEXTURE_HEIGHT 4
+#define SUBTEXTURE_DEPTH 1
+ static GLubyte subtexture[SUBTEXTURE_WIDTH*SUBTEXTURE_HEIGHT*SUBTEXTURE_DEPTH*4] = {
+ G, G, R, R,
+ G, G, R, R,
+ R, R, G, G,
+ R, R, G, G,
+ };
+#undef R
+#undef G
+
+ /* These are the expected compressed textures. (In the case of
+ * a failed comparison, the test program will print out the
+ * actual compressed data in a format that can be directly used
+ * here, if desired.) The brave of heart can calculate the compression
+ * themselves based on the formulae described at:
+ * http://en.wikipedia.org/wiki/S3_Texture_Compression
+ * In a nutshell, each group of 16 bytes encodes a 4x4 texture block.
+ * The first eight bytes of each group are 4-bit alpha values
+ * for each of the 16 pixels in the texture block.
+ * The next four bytes in each group are LSB-first RGB565 colors; the
+ * first two bytes are identified as the color C0, and the next two
+ * are the color C1. (Two more colors C2 and C3 will be calculated
+ * from these, but do not appear in the compression data.) The
+ * last 4 bytes of the group are sixteen 2-bit indices that, for
+ * each of the 16 pixels in the texture block, select one of the
+ * colors C0, C1, C2, or C3.
+ *
+ * For example, our blue/yellow checkerboard is made up of
+ * four identical 4x4 blocks. Each of those blocks will
+ * be encoded as: eight bytes of 0xff (16 alpha values, each 0xf),
+ * C0 as the RGB565 color yellow (0xffe0), encoded LSB-first;
+ * C1 as the RGB565 color blue (0x001f), encoded LSB-first;
+ * and 4 bytes of 16 2-bit color indices reflecting the
+ * choice of color for each of the 16 pixels:
+ * 00, 00, 01, 01, = 0x05
+ * 00, 00, 01, 01, = 0x05
+ * 01, 01, 00, 00, = 0x50
+ * 01, 01, 00, 00, = 0x50
+ */
+ static GLubyte compressedTexture[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50
+ };
+
+ /* The similar calculations for the 4x4 subtexture are left
+ * as an exercise for the reader.
+ */
+ static GLubyte compressedSubTexture[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0xf8, 0xe0, 0x07, 0x05, 0x05, 0x50, 0x50,
+ };
+
+ /* The combined texture replaces the initial blue/yellow
+ * block with the green/red block. (I'd wanted to do
+ * the more interesting exercise of putting the
+ * green/red block in the middle of the blue/yellow
+ * texture, which is a non-trivial replacement, but
+ * the attempt produces GL_INVALID_OPERATION, showing
+ * that you can only replace whole blocks of
+ * subimages with S3TC.) The combined texture looks
+ * like:
+ * G G R R B B Y Y B B Y Y B B Y Y
+ * G G R R B B Y Y B B Y Y B B Y Y
+ * R R G G Y Y B B Y Y B B Y Y B B
+ * R R G G Y Y B B Y Y B B Y Y B B
+ * which encodes just like the green/red block followed
+ * by 3 copies of the yellow/blue block.
+ */
+ static GLubyte compressedCombinedTexture[] = {
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0x00, 0xf8, 0xe0, 0x07, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50,
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+ 0xe0, 0xff, 0x1f, 0x00, 0x05, 0x05, 0x50, 0x50
+ };
+
+ /* These are the data we query about the texture. */
+ GLint queryIsCompressed;
+ GLenum queryCompressedFormat;
+ GLint queryCompressedSize;
+ GLubyte queryCompressedData[sizeof(compressedTexture)];
+
+ /* Query the function pointers we need. We actually won't need most
+ * of these (the "dimension" parameter dictates whether we're testing
+ * 1D, 2D, or 3D textures), but we'll have them all ready just in case.
+ */
+ DECLARE_GLFUNC_PTR(GetCompressedTexImageARB, PFNGLGETCOMPRESSEDTEXIMAGEARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexImage3DARB, PFNGLCOMPRESSEDTEXIMAGE3DARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexSubImage3DARB, PFNGLCOMPRESSEDTEXSUBIMAGE3DARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexImage2DARB, PFNGLCOMPRESSEDTEXIMAGE2DARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexSubImage2DARB, PFNGLCOMPRESSEDTEXSUBIMAGE2DARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexImage1DARB, PFNGLCOMPRESSEDTEXIMAGE1DARBPROC);
+ DECLARE_GLFUNC_PTR(CompressedTexSubImage1DARB, PFNGLCOMPRESSEDTEXSUBIMAGE1DARBPROC);
+
+ /* If the necessary functions are missing, we can't continue */
+ if (GetCompressedTexImageARB == NULL) {
+ fprintf(stderr, "%s: GetCompressedTexImageARB function is missing\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+ switch (dimension) {
+ case GL_TEXTURE_1D:
+ if (CompressedTexImage1DARB == NULL || CompressedTexSubImage1DARB == NULL) {
+ fprintf(stderr, "%s: 1D compressed texture functions are missing\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ };
+ break;
+ case GL_TEXTURE_2D:
+ if (CompressedTexImage2DARB == NULL || CompressedTexSubImage2DARB == NULL) {
+ fprintf(stderr, "%s: 2D compressed texture functions are missing\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ };
+ break;
+ case GL_TEXTURE_3D:
+ if (CompressedTexImage3DARB == NULL || CompressedTexSubImage3DARB == NULL) {
+ fprintf(stderr, "%s: 3D compressed texture functions are missing\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ };
+ break;
+ default:
+ fprintf(stderr, "%s: unknown texture dimension 0x%04x passed.\n",
+ __FUNCTION__, dimension);
+ return GL_FALSE;
+ }
+
+ /* Check the compression of our base texture image. */
+ if (!check_texture_compression("texture compression", dimension,
+ TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, texture,
+ sizeof(compressedTexture), compressedTexture)) {
+
+ /* Something's wrong with texture compression. The function
+ * above will have printed an appropriate error.
+ */
+ return GL_FALSE;
+ }
+
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Do the same for our texture subimage */
+ if (!check_texture_compression("subtexture compression", dimension,
+ SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT, SUBTEXTURE_DEPTH, subtexture,
+ sizeof(compressedSubTexture), compressedSubTexture)) {
+
+ /* Something's wrong with texture compression. The function
+ * above will have printed an appropriate error.
+ */
+ return GL_FALSE;
+ }
+
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Send the base compressed texture down to the hardware. */
+ switch(dimension) {
+ case GL_TEXTURE_3D:
+ (*CompressedTexImage3DARB)(GL_TEXTURE_3D, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ TEXTURE_WIDTH, TEXTURE_HEIGHT, TEXTURE_DEPTH, 0,
+ sizeof(compressedTexture), compressedTexture);
+ break;
+
+ case GL_TEXTURE_2D:
+ (*CompressedTexImage2DARB)(GL_TEXTURE_2D, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ TEXTURE_WIDTH, TEXTURE_HEIGHT, 0,
+ sizeof(compressedTexture), compressedTexture);
+ break;
+
+ case GL_TEXTURE_1D:
+ (*CompressedTexImage1DARB)(GL_TEXTURE_1D, 0,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ TEXTURE_WIDTH, 0,
+ sizeof(compressedTexture), compressedTexture);
+ break;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* For grins, query it to make sure it is as expected. */
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_ARB,
+ &queryIsCompressed);
+ if (!queryIsCompressed) {
+ fprintf(stderr, "%s: compressed texture did not come back as compressed\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_INTERNAL_FORMAT,
+ (GLint *)&queryCompressedFormat);
+ if (queryCompressedFormat != GL_COMPRESSED_RGBA_S3TC_DXT3_EXT) {
+ fprintf(stderr, "%s: got internal format 0x%04x, expected GL_COMPRESSED_RGBA_S3TC_DXT3_EXT [0x%04x]\n",
+ __FUNCTION__, queryCompressedFormat, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
+ return GL_FALSE;
+ }
+ glGetTexLevelParameteriv(dimension, 0, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB,
+ &queryCompressedSize);
+ if (queryCompressedSize != sizeof(compressedTexture)) {
+ fprintf(stderr, "%s: compressed 3D texture changed size: expected %d, actual %d\n",
+ __FUNCTION__, sizeof(compressedTexture), queryCompressedSize);
+ return GL_FALSE;
+ }
+ (*GetCompressedTexImageARB)(dimension, 0, queryCompressedData);
+ if (!compare_bytes(
+ "exercise_CompressedTextures:doublechecking compressed texture",
+ sizeof(compressedTexture), compressedTexture,
+ queryCompressedSize, queryCompressedData)) {
+ return GL_FALSE;
+ }
+
+ /* Now apply the texture subimage. The current implementation of
+ * S3TC requires that subimages be only applied to whole blocks.
+ */
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ switch(dimension) {
+ case GL_TEXTURE_3D:
+ (*CompressedTexSubImage3DARB)(GL_TEXTURE_3D, 0,
+ 0, 0, 0, /* offsets */
+ SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT, SUBTEXTURE_DEPTH,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ sizeof(compressedSubTexture), compressedSubTexture);
+ break;
+ case GL_TEXTURE_2D:
+ (*CompressedTexSubImage2DARB)(GL_TEXTURE_2D, 0,
+ 0, 0, /* offsets */
+ SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ sizeof(compressedSubTexture), compressedSubTexture);
+ break;
+ case GL_TEXTURE_1D:
+ (*CompressedTexSubImage2DARB)(GL_TEXTURE_2D, 0,
+ 0, 0, /* offsets */
+ SUBTEXTURE_WIDTH, SUBTEXTURE_HEIGHT,
+ GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
+ sizeof(compressedSubTexture), compressedSubTexture);
+ break;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query the compressed texture back now, and see that it
+ * is as expected.
+ */
+ (*GetCompressedTexImageARB)(dimension, 0, queryCompressedData);
+ if (!compare_bytes("exercise_CompressedTextures:combined texture",
+ sizeof(compressedCombinedTexture), compressedCombinedTexture,
+ queryCompressedSize, queryCompressedData)) {
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Just for the exercise, uncompress the texture and pull it out.
+ * We don't check it because the compression is lossy, so it won't
+ * compare exactly to the source texture; we just
+ * want to exercise the code paths that convert it.
+ */
+ glGetTexImage(dimension, 0, GL_RGBA, GL_UNSIGNED_BYTE, uncompressedTexture);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* If we survived this far, we pass. */
+ return GL_TRUE;
+}
+
+/**************************************************************************
+ * Functions to assist with GL_EXT_framebuffer_object and
+ * GL_EXT_framebuffer_blit testing.
+ */
+
+#define FB_STATUS_NAME(x) (\
+ x == GL_FRAMEBUFFER_COMPLETE_EXT ? "GL_FRAMEBUFFER_COMPLETE_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT" : \
+ x == GL_FRAMEBUFFER_UNSUPPORTED_EXT ? "GL_FRAMEBUFFER_UNSUPPORTED_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" : \
+ x == GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT ? "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" : \
+ "unknown")
+
+static GLboolean
+exercise_framebuffer(void)
+{
+ GLuint framebufferID = 0;
+ GLuint renderbufferID = 0;
+
+ /* Dimensions of the framebuffer and renderbuffers are arbitrary.
+ * Since they won't be shown on-screen, we can use whatever we want.
+ */
+ const GLint Width = 100;
+ const GLint Height = 100;
+
+ /* Every function we use will be referenced through function pointers.
+ * This will allow this test program to run on OpenGL implementations
+ * that *don't* implement these extensions (though the implementation
+ * used to compile them must have up-to-date header files).
+ */
+ DECLARE_GLFUNC_PTR(GenFramebuffersEXT, PFNGLGENFRAMEBUFFERSEXTPROC);
+ DECLARE_GLFUNC_PTR(IsFramebufferEXT, PFNGLISFRAMEBUFFEREXTPROC);
+ DECLARE_GLFUNC_PTR(DeleteFramebuffersEXT, PFNGLDELETEFRAMEBUFFERSEXTPROC);
+ DECLARE_GLFUNC_PTR(BindFramebufferEXT, PFNGLBINDFRAMEBUFFEREXTPROC);
+ DECLARE_GLFUNC_PTR(GenRenderbuffersEXT, PFNGLGENRENDERBUFFERSEXTPROC);
+ DECLARE_GLFUNC_PTR(IsRenderbufferEXT, PFNGLISRENDERBUFFEREXTPROC);
+ DECLARE_GLFUNC_PTR(DeleteRenderbuffersEXT, PFNGLDELETERENDERBUFFERSEXTPROC);
+ DECLARE_GLFUNC_PTR(BindRenderbufferEXT, PFNGLBINDRENDERBUFFEREXTPROC);
+ DECLARE_GLFUNC_PTR(FramebufferRenderbufferEXT, PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC);
+ DECLARE_GLFUNC_PTR(RenderbufferStorageEXT, PFNGLRENDERBUFFERSTORAGEEXTPROC);
+ DECLARE_GLFUNC_PTR(CheckFramebufferStatusEXT, PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC);
+
+ /* The BlitFramebuffer function comes from a different extension.
+ * It's possible for an implementation to implement all the above,
+ * but not BlitFramebuffer; so it's okay if this one comes back
+ * NULL, as we can still test the rest.
+ */
+ DECLARE_GLFUNC_PTR(BlitFramebufferEXT, PFNGLBLITFRAMEBUFFEREXTPROC);
+
+ /* We cannot test unless we have all the function pointers. */
+ if (
+ GenFramebuffersEXT == NULL ||
+ IsFramebufferEXT == NULL ||
+ DeleteFramebuffersEXT == NULL ||
+ BindFramebufferEXT == NULL ||
+ GenRenderbuffersEXT == NULL ||
+ IsRenderbufferEXT == NULL ||
+ DeleteRenderbuffersEXT == NULL ||
+ BindRenderbufferEXT == NULL ||
+ FramebufferRenderbufferEXT == NULL ||
+ RenderbufferStorageEXT == NULL ||
+ CheckFramebufferStatusEXT == NULL
+ ) {
+ fprintf(stderr, "%s: could not locate all framebuffer functions\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ /* Generate a framebuffer for us to play with. */
+ (*GenFramebuffersEXT)(1, &framebufferID);
+ if (framebufferID == 0) {
+ fprintf(stderr, "%s: failed to generate a frame buffer ID.\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+ /* The generated name is not a framebuffer object until bound. */
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, framebufferID);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ if (!(*IsFramebufferEXT)(framebufferID)) {
+ fprintf(stderr, "%s: generated a frame buffer ID 0x%x that wasn't a framebuffer\n",
+ __FUNCTION__, framebufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ {
+ GLint queriedFramebufferID;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &queriedFramebufferID);
+ if (queriedFramebufferID != framebufferID) {
+ fprintf(stderr, "%s: bound frame buffer 0x%x, but queried 0x%x\n",
+ __FUNCTION__, framebufferID, queriedFramebufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Create a color buffer to attach to the frame buffer object, so
+ * we can actually operate on it. We go through the same basic checks
+ * with the renderbuffer that we do with the framebuffer.
+ */
+ (*GenRenderbuffersEXT)(1, &renderbufferID);
+ if (renderbufferID == 0) {
+ fprintf(stderr, "%s: could not generate a renderbuffer ID\n",
+ __FUNCTION__);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, renderbufferID);
+ if (!(*IsRenderbufferEXT)(renderbufferID)) {
+ fprintf(stderr, "%s: generated renderbuffer 0x%x is not a renderbuffer\n",
+ __FUNCTION__, renderbufferID);
+ (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
+ (*DeleteRenderbuffersEXT)(1, &renderbufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ {
+ GLint queriedRenderbufferID = 0;
+ glGetIntegerv(GL_RENDERBUFFER_BINDING_EXT, &queriedRenderbufferID);
+ if (renderbufferID != queriedRenderbufferID) {
+ fprintf(stderr, "%s: bound renderbuffer 0x%x, but got 0x%x\n",
+ __FUNCTION__, renderbufferID, queriedRenderbufferID);
+ (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
+ (*DeleteRenderbuffersEXT)(1, &renderbufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Add the renderbuffer as a color attachment to the current
+ * framebuffer (which is our generated framebuffer).
+ */
+ (*FramebufferRenderbufferEXT)(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT,
+ GL_RENDERBUFFER_EXT, renderbufferID);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* The renderbuffer will need some dimensions and storage space. */
+ (*RenderbufferStorageEXT)(GL_RENDERBUFFER_EXT, GL_RGB, Width, Height);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* That should be everything we need. If we set up to draw and to
+ * read from our color attachment, we should be "framebuffer complete",
+ * meaning the framebuffer is ready to go.
+ */
+ glDrawBuffer(GL_COLOR_ATTACHMENT1_EXT);
+ glReadBuffer(GL_COLOR_ATTACHMENT1_EXT);
+ {
+ GLenum status = (*CheckFramebufferStatusEXT)(GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ fprintf(stderr, "%s: framebuffer not complete; status = %s [0x%x]\n",
+ __FUNCTION__, FB_STATUS_NAME(status), status);
+ glReadBuffer(0);
+ glDrawBuffer(0);
+ (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
+ (*DeleteRenderbuffersEXT)(1, &renderbufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ return GL_FALSE;
+ }
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Define the contents of the frame buffer */
+ glClearColor(0.5, 0.5, 0.5, 0.0);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* If the GL_EXT_framebuffer_blit is supported, attempt a framebuffer
+ * blit from (5,5)-(10,10) to (90,90)-(95,95). This is *not* an
+ * error if framebuffer_blit is *not* supported (as we can still
+ * effectively test the other functions).
+ */
+ if (BlitFramebufferEXT != NULL) {
+ (*BlitFramebufferEXT)(5, 5, 10, 10, 90, 90, 95, 95,
+ GL_COLOR_BUFFER_BIT, GL_NEAREST);
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* We could now test to see whether the framebuffer had the desired
+ * contents. As this is just a touch test, we'll leave that for now.
+ * Clean up and go home.
+ */
+ glReadBuffer(0);
+ glDrawBuffer(0);
+ (*BindRenderbufferEXT)(GL_RENDERBUFFER_EXT, 0);
+ (*DeleteRenderbuffersEXT)(1, &renderbufferID);
+ (*BindFramebufferEXT)(GL_FRAMEBUFFER_EXT, 0);
+ (*DeleteFramebuffersEXT)(1, &framebufferID);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ return GL_TRUE;
+}
+
+/**************************************************************************
+ * Functions to assist with GL_ARB_shader_objects testing.
+ */
+
+static void
+print_info_log(const char *message, GLhandleARB object)
+{
+ DECLARE_GLFUNC_PTR(GetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC);
+ DECLARE_GLFUNC_PTR(GetInfoLogARB, PFNGLGETINFOLOGARBPROC);
+ int logLength, queryLength;
+ char *log;
+
+ if (GetObjectParameterivARB == NULL) {
+ fprintf(stderr, "%s: could not get GetObjectParameterivARB address\n",
+ message);
+ return;
+ }
+ if (GetInfoLogARB == NULL) {
+ fprintf(stderr, "%s: could not get GetInfoLogARB address\n",
+ message);
+ return;
+ }
+
+ (*GetObjectParameterivARB)(object, GL_OBJECT_INFO_LOG_LENGTH_ARB,
+ &logLength);
+ if (logLength == 0) {
+ fprintf(stderr, "%s: info log length is 0\n", message);
+ return;
+ }
+ log = malloc(logLength);
+ if (log == NULL) {
+ fprintf(stderr, "%s: could not malloc %d bytes for info log\n",
+ message, logLength);
+ }
+ else {
+ (*GetInfoLogARB)(object, logLength, &queryLength, log);
+ fprintf(stderr, "%s: info log says '%s'\n",
+ message, log);
+ }
+ free(log);
+}
+
+static GLboolean
+exercise_uniform_start(const char *fragmentShaderText, const char *uniformName,
+ GLhandleARB *returnProgram, GLint *returnUniformLocation)
+{
+ DECLARE_GLFUNC_PTR(CreateShaderObjectARB, PFNGLCREATESHADEROBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(ShaderSourceARB, PFNGLSHADERSOURCEARBPROC);
+ DECLARE_GLFUNC_PTR(CompileShaderARB, PFNGLCOMPILESHADERARBPROC);
+ DECLARE_GLFUNC_PTR(CreateProgramObjectARB, PFNGLCREATEPROGRAMOBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(AttachObjectARB, PFNGLATTACHOBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(LinkProgramARB, PFNGLLINKPROGRAMARBPROC);
+ DECLARE_GLFUNC_PTR(UseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(ValidateProgramARB, PFNGLVALIDATEPROGRAMARBPROC);
+ DECLARE_GLFUNC_PTR(GetUniformLocationARB, PFNGLGETUNIFORMLOCATIONARBPROC);
+ DECLARE_GLFUNC_PTR(DeleteObjectARB, PFNGLDELETEOBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(GetObjectParameterivARB, PFNGLGETOBJECTPARAMETERIVARBPROC);
+ GLhandleARB fs, program;
+ GLint uniformLocation;
+ GLint shaderCompiled, programValidated;
+
+ if (CreateShaderObjectARB == NULL ||
+ ShaderSourceARB == NULL ||
+ CompileShaderARB == NULL ||
+ CreateProgramObjectARB == NULL ||
+ AttachObjectARB == NULL ||
+ LinkProgramARB == NULL ||
+ UseProgramObjectARB == NULL ||
+ ValidateProgramARB == NULL ||
+ GetUniformLocationARB == NULL ||
+ DeleteObjectARB == NULL ||
+ GetObjectParameterivARB == NULL ||
+ 0) {
+ return GL_FALSE;
+ }
+
+ /* Create the trivial fragment shader and program. For safety
+ * we'll check to make sure they compile and link correctly.
+ */
+ fs = (*CreateShaderObjectARB)(GL_FRAGMENT_SHADER_ARB);
+ (*ShaderSourceARB)(fs, 1, &fragmentShaderText, NULL);
+ (*CompileShaderARB)(fs);
+ (*GetObjectParameterivARB)(fs, GL_OBJECT_COMPILE_STATUS_ARB,
+ &shaderCompiled);
+ if (!shaderCompiled) {
+ print_info_log("shader did not compile", fs);
+ (*DeleteObjectARB)(fs);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ program = (*CreateProgramObjectARB)();
+ (*AttachObjectARB)(program, fs);
+ (*LinkProgramARB)(program);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Make sure we're going to run successfully */
+ (*ValidateProgramARB)(program);
+ (*GetObjectParameterivARB)(program, GL_OBJECT_VALIDATE_STATUS_ARB,
+ &programValidated);
+ if (!programValidated) {;
+ print_info_log("program did not validate", program);
+ (*DeleteObjectARB)(program);
+ (*DeleteObjectARB)(fs);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ /* Put the program in place. We're not allowed to assign to uniform
+ * variables used by the program until the program is put into use.
+ */
+ (*UseProgramObjectARB)(program);
+
+ /* Once the shader is in place, we're free to delete it; this
+ * won't affect the copy that's part of the program.
+ */
+ (*DeleteObjectARB)(fs);
+
+ /* Find the location index of the uniform variable we declared;
+ * the caller will ned that to set the value.
+ */
+ uniformLocation = (*GetUniformLocationARB)(program, uniformName);
+ if (uniformLocation == -1) {
+ fprintf(stderr, "%s: could not determine uniform location\n",
+ __FUNCTION__);
+ (*DeleteObjectARB)(program);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ /* All done with what we're supposed to do - return the program
+ * handle and the uniform location to the caller.
+ */
+ *returnProgram = program;
+ *returnUniformLocation = uniformLocation;
+ return GL_TRUE;
+}
+
+static void
+exercise_uniform_end(GLhandleARB program)
+{
+ DECLARE_GLFUNC_PTR(UseProgramObjectARB, PFNGLUSEPROGRAMOBJECTARBPROC);
+ DECLARE_GLFUNC_PTR(DeleteObjectARB, PFNGLDELETEOBJECTARBPROC);
+ if (UseProgramObjectARB == NULL || DeleteObjectARB == NULL) {
+ return;
+ }
+
+ /* Turn off our program by setting the special value 0, and
+ * then delete the program object.
+ */
+ (*UseProgramObjectARB)(0);
+ (*DeleteObjectARB)(program);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+}
+
+/**************************************************************************
+ * Exercises for fences
+ */
+static GLboolean
+exercise_fences(void)
+{
+ DECLARE_GLFUNC_PTR(DeleteFencesNV, PFNGLDELETEFENCESNVPROC);
+ DECLARE_GLFUNC_PTR(FinishFenceNV, PFNGLFINISHFENCENVPROC);
+ DECLARE_GLFUNC_PTR(GenFencesNV, PFNGLGENFENCESNVPROC);
+ DECLARE_GLFUNC_PTR(GetFenceivNV, PFNGLGETFENCEIVNVPROC);
+ DECLARE_GLFUNC_PTR(IsFenceNV, PFNGLISFENCENVPROC);
+ DECLARE_GLFUNC_PTR(SetFenceNV, PFNGLSETFENCENVPROC);
+ DECLARE_GLFUNC_PTR(TestFenceNV, PFNGLTESTFENCENVPROC);
+ GLuint fence;
+ GLint fenceStatus, fenceCondition;
+ int count;
+
+ /* Make sure we have all the function pointers we need. */
+ if (GenFencesNV == NULL ||
+ SetFenceNV == NULL ||
+ IsFenceNV == NULL ||
+ GetFenceivNV == NULL ||
+ TestFenceNV == NULL ||
+ FinishFenceNV == NULL ||
+ DeleteFencesNV == NULL) {
+ fprintf(stderr, "%s: don't have all the fence functions\n",
+ __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ /* Create and set a simple fence. */
+ (*GenFencesNV)(1, &fence);
+ (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Make sure it reads as a fence. */
+ if (!(*IsFenceNV)(fence)) {
+ fprintf(stderr, "%s: set fence is not a fence\n", __FUNCTION__);
+ (*DeleteFencesNV)(1, &fence);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Try to read back its current status and condition. */
+ (*GetFenceivNV)(fence, GL_FENCE_CONDITION_NV, &fenceCondition);
+ if (fenceCondition != GL_ALL_COMPLETED_NV) {
+ fprintf(stderr, "%s: expected fence condition 0x%x, got 0x%x\n",
+ __FUNCTION__, GL_ALL_COMPLETED_NV, fenceCondition);
+ (*DeleteFencesNV)(1, &fence);
+ return GL_FALSE;
+ }
+ (*GetFenceivNV)(fence, GL_FENCE_STATUS_NV, &fenceStatus);
+ if (fenceStatus != GL_TRUE && fenceStatus != GL_FALSE) {
+ fprintf(stderr,"%s: fence status should be GL_TRUE or GL_FALSE, got 0x%x\n",
+ __FUNCTION__, fenceStatus);
+ (*DeleteFencesNV)(1, &fence);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Set the fence again, query its status, and wait for it to finish
+ * two different ways: once by looping on TestFence(), and a
+ * second time by a simple call to FinishFence();
+ */
+ (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
+ glFlush();
+ count = 1;
+ while (!(*TestFenceNV)(fence)) {
+ count++;
+ if (count == 0) {
+ break;
+ }
+ }
+ if (count == 0) {
+ fprintf(stderr, "%s: fence never returned true\n", __FUNCTION__);
+ (*DeleteFencesNV)(1, &fence);
+ return GL_FALSE;
+ }
+ (*SetFenceNV)(fence, GL_ALL_COMPLETED_NV);
+ (*FinishFenceNV)(fence);
+ if ((*TestFenceNV)(fence) != GL_TRUE) {
+ fprintf(stderr, "%s: finished fence does not have status GL_TRUE\n",
+ __FUNCTION__);
+ (*DeleteFencesNV)(1, &fence);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* All done. Delete the fence and return. */
+ (*DeleteFencesNV)(1, &fence);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ return GL_TRUE;
+}
+
+/**************************************************************************
+ * Exercises for buffer objects
+ */
+enum Map_Buffer_Usage{ Use_Map_Buffer, Use_Map_Buffer_Range};
+static GLboolean
+exercise_buffer_objects(enum Map_Buffer_Usage usage)
+{
+#define BUFFER_DATA_SIZE 1024
+ GLuint bufferID;
+ GLint bufferMapped;
+ static GLubyte data[BUFFER_DATA_SIZE] = {0};
+ float *dataPtr;
+
+ /* Get the function pointers we need. These are from
+ * GL_ARB_vertex_buffer_object and are required in all
+ * cases.
+ */
+ DECLARE_GLFUNC_PTR(GenBuffersARB, PFNGLGENBUFFERSARBPROC);
+ DECLARE_GLFUNC_PTR(BindBufferARB, PFNGLBINDBUFFERARBPROC);
+ DECLARE_GLFUNC_PTR(BufferDataARB, PFNGLBUFFERDATAARBPROC);
+ DECLARE_GLFUNC_PTR(MapBufferARB, PFNGLMAPBUFFERARBPROC);
+ DECLARE_GLFUNC_PTR(UnmapBufferARB, PFNGLUNMAPBUFFERARBPROC);
+ DECLARE_GLFUNC_PTR(DeleteBuffersARB, PFNGLDELETEBUFFERSARBPROC);
+ DECLARE_GLFUNC_PTR(GetBufferParameterivARB, PFNGLGETBUFFERPARAMETERIVARBPROC);
+
+ /* These are from GL_ARB_map_buffer_range, and are optional
+ * unless we're given Use_Map_Buffer_Range. Note that they do *not*
+ * have the standard "ARB" suffixes; this is because the extension
+ * was introduced *after* a superset was standardized in OpenGL 3.0.
+ * (The extension really only exists to allow the functionality on
+ * devices that cannot implement a full OpenGL 3.0 driver.)
+ */
+ DECLARE_GLFUNC_PTR(FlushMappedBufferRange, PFNGLFLUSHMAPPEDBUFFERRANGEPROC);
+ DECLARE_GLFUNC_PTR(MapBufferRange, PFNGLMAPBUFFERRANGEPROC);
+
+ /* This is from APPLE_flush_buffer_range, and is optional even if
+ * we're given Use_Map_Buffer_Range. Test it before using it.
+ */
+ DECLARE_GLFUNC_PTR(BufferParameteriAPPLE, PFNGLBUFFERPARAMETERIAPPLEPROC);
+
+ /* Make sure we have all the function pointers we need. */
+ if (GenBuffersARB == NULL ||
+ BindBufferARB == NULL ||
+ BufferDataARB == NULL ||
+ MapBufferARB == NULL ||
+ UnmapBufferARB == NULL ||
+ DeleteBuffersARB == NULL ||
+ GetBufferParameterivARB == NULL) {
+ fprintf(stderr, "%s: missing basic MapBuffer functions\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ if (usage == Use_Map_Buffer_Range) {
+ if (FlushMappedBufferRange == NULL || MapBufferRange == NULL) {
+ fprintf(stderr, "%s: missing MapBufferRange functions\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+ }
+
+ /* Create and define a buffer */
+ (*GenBuffersARB)(1, &bufferID);
+ (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, bufferID);
+ (*BufferDataARB)(GL_ARRAY_BUFFER_ARB, BUFFER_DATA_SIZE, data,
+ GL_DYNAMIC_DRAW_ARB);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* If we're using MapBufferRange, and if the BufferParameteriAPPLE
+ * function is present, use it before mapping. This particular
+ * use is a no-op, intended just to exercise the entry point.
+ */
+ if (usage == Use_Map_Buffer_Range && BufferParameteriAPPLE != NULL) {
+ (*BufferParameteriAPPLE)(GL_ARRAY_BUFFER_ARB,
+ GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_TRUE);
+ }
+
+ /* Map it, and make sure it's mapped. */
+ switch(usage) {
+ case Use_Map_Buffer:
+ dataPtr = (float *) (*MapBufferARB)(
+ GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
+ break;
+ case Use_Map_Buffer_Range:
+ dataPtr = (float *)(*MapBufferRange)(GL_ARRAY_BUFFER_ARB,
+ 4, 16, GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT);
+ break;
+ }
+ if (dataPtr == NULL) {
+ fprintf(stderr, "%s: %s returned NULL\n", __FUNCTION__,
+ usage == Use_Map_Buffer ? "MapBuffer" : "MapBufferRange");
+ (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
+ (*DeleteBuffersARB)(1, &bufferID);
+ return GL_FALSE;
+ }
+ (*GetBufferParameterivARB)(GL_ARRAY_BUFFER_ARB, GL_BUFFER_MAPPED_ARB,
+ &bufferMapped);
+ if (!bufferMapped) {
+ fprintf(stderr, "%s: buffer should be mapped but isn't\n", __FUNCTION__);
+ (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
+ (*DeleteBuffersARB)(1, &bufferID);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Write something to it, just to make sure we don't segfault. */
+ *dataPtr = 1.5;
+
+ /* Unmap to show we're finished with the buffer. Note that if we're
+ * using MapBufferRange, we first have to flush the range we modified.
+ */
+ if (usage == Use_Map_Buffer_Range) {
+ (*FlushMappedBufferRange)(GL_ARRAY_BUFFER_ARB, 4, 16);
+ }
+ if (!(*UnmapBufferARB)(GL_ARRAY_BUFFER_ARB)) {
+ fprintf(stderr, "%s: UnmapBuffer failed\n", __FUNCTION__);
+ (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
+ (*DeleteBuffersARB)(1, &bufferID);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* All done. */
+ (*BindBufferARB)(GL_ARRAY_BUFFER_ARB, 0);
+ (*DeleteBuffersARB)(1, &bufferID);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+ return GL_TRUE;
+
+#undef BUFFER_DATA_SIZE
+}
+
+/**************************************************************************
+ * Exercises for occlusion query
+ */
+static GLboolean
+exercise_occlusion_query(void)
+{
+ GLuint queryObject;
+ GLint queryReady;
+ GLuint querySampleCount;
+ GLint queryCurrent;
+ GLint queryCounterBits;
+
+ /* Get the function pointers we need. These are from
+ * GL_ARB_vertex_buffer_object and are required in all
+ * cases.
+ */
+ DECLARE_GLFUNC_PTR(GenQueriesARB, PFNGLGENQUERIESARBPROC);
+ DECLARE_GLFUNC_PTR(BeginQueryARB, PFNGLBEGINQUERYARBPROC);
+ DECLARE_GLFUNC_PTR(GetQueryivARB, PFNGLGETQUERYIVARBPROC);
+ DECLARE_GLFUNC_PTR(EndQueryARB, PFNGLENDQUERYARBPROC);
+ DECLARE_GLFUNC_PTR(IsQueryARB, PFNGLISQUERYARBPROC);
+ DECLARE_GLFUNC_PTR(GetQueryObjectivARB, PFNGLGETQUERYOBJECTIVARBPROC);
+ DECLARE_GLFUNC_PTR(GetQueryObjectuivARB, PFNGLGETQUERYOBJECTUIVARBPROC);
+ DECLARE_GLFUNC_PTR(DeleteQueriesARB, PFNGLDELETEQUERIESARBPROC);
+
+ /* Make sure we have all the function pointers we need. */
+ if (GenQueriesARB == NULL ||
+ BeginQueryARB == NULL ||
+ GetQueryivARB == NULL ||
+ EndQueryARB == NULL ||
+ IsQueryARB == NULL ||
+ GetQueryObjectivARB == NULL ||
+ GetQueryObjectuivARB == NULL ||
+ DeleteQueriesARB == NULL) {
+ fprintf(stderr, "%s: don't have all the Query functions\n", __FUNCTION__);
+ return GL_FALSE;
+ }
+
+ /* Create a query object, and start a query. */
+ (*GenQueriesARB)(1, &queryObject);
+ (*BeginQueryARB)(GL_SAMPLES_PASSED_ARB, queryObject);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* While we're in the query, check the functions that are supposed
+ * to return which query we're in and how many bits of resolution
+ * we get.
+ */
+ (*GetQueryivARB)(GL_SAMPLES_PASSED_ARB, GL_CURRENT_QUERY_ARB, &queryCurrent);
+ if (queryCurrent != queryObject) {
+ fprintf(stderr, "%s: current query 0x%x != set query 0x%x\n",
+ __FUNCTION__, queryCurrent, queryObject);
+ (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
+ (*DeleteQueriesARB)(1, &queryObject);
+ return GL_FALSE;
+ }
+ (*GetQueryivARB)(GL_SAMPLES_PASSED_ARB, GL_QUERY_COUNTER_BITS_ARB,
+ &queryCounterBits);
+ if (queryCounterBits < 1) {
+ fprintf(stderr, "%s: query counter bits is too small (%d)\n",
+ __FUNCTION__, queryCounterBits);
+ (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
+ (*DeleteQueriesARB)(1, &queryObject);
+ return GL_FALSE;
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Finish up the query. Since we didn't draw anything, the result
+ * should be 0 passed samples.
+ */
+ (*EndQueryARB)(GL_SAMPLES_PASSED_ARB);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Routine existence test */
+ if (!(*IsQueryARB)(queryObject)) {
+ fprintf(stderr, "%s: query object 0x%x fails existence test\n",
+ __FUNCTION__, queryObject);
+ (*DeleteQueriesARB)(1, &queryObject);
+ return GL_FALSE;
+ }
+
+ /* Loop until the query is ready, then get back the result. We use
+ * the signed query for the boolean value of whether the result is
+ * available, but the unsigned query to actually pull the result;
+ * this is just to test both entrypoints, but in a real query you may
+ * need the extra bit of resolution.
+ */
+ queryReady = GL_FALSE;
+ do {
+ (*GetQueryObjectivARB)(queryObject, GL_QUERY_RESULT_AVAILABLE_ARB,
+ &queryReady);
+ } while (!queryReady);
+ (*GetQueryObjectuivARB)(queryObject, GL_QUERY_RESULT_ARB, &querySampleCount);
+ (*DeleteQueriesARB)(1, &queryObject);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* If sample count isn't 0, something's funny. */
+ if (querySampleCount > 0) {
+ fprintf(stderr, "%s: expected query result of 0, got %ud\n",
+ __FUNCTION__, querySampleCount);
+ return GL_FALSE;
+ }
+
+ /* Here, all is well. */
+ return GL_TRUE;
+}
+
+/**************************************************************************
* The following functions are used to check that the named OpenGL function
* actually does what it's supposed to do.
- * The naming of these functions is signficant. The getprocaddress.py script
+ * The naming of these functions is significant. The getprocaddress.py script
* scans this file and extracts these function names.
*/
+static GLboolean
+test_WeightPointerARB(generic_func func)
+{
+ /* Assume we have at least 2 vertex units (or this extension makes
+ * no sense), and establish a set of 2-element vector weights.
+ * We use floats that can be represented exactly in binary
+ * floating point formats so we can compare correctly later.
+ * We also make sure the 0th entry matches the default weights,
+ * so we can restore the default easily.
+ */
+#define USE_VERTEX_UNITS 2
+#define USE_WEIGHT_INDEX 3
+ static GLfloat weights[] = {
+ 1.0, 0.0,
+ 0.875, 0.125,
+ 0.75, 0.25,
+ 0.625, 0.375,
+ 0.5, 0.5,
+ 0.375, 0.625,
+ 0.25, 0.75,
+ 0.125, 0.875,
+ 0.0, 1.0,
+ };
+ GLint numVertexUnits;
+ GLfloat *currentWeights;
+ int i;
+ int errorCount = 0;
+
+ PFNGLWEIGHTPOINTERARBPROC WeightPointerARB = (PFNGLWEIGHTPOINTERARBPROC) func;
+
+ /* Make sure we have at least two vertex units */
+ glGetIntegerv(GL_MAX_VERTEX_UNITS_ARB, &numVertexUnits);
+ if (numVertexUnits < USE_VERTEX_UNITS) {
+ fprintf(stderr, "%s: need %d vertex units, got %d\n",
+ __FUNCTION__, USE_VERTEX_UNITS, numVertexUnits);
+ return GL_FALSE;
+ }
+
+ /* Make sure we allocate enough room to query all the current weights */
+ currentWeights = (GLfloat *)malloc(numVertexUnits * sizeof(GLfloat));
+ if (currentWeights == NULL) {
+ fprintf(stderr, "%s: couldn't allocate room for %d floats\n",
+ __FUNCTION__, numVertexUnits);
+ return GL_FALSE;
+ }
+
+ /* Set up the pointer, enable the state, and try to send down a
+ * weight vector (we'll arbitrarily send index 2).
+ */
+ (*WeightPointerARB)(USE_VERTEX_UNITS, GL_FLOAT, 0, weights);
+ glEnableClientState(GL_WEIGHT_ARRAY_ARB);
+ glArrayElement(USE_WEIGHT_INDEX);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Verify that it changed the current state. */
+ glGetFloatv(GL_CURRENT_WEIGHT_ARB, currentWeights);
+ for (i = 0; i < numVertexUnits; i++) {
+ if (i < USE_VERTEX_UNITS) {
+ /* This is one of the units we explicitly set. */
+ if (currentWeights[i] != weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]) {
+ fprintf(stderr, "%s: current weight at index %d is %f, should be %f\n",
+ __FUNCTION__, i, currentWeights[i],
+ weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]);
+ errorCount++;
+ }
+ }
+ else {
+ /* All other weights should be 0. */
+ if (currentWeights[i] != 0.0) {
+ fprintf(stderr, "%s: current weight at index %d is %f, should be %f\n",
+ __FUNCTION__, i, 0.0,
+ weights[USE_VERTEX_UNITS*USE_WEIGHT_INDEX + i]);
+ errorCount++;
+ }
+ }
+ }
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Restore the old state. We know the default set of weights is in
+ * index 0.
+ */
+ glArrayElement(0);
+ glDisableClientState(GL_WEIGHT_ARRAY_ARB);
+ (*WeightPointerARB)(0, GL_FLOAT, 0, NULL);
+ free(currentWeights);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* We're fine if we didn't get any mismatches. */
+ if (errorCount == 0) {
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
+ }
+}
+
+/* Wrappers on the exercise_occlusion_query function */
+static GLboolean
+test_GenQueriesARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_BeginQueryARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_GetQueryivARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_EndQueryARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_IsQueryARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_GetQueryObjectivARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_GetQueryObjectuivARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+static GLboolean
+test_DeleteQueriesARB(generic_func func)
+{
+ (void) func;
+ return exercise_occlusion_query();
+}
+
+/* Wrappers on the exercise_buffer_objects() function */
+static GLboolean
+test_GenBuffersARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_BindBufferARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_BufferDataARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_MapBufferARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_UnmapBufferARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_DeleteBuffersARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_GetBufferParameterivARB(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer);
+}
+static GLboolean
+test_FlushMappedBufferRange(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer_Range);
+}
+static GLboolean
+test_MapBufferRange(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer_Range);
+}
+static GLboolean
+test_BufferParameteriAPPLE(generic_func func)
+{
+ (void) func;
+ return exercise_buffer_objects(Use_Map_Buffer_Range);
+}
+
+/* Wrappers on the exercise_framebuffer() function */
+static GLboolean
+test_BindFramebufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_BindRenderbufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_CheckFramebufferStatusEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_DeleteFramebuffersEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_DeleteRenderbuffersEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_FramebufferRenderbufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_GenFramebuffersEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_GenRenderbuffersEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_IsFramebufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_IsRenderbufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_RenderbufferStorageEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+static GLboolean
+test_BlitFramebufferEXT(generic_func func)
+{
+ (void) func;
+ return exercise_framebuffer();
+}
+
+/* These are wrappers on the exercise_CompressedTextures function.
+ * Unfortunately, we cannot test the 1D counterparts, because the
+ * texture compressions available all support 2D and higher only.
+ */
+static GLboolean
+test_CompressedTexImage2DARB(generic_func func)
+{
+ (void) func;
+ return exercise_CompressedTextures(GL_TEXTURE_2D);
+}
+static GLboolean
+test_CompressedTexSubImage2DARB(generic_func func)
+{
+ (void) func;
+ return exercise_CompressedTextures(GL_TEXTURE_2D);
+}
+static GLboolean
+test_CompressedTexImage3DARB(generic_func func)
+{
+ (void) func;
+ return exercise_CompressedTextures(GL_TEXTURE_3D);
+}
+static GLboolean
+test_CompressedTexSubImage3DARB(generic_func func)
+{
+ (void) func;
+ return exercise_CompressedTextures(GL_TEXTURE_3D);
+}
+static GLboolean
+test_GetCompressedTexImageARB(generic_func func)
+{
+ (void) func;
+ return exercise_CompressedTextures(GL_TEXTURE_3D);
+}
+
+/* Wrappers on exercise_fences(). */
+static GLboolean
+test_DeleteFencesNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_GenFencesNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_SetFenceNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_TestFenceNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_FinishFenceNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_GetFenceivNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+static GLboolean
+test_IsFenceNV(generic_func func)
+{
+ (void) func;
+ return exercise_fences();
+}
+
+/* A bunch of glUniform*() tests */
+static GLboolean
+test_Uniform1iv(generic_func func)
+{
+ PFNGLUNIFORM1IVARBPROC Uniform1ivARB = (PFNGLUNIFORM1IVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform int uniformColor;"
+ "void main() {gl_FragColor.r = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[1] = {1};
+ GLint queriedUniform[1];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * so we must set it using integer versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform1ivARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 1, uniform, 1, queriedUniform);
+}
+
+static GLboolean
+test_Uniform1i(generic_func func)
+{
+ PFNGLUNIFORM1IARBPROC Uniform1iARB = (PFNGLUNIFORM1IARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform int uniformColor;"
+ "void main() {gl_FragColor.r = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[1] = {1};
+ GLint queriedUniform[4];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * so we must set it using integer versions
+ * of the Uniform* functions.
+ */
+ (*Uniform1iARB)(uniformLocation, uniform[0]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 1, uniform, 1, queriedUniform);
+}
+
+static GLboolean
+test_Uniform1fv(generic_func func)
+{
+ PFNGLUNIFORM1FVARBPROC Uniform1fvARB = (PFNGLUNIFORM1FVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform float uniformColor;"
+ "void main() {gl_FragColor.r = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[1] = {1.1};
+ GLfloat queriedUniform[1];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * so we must set it using float versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform1fvARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 1, uniform, 1, queriedUniform);
+}
+
+static GLboolean
+test_Uniform1f(generic_func func)
+{
+ PFNGLUNIFORM1FARBPROC Uniform1fARB = (PFNGLUNIFORM1FARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform float uniformColor;"
+ "void main() {gl_FragColor.r = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[1] = {1.1};
+ GLfloat queriedUniform[1];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * so we must set it using float versions
+ * of the Uniform* functions.
+ */
+ (*Uniform1fARB)(uniformLocation, uniform[0]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 1, uniform, 1, queriedUniform);
+}
+
+static GLboolean
+test_Uniform2iv(generic_func func)
+{
+ PFNGLUNIFORM2IVARBPROC Uniform2ivARB = (PFNGLUNIFORM2IVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec2 uniformColor;"
+ "void main() {gl_FragColor.rg = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[2] = {1,2};
+ GLint queriedUniform[2];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector 2 (ivec2), so we must set it using integer versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform2ivARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 2, uniform, 2, queriedUniform);
+}
+
+static GLboolean
+test_Uniform2i(generic_func func)
+{
+ PFNGLUNIFORM2IARBPROC Uniform2iARB = (PFNGLUNIFORM2IARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec2 uniformColor;"
+ "void main() {gl_FragColor.rg = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[2] = {1,2};
+ GLint queriedUniform[4];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector 2 (ivec2), so we must set it using integer versions
+ * of the Uniform* functions.
+ */
+ (*Uniform2iARB)(uniformLocation, uniform[0], uniform[1]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 2, uniform, 2, queriedUniform);
+}
+
+static GLboolean
+test_Uniform2fv(generic_func func)
+{
+ PFNGLUNIFORM2FVARBPROC Uniform2fvARB = (PFNGLUNIFORM2FVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec2 uniformColor;"
+ "void main() {gl_FragColor.rg = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[2] = {1.1,2.2};
+ GLfloat queriedUniform[2];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * vector 2 (vec2), so we must set it using float versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform2fvARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 2, uniform, 2, queriedUniform);
+}
+
+static GLboolean
+test_Uniform2f(generic_func func)
+{
+ PFNGLUNIFORM2FARBPROC Uniform2fARB = (PFNGLUNIFORM2FARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec2 uniformColor;"
+ "void main() {gl_FragColor.rg = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[2] = {1.1,2.2};
+ GLfloat queriedUniform[2];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * vector 2 (vec2), so we must set it using float versions
+ * of the Uniform* functions.
+ */
+ (*Uniform2fARB)(uniformLocation, uniform[0], uniform[1]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 2, uniform, 2, queriedUniform);
+}
+
+static GLboolean
+test_Uniform3iv(generic_func func)
+{
+ PFNGLUNIFORM3IVARBPROC Uniform3ivARB = (PFNGLUNIFORM3IVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec3 uniformColor;"
+ "void main() {gl_FragColor.rgb = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[3] = {1,2,3};
+ GLint queriedUniform[3];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector 3 (ivec3), so we must set it using integer versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform3ivARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 3, uniform, 3, queriedUniform);
+}
+
+static GLboolean
+test_Uniform3i(generic_func func)
+{
+ PFNGLUNIFORM3IARBPROC Uniform3iARB = (PFNGLUNIFORM3IARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec3 uniformColor;"
+ "void main() {gl_FragColor.rgb = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[3] = {1,2,3};
+ GLint queriedUniform[4];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector 3 (ivec3), so we must set it using integer versions
+ * of the Uniform* functions.
+ */
+ (*Uniform3iARB)(uniformLocation, uniform[0], uniform[1], uniform[2]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 3, uniform, 3, queriedUniform);
+}
+
+static GLboolean
+test_Uniform3fv(generic_func func)
+{
+ PFNGLUNIFORM3FVARBPROC Uniform3fvARB = (PFNGLUNIFORM3FVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec3 uniformColor;"
+ "void main() {gl_FragColor.rgb = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[3] = {1.1,2.2,3.3};
+ GLfloat queriedUniform[3];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * vector 3 (vec3), so we must set it using float versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform3fvARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 3, uniform, 3, queriedUniform);
+}
+
+static GLboolean
+test_Uniform3f(generic_func func)
+{
+ PFNGLUNIFORM3FARBPROC Uniform3fARB = (PFNGLUNIFORM3FARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec3 uniformColor;"
+ "void main() {gl_FragColor.rgb = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[3] = {1.1,2.2,3.3};
+ GLfloat queriedUniform[3];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * vector 3 (vec3), so we must set it using float versions
+ * of the Uniform* functions.
+ */
+ (*Uniform3fARB)(uniformLocation, uniform[0], uniform[1], uniform[2]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 3, uniform, 3, queriedUniform);
+}
+
+static GLboolean
+test_Uniform4iv(generic_func func)
+{
+ PFNGLUNIFORM4IVARBPROC Uniform4ivARB = (PFNGLUNIFORM4IVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[4] = {1,2,3,4};
+ GLint queriedUniform[4];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector (ivec4), so we must set it using integer versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform4ivARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 4, uniform, 4, queriedUniform);
+}
+
+static GLboolean
+test_Uniform4i(generic_func func)
+{
+ PFNGLUNIFORM4IARBPROC Uniform4iARB = (PFNGLUNIFORM4IARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformivARB, PFNGLGETUNIFORMIVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform ivec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLint uniform[4] = {1,2,3,4};
+ GLint queriedUniform[4];
+
+ if (GetUniformivARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector (ivec4), so we must set it using integer versions
+ * of the Uniform* functions.
+ */
+ (*Uniform4iARB)(uniformLocation, uniform[0], uniform[1], uniform[2],
+ uniform[3]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformivARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_ints(__FUNCTION__, 4, uniform, 4, queriedUniform);
+}
+
+static GLboolean
+test_Uniform4fv(generic_func func)
+{
+ PFNGLUNIFORM4FVARBPROC Uniform4fvARB = (PFNGLUNIFORM4FVARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[4] = {1.1,2.2,3.3,4.4};
+ GLfloat queriedUniform[4];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is a float
+ * vector (vec4), so we must set it using float versions
+ * of the Uniform* functions. The "1" means we're setting
+ * one vector's worth of information.
+ */
+ (*Uniform4fvARB)(uniformLocation, 1, uniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 4, uniform, 4, queriedUniform);
+}
+
+static GLboolean
+test_Uniform4f(generic_func func)
+{
+ PFNGLUNIFORM4FARBPROC Uniform4fARB = (PFNGLUNIFORM4FARBPROC) func;
+ DECLARE_GLFUNC_PTR(GetUniformfvARB, PFNGLGETUNIFORMFVARBPROC);
+
+ /* This is a trivial fragment shader that sets the color of the
+ * fragment to the uniform value passed in.
+ */
+ static const char *fragmentShaderText =
+ "uniform vec4 uniformColor; void main() {gl_FragColor = uniformColor;}";
+ static const char *uniformName = "uniformColor";
+
+ GLhandleARB program;
+ GLint uniformLocation;
+ const GLfloat uniform[4] = {1.1,2.2,3.3,4.4};
+ GLfloat queriedUniform[4];
+
+ if (GetUniformfvARB == NULL) {
+ return GL_FALSE;
+ }
+
+ /* Call a helper function to compile up the shader and give
+ * us back the validated program and uniform location.
+ * If it fails, something's wrong and we can't continue.
+ */
+ if (!exercise_uniform_start(fragmentShaderText, uniformName,
+ &program, &uniformLocation)) {
+ return GL_FALSE;
+ }
+
+ /* Set the value of the program uniform. Note that you must
+ * use a compatible type. Our uniform above is an integer
+ * vector (ivec4), so we must set it using integer versions
+ * of the Uniform* functions.
+ */
+ (*Uniform4fARB)(uniformLocation, uniform[0], uniform[1], uniform[2],
+ uniform[3]);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Query it back */
+ (*GetUniformfvARB)(program, uniformLocation, queriedUniform);
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
+
+ /* Clean up before we check to see whether it came back unscathed */
+ exercise_uniform_end(program);
+
+ /* Now check to see whether the uniform came back as expected. This
+ * will return GL_TRUE if all is well, or GL_FALSE if the comparison failed.
+ */
+ return compare_floats(__FUNCTION__, 4, uniform, 4, queriedUniform);
+}
static GLboolean
test_ActiveTextureARB(generic_func func)
@@ -107,6 +2694,40 @@ test_VertexAttrib1fvARB(generic_func func)
}
static GLboolean
+test_VertexAttrib1dvARB(generic_func func)
+{
+ PFNGLVERTEXATTRIB1DVARBPROC vertexAttrib1dvARB = (PFNGLVERTEXATTRIB1DVARBPROC) func;
+ PFNGLGETVERTEXATTRIBDVARBPROC getVertexAttribdvARB = (PFNGLGETVERTEXATTRIBDVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvARB");
+
+ const GLdouble v[1] = {25.0};
+ const GLdouble def[1] = {0};
+ GLdouble res[4];
+ GLboolean pass;
+ (*vertexAttrib1dvARB)(6, v);
+ (*getVertexAttribdvARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
+ pass = (res[0] == 25.0 && res[1] == 0.0 && res[2] == 0.0 && res[3] == 1.0);
+ (*vertexAttrib1dvARB)(6, def);
+ return pass;
+}
+
+static GLboolean
+test_VertexAttrib1svARB(generic_func func)
+{
+ PFNGLVERTEXATTRIB1SVARBPROC vertexAttrib1svARB = (PFNGLVERTEXATTRIB1SVARBPROC) func;
+ PFNGLGETVERTEXATTRIBIVARBPROC getVertexAttribivARB = (PFNGLGETVERTEXATTRIBIVARBPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivARB");
+
+ const GLshort v[1] = {25.0};
+ const GLshort def[1] = {0};
+ GLint res[4];
+ GLboolean pass;
+ (*vertexAttrib1svARB)(6, v);
+ (*getVertexAttribivARB)(6, GL_CURRENT_VERTEX_ATTRIB_ARB, res);
+ pass = (res[0] == 25 && res[1] == 0 && res[2] == 0 && res[3] == 1);
+ (*vertexAttrib1svARB)(6, def);
+ return pass;
+}
+
+static GLboolean
test_VertexAttrib4NubvARB(generic_func func)
{
PFNGLVERTEXATTRIB4NUBVARBPROC vertexAttrib4NubvARB = (PFNGLVERTEXATTRIB4NUBVARBPROC) func;
@@ -177,7 +2798,6 @@ test_VertexAttrib4NsvARB(generic_func func)
return pass;
}
-
static GLboolean
test_VertexAttrib4NusvARB(generic_func func)
{
@@ -195,42 +2815,110 @@ test_VertexAttrib4NusvARB(generic_func func)
return pass;
}
+static GLboolean
+test_VertexAttrib1sNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB1SNVPROC vertexAttrib1sNV = (PFNGLVERTEXATTRIB1SNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 0, 0, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib1sNV)(6, v[0]);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib1sNV)(6, def[0]);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
static GLboolean
-test_VertexAttrib4ubNV(generic_func func)
+test_VertexAttrib1fNV(generic_func func)
{
- PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) func;
+ PFNGLVERTEXATTRIB1FNVPROC vertexAttrib1fNV = (PFNGLVERTEXATTRIB1FNVPROC) func;
PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
- const GLubyte v[4] = {255, 0, 255, 0};
- const GLubyte def[4] = {0, 0, 0, 255};
+ const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
GLfloat res[4];
- GLboolean pass;
- (*vertexAttrib4ubNV)(6, v[0], v[1], v[2], v[3]);
+ (*vertexAttrib1fNV)(6, v[0]);
(*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
- pass = (res[0] == 1.0 && res[1] == 0.0 && res[2] == 1.0 && res[3] == 0.0);
- (*vertexAttrib4ubNV)(6, def[0], def[1], def[2], def[3]);
- return pass;
+ (*vertexAttrib1fNV)(6, def[0]);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
}
+static GLboolean
+test_VertexAttrib1dNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB1DNVPROC vertexAttrib1dNV = (PFNGLVERTEXATTRIB1DNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib1dNV)(6, v[0]);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib1dNV)(6, def[0]);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
static GLboolean
test_VertexAttrib2sNV(generic_func func)
{
PFNGLVERTEXATTRIB2SNVPROC vertexAttrib2sNV = (PFNGLVERTEXATTRIB2SNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 0, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib2sNV)(6, v[0], v[1]);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib2sNV)(6, def[0], def[1]);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib2fNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB2FNVPROC vertexAttrib2fNV = (PFNGLVERTEXATTRIB2FNVPROC) func;
PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
- const GLshort v[2] = {2, -4,};
- const GLshort def[2] = {0, 0};
+ const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
GLfloat res[4];
- GLboolean pass;
- (*vertexAttrib2sNV)(6, v[0], v[1]);
+ (*vertexAttrib2fNV)(6, v[0], v[1]);
(*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
- pass = (EQUAL(res[0], 2) && EQUAL(res[1], -4) && EQUAL(res[2], 0) && res[3] == 1.0);
- (*vertexAttrib2sNV)(6, def[0], def[1]);
- return pass;
+ (*vertexAttrib2fNV)(6, def[0], def[1]);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib2dNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB2DNVPROC vertexAttrib2dNV = (PFNGLVERTEXATTRIB2DNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib2dNV)(6, v[0], v[1]);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib2dNV)(6, def[0], def[1]);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
}
+static GLboolean
+test_VertexAttrib3sNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB3SNVPROC vertexAttrib3sNV = (PFNGLVERTEXATTRIB3SNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib3sNV)(6, v[0], v[1], v[2]);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib3sNV)(6, def[0], def[1], def[2]);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
static GLboolean
test_VertexAttrib3fNV(generic_func func)
@@ -238,35 +2926,467 @@ test_VertexAttrib3fNV(generic_func func)
PFNGLVERTEXATTRIB3FNVPROC vertexAttrib3fNV = (PFNGLVERTEXATTRIB3FNVPROC) func;
PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
- const GLfloat v[3] = {0.2, 0.4, 0.8};
- const GLfloat def[3] = {0, 0, 0};
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
GLfloat res[4];
- GLboolean pass;
(*vertexAttrib3fNV)(6, v[0], v[1], v[2]);
(*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
- pass = (EQUAL(res[0], 0.2) && EQUAL(res[1], 0.4) && EQUAL(res[2], 0.8) && res[3] == 1.0);
(*vertexAttrib3fNV)(6, def[0], def[1], def[2]);
- return pass;
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
}
+static GLboolean
+test_VertexAttrib3dNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB3DNVPROC vertexAttrib3dNV = (PFNGLVERTEXATTRIB3DNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib3dNV)(6, v[0], v[1], v[2]);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib3dNV)(6, def[0], def[1], def[2]);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4sNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4SNVPROC vertexAttrib4sNV = (PFNGLVERTEXATTRIB4SNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 5};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib4sNV)(6, v[0], v[1], v[2], v[3]);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4sNV)(6, def[0], def[1], def[2], def[3]);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4fNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4FNVPROC vertexAttrib4fNV = (PFNGLVERTEXATTRIB4FNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttrib4fNV)(6, v[0], v[1], v[2], v[3]);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4fNV)(6, def[0], def[1], def[2], def[3]);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4dNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4DNVPROC vertexAttrib4dNV = (PFNGLVERTEXATTRIB4DNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib4dNV)(6, v[0], v[1], v[2], v[3]);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4dNV)(6, def[0], def[1], def[2], def[3]);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4ubNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4UBNVPROC vertexAttrib4ubNV = (PFNGLVERTEXATTRIB4UBNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLubyte v[4] = {255, 0, 255, 0};
+ const GLubyte def[4] = {0, 0, 0, 255};
+ GLfloat res[4];
+ /* There's no byte-value query; so we use the float-value query.
+ * Bytes are interpreted as steps between 0 and 1, so the
+ * expected float values will be 0.0 for byte value 0 and 1.0 for
+ * byte value 255.
+ */
+ GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
+ (*vertexAttrib4ubNV)(6, v[0], v[1], v[2], v[3]);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4ubNV)(6, def[0], def[1], def[2], def[3]);
+ return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib1fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB1FVNVPROC vertexAttrib1fvNV = (PFNGLVERTEXATTRIB1FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttrib1fvNV)(6, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib1fvNV)(6, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib1dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB1DVNVPROC vertexAttrib1dvNV = (PFNGLVERTEXATTRIB1DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib1dvNV)(6, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib1dvNV)(6, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib2svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB2SVNVPROC vertexAttrib2svNV = (PFNGLVERTEXATTRIB2SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 0, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib2svNV)(6, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib2svNV)(6, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib2fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB2FVNVPROC vertexAttrib2fvNV = (PFNGLVERTEXATTRIB2FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttrib2fvNV)(6, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib2fvNV)(6, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib2dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB2DVNVPROC vertexAttrib2dvNV = (PFNGLVERTEXATTRIB2DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib2dvNV)(6, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib2dvNV)(6, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib3svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB3SVNVPROC vertexAttrib3svNV = (PFNGLVERTEXATTRIB3SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib3svNV)(6, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib3svNV)(6, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib3fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB3FVNVPROC vertexAttrib3fvNV = (PFNGLVERTEXATTRIB3FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttrib3fvNV)(6, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib3fvNV)(6, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib3dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB3DVNVPROC vertexAttrib3dvNV = (PFNGLVERTEXATTRIB3DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib3dvNV)(6, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib3dvNV)(6, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4SVNVPROC vertexAttrib4svNV = (PFNGLVERTEXATTRIB4SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 5};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttrib4svNV)(6, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4svNV)(6, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4FVNVPROC vertexAttrib4fvNV = (PFNGLVERTEXATTRIB4FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttrib4fvNV)(6, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4fvNV)(6, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
static GLboolean
test_VertexAttrib4dvNV(generic_func func)
{
PFNGLVERTEXATTRIB4DVNVPROC vertexAttrib4dvNV = (PFNGLVERTEXATTRIB4DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttrib4dvNV)(6, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4dvNV)(6, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttrib4ubvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIB4UBVNVPROC vertexAttrib4ubvNV = (PFNGLVERTEXATTRIB4UBVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLubyte v[4] = {255, 0, 255, 0};
+ const GLubyte def[4] = {0, 0, 0, 255};
+ GLfloat res[4];
+ /* There's no byte-value query; so we use the float-value query.
+ * Bytes are interpreted as steps between 0 and 1, so the
+ * expected float values will be 0.0 for byte value 0 and 1.0 for
+ * byte value 255.
+ */
+ GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
+ (*vertexAttrib4ubvNV)(6, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttrib4ubvNV)(6, def);
+ return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs1fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS1FVNVPROC vertexAttribs1fvNV = (PFNGLVERTEXATTRIBS1FVNVPROC) func;
PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
- const GLdouble v[4] = {0.2, 0.4, 0.8, 1.2};
+ const GLfloat v[4] = {2.5, 0.0, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttribs1fvNV)(6, 1, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs1fvNV)(6, 1, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs1dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS1DVNVPROC vertexAttribs1dvNV = (PFNGLVERTEXATTRIBS1DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 0.0, 0.0, 1.0};
const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttribs1dvNV)(6, 1, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs1dvNV)(6, 1, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs2svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS2SVNVPROC vertexAttribs2svNV = (PFNGLVERTEXATTRIBS2SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 0, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttribs2svNV)(6, 1, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs2svNV)(6, 1, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs2fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS2FVNVPROC vertexAttribs2fvNV = (PFNGLVERTEXATTRIBS2FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
GLfloat res[4];
- GLboolean pass;
- (*vertexAttrib4dvNV)(6, v);
+ (*vertexAttribs2fvNV)(6, 1, v);
(*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
- pass = (EQUAL(res[0], 0.2) && EQUAL(res[1], 0.4) && EQUAL(res[2], 0.8) && EQUAL(res[3], 1.2));
- (*vertexAttrib4dvNV)(6, def);
- return pass;
+ (*vertexAttribs2fvNV)(6, 1, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs2dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS2DVNVPROC vertexAttribs2dvNV = (PFNGLVERTEXATTRIBS2DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 0.0, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttribs2dvNV)(6, 1, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs2dvNV)(6, 1, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
}
+static GLboolean
+test_VertexAttribs3svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS3SVNVPROC vertexAttribs3svNV = (PFNGLVERTEXATTRIBS3SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 1};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttribs3svNV)(6, 1, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs3svNV)(6, 1, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs3fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS3FVNVPROC vertexAttribs3fvNV = (PFNGLVERTEXATTRIBS3FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttribs3fvNV)(6, 1, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs3fvNV)(6, 1, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs3dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS3DVNVPROC vertexAttribs3dvNV = (PFNGLVERTEXATTRIBS3DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 1.0};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttribs3dvNV)(6, 1, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs3dvNV)(6, 1, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs4svNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS4SVNVPROC vertexAttribs4svNV = (PFNGLVERTEXATTRIBS4SVNVPROC) func;
+ PFNGLGETVERTEXATTRIBIVNVPROC getVertexAttribivNV = (PFNGLGETVERTEXATTRIBIVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribivNV");
+
+ const GLshort v[4] = {2, 4, 7, 5};
+ const GLshort def[4] = {0, 0, 0, 1};
+ GLint res[4];
+ (*vertexAttribs4svNV)(6, 1, v);
+ (*getVertexAttribivNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs4svNV)(6, 1, def);
+ return compare_shorts_to_ints(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs4fvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS4FVNVPROC vertexAttribs4fvNV = (PFNGLVERTEXATTRIBS4FVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLfloat v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLfloat def[4] = {0, 0, 0, 1};
+ GLfloat res[4];
+ (*vertexAttribs4fvNV)(6, 1, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs4fvNV)(6, 1, def);
+ return compare_floats(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs4dvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS4DVNVPROC vertexAttribs4dvNV = (PFNGLVERTEXATTRIBS4DVNVPROC) func;
+ PFNGLGETVERTEXATTRIBDVNVPROC getVertexAttribdvNV = (PFNGLGETVERTEXATTRIBDVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribdvNV");
+
+ const GLdouble v[4] = {2.5, 4.25, 7.125, 5.0625};
+ const GLdouble def[4] = {0, 0, 0, 1};
+ GLdouble res[4];
+ (*vertexAttribs4dvNV)(6, 1, v);
+ (*getVertexAttribdvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs4dvNV)(6, 1, def);
+ return compare_doubles(__FUNCTION__, 4, v, 4, res);
+}
+
+static GLboolean
+test_VertexAttribs4ubvNV(generic_func func)
+{
+ PFNGLVERTEXATTRIBS4UBVNVPROC vertexAttribs4ubvNV = (PFNGLVERTEXATTRIBS4UBVNVPROC) func;
+ PFNGLGETVERTEXATTRIBFVNVPROC getVertexAttribfvNV = (PFNGLGETVERTEXATTRIBFVNVPROC) glXGetProcAddressARB((const GLubyte *) "glGetVertexAttribfvNV");
+
+ const GLubyte v[4] = {255, 0, 255, 0};
+ const GLubyte def[4] = {0, 0, 0, 255};
+ GLfloat res[4];
+ /* There's no byte-value query; so we use the float-value query.
+ * Bytes are interpreted as steps between 0 and 1, so the
+ * expected float values will be 0.0 for byte value 0 and 1.0 for
+ * byte value 255.
+ */
+ GLfloat expectedResults[4] = {1.0, 0.0, 1.0, 0.0};
+ (*vertexAttribs4ubvNV)(6, 1, v);
+ (*getVertexAttribfvNV)(6, GL_CURRENT_ATTRIB_NV, res);
+ (*vertexAttribs4ubvNV)(6, 1, def);
+ return compare_floats(__FUNCTION__, 4, expectedResults, 4, res);
+}
static GLboolean
test_StencilFuncSeparateATI(generic_func func)
@@ -387,17 +3507,32 @@ extension_supported(const char *haystack, const char *needle)
}
-static void
+/* Run all the known extension function tests, if the extension is supported.
+ * Return a count of how many failed.
+ */
+static int
check_functions( const char *extensions )
{
struct name_test_pair *entry;
- int failures = 0, passes = 0;
- int totalFail = 0, totalPass = 0;
+ int failures = 0, passes = 0, untested = 0;
+ int totalFail = 0, totalPass = 0, totalUntested = 0, totalUnsupported = 0;
int doTests;
-
+ const char *version = (const char *) glGetString(GL_VERSION);
+
+ /* The functions list will have "real" entries (consisting of
+ * a GL function name and a pointer to an exercise function for
+ * that GL function), and "group" entries (indicated as
+ * such by having a "-" as the first character of the name).
+ * "Group" names always start with the "-" character, and can
+ * be numeric (e.g. "-1.0", "-2.1"), indicating that a particular
+ * OpenGL version is required for the following functions; or can be
+ * an extension name (e.g. "-GL_ARB_multitexture") that means
+ * that the named extension is required for the following functions.
+ */
for (entry = functions; entry->name; entry++) {
+ /* Check if this is a group indicator */
if (entry->name[0] == '-') {
- const char *version = (const char *) glGetString(GL_VERSION);
+ /* A group indicator; check if it's an OpenGL version group */
if (entry->name[1] == '1') {
/* check GL version 1.x */
if (version[0] == '1' &&
@@ -419,14 +3554,27 @@ check_functions( const char *extensions )
/* check if the named extension is available */
doTests = extension_supported(extensions, entry->name+1);
}
+
+ /* doTests is now set if we're starting an OpenGL version
+ * group, and the running OpenGL version is at least the
+ * version required; or if we're starting an OpenGL extension
+ * group, and the extension is supported.
+ */
if (doTests)
printf("Testing %s functions\n", entry->name + 1);
- totalFail += failures;
- totalPass += passes;
+
+ /* Each time we hit a title function, reset the function
+ * counts.
+ */
failures = 0;
passes = 0;
+ untested = 0;
}
else if (doTests) {
+ /* Here, we know we're trying to exercise a function for
+ * a supported extension. See whether we have a test for
+ * it, and try to run it.
+ */
generic_func funcPtr = (generic_func) glXGetProcAddressARB((const GLubyte *) entry->name);
if (funcPtr) {
if (entry->test) {
@@ -436,21 +3584,36 @@ check_functions( const char *extensions )
if (b) {
printf(" Pass\n");
passes++;
+ totalPass++;
}
else {
printf(" FAIL!!!\n");
failures++;
+ totalFail++;
}
}
else {
- passes++;
+ untested++;
+ totalUntested++;
}
}
else {
printf(" glXGetProcAddress(%s) failed!\n", entry->name);
failures++;
+ totalFail++;
}
}
+ else {
+ /* Here, we have a function that belongs to a group that
+ * is known to be unsupported.
+ */
+ totalUnsupported++;
+ }
+
+ /* Make sure a poor test case doesn't leave any lingering
+ * OpenGL errors.
+ */
+ CheckGLError(__LINE__, __FILE__, __FUNCTION__);
if (doTests && (!(entry+1)->name || (entry+1)->name[0] == '-')) {
if (failures > 0) {
@@ -459,18 +3622,29 @@ check_functions( const char *extensions )
if (passes > 0) {
printf(" %d passed.\n", passes);
}
+ if (untested > 0) {
+ printf(" %d untested.\n", untested);
+ }
}
}
- totalFail += failures;
- totalPass += passes;
printf("-----------------------------\n");
- printf("Total: %d pass %d fail\n", totalPass, totalFail);
+ printf("Total: %d pass %d fail %d untested %d unsupported %d total\n",
+ totalPass, totalFail, totalUntested, totalUnsupported,
+ totalPass + totalFail + totalUntested + totalUnsupported);
+
+ return totalFail;
}
+/* Return an error code */
+#define ERROR_NONE 0
+#define ERROR_NO_VISUAL 1
+#define ERROR_NO_CONTEXT 2
+#define ERROR_NO_MAKECURRENT 3
+#define ERROR_FAILED 4
-static void
+static int
print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
{
Window win;
@@ -496,6 +3670,7 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
GLXContext ctx;
XVisualInfo *visinfo;
int width = 100, height = 100;
+ int failures;
root = RootWindow(dpy, scrnum);
@@ -504,7 +3679,7 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
visinfo = glXChooseVisual(dpy, scrnum, attribDouble);
if (!visinfo) {
fprintf(stderr, "Error: couldn't find RGB GLX visual\n");
- return;
+ return ERROR_NO_VISUAL;
}
}
@@ -521,26 +3696,29 @@ print_screen_info(Display *dpy, int scrnum, Bool allowDirect)
if (!ctx) {
fprintf(stderr, "Error: glXCreateContext failed\n");
XDestroyWindow(dpy, win);
- return;
+ return ERROR_NO_CONTEXT;
}
- if (glXMakeCurrent(dpy, win, ctx)) {
- check_functions( (const char *) glGetString(GL_EXTENSIONS) );
- }
- else {
+ if (!glXMakeCurrent(dpy, win, ctx)) {
fprintf(stderr, "Error: glXMakeCurrent failed\n");
+ glXDestroyContext(dpy, ctx);
+ XDestroyWindow(dpy, win);
+ return ERROR_NO_MAKECURRENT;
}
+ failures = check_functions( (const char *) glGetString(GL_EXTENSIONS) );
glXDestroyContext(dpy, ctx);
XDestroyWindow(dpy, win);
-}
+ return (failures == 0 ? ERROR_NONE : ERROR_FAILED);
+}
int
main(int argc, char *argv[])
{
char *displayName = NULL;
Display *dpy;
+ int returnCode;
dpy = XOpenDisplay(displayName);
if (!dpy) {
@@ -548,9 +3726,9 @@ main(int argc, char *argv[])
return -1;
}
- print_screen_info(dpy, 0, GL_TRUE);
+ returnCode = print_screen_info(dpy, 0, GL_TRUE);
XCloseDisplay(dpy);
- return 0;
+ return returnCode;
}
diff --git a/progs/tests/getprocaddress.py b/progs/tests/getprocaddress.py
index 8adfc51bd6..699195bd48 100644
--- a/progs/tests/getprocaddress.py
+++ b/progs/tests/getprocaddress.py
@@ -52,7 +52,7 @@ static struct name_test_pair functions[] = {"""
prev_category = None
- for f in api.functionIterateByOffset():
+ for f in api.functionIterateByCategory():
[category, num] = api.get_category_for_name( f.name )
if category != prev_category:
print ' { "-%s", NULL},' % category
diff --git a/progs/tests/getteximage.c b/progs/tests/getteximage.c
index e4818a8fab..71f29b4ac8 100644
--- a/progs/tests/getteximage.c
+++ b/progs/tests/getteximage.c
@@ -15,7 +15,7 @@ static int Win;
static void
-TestGetTexImage(void)
+TestGetTexImage(GLboolean npot)
{
GLuint iter;
GLubyte *data = (GLubyte *) malloc(1024 * 1024 * 4);
@@ -27,8 +27,8 @@ TestGetTexImage(void)
for (iter = 0; iter < 8; iter++) {
GLint p = (iter % 8) + 3;
- GLint w = (1 << p);
- GLint h = (1 << p);
+ GLint w = npot ? (p * 20) : (1 << p);
+ GLint h = npot ? (p * 10) : (1 << p);
GLuint i;
GLint level = 0;
@@ -83,63 +83,94 @@ ColorsEqual(const GLubyte ref[4], const GLubyte act[4])
static void
-TestGetTexImageRTT(void)
+TestGetTexImageRTT(GLboolean npot)
{
GLuint iter;
- GLuint fb, tex;
- GLint w = 512;
- GLint h = 256;
- GLint level = 0;
-
- glGenTextures(1, &tex);
- glGenFramebuffersEXT(1, &fb);
-
- glBindTexture(GL_TEXTURE_2D, tex);
- 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, GL_RGBA, w, h, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
-
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, fb);
- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
- GL_TEXTURE_2D, tex, level);
printf("Render to texture + glGetTexImage:\n");
- printf(" Testing %d x %d tex image\n", w, h);
+
for (iter = 0; iter < 8; iter++) {
- GLubyte color[4];
- GLubyte *data2 = (GLubyte *) malloc(w * h * 4);
- GLuint i;
- /* random clear color */
- for (i = 0; i < 4; i++) {
- color[i] = rand() % 256;
+ GLuint fb, tex;
+ GLint w, h;
+ GLint level = 0;
+
+ if (npot) {
+ w = 200 + iter * 40;
+ h = 200 + iter * 12;
+ }
+ else {
+ w = 4 << iter;
+ h = 4 << iter;
}
- glClearColor(color[0] / 255.0,
- color[1] / 255.0,
- color[2] / 255.0,
- color[3] / 255.0);
+ glGenTextures(1, &tex);
+ glGenFramebuffersEXT(1, &fb);
- glClear(GL_COLOR_BUFFER_BIT);
+ glBindTexture(GL_TEXTURE_2D, tex);
+ 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, GL_RGBA, w, h, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- /* get */
- glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_UNSIGNED_BYTE, data2);
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fb);
+ glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
+ GL_TEXTURE_2D, tex, level);
- /* compare */
- for (i = 0; i < w * h; i += 4) {
- if (!ColorsEqual(color, data2 + i * 4)) {
- printf("Render to texture failure!\n");
- abort();
+ glViewport(0, 0, w, h);
+
+ printf(" Testing %d x %d tex image\n", w, h);
+ {
+ static const GLubyte blue[4] = {0, 0, 255, 255};
+ GLubyte color[4];
+ GLubyte *data2 = (GLubyte *) malloc(w * h * 4);
+ GLuint i;
+
+ /* random clear color */
+ for (i = 0; i < 4; i++) {
+ color[i] = rand() % 256;
+ }
+
+ glClearColor(color[0] / 255.0,
+ color[1] / 255.0,
+ color[2] / 255.0,
+ color[3] / 255.0);
+
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /* draw polygon over top half, in blue */
+ glColor4ubv(blue);
+ glRectf(0, 0.5, 1.0, 1.0);
+
+ /* get */
+ glGetTexImage(GL_TEXTURE_2D, level, GL_RGBA, GL_UNSIGNED_BYTE, data2);
+
+ /* compare */
+ for (i = 0; i < w * h; i += 4) {
+ if (i < w * h / 2) {
+ /* lower half */
+ if (!ColorsEqual(color, data2 + i * 4)) {
+ printf("Render to texture failure (expected clear color)!\n");
+ abort();
+ }
+ }
+ else {
+ /* upper half */
+ if (!ColorsEqual(blue, data2 + i * 4)) {
+ printf("Render to texture failure (expected blue)!\n");
+ abort();
+ }
+ }
}
+
+ free(data2);
}
- free(data2);
- }
+ glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
+ glDeleteFramebuffersEXT(1, &fb);
+ glDeleteTextures(1, &tex);
- glBindFramebuffer(GL_FRAMEBUFFER_EXT, 0);
- glDeleteFramebuffersEXT(1, &fb);
- glDeleteTextures(1, &tex);
+ }
printf("Passed\n");
}
@@ -152,11 +183,16 @@ Draw(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
- TestGetTexImage();
+ TestGetTexImage(GL_FALSE);
+ if (glutExtensionSupported("GL_ARB_texture_non_power_of_two"))
+ TestGetTexImage(GL_TRUE);
if (glutExtensionSupported("GL_EXT_framebuffer_object") ||
- glutExtensionSupported("GL_ARB_framebuffer_object"))
- TestGetTexImageRTT();
+ glutExtensionSupported("GL_ARB_framebuffer_object")) {
+ TestGetTexImageRTT(GL_FALSE);
+ if (glutExtensionSupported("GL_ARB_texture_non_power_of_two"))
+ TestGetTexImageRTT(GL_TRUE);
+ }
glutDestroyWindow(Win);
exit(0);
@@ -171,10 +207,10 @@ Reshape(int width, int height)
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
- glFrustum(-1.0, 1.0, -1.0, 1.0, 5.0, 25.0);
+ glOrtho(0, 1, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
- glTranslatef(0.0, 0.0, -15.0);
+ glTranslatef(0.0, 0.0, 0.0);
}
diff --git a/progs/tests/texcmp.c b/progs/tests/texcmp.c
index 52c504a318..d1e829d1b7 100644
--- a/progs/tests/texcmp.c
+++ b/progs/tests/texcmp.c
@@ -371,11 +371,11 @@ int main( int argc, char *argv[] )
glutInitDisplayMode( GLUT_RGB | GLUT_DOUBLE );
if (glutCreateWindow(argv[0]) <= 0) {
- glewInit();
printf("Couldn't create window\n");
exit(0);
}
+ glewInit();
gl_version = atof( (const char *) glGetString( GL_VERSION ) );
if ( (gl_version < 1.3)
&& !glutExtensionSupported("GL_ARB_texture_compression") ) {
diff --git a/progs/tests/texcompsub.c b/progs/tests/texcompsub.c
index 79a5f958a1..50106bf1e2 100644
--- a/progs/tests/texcompsub.c
+++ b/progs/tests/texcompsub.c
@@ -6,6 +6,7 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>
@@ -31,6 +32,8 @@ CheckError(int line)
static void
LoadCompressedImage(void)
{
+ unsigned char ImgDataTemp[ImgSize / 4];
+ unsigned i;
const GLenum filter = GL_LINEAR;
glTexImage2D(Target, 0, CompFormat, ImgWidth, ImgHeight, 0,
GL_RGB, GL_UNSIGNED_BYTE, NULL);
@@ -40,11 +43,24 @@ LoadCompressedImage(void)
0, 0, /* pos */
ImgWidth, ImgHeight / 2,
CompFormat, ImgSize / 2, ImgData + ImgSize / 2);
- /* top half */
+
+ /* top left */
+ for (i = 0; i < ImgHeight / 8; i++) {
+ memcpy(&ImgDataTemp[i * ImgWidth], &ImgData[i * 2 * ImgWidth], ImgWidth);
+ }
glCompressedTexSubImage2DARB(Target, 0,
0, ImgHeight / 2, /* pos */
- ImgWidth, ImgHeight / 2,
- CompFormat, ImgSize / 2, ImgData);
+ ImgWidth / 2, ImgHeight / 2,
+ CompFormat, ImgSize / 4, ImgDataTemp);
+
+ /* top right */
+ for (i = 0; i < ImgHeight / 8; i++) {
+ memcpy(&ImgDataTemp[i * ImgWidth], &ImgData[i * 2 * ImgWidth + ImgWidth], ImgWidth);
+ }
+ glCompressedTexSubImage2DARB(Target, 0,
+ ImgWidth / 2, ImgHeight / 2, /* pos */
+ ImgWidth / 2, ImgHeight / 2,
+ CompFormat, ImgSize / 4, ImgDataTemp);
glTexParameteri(Target, GL_TEXTURE_MIN_FILTER, filter);
glTexParameteri(Target, GL_TEXTURE_MAG_FILTER, filter);
diff --git a/progs/tests/texwrap.c b/progs/tests/texwrap.c
index 12f045b72e..92c8a2f14c 100644
--- a/progs/tests/texwrap.c
+++ b/progs/tests/texwrap.c
@@ -258,8 +258,26 @@ static void Init( void )
}
glBindTexture(GL_TEXTURE_2D, BORDER_TEXTURE);
+#ifdef TEST_PBO_DLIST
+ /* test fetching teximage from PBO in display list */
+ {
+ GLuint b = 42, l = 10;
+
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, b);
+ glBufferDataARB(GL_PIXEL_UNPACK_BUFFER, sizeof(BorderImage),
+ BorderImage, GL_STREAM_DRAW);
+
+ glNewList(l, GL_COMPILE);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1,
+ GL_RGBA, GL_UNSIGNED_BYTE, (void *) 0/* BorderImage*/);
+ glEndList();
+ glCallList(l);
+ glBindBufferARB(GL_PIXEL_UNPACK_BUFFER, 0);
+ }
+#else
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, SIZE+2, SIZE+2, 1,
GL_RGBA, GL_UNSIGNED_BYTE, (void *) BorderImage);
+#endif
for (i = 0; i < SIZE; i++) {
for (j = 0; j < SIZE; j++) {
diff --git a/progs/tests/zreaddraw.c b/progs/tests/zreaddraw.c
index 2cbfeb6ff1..7dfed20cfb 100644
--- a/progs/tests/zreaddraw.c
+++ b/progs/tests/zreaddraw.c
@@ -12,18 +12,23 @@
#include <GL/glut.h>
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);
+ glEnable(GL_DEPTH_TEST);
+
/* draw a sphere */
glViewport(0, 0, 100, 100);
glMatrixMode(GL_PROJECTION);
@@ -33,21 +38,63 @@ 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);
+ glColor4f(1, 0, 0, 0);
glWindowPos2i(100, 0);
- glDrawPixels(100, 100, GL_DEPTH_COMPONENT, GL_FLOAT, depth);
+ if (Invert) {
+ glPixelTransferf(GL_DEPTH_SCALE, -1.0);
+ glPixelTransferf(GL_DEPTH_BIAS, 1.0);
+ }
+ 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 */
glReadPixels(100, 0, 400, 400, GL_DEPTH_COMPONENT, GL_FLOAT, depth2);
@@ -72,6 +119,17 @@ static void Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
+ 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;
@@ -96,7 +154,6 @@ static void Init(void)
glLightfv(GL_LIGHT0, GL_POSITION, pos);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
- glEnable(GL_DEPTH_TEST);
}
diff --git a/progs/trivial/.gitignore b/progs/trivial/.gitignore
index dce733a70a..4d6e405c50 100644
--- a/progs/trivial/.gitignore
+++ b/progs/trivial/.gitignore
@@ -5,10 +5,17 @@ clear-random
clear-repeat
clear-scissor
clear-undefined
+createwin
+dlist-begin-call-end
dlist-dangling
dlist-degenerate
dlist-edgeflag
dlist-edgeflag-dangling
+dlist-flat-tri
+dlist-mat-tri
+dlist-recursive-call
+dlist-tri-flat-tri
+dlist-tri-mat-tri
draw2arrays
drawarrays
drawelements
@@ -31,6 +38,7 @@ lineloop
lineloop-clip
lineloop-elts
linestrip
+linestrip-clip
linestrip-flat-stipple
linestrip-stipple
linestrip-stipple-wide
@@ -71,8 +79,10 @@ quadstrip-cont
quadstrip-flat
readtex.c
readtex.h
+readpixels
tri
tri-alpha
+tri-alpha-tex
tri-array-interleaved
tri-blend
tri-blend-color
@@ -80,6 +90,7 @@ tri-blend-max
tri-blend-min
tri-blend-revsub
tri-blend-sub
+tri-clear
tri-clip
tri-cull
tri-cull-both
@@ -94,6 +105,7 @@ tri-fog
tri-fp
tri-fp-const-imm
tri-lit
+tri-lit-material
tri-logicop-none
tri-logicop-xor
tri-mask-tri
@@ -102,6 +114,7 @@ tri-orig
tri-query
tri-repeat
tri-scissor-tri
+tri-square
tri-stencil
tri-stipple
tri-tex
@@ -111,6 +124,7 @@ tri-unfilled
tri-unfilled-clip
tri-unfilled-edgeflag
tri-unfilled-fog
+tri-unfilled-point
tri-unfilled-smooth
tri-unfilled-tri
tri-unfilled-tri-lit
@@ -119,6 +133,7 @@ tri-unfilled-userclip-stip
tri-userclip
tri-viewport
tri-z
+tri-z-9
tri-z-eq
trifan
trifan-flat
diff --git a/progs/trivial/Makefile b/progs/trivial/Makefile
index 3bd8faff99..70728616d2 100644
--- a/progs/trivial/Makefile
+++ b/progs/trivial/Makefile
@@ -18,6 +18,7 @@ SOURCES = \
clear-repeat.c \
clear-random.c \
clear.c \
+ createwin.c \
dlist-dangling.c \
dlist-flat-tri.c \
dlist-mat-tri.c \
@@ -48,6 +49,7 @@ SOURCES = \
lineloop-clip.c \
lineloop-elts.c \
lineloop.c \
+ linestrip-clip.c \
linestrip-flat-stipple.c \
linestrip-stipple-wide.c \
linestrip-stipple.c \
@@ -87,7 +89,9 @@ SOURCES = \
quadstrip-cont.c \
quadstrip-flat.c \
quadstrip.c \
+ readpixels.c \
tri-alpha.c \
+ tri-alpha-tex.c \
tri-array-interleaved.c \
tri-blend-color.c \
tri-blend-max.c \
@@ -95,6 +99,7 @@ SOURCES = \
tri-blend-revsub.c \
tri-blend-sub.c \
tri-blend.c \
+ tri-clear.c \
tri-clip.c \
tri-cull-both.c \
tri-cull.c \
@@ -117,6 +122,7 @@ SOURCES = \
tri-query.c \
tri-repeat.c \
tri-scissor-tri.c \
+ tri-square.c \
tri-stencil.c \
tri-stipple.c \
tri-multitex-vbo.c \
@@ -126,6 +132,7 @@ SOURCES = \
tri-unfilled-fog.c \
tri-unfilled-edgeflag.c \
tri-unfilled-clip.c \
+ tri-unfilled-point.c \
tri-unfilled-smooth.c \
tri-unfilled-tri.c \
tri-unfilled-tri-lit.c \
@@ -134,6 +141,7 @@ SOURCES = \
tri-unfilled.c \
tri-userclip.c \
tri-viewport.c \
+ tri-z-9.c \
tri-z-eq.c \
tri-z.c \
tri.c \
diff --git a/progs/util/glutskel.c b/progs/util/glutskel.c
index 273ed9a2f5..8499e12a9d 100644
--- a/progs/util/glutskel.c
+++ b/progs/util/glutskel.c
@@ -11,6 +11,7 @@
#include <GL/glut.h>
static int Win;
+static int WinWidth = 400, WinHeight = 400;
static GLfloat Xrot = 0, Yrot = 0, Zrot = 0;
static GLboolean Anim = GL_FALSE;
@@ -46,6 +47,8 @@ Draw(void)
static void
Reshape(int width, int height)
{
+ WinWidth = width;
+ WinHeight = height;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
@@ -63,23 +66,23 @@ Key(unsigned char key, int x, int y)
(void) x;
(void) y;
switch (key) {
- case 'a':
- Anim = !Anim;
- if (Anim)
- glutIdleFunc(Idle);
- else
- glutIdleFunc(NULL);
- break;
- case 'z':
- Zrot -= step;
- break;
- case 'Z':
- Zrot += step;
- break;
- case 27:
- glutDestroyWindow(Win);
- exit(0);
- break;
+ case 'a':
+ Anim = !Anim;
+ if (Anim)
+ glutIdleFunc(Idle);
+ else
+ glutIdleFunc(NULL);
+ break;
+ case 'z':
+ Zrot -= step;
+ break;
+ case 'Z':
+ Zrot += step;
+ break;
+ case 27:
+ glutDestroyWindow(Win);
+ exit(0);
+ break;
}
glutPostRedisplay();
}
@@ -92,18 +95,18 @@ SpecialKey(int key, int x, int y)
(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;
+ 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();
}
@@ -123,8 +126,7 @@ int
main(int argc, char *argv[])
{
glutInit(&argc, argv);
- glutInitWindowPosition(0, 0);
- glutInitWindowSize(400, 400);
+ glutInitWindowSize(WinWidth, WinHeight);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
Win = glutCreateWindow(argv[0]);
glutReshapeFunc(Reshape);
diff --git a/progs/util/shaderutil.c b/progs/util/shaderutil.c
index 13b68d90e0..4db950016b 100644
--- a/progs/util/shaderutil.c
+++ b/progs/util/shaderutil.c
@@ -9,19 +9,16 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "shaderutil.h"
+/** time to compile previous shader */
+static GLdouble CompileTime = 0.0;
-static void
-Init(void)
-{
- static GLboolean firstCall = GL_TRUE;
- if (firstCall) {
- firstCall = GL_FALSE;
- }
-}
+/** time to linke previous program */
+static GLdouble LinkTime = 0.0;
GLboolean
@@ -46,12 +43,17 @@ CompileShaderText(GLenum shaderType, const char *text)
{
GLuint shader;
GLint stat;
-
- Init();
+ GLdouble t0, t1;
shader = glCreateShader(shaderType);
glShaderSource(shader, 1, (const GLchar **) &text, NULL);
+
+ t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
glCompileShader(shader);
+ t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+ CompileTime = t1 - t0;
+
glGetShaderiv(shader, GL_COMPILE_STATUS, &stat);
if (!stat) {
GLchar log[1000];
@@ -79,9 +81,6 @@ CompileShaderFile(GLenum shaderType, const char *filename)
GLuint shader;
FILE *f;
- Init();
-
-
f = fopen(filename, "r");
if (!f) {
fprintf(stderr, "Unable to open shader file %s\n", filename);
@@ -109,6 +108,7 @@ GLuint
LinkShaders(GLuint vertShader, GLuint fragShader)
{
GLuint program = glCreateProgram();
+ GLdouble t0, t1;
assert(vertShader || fragShader);
@@ -116,7 +116,12 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
glAttachShader(program, fragShader);
if (vertShader)
glAttachShader(program, vertShader);
+
+ t0 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
glLinkProgram(program);
+ t1 = glutGet(GLUT_ELAPSED_TIME) * 0.001;
+
+ LinkTime = t1 - t0;
/* check link */
{
@@ -135,8 +140,41 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
}
+GLboolean
+ValidateShaderProgram(GLuint program)
+{
+ GLint stat;
+ glValidateProgramARB(program);
+ glGetProgramiv(program, GL_VALIDATE_STATUS, &stat);
+
+ if (!stat) {
+ GLchar log[1000];
+ GLsizei len;
+ glGetProgramInfoLog(program, 1000, &len, log);
+ fprintf(stderr, "Program validation error:\n%s\n", log);
+ return 0;
+ }
+
+ return (GLboolean) stat;
+}
+
+
+GLdouble
+GetShaderCompileTime(void)
+{
+ return CompileTime;
+}
+
+
+GLdouble
+GetShaderLinkTime(void)
+{
+ return LinkTime;
+}
+
+
void
-InitUniforms(GLuint program, struct uniform_info uniforms[])
+SetUniformValues(GLuint program, struct uniform_info uniforms[])
{
GLuint i;
@@ -144,28 +182,134 @@ InitUniforms(GLuint program, struct uniform_info uniforms[])
uniforms[i].location
= glGetUniformLocation(program, uniforms[i].name);
- printf("Uniform %s location: %d\n", uniforms[i].name,
- uniforms[i].location);
-
- switch (uniforms[i].size) {
- case 1:
- if (uniforms[i].type == GL_INT)
- glUniform1i(uniforms[i].location,
- (GLint) uniforms[i].value[0]);
- else
- glUniform1fv(uniforms[i].location, 1, uniforms[i].value);
+ switch (uniforms[i].type) {
+ case GL_INT:
+ case GL_SAMPLER_1D:
+ case GL_SAMPLER_2D:
+ case GL_SAMPLER_3D:
+ case GL_SAMPLER_CUBE:
+ case GL_SAMPLER_2D_RECT_ARB:
+ assert(uniforms[i].value[0] >= 0.0F);
+ glUniform1i(uniforms[i].location,
+ (GLint) uniforms[i].value[0]);
+ break;
+ case GL_FLOAT:
+ glUniform1fv(uniforms[i].location, 1, uniforms[i].value);
break;
- case 2:
+ case GL_FLOAT_VEC2:
glUniform2fv(uniforms[i].location, 1, uniforms[i].value);
break;
- case 3:
+ case GL_FLOAT_VEC3:
glUniform3fv(uniforms[i].location, 1, uniforms[i].value);
break;
- case 4:
+ case GL_FLOAT_VEC4:
glUniform4fv(uniforms[i].location, 1, uniforms[i].value);
break;
default:
- abort();
+ if (strncmp(uniforms[i].name, "gl_", 3) == 0) {
+ /* built-in uniform: ignore */
+ }
+ else {
+ fprintf(stderr,
+ "Unexpected uniform data type in SetUniformValues\n");
+ abort();
+ }
}
}
}
+
+
+/** Get list of uniforms used in the program */
+GLuint
+GetUniforms(GLuint program, struct uniform_info uniforms[])
+{
+ GLint n, max, i;
+
+ glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &n);
+ glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &max);
+
+ for (i = 0; i < n; i++) {
+ GLint size, len;
+ GLenum type;
+ char name[100];
+
+ glGetActiveUniform(program, i, 100, &len, &size, &type, name);
+
+ uniforms[i].name = strdup(name);
+ uniforms[i].size = size;
+ uniforms[i].type = type;
+ uniforms[i].location = glGetUniformLocation(program, name);
+ }
+
+ uniforms[i].name = NULL; /* end of list */
+
+ return n;
+}
+
+
+void
+PrintUniforms(const struct uniform_info uniforms[])
+{
+ GLint i;
+
+ printf("Uniforms:\n");
+
+ for (i = 0; uniforms[i].name; i++) {
+ printf(" %d: %s size=%d type=0x%x loc=%d value=%g, %g, %g, %g\n",
+ i,
+ uniforms[i].name,
+ uniforms[i].size,
+ uniforms[i].type,
+ uniforms[i].location,
+ uniforms[i].value[0],
+ uniforms[i].value[1],
+ uniforms[i].value[2],
+ uniforms[i].value[3]);
+ }
+}
+
+
+/** Get list of attribs used in the program */
+GLuint
+GetAttribs(GLuint program, struct attrib_info attribs[])
+{
+ GLint n, max, i;
+
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTES, &n);
+ glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &max);
+
+ for (i = 0; i < n; i++) {
+ GLint size, len;
+ GLenum type;
+ char name[100];
+
+ glGetActiveAttrib(program, i, 100, &len, &size, &type, name);
+
+ attribs[i].name = strdup(name);
+ attribs[i].size = size;
+ attribs[i].type = type;
+ attribs[i].location = glGetAttribLocation(program, name);
+ }
+
+ attribs[i].name = NULL; /* end of list */
+
+ return n;
+}
+
+
+void
+PrintAttribs(const struct attrib_info attribs[])
+{
+ GLint i;
+
+ printf("Attribs:\n");
+
+ for (i = 0; attribs[i].name; i++) {
+ printf(" %d: %s size=%d type=0x%x loc=%d\n",
+ i,
+ attribs[i].name,
+ attribs[i].size,
+ attribs[i].type,
+ attribs[i].location);
+ }
+}
diff --git a/progs/util/shaderutil.h b/progs/util/shaderutil.h
index cfb8c1f3b0..98c7181156 100644
--- a/progs/util/shaderutil.h
+++ b/progs/util/shaderutil.h
@@ -6,8 +6,8 @@
struct uniform_info
{
const char *name;
- GLuint size;
- GLenum type; /**< GL_FLOAT or GL_INT */
+ GLuint size; /**< number of value[] elements: 1, 2, 3 or 4 */
+ GLenum type; /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
GLfloat value[4];
GLint location; /**< filled in by InitUniforms() */
};
@@ -15,6 +15,15 @@ struct uniform_info
#define END_OF_UNIFORMS { NULL, 0, GL_NONE, { 0, 0, 0, 0 }, -1 }
+struct attrib_info
+{
+ const char *name;
+ GLuint size; /**< number of value[] elements: 1, 2, 3 or 4 */
+ GLenum type; /**< GL_FLOAT, GL_FLOAT_VEC4, GL_INT, etc */
+ GLint location;
+};
+
+
extern GLboolean
ShadersSupported(void);
@@ -27,8 +36,28 @@ CompileShaderFile(GLenum shaderType, const char *filename);
extern GLuint
LinkShaders(GLuint vertShader, GLuint fragShader);
+extern GLboolean
+ValidateShaderProgram(GLuint program);
+
+extern GLdouble
+GetShaderCompileTime(void);
+
+extern GLdouble
+GetShaderLinkTime(void);
+
+extern void
+SetUniformValues(GLuint program, struct uniform_info uniforms[]);
+
+extern GLuint
+GetUniforms(GLuint program, struct uniform_info uniforms[]);
+
extern void
-InitUniforms(GLuint program, struct uniform_info uniforms[]);
+PrintUniforms(const struct uniform_info uniforms[]);
+
+extern GLuint
+GetAttribs(GLuint program, struct attrib_info attribs[]);
+extern void
+PrintAttribs(const struct attrib_info attribs[]);
#endif /* SHADER_UTIL_H */
diff --git a/progs/vp/arl-static.txt b/progs/vp/arl-static.txt
index aea87b79a4..83aebf689e 100644
--- a/progs/vp/arl-static.txt
+++ b/progs/vp/arl-static.txt
@@ -1,5 +1,5 @@
!!ARBvp1.0
-PARAM arr[5] = { {.0,.1,.2,.3}, {.4,.5,.6,.7}, {.8,.9,.10,.1}, {.12,.3,.4,.14}, {.5,.8,.1,.9}, {.2,0,.4,.1}, {.6,.1,.8,.9}};
+PARAM arr[7] = { {.0,.1,.2,.3}, {.4,.5,.6,.7}, {.8,.9,.10,.1}, {.12,.3,.4,.14}, {.5,.8,.1,.9}, {.2,0,.4,.1}, {.6,.1,.8,.9}};
ADDRESS addr;
ARL addr.x, {3}.x;
MOV result.color, arr[addr.x];
diff --git a/progs/vp/arl-unused.txt b/progs/vp/arl-unused.txt
index 7bdbb8e86c..c2afe3c092 100644
--- a/progs/vp/arl-unused.txt
+++ b/progs/vp/arl-unused.txt
@@ -1,5 +1,5 @@
!!ARBvp1.0
-PARAM arr[5] = { {.0,.1,.2,.3}, {.4,.5,.6,.7}, {.8,.9,.10,.1}, {.12,.3,.4,.14}, {.5,.8,.1,.9}, {.2,0,.4,.1}, {.6,.1,.8,.9}};
+PARAM arr[7] = { {.0,.1,.2,.3}, {.4,.5,.6,.7}, {.8,.9,.10,.1}, {.12,.3,.4,.14}, {.5,.8,.1,.9}, {.2,0,.4,.1}, {.6,.1,.8,.9}};
ADDRESS addr;
ARL addr.x, {3}.x; # not actually used
MOV result.color, arr[3];
diff --git a/progs/vp/vp-tris.c b/progs/vp/vp-tris.c
index 97995accdd..1356242d97 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/progs/xdemos/.gitignore b/progs/xdemos/.gitignore
index 92446dd9fc..1b9b3a87c0 100644
--- a/progs/xdemos/.gitignore
+++ b/progs/xdemos/.gitignore
@@ -13,6 +13,7 @@ glxpixmap
glxsnoop
glxswapcontrol
manywin
+multictx
offset
overlay
pbdemo
diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile
index 6581df8039..53e1c54ef3 100644
--- a/progs/xdemos/Makefile
+++ b/progs/xdemos/Makefile
@@ -26,6 +26,7 @@ PROGS = \
glxsnoop \
glxswapcontrol \
manywin \
+ multictx \
offset \
overlay \
pbinfo \
diff --git a/progs/xdemos/glxcontexts.c b/progs/xdemos/glxcontexts.c
index 481749be3d..9f83679acd 100644
--- a/progs/xdemos/glxcontexts.c
+++ b/progs/xdemos/glxcontexts.c
@@ -378,6 +378,9 @@ make_window( Display *dpy, const char *name,
scrnum = DefaultScreen( dpy );
root = RootWindow( dpy, scrnum );
+ if (visinfo)
+ XFree(visinfo);
+
visinfo = glXChooseVisual( dpy, scrnum, attribs );
if (!visinfo) {
printf("Error: couldn't get an RGB, Double-buffered visual\n");
diff --git a/progs/xdemos/glxgears.c b/progs/xdemos/glxgears.c
index bc84ee3dbd..088f25a357 100644
--- a/progs/xdemos/glxgears.c
+++ b/progs/xdemos/glxgears.c
@@ -23,10 +23,7 @@
* This is a port of the infamous "gears" demo to straight GLX (i.e. no GLUT)
* Port by Brian Paul 23 March 2001
*
- * Command line options:
- * -info print GL implementation information
- * -stereo use stereo enabled GLX visual
- *
+ * See usage() below for command line options.
*/
@@ -45,10 +42,6 @@ typedef int (*PFNGLXGETSWAPINTERVALMESAPROC)(void);
#endif
-static int is_glx_extension_supported(Display *dpy, const char *query);
-
-static void query_vsync(Display *dpy);
-
#define BENCHMARK
#ifdef BENCHMARK
@@ -572,7 +565,7 @@ make_window( Display *dpy, const char *name,
/**
* Determine whether or not a GLX extension is supported.
*/
-int
+static int
is_glx_extension_supported(Display *dpy, const char *query)
{
const int scrnum = DefaultScreen(dpy);
@@ -592,7 +585,7 @@ is_glx_extension_supported(Display *dpy, const char *query)
/**
* Attempt to determine whether or not the display is synched to vblank.
*/
-void
+static void
query_vsync(Display *dpy)
{
int interval = 0;
diff --git a/progs/xdemos/glxswapcontrol.c b/progs/xdemos/glxswapcontrol.c
index df9f7ad784..cd60d460a0 100644
--- a/progs/xdemos/glxswapcontrol.c
+++ b/progs/xdemos/glxswapcontrol.c
@@ -587,6 +587,9 @@ event_loop(Display *dpy, Window win)
angle += 2.0;
draw();
+
+ glXSwapBuffers(dpy, win);
+
if ( get_frame_usage != NULL ) {
GLfloat temp;
@@ -594,8 +597,6 @@ event_loop(Display *dpy, Window win)
frame_usage += temp;
}
- glXSwapBuffers(dpy, win);
-
/* calc framerate */
{
static int t0 = -1;
diff --git a/progs/xdemos/multictx.c b/progs/xdemos/multictx.c
new file mode 100644
index 0000000000..75255b2860
--- /dev/null
+++ b/progs/xdemos/multictx.c
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Test rendering with two contexts into one window.
+ * Setup different rendering state for each context to check that
+ * context switching is handled properly.
+ *
+ * Brian Paul
+ * 6 Aug 2009
+ */
+
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/keysym.h>
+#include <GL/gl.h>
+#include <GL/glx.h>
+
+
+
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+
+/** Event handler results: */
+#define NOP 0
+#define EXIT 1
+#define DRAW 2
+
+static GLfloat view_rotx = 0.0, view_roty = 210.0, view_rotz = 0.0;
+static GLint gear1, gear2;
+static GLfloat angle = 0.0;
+
+static GLboolean animate = GL_TRUE; /* Animation */
+
+
+static double
+current_time(void)
+{
+ struct timeval tv;
+#ifdef __VMS
+ (void) gettimeofday(&tv, NULL );
+#else
+ struct timezone tz;
+ (void) gettimeofday(&tv, &tz);
+#endif
+ return (double) tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+
+/*
+ *
+ * Draw a gear wheel. You'll probably want to call this function when
+ * building a display list since we do a lot of trig here.
+ *
+ * Input: inner_radius - radius of hole at center
+ * outer_radius - radius at center of teeth
+ * width - width of gear
+ * teeth - number of teeth
+ * tooth_depth - depth of tooth
+ */
+static void
+gear(GLfloat inner_radius, GLfloat outer_radius, GLfloat width,
+ GLint teeth, GLfloat tooth_depth)
+{
+ GLint i;
+ GLfloat r0, r1, r2;
+ GLfloat angle, da;
+ GLfloat u, v, len;
+
+ r0 = inner_radius;
+ r1 = outer_radius - tooth_depth / 2.0;
+ r2 = outer_radius + tooth_depth / 2.0;
+
+ da = 2.0 * M_PI / teeth / 4.0;
+
+ glShadeModel(GL_FLAT);
+
+ glNormal3f(0.0, 0.0, 1.0);
+
+ /* draw front face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw front sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ }
+ glEnd();
+
+ glNormal3f(0.0, 0.0, -1.0);
+
+ /* draw back face */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ if (i < teeth) {
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ }
+ }
+ glEnd();
+
+ /* draw back sides of teeth */
+ glBegin(GL_QUADS);
+ da = 2.0 * M_PI / teeth / 4.0;
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ }
+ glEnd();
+
+ /* draw outward faces of teeth */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i < teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), width * 0.5);
+ glVertex3f(r1 * cos(angle), r1 * sin(angle), -width * 0.5);
+ u = r2 * cos(angle + da) - r1 * cos(angle);
+ v = r2 * sin(angle + da) - r1 * sin(angle);
+ len = sqrt(u * u + v * v);
+ u /= len;
+ v /= len;
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), width * 0.5);
+ glVertex3f(r2 * cos(angle + da), r2 * sin(angle + da), -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ width * 0.5);
+ glVertex3f(r2 * cos(angle + 2 * da), r2 * sin(angle + 2 * da),
+ -width * 0.5);
+ u = r1 * cos(angle + 3 * da) - r2 * cos(angle + 2 * da);
+ v = r1 * sin(angle + 3 * da) - r2 * sin(angle + 2 * da);
+ glNormal3f(v, -u, 0.0);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ width * 0.5);
+ glVertex3f(r1 * cos(angle + 3 * da), r1 * sin(angle + 3 * da),
+ -width * 0.5);
+ glNormal3f(cos(angle), sin(angle), 0.0);
+ }
+
+ glVertex3f(r1 * cos(0), r1 * sin(0), width * 0.5);
+ glVertex3f(r1 * cos(0), r1 * sin(0), -width * 0.5);
+
+ glEnd();
+
+ glShadeModel(GL_SMOOTH);
+
+ /* draw inside radius cylinder */
+ glBegin(GL_QUAD_STRIP);
+ for (i = 0; i <= teeth; i++) {
+ angle = i * 2.0 * M_PI / teeth;
+ glNormal3f(-cos(angle), -sin(angle), 0.0);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), -width * 0.5);
+ glVertex3f(r0 * cos(angle), r0 * sin(angle), width * 0.5);
+ }
+ glEnd();
+}
+
+
+static void
+draw(int ctx)
+{
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glPushMatrix();
+ glRotatef(view_rotx, 1.0, 0.0, 0.0);
+ glRotatef(view_roty + angle, 0.0, 1.0, 0.0);
+ glRotatef(view_rotz, 0.0, 0.0, 1.0);
+
+ if (ctx == 0) {
+ glDisable(GL_CULL_FACE);
+ glPushMatrix();
+ glRotatef(angle, 0.0, 0.0, 1.0);
+ glCallList(gear1);
+ glPopMatrix();
+ /* This should not effect the other context's rendering */
+ glEnable(GL_CULL_FACE);
+ glCullFace(GL_FRONT_AND_BACK);
+ }
+ else {
+ glPushMatrix();
+ glRotatef(-2.0 * angle - 9.0, 0.0, 0.0, 1.0);
+ glCallList(gear2);
+ glPopMatrix();
+ }
+
+ glPopMatrix();
+
+ /* this flush is important since we'll be switching contexts next */
+ glFlush();
+}
+
+
+
+static void
+draw_frame(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
+{
+ static double tRot0 = -1.0;
+ double dt, t = current_time();
+
+ if (tRot0 < 0.0)
+ tRot0 = t;
+ dt = t - tRot0;
+ tRot0 = t;
+
+ if (animate) {
+ /* advance rotation for next frame */
+ angle += 70.0 * dt; /* 70 degrees per second */
+ if (angle > 3600.0)
+ angle -= 3600.0;
+ }
+
+ glXMakeCurrent(dpy, (GLXDrawable) win, ctx1);
+ draw(0);
+
+ glXMakeCurrent(dpy, (GLXDrawable) win, ctx2);
+ draw(1);
+
+ glXSwapBuffers(dpy, win);
+}
+
+
+/* new window size or exposure */
+static void
+reshape(Display *dpy, Window win,
+ GLXContext ctx1, GLXContext ctx2, int width, int height)
+{
+ int i;
+
+ width /= 2;
+
+ /* loop: left half of window, right half of window */
+ for (i = 0; i < 2; i++) {
+ if (i == 0)
+ glXMakeCurrent(dpy, win, ctx1);
+ else
+ glXMakeCurrent(dpy, win, ctx2);
+
+ glViewport(width * i, 0, width, height);
+ glScissor(width * i, 0, width, height);
+
+ {
+ GLfloat h = (GLfloat) height / (GLfloat) width;
+
+ glMatrixMode(GL_PROJECTION);
+ glLoadIdentity();
+ glFrustum(-1.0, 1.0, -h, h, 5.0, 60.0);
+ }
+
+ glMatrixMode(GL_MODELVIEW);
+ glLoadIdentity();
+ glTranslatef(0.0, 0.0, -30.0);
+ }
+}
+
+
+
+static void
+init(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
+{
+ static GLfloat pos[4] = { 5.0, 5.0, 10.0, 0.0 };
+ static GLfloat red[4] = { 0.8, 0.1, 0.0, 1.0 };
+ static GLfloat green[4] = { 0.0, 0.8, 0.2, 0.5 };
+ /*static GLfloat blue[4] = { 0.2, 0.2, 1.0, 1.0 };*/
+
+ /* first ctx */
+ {
+ static GLuint stipple[32] = {
+ 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
+ 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
+
+ 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
+ 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
+
+ 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
+ 0x00ff00ff, 0x00ff00ff, 0x00ff00ff, 0x00ff00ff,
+
+ 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00,
+ 0xff00ff00, 0xff00ff00, 0xff00ff00, 0xff00ff00
+ };
+
+ glXMakeCurrent(dpy, win, ctx1);
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ gear1 = glGenLists(1);
+ glNewList(gear1, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);
+ gear(1.0, 4.0, 1.0, 20, 0.7);
+ glEndList();
+
+ glEnable(GL_NORMALIZE);
+ glEnable(GL_SCISSOR_TEST);
+ glClearColor(0.4, 0.4, 0.4, 1.0);
+
+ glPolygonStipple((GLubyte *) stipple);
+ glEnable(GL_POLYGON_STIPPLE);
+ }
+
+ /* second ctx */
+ {
+ glXMakeCurrent(dpy, win, ctx2);
+
+ glLightfv(GL_LIGHT0, GL_POSITION, pos);
+ glEnable(GL_LIGHTING);
+ glEnable(GL_LIGHT0);
+ glEnable(GL_DEPTH_TEST);
+
+ gear2 = glGenLists(1);
+ glNewList(gear2, GL_COMPILE);
+ glMaterialfv(GL_FRONT, GL_AMBIENT_AND_DIFFUSE, green);
+ gear(1.5, 3.0, 1.5, 16, 0.7);
+ glEndList();
+
+ glEnable(GL_NORMALIZE);
+ glEnable(GL_SCISSOR_TEST);
+ glClearColor(0.6, 0.6, 0.6, 1.0);
+
+ glEnable(GL_BLEND);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+}
+
+
+/**
+ * Create an RGB, double-buffered window.
+ * Return the window and two context handles.
+ */
+static void
+make_window_and_contexts( Display *dpy, const char *name,
+ int x, int y, int width, int height,
+ Window *winRet,
+ GLXContext *ctxRet1,
+ GLXContext *ctxRet2)
+{
+ int attribs[] = { GLX_RGBA,
+ GLX_RED_SIZE, 1,
+ GLX_GREEN_SIZE, 1,
+ GLX_BLUE_SIZE, 1,
+ GLX_DOUBLEBUFFER,
+ GLX_DEPTH_SIZE, 1,
+ None };
+ int scrnum;
+ XSetWindowAttributes attr;
+ unsigned long mask;
+ Window root;
+ Window win;
+ XVisualInfo *visinfo;
+
+ scrnum = DefaultScreen( dpy );
+ root = RootWindow( dpy, scrnum );
+
+ visinfo = glXChooseVisual( dpy, scrnum, attribs );
+ if (!visinfo) {
+ printf("Error: couldn't get an RGB, Double-buffered visual\n");
+ exit(1);
+ }
+
+ /* window attributes */
+ attr.background_pixel = 0;
+ attr.border_pixel = 0;
+ attr.colormap = XCreateColormap( dpy, root, visinfo->visual, AllocNone);
+ attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
+ mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
+
+ win = XCreateWindow( dpy, root, x, y, width, height,
+ 0, visinfo->depth, InputOutput,
+ visinfo->visual, mask, &attr );
+
+ /* set hints and properties */
+ {
+ XSizeHints sizehints;
+ sizehints.x = x;
+ sizehints.y = y;
+ sizehints.width = width;
+ sizehints.height = height;
+ sizehints.flags = USSize | USPosition;
+ XSetNormalHints(dpy, win, &sizehints);
+ XSetStandardProperties(dpy, win, name, name,
+ None, (char **)NULL, 0, &sizehints);
+ }
+
+ *winRet = win;
+ *ctxRet1 = glXCreateContext( dpy, visinfo, NULL, True );
+ *ctxRet2 = glXCreateContext( dpy, visinfo, NULL, True );
+
+ if (!*ctxRet1 || !*ctxRet2) {
+ printf("Error: glXCreateContext failed\n");
+ exit(1);
+ }
+
+ XFree(visinfo);
+}
+
+
+/**
+ * Handle one X event.
+ * \return NOP, EXIT or DRAW
+ */
+static int
+handle_event(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2,
+ XEvent *event)
+{
+ (void) dpy;
+ (void) win;
+
+ switch (event->type) {
+ case Expose:
+ return DRAW;
+ case ConfigureNotify:
+ reshape(dpy, win, ctx1, ctx2,
+ event->xconfigure.width, event->xconfigure.height);
+ break;
+ case KeyPress:
+ {
+ char buffer[10];
+ int r, code;
+ code = XLookupKeysym(&event->xkey, 0);
+ if (code == XK_Left) {
+ view_roty += 5.0;
+ }
+ else if (code == XK_Right) {
+ view_roty -= 5.0;
+ }
+ else if (code == XK_Up) {
+ view_rotx += 5.0;
+ }
+ else if (code == XK_Down) {
+ view_rotx -= 5.0;
+ }
+ else {
+ r = XLookupString(&event->xkey, buffer, sizeof(buffer),
+ NULL, NULL);
+ if (buffer[0] == 27) {
+ /* escape */
+ return EXIT;
+ }
+ else if (buffer[0] == 'a' || buffer[0] == 'A') {
+ animate = !animate;
+ }
+ }
+ return DRAW;
+ }
+ }
+ return NOP;
+}
+
+
+static void
+event_loop(Display *dpy, Window win, GLXContext ctx1, GLXContext ctx2)
+{
+ while (1) {
+ int op;
+ while (!animate || XPending(dpy) > 0) {
+ XEvent event;
+ XNextEvent(dpy, &event);
+ op = handle_event(dpy, win, ctx1, ctx2, &event);
+ if (op == EXIT)
+ return;
+ else if (op == DRAW)
+ break;
+ }
+
+ draw_frame(dpy, win, ctx1, ctx2);
+ }
+}
+
+
+int
+main(int argc, char *argv[])
+{
+ unsigned int winWidth = 800, winHeight = 400;
+ int x = 0, y = 0;
+ Display *dpy;
+ Window win;
+ GLXContext ctx1, ctx2;
+ char *dpyName = NULL;
+ GLboolean printInfo = GL_FALSE;
+ int i;
+
+ for (i = 1; i < argc; i++) {
+ if (strcmp(argv[i], "-display") == 0) {
+ dpyName = argv[i+1];
+ i++;
+ }
+ else {
+ return 1;
+ }
+ }
+
+ dpy = XOpenDisplay(dpyName);
+ if (!dpy) {
+ printf("Error: couldn't open display %s\n",
+ dpyName ? dpyName : getenv("DISPLAY"));
+ return -1;
+ }
+
+ make_window_and_contexts(dpy, "multictx", x, y, winWidth, winHeight,
+ &win, &ctx1, &ctx2);
+ XMapWindow(dpy, win);
+
+ if (printInfo) {
+ printf("GL_RENDERER = %s\n", (char *) glGetString(GL_RENDERER));
+ printf("GL_VERSION = %s\n", (char *) glGetString(GL_VERSION));
+ printf("GL_VENDOR = %s\n", (char *) glGetString(GL_VENDOR));
+ printf("GL_EXTENSIONS = %s\n", (char *) glGetString(GL_EXTENSIONS));
+ }
+
+ init(dpy, win, ctx1, ctx2);
+
+ /* Set initial projection/viewing transformation.
+ * We can't be sure we'll get a ConfigureNotify event when the window
+ * first appears.
+ */
+ reshape(dpy, win, ctx1, ctx2, winWidth, winHeight);
+
+ event_loop(dpy, win, ctx1, ctx2);
+
+ glDeleteLists(gear1, 1);
+ glDeleteLists(gear2, 1);
+ glXDestroyContext(dpy, ctx1);
+ glXDestroyContext(dpy, ctx2);
+ XDestroyWindow(dpy, win);
+ XCloseDisplay(dpy);
+
+ return 0;
+}
diff --git a/scons/dxsdk.py b/scons/dxsdk.py
index de090e4f99..920cc2f689 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 e9e799dc78..38782ac726 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -334,12 +334,17 @@ 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',
#'-march=pentium4',
'-mmmx', '-msse', '-msse2', # enable SIMD intrinsics
+ '-mstackrealign', # ensure stack is aligned -- do not enabled -msse without it!
#'-mfpmath=sse',
]
if env['machine'] == 'x86_64':
@@ -462,6 +467,8 @@ def generate(env):
shlinkflags += [
'-Wl,-Bsymbolic',
]
+ # Handle circular dependencies in the libraries
+ env['_LIBFLAGS'] = '-Wl,--start-group ' + env['_LIBFLAGS'] + ' -Wl,--end-group'
if platform == 'windows' and msvc:
# See also:
# - http://msdn2.microsoft.com/en-us/library/y0zzbyt4.aspx
diff --git a/scons/llvm.py b/scons/llvm.py
new file mode 100644
index 0000000000..d3293bb404
--- /dev/null
+++ b/scons/llvm.py
@@ -0,0 +1,78 @@
+"""llvm
+
+Tool-specific initialization for LLVM
+
+"""
+
+#
+# Copyright (c) 2009 VMware, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+import os
+import os.path
+
+import SCons.Errors
+import SCons.Util
+
+
+def generate(env):
+ try:
+ llvm_dir = os.environ['LLVM']
+ except KeyError:
+ # Do nothing -- use the system headers/libs
+ pass
+ else:
+ if not os.path.isdir(llvm_dir):
+ raise SCons.Errors.InternalError, "Specified LLVM directory not found"
+
+ if env['debug']:
+ llvm_subdir = 'Debug'
+ else:
+ llvm_subdir = 'Release'
+
+ llvm_bin_dir = os.path.join(llvm_dir, llvm_subdir, 'bin')
+ if not os.path.isdir(llvm_bin_dir):
+ 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)
+
+ if env.Detect('llvm-config'):
+ version = env.backtick('llvm-config --version').rstrip()
+
+ try:
+ env.ParseConfig('llvm-config --cppflags')
+ env.ParseConfig('llvm-config --libs jit interpreter nativecodegen bitwriter')
+ env.ParseConfig('llvm-config --ldflags')
+ 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
+
+def exists(env):
+ return True
+
+# vim:set ts=4 sw=4 et:
diff --git a/scons/udis86.py b/scons/udis86.py
new file mode 100644
index 0000000000..ba71d4eb0b
--- /dev/null
+++ b/scons/udis86.py
@@ -0,0 +1,42 @@
+"""udis86
+
+Tool-specific initialization for udis86
+
+"""
+
+#
+# Copyright (c) 2009 VMware, Inc.
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
+# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
+# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+
+def generate(env):
+ conf = env.Configure()
+
+ if conf.CheckHeader('udis86.h'): # and conf.CheckLib('udis86'):
+ env.Append(CPPDEFINES = [('HAVE_UDIS86', '1')])
+ env.Prepend(LIBS = ['udis86'])
+
+ conf.Finish()
+
+def exists(env):
+ return True
+
+# vim:set ts=4 sw=4 et:
diff --git a/scons/winddk.py b/scons/winddk.py
index afcea9909a..4dac16ee66 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/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c
index f316974d83..aea4894448 100644
--- a/src/egl/drivers/demo/demo.c
+++ b/src/egl/drivers/demo/demo.c
@@ -49,9 +49,8 @@ typedef struct demo_context
static EGLBoolean
-demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+demoInitialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLScreen *scrn;
EGLint i;
@@ -85,7 +84,9 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
_eglAddConfig(disp, config);
}
- drv->Initialized = EGL_TRUE;
+ /* enable supported extensions */
+ disp->Extensions.MESA_screen_surface = EGL_TRUE;
+ disp->Extensions.MESA_copy_context = EGL_TRUE;
*major = 1;
*minor = 0;
@@ -95,71 +96,56 @@ demoInitialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
static EGLBoolean
-demoTerminate(_EGLDriver *drv, EGLDisplay dpy)
+demoTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
- free(drv);
return EGL_TRUE;
}
static DemoContext *
-LookupDemoContext(EGLContext ctx)
+LookupDemoContext(_EGLContext *c)
{
- _EGLContext *c = _eglLookupContext(ctx);
return (DemoContext *) c;
}
static DemoSurface *
-LookupDemoSurface(EGLSurface surf)
+LookupDemoSurface(_EGLSurface *s)
{
- _EGLSurface *s = _eglLookupSurface(surf);
return (DemoSurface *) s;
}
-
-static EGLContext
-demoCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+demoCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
{
- _EGLConfig *conf;
DemoContext *c;
int i;
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
-
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateContext");
- return EGL_NO_CONTEXT;
+ return NULL;
}
}
c = (DemoContext *) calloc(1, sizeof(DemoContext));
if (!c)
- return EGL_NO_CONTEXT;
+ return NULL;
_eglInitContext(drv, &c->Base, conf, attrib_list);
c->DemoStuff = 1;
printf("demoCreateContext\n");
- /* link to display */
- _eglLinkContext(&c->Base, _eglLookupDisplay(dpy));
- assert(_eglGetContextHandle(&c->Base));
-
- return _eglGetContextHandle(&c->Base);
+ return &c->Base;
}
-static EGLSurface
-demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
{
int i;
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
@@ -167,102 +153,88 @@ demoCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, Nativ
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreateWindowSurface");
- return EGL_NO_SURFACE;
+ return NULL;
}
}
printf("eglCreateWindowSurface()\n");
/* XXX unfinished */
- return EGL_NO_SURFACE;
+ return NULL;
}
-static EGLSurface
-demoCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+static _EGLSurface *
+demoCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
{
- _EGLConfig *conf;
EGLint i;
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
- return EGL_NO_SURFACE;
- }
-
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
- return EGL_NO_SURFACE;
+ return NULL;
}
}
if (conf->Attrib[EGL_SURFACE_TYPE - FIRST_ATTRIB] == 0) {
_eglError(EGL_BAD_MATCH, "eglCreatePixmapSurface");
- return EGL_NO_SURFACE;
+ return NULL;
}
printf("eglCreatePixmapSurface()\n");
- return EGL_NO_SURFACE;
+ return NULL;
}
-static EGLSurface
-demoCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+demoCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
DemoSurface *surf = (DemoSurface *) calloc(1, sizeof(DemoSurface));
- _EGLConfig *conf;
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
- conf = _eglLookupConfig(drv, dpy, config);
if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
/* a real driver would allocate the pbuffer memory here */
- return surf->Base.Handle;
+ return &surf->Base;
}
static EGLBoolean
-demoDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+demoDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
{
DemoSurface *fs = LookupDemoSurface(surface);
- _eglUnlinkSurface(&fs->Base);
- if (!fs->Base.IsBound)
+ if (!_eglIsSurfaceBound(&fs->Base))
free(fs);
return EGL_TRUE;
}
static EGLBoolean
-demoDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+demoDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
{
DemoContext *fc = LookupDemoContext(context);
- _eglUnlinkContext(&fc->Base);
- if (!fc->Base.IsBound)
+ if (!_eglIsContextBound(&fc->Base))
free(fc);
return EGL_TRUE;
}
static EGLBoolean
-demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+demoMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *drawSurf, _EGLSurface *readSurf, _EGLContext *ctx)
{
/*DemoDriver *demo = DEMO_DRIVER(dpy);*/
- DemoSurface *readSurf = LookupDemoSurface(read);
- DemoSurface *drawSurf = LookupDemoSurface(draw);
- DemoContext *ctx = LookupDemoContext(context);
EGLBoolean b;
- b = _eglMakeCurrent(drv, dpy, draw, read, context);
+ b = _eglMakeCurrent(drv, dpy, drawSurf, readSurf, ctx);
if (!b)
return EGL_FALSE;
@@ -276,12 +248,19 @@ demoMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
}
+static void
+demoUnload(_EGLDriver *drv)
+{
+ free(drv);
+}
+
+
/**
* The bootstrap function. Return a new DemoDriver object and
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
DemoDriver *demo;
@@ -303,9 +282,8 @@ _eglMain(_EGLDisplay *dpy, const char *args)
demo->Base.API.DestroySurface = demoDestroySurface;
demo->Base.API.DestroyContext = demoDestroyContext;
- /* enable supported extensions */
- demo->Base.Extensions.MESA_screen_surface = EGL_TRUE;
- demo->Base.Extensions.MESA_copy_context = EGL_TRUE;
+ demo->Base.Name = "egl/demo";
+ demo->Base.Unload = demoUnload;
return &demo->Base;
}
diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile
index 567edfae97..7339c97c77 100644
--- a/src/egl/drivers/dri/Makefile
+++ b/src/egl/drivers/dri/Makefile
@@ -55,6 +55,7 @@ install:
clean:
-rm -f *.o
-rm -f *.so
+ -rm -f depend depend.bak
depend: $(SOURCES) $(HEADERS)
@ echo "running $(MKDEP)"
diff --git a/src/egl/drivers/dri/egldri.c b/src/egl/drivers/dri/egldri.c
index 3f9617a8f9..9e400be624 100644
--- a/src/egl/drivers/dri/egldri.c
+++ b/src/egl/drivers/dri/egldri.c
@@ -296,7 +296,7 @@ _eglDRIDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
fs->drawable.destroyDrawable(disp, fs->drawable.private);
- if (!fs->Base.IsBound)
+ if (!_eglIsSurfaceBound(&fs->Base))
free(fs);
return EGL_TRUE;
}
@@ -312,7 +312,7 @@ _eglDRIDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
fc->driContext.destroyContext(disp, 0, fc->driContext.private);
- if (!fc->Base.IsBound)
+ if (!_eglIsContextBound(&fc->Base))
free(fc);
return EGL_TRUE;
}
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index 207b1ea779..4685f600e2 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -50,14 +50,11 @@
#include <GL/gl.h>
#include "glxclient.h"
-#define _EGL_PLATFORM_X
-
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
@@ -106,7 +103,13 @@ struct visual_attribs
struct GLX_egl_driver
{
_EGLDriver Base; /**< base class */
+};
+
+/** driver data of _EGLDisplay */
+struct GLX_egl_display
+{
+ Display *dpy;
XVisualInfo *visuals;
GLXFBConfig *fbconfigs;
@@ -136,6 +139,7 @@ struct GLX_egl_surface
struct GLX_egl_config
{
_EGLConfig Base; /**< base class */
+ int index;
};
/** cast wrapper */
@@ -145,6 +149,12 @@ GLX_egl_driver(_EGLDriver *drv)
return (struct GLX_egl_driver *) drv;
}
+static struct GLX_egl_display *
+GLX_egl_display(_EGLDisplay *dpy)
+{
+ return (struct GLX_egl_display *) dpy->DriverData;
+}
+
static struct GLX_egl_context *
GLX_egl_context(_EGLContext *ctx)
{
@@ -157,6 +167,12 @@ GLX_egl_surface(_EGLSurface *surf)
return (struct GLX_egl_surface *) surf;
}
+static int
+GLX_egl_config_index(_EGLConfig *conf)
+{
+ return ((struct GLX_egl_config *) conf)->index;
+}
+
static GLboolean
get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
struct visual_attribs *attribs)
@@ -267,6 +283,7 @@ glx_token_to_visual_class(int visual_type)
return None;
}
}
+
static int
get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
struct visual_attribs *attribs)
@@ -345,23 +362,22 @@ get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
#endif
static EGLBoolean
-create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
+create_configs(_EGLDisplay *disp, struct GLX_egl_display *GLX_dpy)
{
XVisualInfo theTemplate;
int numVisuals;
long mask;
int i;
- int egl_configs = 1;
struct visual_attribs attribs;
- GLX_drv->fbconfigs = NULL;
+ GLX_dpy->fbconfigs = NULL;
#ifdef GLX_VERSION_1_3
/* get list of all fbconfigs on this screen */
- GLX_drv->fbconfigs = glXGetFBConfigs(disp->Xdpy, DefaultScreen(disp->Xdpy), &numVisuals);
+ GLX_dpy->fbconfigs = glXGetFBConfigs(GLX_dpy->dpy, DefaultScreen(GLX_dpy->dpy), &numVisuals);
if (numVisuals == 0) {
- GLX_drv->fbconfigs = NULL;
+ GLX_dpy->fbconfigs = NULL;
goto xvisual;
}
@@ -369,12 +385,13 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
struct GLX_egl_config *config;
int bit;
- bit = get_fbconfig_attribs(disp->Xdpy, GLX_drv->fbconfigs[i], &attribs);
+ bit = get_fbconfig_attribs(GLX_dpy->dpy, GLX_dpy->fbconfigs[i], &attribs);
if (!bit)
continue;
config = CALLOC_STRUCT(GLX_egl_config);
+ config->index = i;
_eglInitConfig(&config->Base, (i+1));
SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id);
SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize);
@@ -400,18 +417,19 @@ create_configs(_EGLDisplay *disp, struct GLX_egl_driver *GLX_drv)
xvisual:
/* get list of all visuals on this screen */
- theTemplate.screen = DefaultScreen(disp->Xdpy);
+ theTemplate.screen = DefaultScreen(GLX_dpy->dpy);
mask = VisualScreenMask;
- GLX_drv->visuals = XGetVisualInfo(disp->Xdpy, mask, &theTemplate, &numVisuals);
+ GLX_dpy->visuals = XGetVisualInfo(GLX_dpy->dpy, mask, &theTemplate, &numVisuals);
for (i = 0; i < numVisuals; i++) {
struct GLX_egl_config *config;
- if (!get_visual_attribs(disp->Xdpy, &GLX_drv->visuals[i], &attribs))
+ if (!get_visual_attribs(GLX_dpy->dpy, &GLX_dpy->visuals[i], &attribs))
continue;
config = CALLOC_STRUCT(GLX_egl_config);
+ config->index = i;
_eglInitConfig(&config->Base, (i+1));
SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_ID, attribs.id);
SET_CONFIG_ATTRIB(&config->Base, EGL_BUFFER_SIZE, attribs.bufferSize);
@@ -441,76 +459,60 @@ end:
* Called via eglInitialize(), GLX_drv->API.Initialize().
*/
static EGLBoolean
-GLX_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
- EGLint *minor, EGLint *major)
+GLX_eglInitialize(_EGLDriver *drv, _EGLDisplay *disp,
+ EGLint *major, EGLint *minor)
{
- struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct GLX_egl_display *GLX_dpy;
- _eglLog(_EGL_DEBUG, "GLX: eglInitialize");
+ GLX_dpy = CALLOC_STRUCT(GLX_egl_display);
+ if (!GLX_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
- if (!disp->Xdpy) {
- disp->Xdpy = XOpenDisplay(NULL);
- if (!disp->Xdpy) {
+ GLX_dpy->dpy = (Display *) disp->NativeDisplay;
+ if (!GLX_dpy->dpy) {
+ GLX_dpy->dpy = XOpenDisplay(NULL);
+ if (!GLX_dpy->dpy) {
_eglLog(_EGL_WARNING, "GLX: XOpenDisplay failed");
+ free(GLX_dpy);
return EGL_FALSE;
}
- }
+ }
- glXQueryVersion(disp->Xdpy, &GLX_drv->glx_maj, &GLX_drv->glx_min);
-
- GLX_drv->Base.Initialized = EGL_TRUE;
+ disp->DriverData = (void *) GLX_dpy;
+ disp->ClientAPIsMask = all_apis;
- GLX_drv->Base.Name = "GLX";
+ glXQueryVersion(GLX_dpy->dpy, &GLX_dpy->glx_maj, &GLX_dpy->glx_min);
/* we're supporting EGL 1.4 */
- *minor = 1;
- *major = 4;
+ *major = 1;
+ *minor = 4;
- create_configs(disp, GLX_drv);
+ create_configs(disp, GLX_dpy);
return EGL_TRUE;
}
-/*
- * Do some clean-up that normally occurs in XCloseDisplay().
- * We do this here because we're about to unload a dynamic library
- * that has added some per-display extension data and callbacks.
- * If we don't do this here we'll crash in XCloseDisplay() because it'll
- * try to call functions that went away when the driver library was unloaded.
- */
-static void
-FreeDisplayExt(Display *dpy)
-{
- _XExtension *ext, *next;
-
- for (ext = dpy->ext_procs; ext; ext = next) {
- next = ext->next;
- if (ext->close_display) {
- ext->close_display(dpy, &ext->codes);
- ext->close_display = NULL;
- }
- if (ext->name)
- Xfree(ext->name);
- Xfree(ext);
- }
- dpy->ext_procs = NULL;
-
- _XFreeExtData (dpy->ext_data);
- dpy->ext_data = NULL;
-}
-
/**
* Called via eglTerminate(), drv->API.Terminate().
*/
static EGLBoolean
-GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+GLX_eglTerminate(_EGLDriver *drv, _EGLDisplay *disp)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
- _eglLog(_EGL_DEBUG, "GLX: eglTerminate");
+ _eglReleaseDisplayResources(drv, disp);
+ _eglCleanupDisplay(disp);
- FreeDisplayExt(disp->Xdpy);
+ if (GLX_dpy->visuals)
+ XFree(GLX_dpy->visuals);
+ if (GLX_dpy->fbconfigs)
+ XFree(GLX_dpy->fbconfigs);
+
+ if (!disp->NativeDisplay)
+ XCloseDisplay(GLX_dpy->dpy);
+ free(GLX_dpy);
+
+ disp->DriverData = NULL;
return EGL_TRUE;
}
@@ -519,52 +521,54 @@ GLX_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
-static EGLContext
-GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+GLX_eglCreateContext(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
struct GLX_egl_context *GLX_ctx = CALLOC_STRUCT(GLX_egl_context);
- struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
- struct GLX_egl_context *GLX_ctx_shared = NULL;
- _EGLConfig *conf;
-
- if (!GLX_ctx)
- return EGL_NO_CONTEXT;
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
+ struct GLX_egl_context *GLX_ctx_shared = GLX_egl_context(share_list);
- conf = _eglLookupConfig(drv, dpy, config);
- assert(conf);
+ if (!GLX_ctx) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+ return NULL;
+ }
if (!_eglInitContext(drv, &GLX_ctx->Base, conf, attrib_list)) {
free(GLX_ctx);
- return EGL_NO_CONTEXT;
- }
-
- if (share_list != EGL_NO_CONTEXT) {
- _EGLContext *shareCtx = _eglLookupContext(share_list);
- if (!shareCtx) {
- _eglError(EGL_BAD_CONTEXT, "eglCreateContext(share_list)");
- return EGL_FALSE;
- }
- GLX_ctx_shared = GLX_egl_context(shareCtx);
+ return NULL;
}
#ifdef GLX_VERSION_1_3
- if (GLX_drv->fbconfigs)
- GLX_ctx->context = glXCreateNewContext(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], GLX_RGBA_TYPE, GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE);
+ if (GLX_dpy->fbconfigs)
+ GLX_ctx->context =
+ glXCreateNewContext(GLX_dpy->dpy,
+ GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
+ GLX_RGBA_TYPE,
+ GLX_ctx_shared ? GLX_ctx_shared->context : NULL,
+ GL_TRUE);
else
#endif
- GLX_ctx->context = glXCreateContext(disp->Xdpy, &GLX_drv->visuals[(int)config-1], GLX_ctx_shared ? GLX_ctx_shared->context : NULL, GL_TRUE);
- if (!GLX_ctx->context)
- return EGL_FALSE;
+ GLX_ctx->context =
+ glXCreateContext(GLX_dpy->dpy,
+ &GLX_dpy->visuals[GLX_egl_config_index(conf)],
+ GLX_ctx_shared ? GLX_ctx_shared->context : NULL,
+ GL_TRUE);
+ if (!GLX_ctx->context) {
+ free(GLX_ctx);
+ return NULL;
+ }
#if 1
/* (maybe?) need to have a direct rendering context */
- if (!glXIsDirect(disp->Xdpy, GLX_ctx->context))
- return EGL_FALSE;
+ if (!glXIsDirect(GLX_dpy->dpy, GLX_ctx->context)) {
+ glXDestroyContext(GLX_dpy->dpy, GLX_ctx->context);
+ free(GLX_ctx);
+ return NULL;
+ }
#endif
- return _eglLinkContext(&GLX_ctx->Base, disp);
+ return &GLX_ctx->Base;
}
@@ -572,27 +576,32 @@ GLX_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
static EGLBoolean
-GLX_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
- EGLSurface r, EGLContext context)
+GLX_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *dsurf,
+ _EGLSurface *rsurf, _EGLContext *ctx)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLContext *ctx = _eglLookupContext(context);
- _EGLSurface *dsurf = _eglLookupSurface(d);
- _EGLSurface *rsurf = _eglLookupSurface(r);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_dsurf = GLX_egl_surface(dsurf);
struct GLX_egl_surface *GLX_rsurf = GLX_egl_surface(rsurf);
struct GLX_egl_context *GLX_ctx = GLX_egl_context(ctx);
+ GLXDrawable ddraw, rdraw;
+ GLXContext cctx;
- if (!_eglMakeCurrent(drv, dpy, d, r, context))
+ if (!_eglMakeCurrent(drv, disp, dsurf, rsurf, ctx))
return EGL_FALSE;
+ ddraw = (GLX_dsurf) ? GLX_dsurf->drawable : None;
+ rdraw = (GLX_rsurf) ? GLX_rsurf->drawable : None;
+ cctx = (GLX_ctx) ? GLX_ctx->context : NULL;
+
#ifdef GLX_VERSION_1_3
- if (!glXMakeContextCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_rsurf ? GLX_rsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL))
+ if (glXMakeContextCurrent(GLX_dpy->dpy, ddraw, rdraw, cctx))
+ return EGL_TRUE;
#endif
- if (!glXMakeCurrent(disp->Xdpy, GLX_dsurf ? GLX_dsurf->drawable : 0, GLX_ctx ? GLX_ctx->context : NULL))
- return EGL_FALSE;
- return EGL_TRUE;
+ if (ddraw == rdraw && glXMakeCurrent(GLX_dpy->dpy, ddraw, cctx))
+ return EGL_TRUE;
+
+ return EGL_FALSE;
}
/** Get size of given window */
@@ -612,104 +621,106 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
-static EGLSurface
-GLX_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+GLX_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
uint width, height;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- assert(conf);
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
- if (!GLX_surf)
- return EGL_NO_SURFACE;
+ if (!GLX_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ return NULL;
+ }
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(GLX_surf);
- return EGL_FALSE;
+ return NULL;
}
- _eglLinkSurface(&GLX_surf->Base, disp);
-
GLX_surf->drawable = window;
- get_drawable_size(disp->Xdpy, window, &width, &height);
+ get_drawable_size(GLX_dpy->dpy, window, &width, &height);
GLX_surf->Base.Width = width;
GLX_surf->Base.Height = height;
- return _eglGetSurfaceHandle(&GLX_surf->Base);
+ return &GLX_surf->Base;
}
#ifdef GLX_VERSION_1_3
-static EGLSurface
-GLX_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+GLX_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
NativePixmapType pixmap, const EGLint *attrib_list)
{
- struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
- _EGLConfig *conf;
int i;
- conf = _eglLookupConfig(drv, dpy, config);
- assert(conf);
+ /* GLX must >= 1.3 */
+ if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3))
+ return NULL;
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
- if (!GLX_surf)
- return EGL_NO_SURFACE;
+ if (!GLX_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePixmapSurface");
+ return NULL;
+ }
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PIXMAP_BIT,
conf, attrib_list)) {
free(GLX_surf);
- return EGL_FALSE;
+ return NULL;
}
- _eglLinkSurface(&GLX_surf->Base, disp);
-
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs at this time */
default:
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePixmapSurface");
- return EGL_NO_SURFACE;
+ free(GLX_surf);
+ return NULL;
}
}
- GLX_surf->drawable = glXCreatePixmap(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], pixmap, NULL);
+ GLX_surf->drawable =
+ glXCreatePixmap(GLX_dpy->dpy,
+ GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
+ pixmap, NULL);
+ if (!GLX_surf->drawable) {
+ free(GLX_surf);
+ return NULL;
+ }
- return _eglGetSurfaceHandle(&GLX_surf->Base);
+ return &GLX_surf->Base;
}
-static EGLSurface
-GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- const EGLint *attrib_list)
+static _EGLSurface *
+GLX_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp,
+ _EGLConfig *conf, const EGLint *attrib_list)
{
- struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf;
- _EGLConfig *conf;
int attribs[5];
int i = 0, j = 0;
- conf = _eglLookupConfig(drv, dpy, config);
- assert(conf);
+ /* GLX must >= 1.3 */
+ if (!(GLX_dpy->glx_maj == 1 && GLX_dpy->glx_min >= 3))
+ return NULL;
GLX_surf = CALLOC_STRUCT(GLX_egl_surface);
- if (!GLX_surf)
- return EGL_NO_SURFACE;
+ if (!GLX_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
if (!_eglInitSurface(drv, &GLX_surf->Base, EGL_PBUFFER_BIT,
conf, attrib_list)) {
free(GLX_surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglLinkSurface(&GLX_surf->Base, disp);
-
while(attrib_list[i] != EGL_NONE) {
switch (attrib_list[i]) {
case EGL_WIDTH:
@@ -725,76 +736,81 @@ GLX_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
}
attribs[j++] = 0;
- GLX_surf->drawable = glXCreatePbuffer(disp->Xdpy, GLX_drv->fbconfigs[(int)config-1], attribs);
+ GLX_surf->drawable =
+ glXCreatePbuffer(GLX_dpy->dpy,
+ GLX_dpy->fbconfigs[GLX_egl_config_index(conf)],
+ attribs);
+ if (!GLX_surf->drawable) {
+ free(GLX_surf);
+ return NULL;
+ }
- return _eglGetSurfaceHandle(&GLX_surf->Base);
+ return &GLX_surf->Base;
}
#endif
static EGLBoolean
-GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+GLX_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(surface);
- return EGL_TRUE;
- if (surf) {
- _eglUnlinkSurface(surf);
- if (!surf->IsBound)
- free(surf);
-
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
+ if (!_eglIsSurfaceBound(surf)) {
+ struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
+ switch (surf->Type) {
+ case EGL_PBUFFER_BIT:
+ glXDestroyPbuffer(GLX_dpy->dpy, GLX_surf->drawable);
+ break;
+ case EGL_PIXMAP_BIT:
+ glXDestroyPixmap(GLX_dpy->dpy, GLX_surf->drawable);
+ break;
+ default:
+ break;
+ }
+ free(surf);
}
+
+ return EGL_TRUE;
}
static EGLBoolean
-GLX_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+GLX_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint buffer)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(surface);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
/* buffer ?? */
- glXBindTexImageEXT(disp->Xdpy, GLX_surf->drawable, GLX_FRONT_LEFT_EXT, NULL);
+ glXBindTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable,
+ GLX_FRONT_LEFT_EXT, NULL);
return EGL_TRUE;
}
static EGLBoolean
-GLX_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+GLX_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *surf,
EGLint buffer)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(surface);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
/* buffer ?? */
- glXReleaseTexImageEXT(disp->Xdpy, GLX_surf->drawable, GLX_FRONT_LEFT_EXT);
+ glXReleaseTexImageEXT(GLX_dpy->dpy, GLX_surf->drawable,
+ GLX_FRONT_LEFT_EXT);
return EGL_TRUE;
}
static EGLBoolean
-GLX_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+GLX_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *disp, _EGLSurface *draw)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLSurface *surf = _eglLookupSurface(draw);
- struct GLX_egl_surface *GLX_surf = GLX_egl_surface(surf);
+ struct GLX_egl_display *GLX_dpy = GLX_egl_display(disp);
+ struct GLX_egl_surface *GLX_surf = GLX_egl_surface(draw);
_eglLog(_EGL_DEBUG, "GLX: EGL SwapBuffers 0x%x",draw);
- /* error checking step: */
- if (!_eglSwapBuffers(drv, dpy, draw))
- return EGL_FALSE;
-
- glXSwapBuffers(disp->Xdpy, GLX_surf->drawable);
+ glXSwapBuffers(GLX_dpy->dpy, GLX_surf->drawable);
return EGL_TRUE;
}
@@ -810,28 +826,35 @@ GLX_eglGetProcAddress(const char *procname)
* some point.
*/
_EGLProc (*get_proc_addr)(const char *procname);
+ _EGLProc proc_addr;
get_proc_addr = dlsym(NULL, "st_get_proc_address");
if (get_proc_addr)
return get_proc_addr(procname);
- get_proc_addr = glXGetProcAddress((const GLubyte *)procname);
- if (get_proc_addr)
- return get_proc_addr(procname);
+ proc_addr = glXGetProcAddress((const GLubyte *)procname);
+ if (proc_addr)
+ return proc_addr;
return (_EGLProc)dlsym(NULL, procname);
}
+static void
+GLX_Unload(_EGLDriver *drv)
+{
+ struct GLX_egl_driver *GLX_drv = GLX_egl_driver(drv);
+ free(GLX_drv);
+}
+
+
/**
* This is the main entrypoint into the driver, called by libEGL.
* Create a new _EGLDriver object and init its dispatch table.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *disp, const char *args)
+_eglMain(const char *args)
{
struct GLX_egl_driver *GLX_drv = CALLOC_STRUCT(GLX_egl_driver);
- char *env;
- int maj = 0, min = 0;
if (!GLX_drv)
return NULL;
@@ -843,13 +866,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
GLX_drv->Base.API.MakeCurrent = GLX_eglMakeCurrent;
GLX_drv->Base.API.CreateWindowSurface = GLX_eglCreateWindowSurface;
#ifdef GLX_VERSION_1_3
- if (GLX_drv->glx_maj == 1 && GLX_drv->glx_min >= 3) {
- GLX_drv->Base.API.CreatePixmapSurface = GLX_eglCreatePixmapSurface;
- GLX_drv->Base.API.CreatePbufferSurface = GLX_eglCreatePbufferSurface;
- printf("GLX: Pbuffer and Pixmap support\n");
- } else {
- printf("GLX: No pbuffer or pixmap support\n");
- }
+ GLX_drv->Base.API.CreatePixmapSurface = GLX_eglCreatePixmapSurface;
+ GLX_drv->Base.API.CreatePbufferSurface = GLX_eglCreatePbufferSurface;
#endif
GLX_drv->Base.API.DestroySurface = GLX_eglDestroySurface;
GLX_drv->Base.API.BindTexImage = GLX_eglBindTexImage;
@@ -857,22 +875,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
GLX_drv->Base.API.SwapBuffers = GLX_eglSwapBuffers;
GLX_drv->Base.API.GetProcAddress = GLX_eglGetProcAddress;
- GLX_drv->Base.ClientAPIsMask = all_apis;
GLX_drv->Base.Name = "GLX";
-
- _eglLog(_EGL_DEBUG, "GLX: main(%s)", args);
-
- /* set new DRI path to pick up EGL version (which doesn't contain any mesa
- * code), but don't override if one is already set.
- */
- env = getenv("LIBGL_DRIVERS_PATH");
- if (env) {
- if (!strstr(env, "egl")) {
- sprintf(env, "%s/egl", env);
- setenv("LIBGL_DRIVERS_PATH", env, 1);
- }
- } else
- setenv("LIBGL_DRIVERS_PATH", DEFAULT_DRIVER_DIR"/egl", 0);
+ GLX_drv->Base.Unload = GLX_Unload;
return &GLX_drv->Base;
}
diff --git a/src/egl/drivers/xdri/Makefile b/src/egl/drivers/xdri/Makefile
index 8a14027fc7..4c1fc9071c 100644
--- a/src/egl/drivers/xdri/Makefile
+++ b/src/egl/drivers/xdri/Makefile
@@ -16,19 +16,24 @@ INCLUDE_DIRS = \
$(shell pkg-config --cflags-only-I libdrm) \
-I$(TOP)/include \
-I$(TOP)/include/GL/internal \
+ -I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/glapi \
- -I$(TOP)/src/mesa/drivers/dri/common \
-I$(TOP)/src/egl/main \
-I$(TOP)/src/glx/x11
-SOURCES = egl_xdri.c
+HEADERS = glxinit.h driinit.h
+SOURCES = egl_xdri.c glxinit.c driinit.c
+
+DRI_SOURCES = dri_common.c XF86dri.c dri2.c dri2_glx.c dri_glx.c
+DRI_SOURCES := $(addprefix ../../../glx/x11/,$(DRI_SOURCES))
+
+SOURCES += $(DRI_SOURCES)
OBJECTS = $(SOURCES:.c=.o)
DRM_LIB = `pkg-config --libs libdrm`
-MISC_LIBS = -ldl -lXext -lGL
-
+CFLAGS += -DGLX_DIRECT_RENDERING
.c.o:
$(CC) -c $(INCLUDE_DIRS) $(CFLAGS) $< -o $@
@@ -50,7 +55,7 @@ $(TOP)/$(LIB_DIR)/$(DRIVER_NAME): $(OBJECTS)
-major 1 -minor 0 \
-L$(TOP)/$(LIB_DIR) \
-install $(TOP)/$(LIB_DIR) \
- $(OBJECTS) $(DRM_LIB) $(MISC_LIBS)
+ $(OBJECTS) $(DRM_LIB) $(GL_LIB_DEPS)
install:
$(INSTALL) -d $(DESTDIR)$(INSTALL_LIB_DIR)
diff --git a/src/egl/drivers/xdri/driinit.c b/src/egl/drivers/xdri/driinit.c
new file mode 100644
index 0000000000..12da1bcd24
--- /dev/null
+++ b/src/egl/drivers/xdri/driinit.c
@@ -0,0 +1,67 @@
+/**
+ * DRI initialization. The DRI loaders are defined in src/glx/x11/.
+ */
+
+#include <sys/time.h>
+
+#include "glxclient.h"
+#include "driinit.h"
+
+/* for __DRI_SYSTEM_TIME extension */
+_X_HIDDEN int
+__glXGetUST(int64_t * ust)
+{
+ struct timeval tv;
+
+ if (ust == NULL) {
+ return -EFAULT;
+ }
+
+ if (gettimeofday(&tv, NULL) == 0) {
+ ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
+ return 0;
+ }
+ else {
+ return -errno;
+ }
+}
+
+_X_HIDDEN GLboolean
+__driGetMscRateOML(__DRIdrawable * draw,
+ int32_t * numerator, int32_t * denominator, void *private)
+{
+ return GL_FALSE;
+}
+
+/* ignore glx extensions */
+_X_HIDDEN void
+__glXEnableDirectExtension(__GLXscreenConfigs * psc, const char *name)
+{
+}
+
+_X_HIDDEN __GLXDRIdisplay *
+__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version)
+{
+ __GLXDRIdisplay *driDisplay;
+ int ver = 0;
+
+ /* try DRI2 first */
+ driDisplay = dri2CreateDisplay(dpyPriv->dpy);
+ if (driDisplay) {
+ /* fill in the required field */
+ dpyPriv->dri2Display = driDisplay;
+ ver = 2;
+ }
+ else {
+ /* try DRI */
+ driDisplay = driCreateDisplay(dpyPriv->dpy);
+ if (driDisplay) {
+ dpyPriv->driDisplay = driDisplay;
+ ver = 1;
+ }
+ }
+
+ if (version)
+ *version = ver;
+ return driDisplay;
+}
diff --git a/src/egl/drivers/xdri/driinit.h b/src/egl/drivers/xdri/driinit.h
new file mode 100644
index 0000000000..6ea05cebef
--- /dev/null
+++ b/src/egl/drivers/xdri/driinit.h
@@ -0,0 +1,9 @@
+#ifndef DRIINIT_INCLUDED
+#define DRIINIT_INCLUDED
+
+#include "glxclient.h"
+
+extern __GLXDRIdisplay *
+__driCreateDisplay(__GLXdisplayPrivate *dpyPriv, int *version);
+
+#endif /* DRIINIT_INCLUDED */
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index e040efdd43..518091a2d1 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -39,63 +39,40 @@
* Authors: Brian Paul
*/
-
#include <assert.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include "dlfcn.h"
+#include <stdlib.h>
#include <X11/Xlib.h>
-#include <GL/gl.h>
-#include "xf86dri.h"
-#include "glxclient.h"
-#include "dri_util.h"
-#include "drm_sarea.h"
-#define _EGL_PLATFORM_X
+#include "glxinit.h"
+#include "driinit.h"
+#include "glapi/glapi.h" /* for glapi functions */
#include "eglconfig.h"
#include "eglcontext.h"
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
-#include <GL/gl.h>
-
-typedef void (*glGetIntegerv_t)(GLenum, GLint *);
-typedef void (*glBindTexture_t)(GLenum, GLuint);
-typedef void (*glCopyTexImage2D_t)(GLenum, GLint, GLenum, GLint, GLint,
- GLint, GLint, GLint);
-
-
#define CALLOC_STRUCT(T) (struct T *) calloc(1, sizeof(struct T))
-
/** subclass of _EGLDriver */
struct xdri_egl_driver
{
_EGLDriver Base; /**< base class */
-
- const char *dri_driver_name; /**< name of DRI driver to load */
- void *dri_driver_handle; /**< returned by dlopen(dri_driver_name) */
-
- __GLXdisplayPrivate *glx_priv;
+};
- /* XXX we're not actually using these at this time: */
- int chipset;
- int minor;
- int drmFD;
+/** driver data of _EGLDisplay */
+struct xdri_egl_display
+{
+ Display *dpy;
+ __GLXdisplayPrivate *dpyPriv;
+ __GLXDRIdisplay *driDisplay;
- __DRIframebuffer framebuffer;
- drm_handle_t hSAREA;
- drmAddress pSAREA;
- char *busID;
- drm_magic_t magic;
+ __GLXscreenConfigs *psc;
+ EGLint scr;
};
@@ -104,9 +81,10 @@ struct xdri_egl_context
{
_EGLContext Base; /**< base class */
- __DRIcontext driContext;
+ /* just enough info to create dri contexts */
+ GLXContext dummy_gc;
- GLint bound_tex_object;
+ __GLXDRIcontext *driContext;
};
@@ -115,8 +93,8 @@ struct xdri_egl_surface
{
_EGLSurface Base; /**< base class */
- __DRIid driDrawable; /**< DRI surface */
- drm_drawable_t hDrawable;
+ Drawable drawable;
+ __GLXDRIdrawable *driDrawable;
};
@@ -131,46 +109,44 @@ struct xdri_egl_config
/** cast wrapper */
-static struct xdri_egl_driver *
+static INLINE struct xdri_egl_driver *
xdri_egl_driver(_EGLDriver *drv)
{
return (struct xdri_egl_driver *) drv;
}
+static INLINE struct xdri_egl_display *
+lookup_display(_EGLDisplay *dpy)
+{
+ return (struct xdri_egl_display *) dpy->DriverData;
+}
+
+
/** Map EGLSurface handle to xdri_egl_surface object */
-static struct xdri_egl_surface *
-lookup_surface(EGLSurface surf)
+static INLINE struct xdri_egl_surface *
+lookup_surface(_EGLSurface *surface)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
return (struct xdri_egl_surface *) surface;
}
/** Map EGLContext handle to xdri_egl_context object */
-static struct xdri_egl_context *
-lookup_context(EGLContext c)
+static INLINE struct xdri_egl_context *
+lookup_context(_EGLContext *context)
{
- _EGLContext *context = _eglLookupContext(c);
return (struct xdri_egl_context *) context;
}
-static struct xdri_egl_context *
-current_context(void)
-{
- return (struct xdri_egl_context *) _eglGetCurrentContext();
-}
/** Map EGLConfig handle to xdri_egl_config object */
-static struct xdri_egl_config *
-lookup_config(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+static INLINE struct xdri_egl_config *
+lookup_config(_EGLConfig *conf)
{
- _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
return (struct xdri_egl_config *) conf;
}
-
/** Get size of given window */
static Status
get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
@@ -188,22 +164,18 @@ get_drawable_size(Display *dpy, Drawable d, uint *width, uint *height)
/**
* Produce a set of EGL configs.
- * Note that we get the list of GLcontextModes from the GLX library.
- * This dependency on GLX lib will be removed someday.
*/
-static void
-create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
+static EGLint
+create_configs(_EGLDisplay *disp, const __GLcontextModes *m, EGLint first_id)
{
static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
EGL_OPENGL_ES2_BIT |
EGL_OPENVG_BIT |
EGL_OPENGL_BIT);
- __GLXscreenConfigs *scrn = glx_priv->screenConfigs;
- const __GLcontextModes *m;
- int id = 1;
+ int id = first_id;
- for (m = scrn->configs; m; m = m->next) {
- /* EGL requires double-buffered configs */
+ for (; m; m = m->next) {
+ /* add double buffered visual */
if (m->doubleBufferMode) {
struct xdri_egl_config *config = CALLOC_STRUCT(xdri_egl_config);
@@ -222,9 +194,7 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
SET_CONFIG_ATTRIB(&config->Base, EGL_NATIVE_VISUAL_TYPE, m->visualType);
SET_CONFIG_ATTRIB(&config->Base, EGL_CONFORMANT, all_apis);
SET_CONFIG_ATTRIB(&config->Base, EGL_RENDERABLE_TYPE, all_apis);
- /* XXX only window rendering allowed ATM */
- SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE,
- (EGL_WINDOW_BIT | EGL_PBUFFER_BIT));
+ SET_CONFIG_ATTRIB(&config->Base, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
/* XXX possibly other things to init... */
@@ -234,431 +204,76 @@ create_configs(_EGLDisplay *disp, __GLXdisplayPrivate *glx_priv)
_eglAddConfig(disp, &config->Base);
}
}
-}
-
-/**
- * Called via __DRIinterfaceMethods object
- */
-static __DRIfuncPtr
-dri_get_proc_address(const char * proc_name)
-{
- return NULL;
-}
-
-
-static void
-dri_context_modes_destroy(__GLcontextModes *modes)
-{
- _eglLog(_EGL_DEBUG, "%s", __FUNCTION__);
-
- while (modes) {
- __GLcontextModes * const next = modes->next;
- free(modes);
- modes = next;
- }
+ return id;
}
/**
- * Create a linked list of 'count' GLcontextModes.
- * These are used during the client/server visual negotiation phase,
- * then discarded.
+ * Called via eglInitialize(), xdri_dpy->API.Initialize().
*/
-static __GLcontextModes *
-dri_context_modes_create(unsigned count, size_t minimum_size)
-{
- /* This code copied from libGLX, and modified */
- const size_t size = (minimum_size > sizeof(__GLcontextModes))
- ? minimum_size : sizeof(__GLcontextModes);
- __GLcontextModes * head = NULL;
- __GLcontextModes ** next;
- unsigned i;
-
- next = & head;
- for (i = 0 ; i < count ; i++) {
- *next = (__GLcontextModes *) calloc(1, size);
- if (*next == NULL) {
- dri_context_modes_destroy(head);
- head = NULL;
- break;
- }
-
- (*next)->doubleBufferMode = 1;
- (*next)->visualID = GLX_DONT_CARE;
- (*next)->visualType = GLX_DONT_CARE;
- (*next)->visualRating = GLX_NONE;
- (*next)->transparentPixel = GLX_NONE;
- (*next)->transparentRed = GLX_DONT_CARE;
- (*next)->transparentGreen = GLX_DONT_CARE;
- (*next)->transparentBlue = GLX_DONT_CARE;
- (*next)->transparentAlpha = GLX_DONT_CARE;
- (*next)->transparentIndex = GLX_DONT_CARE;
- (*next)->xRenderable = GLX_DONT_CARE;
- (*next)->fbconfigID = GLX_DONT_CARE;
- (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
- (*next)->bindToTextureRgb = GLX_DONT_CARE;
- (*next)->bindToTextureRgba = GLX_DONT_CARE;
- (*next)->bindToMipmapTexture = GLX_DONT_CARE;
- (*next)->bindToTextureTargets = 0;
- (*next)->yInverted = GLX_DONT_CARE;
-
- next = & ((*next)->next);
- }
-
- return head;
-}
-
-
-static __DRIscreen *
-dri_find_dri_screen(__DRInativeDisplay *ndpy, int scrn)
-{
- __GLXdisplayPrivate *priv = __glXInitialize(ndpy);
- __GLXscreenConfigs *scrnConf = priv->screenConfigs;
- return &scrnConf->driScreen;
-}
-
-
-static GLboolean
-dri_window_exists(__DRInativeDisplay *ndpy, __DRIid draw)
-{
- return EGL_TRUE;
-}
-
-
-static GLboolean
-dri_create_context(__DRInativeDisplay *ndpy, int screenNum, int configID,
- void * contextID, drm_context_t * hw_context)
-{
- assert(configID >= 0);
- return XF86DRICreateContextWithConfig(ndpy, screenNum,
- configID, contextID, hw_context);
-}
-
-
-static GLboolean
-dri_destroy_context(__DRInativeDisplay * ndpy, int screen, __DRIid context)
-{
- return XF86DRIDestroyContext(ndpy, screen, context);
-}
-
-
-static GLboolean
-dri_create_drawable(__DRInativeDisplay * ndpy, int screen,
- __DRIid drawable, drm_drawable_t * hHWDrawable)
-{
- _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
-
- /* Create DRI drawable for given window ID (drawable) */
- if (!XF86DRICreateDrawable(ndpy, screen, drawable, hHWDrawable))
- return EGL_FALSE;
-
- return EGL_TRUE;
-}
-
-
-static GLboolean
-dri_destroy_drawable(__DRInativeDisplay * ndpy, int screen, __DRIid drawable)
-{
- _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
- return XF86DRIDestroyDrawable(ndpy, screen, drawable);
-}
-
-
-static GLboolean
-dri_get_drawable_info(__DRInativeDisplay *ndpy, int scrn,
- __DRIid draw, unsigned int * index, unsigned int * stamp,
- int * x, int * y, int * width, int * height,
- int * numClipRects, drm_clip_rect_t ** pClipRects,
- int * backX, int * backY,
- int * numBackClipRects,
- drm_clip_rect_t ** pBackClipRects)
-{
- _eglLog(_EGL_DEBUG, "XDRI: %s", __FUNCTION__);
-
- if (!XF86DRIGetDrawableInfo(ndpy, scrn, draw, index, stamp,
- x, y, width, height,
- numClipRects, pClipRects,
- backX, backY,
- numBackClipRects, pBackClipRects)) {
- return EGL_FALSE;
- }
-
- return EGL_TRUE;
-}
-
-
-/**
- * Table of functions exported by the loader to the driver.
- */
-static const __DRIinterfaceMethods interface_methods = {
- dri_get_proc_address,
-
- dri_context_modes_create,
- dri_context_modes_destroy,
-
- dri_find_dri_screen,
- dri_window_exists,
-
- dri_create_context,
- dri_destroy_context,
-
- dri_create_drawable,
- dri_destroy_drawable,
- dri_get_drawable_info,
-
- NULL,/*__eglGetUST,*/
- NULL,/*__eglGetMSCRate,*/
-};
-
-
-
static EGLBoolean
-init_drm(struct xdri_egl_driver *xdri_drv, _EGLDisplay *disp)
+xdri_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLint *minor, EGLint *major)
{
- __DRIversion ddx_version;
- __DRIversion dri_version;
- __DRIversion drm_version;
- drmVersionPtr version;
- drm_handle_t hFB;
- int newlyopened;
- int status;
- int scrn = DefaultScreen(disp->Xdpy);
-
-#if 0
- createNewScreen = (PFNCREATENEWSCREENFUNC)
- dlsym(xdri_drv->dri_driver_handle, createNewScreenName);
- if (!createNewScreen) {
- _eglLog(_EGL_WARNING, "XDRI: Couldn't find %s function in the driver.",
- createNewScreenName);
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: Found %s", createNewScreenName);
- }
-#endif
-
- /*
- * Get the DRI X extension version.
- */
- dri_version.major = 4;
- dri_version.minor = 0;
- dri_version.patch = 0;
-
- if (!XF86DRIOpenConnection(disp->Xdpy, scrn,
- &xdri_drv->hSAREA, &xdri_drv->busID)) {
- _eglLog(_EGL_WARNING, "XF86DRIOpenConnection failed");
- }
-
- xdri_drv->drmFD = drmOpenOnce(NULL, xdri_drv->busID, &newlyopened);
- if (xdri_drv->drmFD < 0) {
- perror("drmOpenOnce failed: ");
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: drmOpenOnce returned %d", xdri_drv->drmFD);
- }
-
-
- if (drmGetMagic(xdri_drv->drmFD, &xdri_drv->magic)) {
- perror("drmGetMagic failed: ");
- return EGL_FALSE;
- }
-
- version = drmGetVersion(xdri_drv->drmFD);
- if (version) {
- drm_version.major = version->version_major;
- drm_version.minor = version->version_minor;
- drm_version.patch = version->version_patchlevel;
- drmFreeVersion(version);
- _eglLog(_EGL_DEBUG, "XDRI: Got DRM version %d.%d.%d",
- drm_version.major,
- drm_version.minor,
- drm_version.patch);
- }
- else {
- drm_version.major = -1;
- drm_version.minor = -1;
- drm_version.patch = -1;
- _eglLog(_EGL_WARNING, "XDRI: drmGetVersion() failed");
- return EGL_FALSE;
- }
-
- /* Authenticate w/ server.
- */
- if (!XF86DRIAuthConnection(disp->Xdpy, scrn, xdri_drv->magic)) {
- _eglLog(_EGL_WARNING, "XDRI: XF86DRIAuthConnection() failed");
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: XF86DRIAuthConnection() success");
- }
-
- /* Get ddx version.
- */
- {
- char *driverName;
-
- /*
- * Get device name (like "tdfx") and the ddx version
- * numbers. We'll check the version in each DRI driver's
- * "createNewScreen" function.
- */
- if (!XF86DRIGetClientDriverName(disp->Xdpy, scrn,
- &ddx_version.major,
- &ddx_version.minor,
- &ddx_version.patch,
- &driverName)) {
- _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetClientDriverName failed");
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetClientDriverName returned %s", driverName);
- }
- }
-
- /* Get framebuffer info.
- */
- {
- int junk;
- if (!XF86DRIGetDeviceInfo(disp->Xdpy, scrn,
- &hFB,
- &junk,
- &xdri_drv->framebuffer.size,
- &xdri_drv->framebuffer.stride,
- &xdri_drv->framebuffer.dev_priv_size,
- &xdri_drv->framebuffer.dev_priv)) {
- _eglLog(_EGL_WARNING, "XDRI: XF86DRIGetDeviceInfo() failed");
- return EGL_FALSE;
+ struct xdri_egl_display *xdri_dpy;
+ __GLXdisplayPrivate *dpyPriv;
+ __GLXDRIdisplay *driDisplay;
+ __GLXscreenConfigs *psc;
+ EGLint first_id = 1;
+ int scr;
+
+ xdri_dpy = CALLOC_STRUCT(xdri_egl_display);
+ if (!xdri_dpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ xdri_dpy->dpy = (Display *) dpy->NativeDisplay;
+ if (!xdri_dpy->dpy) {
+ xdri_dpy->dpy = XOpenDisplay(NULL);
+ if (!xdri_dpy->dpy) {
+ free(xdri_dpy);
+ return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
}
- else {
- _eglLog(_EGL_DEBUG, "XDRI: XF86DRIGetDeviceInfo() success");
- }
- xdri_drv->framebuffer.width = DisplayWidth(disp->Xdpy, scrn);
- xdri_drv->framebuffer.height = DisplayHeight(disp->Xdpy, scrn);
- }
-
- /* Map the framebuffer region. (this may not be needed)
- */
- status = drmMap(xdri_drv->drmFD, hFB, xdri_drv->framebuffer.size,
- (drmAddressPtr) &xdri_drv->framebuffer.base);
- if (status != 0) {
- _eglLog(_EGL_WARNING, "XDRI: drmMap(framebuffer) failed");
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: drmMap(framebuffer) success");
}
- /* Map the SAREA region.
- */
- status = drmMap(xdri_drv->drmFD, xdri_drv->hSAREA, SAREA_MAX, &xdri_drv->pSAREA);
- if (status != 0) {
- _eglLog(_EGL_WARNING, "XDRI: drmMap(sarea) failed");
- return EGL_FALSE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: drmMap(sarea) success");
- }
-
- return EGL_TRUE;
-}
-
-
-/**
- * Load the DRI driver named by "xdri_drv->dri_driver_name".
- * Basically, dlopen() the library to set "xdri_drv->dri_driver_handle".
- *
- * Later, we'll call dlsym(createNewScreenName) to get a pointer to
- * the driver's createNewScreen() function which is the bootstrap function.
- *
- * \return EGL_TRUE for success, EGL_FALSE for failure
- */
-static EGLBoolean
-load_dri_driver(struct xdri_egl_driver *xdri_drv)
-{
- char filename[100];
- int flags = RTLD_NOW;
-
- /* try "egl_xxx_dri.so" first */
- snprintf(filename, sizeof(filename), "egl_%s.so", xdri_drv->dri_driver_name);
- _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
- xdri_drv->dri_driver_handle = dlopen(filename, flags);
- if (xdri_drv->dri_driver_handle) {
- _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
- return EGL_TRUE;
- }
- else {
- _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) fail (%s)", filename, dlerror());
+ dpyPriv = __glXInitialize(xdri_dpy->dpy);
+ if (!dpyPriv) {
+ _eglLog(_EGL_WARNING, "failed to create GLX display");
+ free(xdri_dpy);
+ return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
}
- /* try regular "xxx_dri.so" next */
- snprintf(filename, sizeof(filename), "%s.so", xdri_drv->dri_driver_name);
- _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s)", filename);
- xdri_drv->dri_driver_handle = dlopen(filename, flags);
- if (xdri_drv->dri_driver_handle) {
- _eglLog(_EGL_DEBUG, "XDRI: dlopen(%s) OK", filename);
- return EGL_TRUE;
+ driDisplay = __driCreateDisplay(dpyPriv, NULL);
+ if (!driDisplay) {
+ _eglLog(_EGL_WARNING, "failed to create DRI display");
+ free(xdri_dpy);
+ return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
}
- _eglLog(_EGL_WARNING, "XDRI Could not open %s (%s)", filename, dlerror());
- return EGL_FALSE;
-}
-
-
-/**
- * Called via eglInitialize(), xdri_drv->API.Initialize().
- */
-static EGLBoolean
-xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
- EGLint *minor, EGLint *major)
-{
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- static char name[100];
+ scr = DefaultScreen(xdri_dpy->dpy);
+ psc = &dpyPriv->screenConfigs[scr];
- _eglLog(_EGL_DEBUG, "XDRI: eglInitialize");
+ xdri_dpy->dpyPriv = dpyPriv;
+ xdri_dpy->driDisplay = driDisplay;
+ xdri_dpy->psc = psc;
+ xdri_dpy->scr = scr;
- if (!disp->Xdpy) {
- disp->Xdpy = XOpenDisplay(NULL);
- if (!disp->Xdpy) {
- _eglLog(_EGL_WARNING, "XDRI: XOpenDisplay failed");
- return EGL_FALSE;
- }
+ psc->driScreen = driDisplay->createScreen(psc, scr, dpyPriv);
+ if (!psc->driScreen) {
+ _eglLog(_EGL_WARNING, "failed to create DRI screen #%d", scr);
+ free(xdri_dpy);
+ return _eglError(EGL_NOT_INITIALIZED, "eglInitialize");
}
-#if 0
- /* choose the DRI driver to load */
- xdri_drv->dri_driver_name = _eglChooseDRMDriver(0);
- if (!load_dri_driver(xdri_drv))
- return EGL_FALSE;
-#else
- (void) load_dri_driver;
-#endif
-
-#if 0
- if (!init_drm(xdri_drv, disp))
- return EGL_FALSE;
-#else
- (void) init_drm;
-#endif
-
- /*
- * NOTE: this call to __glXInitialize() bootstraps the whole GLX/DRI
- * interface, loads the DRI driver, etc.
- * This replaces the load_dri_driver() and init_drm() code above.
- */
- xdri_drv->glx_priv = __glXInitialize(disp->Xdpy);
-
- create_configs(disp, xdri_drv->glx_priv);
-
- xdri_drv->Base.Initialized = EGL_TRUE;
+ /* add visuals and fbconfigs */
+ first_id = create_configs(dpy, psc->visuals, first_id);
+ create_configs(dpy, psc->configs, first_id);
- if (xdri_drv->dri_driver_name)
- snprintf(name, sizeof(name), "X/DRI:%s", xdri_drv->dri_driver_name);
- else
- snprintf(name, sizeof(name), "X/DRI");
- xdri_drv->Base.Name = name;
+ dpy->DriverData = xdri_dpy;
+ dpy->ClientAPIsMask = (EGL_OPENGL_BIT |
+ EGL_OPENGL_ES_BIT |
+ EGL_OPENGL_ES2_BIT |
+ EGL_OPENVG_BIT);
/* we're supporting EGL 1.4 */
*minor = 1;
@@ -668,57 +283,37 @@ xdri_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
}
-/*
- * Do some clean-up that normally occurs in XCloseDisplay().
- * We do this here because we're about to unload a dynamic library
- * that has added some per-display extension data and callbacks.
- * If we don't do this here we'll crash in XCloseDisplay() because it'll
- * try to call functions that went away when the driver library was unloaded.
- */
-static void
-FreeDisplayExt(Display *dpy)
-{
- _XExtension *ext, *next;
-
- for (ext = dpy->ext_procs; ext; ext = next) {
- next = ext->next;
- if (ext->close_display) {
- ext->close_display(dpy, &ext->codes);
- ext->close_display = NULL;
- }
- if (ext->name)
- Xfree(ext->name);
- Xfree(ext);
- }
- dpy->ext_procs = NULL;
-
- _XFreeExtData (dpy->ext_data);
- dpy->ext_data = NULL;
-}
-
-
/**
* Called via eglTerminate(), drv->API.Terminate().
*/
static EGLBoolean
-xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+xdri_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+ __GLXscreenConfigs *psc;
- _eglLog(_EGL_DEBUG, "XDRI: eglTerminate");
+ _eglReleaseDisplayResources(drv, dpy);
+ _eglCleanupDisplay(dpy);
- _eglLog(_EGL_DEBUG, "XDRI: Closing %s", xdri_drv->dri_driver_name);
-
- FreeDisplayExt(disp->Xdpy);
+ psc = xdri_dpy->psc;
+ if (psc->driver_configs) {
+ unsigned int i;
+ for (i = 0; psc->driver_configs[i]; i++)
+ free((__DRIconfig *) psc->driver_configs[i]);
+ free(psc->driver_configs);
+ psc->driver_configs = NULL;
+ }
+ if (psc->driScreen) {
+ psc->driScreen->destroyScreen(psc);
+ free(psc->driScreen);
+ psc->driScreen = NULL;
+ }
-#if 0
- /* this causes a segfault for some reason */
- dlclose(xdri_drv->dri_driver_handle);
-#endif
- xdri_drv->dri_driver_handle = NULL;
+ xdri_dpy->driDisplay->destroyDisplay(xdri_dpy->driDisplay);
+ __glXRelease(xdri_dpy->dpyPriv);
- free((void*) xdri_drv->dri_driver_name);
+ free(xdri_dpy);
+ dpy->DriverData = NULL;
return EGL_TRUE;
}
@@ -730,71 +325,77 @@ xdri_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
static _EGLProc
xdri_eglGetProcAddress(const char *procname)
{
-#if 0
- _EGLDriver *drv = NULL;
-
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- /*_EGLDisplay *disp = _eglLookupDisplay(dpy);*/
- _EGLProc *proc = xdri_drv->driScreen.getProcAddress(procname);
- return proc;
-#elif 1
- /* This is a bit of a hack to get at the gallium/Mesa state tracker
- * function st_get_proc_address(). This will probably change at
- * some point.
- */
- _EGLProc (*st_get_proc_addr)(const char *procname);
- st_get_proc_addr = dlsym(NULL, "st_get_proc_address");
- if (st_get_proc_addr) {
- return st_get_proc_addr(procname);
- }
- return NULL;
-#else
- return NULL;
-#endif
+ /* the symbol is defined in libGL.so */
+ return (_EGLProc) _glapi_get_proc_address(procname);
}
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
-static EGLContext
-xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- EGLContext share_list, const EGLint *attrib_list)
-{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
- void *shared = NULL;
+static _EGLContext *
+xdri_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
+{
+ struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+ struct xdri_egl_config *xdri_config = lookup_config(conf);
+ struct xdri_egl_context *shared = lookup_context(share_list);
+ __GLXscreenConfigs *psc = xdri_dpy->psc;
int renderType = GLX_RGBA_BIT;
+ struct xdri_egl_context *xdri_ctx;
- struct xdri_egl_context *xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
- if (!xdri_ctx)
- return EGL_NO_CONTEXT;
+ xdri_ctx = CALLOC_STRUCT(xdri_egl_context);
+ if (!xdri_ctx) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
+ return NULL;
+ }
- if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
+ xdri_ctx->dummy_gc = CALLOC_STRUCT(__GLXcontextRec);
+ if (!xdri_ctx->dummy_gc) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateContext");
free(xdri_ctx);
- return EGL_NO_CONTEXT;
+ return NULL;
}
- assert(xdri_config);
-
- {
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
- xdri_ctx->driContext.private =
- scrnConf->driScreen.createNewContext(disp->Xdpy,
- xdri_config->mode, renderType,
- shared, &xdri_ctx->driContext);
+ if (!_eglInitContext(drv, &xdri_ctx->Base, &xdri_config->Base, attrib_list)) {
+ free(xdri_ctx->dummy_gc);
+ free(xdri_ctx);
+ return NULL;
}
- if (!xdri_ctx->driContext.private) {
- _eglLog(_EGL_DEBUG, "driScreen.createNewContext failed");
+ xdri_ctx->driContext =
+ psc->driScreen->createContext(psc,
+ xdri_config->mode,
+ xdri_ctx->dummy_gc,
+ (shared) ? shared->dummy_gc : NULL,
+ renderType);
+ if (!xdri_ctx->driContext) {
+ free(xdri_ctx->dummy_gc);
free(xdri_ctx);
- return EGL_NO_CONTEXT;
+ return NULL;
}
- xdri_ctx->driContext.mode = xdri_config->mode;
+ /* fill in the required field */
+ xdri_ctx->dummy_gc->driContext = xdri_ctx->driContext;
- return _eglLinkContext(&xdri_ctx->Base, &disp);
+ return &xdri_ctx->Base;
+}
+
+
+static EGLBoolean
+xdri_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
+{
+ struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+ struct xdri_egl_context *xdri_ctx = lookup_context(ctx);
+
+ if (!_eglIsContextBound(ctx)) {
+ xdri_ctx->driContext->destroyContext(xdri_ctx->driContext,
+ xdri_dpy->psc, xdri_dpy->dpy);
+ free(xdri_ctx->dummy_gc);
+ free(xdri_ctx);
+ }
+
+ return EGL_TRUE;
}
@@ -802,25 +403,32 @@ xdri_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
static EGLBoolean
-xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
- EGLSurface r, EGLContext context)
+xdri_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *d,
+ _EGLSurface *r, _EGLContext *context)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
struct xdri_egl_context *xdri_ctx = lookup_context(context);
- struct xdri_egl_surface *xdri_draw = lookup_surface(d);
- struct xdri_egl_surface *xdri_read = lookup_surface(r);
- __DRIid draw = xdri_draw ? xdri_draw->driDrawable : 0;
- __DRIid read = xdri_read ? xdri_read->driDrawable : 0;
- int scrn = DefaultScreen(disp->Xdpy);
+ struct xdri_egl_surface *draw = lookup_surface(d);
+ struct xdri_egl_surface *read = lookup_surface(r);
if (!_eglMakeCurrent(drv, dpy, d, r, context))
return EGL_FALSE;
+ /* the symbol is defined in libGL.so */
+ _glapi_check_multithread();
- if (xdri_ctx &&
- !xdri_ctx->driContext.bindContext(disp->Xdpy, scrn, draw, read,
- &xdri_ctx->driContext)) {
- return EGL_FALSE;
+ if (xdri_ctx) {
+ if (!xdri_ctx->driContext->bindContext(xdri_ctx->driContext,
+ draw->driDrawable,
+ read->driDrawable)) {
+ return EGL_FALSE;
+ }
+ }
+ else {
+ _EGLContext *old = _eglGetCurrentContext();
+ if (old) {
+ xdri_ctx = lookup_context(old);
+ xdri_ctx->driContext->unbindContext(xdri_ctx->driContext);
+ }
}
return EGL_TRUE;
@@ -830,307 +438,106 @@ xdri_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
-static EGLSurface
-xdri_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xdri_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
+ struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+ struct xdri_egl_config *xdri_config = lookup_config(conf);
struct xdri_egl_surface *xdri_surf;
- int scrn = DefaultScreen(disp->Xdpy);
uint width, height;
xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
- if (!xdri_surf)
- return EGL_NO_SURFACE;
+ if (!xdri_surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreateWindowSurface");
+ return NULL;
+ }
if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_WINDOW_BIT,
&xdri_config->Base, attrib_list)) {
free(xdri_surf);
- return EGL_FALSE;
+ return NULL;
}
- if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) {
+ xdri_surf->driDrawable =
+ xdri_dpy->psc->driScreen->createDrawable(xdri_dpy->psc,
+ (XID) window,
+ (GLXDrawable) window,
+ xdri_config->mode);
+ if (!xdri_surf->driDrawable) {
free(xdri_surf);
- return EGL_FALSE;
+ return NULL;
}
- xdri_surf->driDrawable = window;
+ xdri_surf->drawable = (Drawable) window;
- _eglLinkSurface(&xdri_surf->Base, disp);
-
- get_drawable_size(disp->Xdpy, window, &width, &height);
+ get_drawable_size(xdri_dpy->dpy, window, &width, &height);
xdri_surf->Base.Width = width;
xdri_surf->Base.Height = height;
- _eglLog(_EGL_DEBUG,
- "XDRI: CreateWindowSurface win 0x%x handle %d hDrawable %d",
- (int) window, _eglGetSurfaceHandle(&xdri_surf->Base),
- (int) xdri_surf->hDrawable);
-
- return _eglGetSurfaceHandle(&xdri_surf->Base);
+ return &xdri_surf->Base;
}
/**
* Called via eglCreatePbufferSurface(), drv->API.CreatePbufferSurface().
*/
-static EGLSurface
-xdri_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xdri_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- struct xdri_egl_surface *xdri_surf;
- struct xdri_egl_config *xdri_config = lookup_config(drv, dpy, config);
- int scrn = DefaultScreen(disp->Xdpy);
- Window window;
-
- xdri_surf = CALLOC_STRUCT(xdri_egl_surface);
- if (!xdri_surf)
- return EGL_NO_SURFACE;
-
- if (!_eglInitSurface(drv, &xdri_surf->Base, EGL_PBUFFER_BIT,
- &xdri_config->Base, attrib_list)) {
- free(xdri_surf);
- return EGL_FALSE;
- }
-
- /* Create a dummy X window */
- {
- Window root = RootWindow(disp->Xdpy, scrn);
- XSetWindowAttributes attr;
- XVisualInfo *visInfo, visTemplate;
- unsigned mask;
- int nvis;
-
- visTemplate.visualid = xdri_config->mode->visualID;
- visInfo = XGetVisualInfo(disp->Xdpy, VisualIDMask, &visTemplate, &nvis);
- if (!visInfo) {
- return EGL_NO_SURFACE;
- }
-
- attr.background_pixel = 0;
- attr.border_pixel = 0;
- attr.colormap = XCreateColormap(disp->Xdpy, root,
- visInfo->visual, AllocNone);
- attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask;
- mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask;
-
- window = XCreateWindow(disp->Xdpy, root, 0, 0,
- xdri_surf->Base.Width, xdri_surf->Base.Height,
- 0, visInfo->depth, InputOutput,
- visInfo->visual, mask, &attr);
-
- /*XMapWindow(disp->Xdpy, window);*/
- XFree(visInfo);
-
- /* set hints and properties */
- /*
- sizehints.width = xdri_surf->Base.Width;
- sizehints.height = xdri_surf->Base.Height;
- sizehints.flags = USPosition;
- XSetNormalHints(disp->Xdpy, window, &sizehints);
- */
- }
-
- if (!XF86DRICreateDrawable(disp->Xdpy, scrn, window, &xdri_surf->hDrawable)) {
- free(xdri_surf);
- return EGL_FALSE;
- }
-
- xdri_surf->driDrawable = window;
-
- _eglLinkSurface(&xdri_surf->Base, disp);
-
- _eglLog(_EGL_DEBUG,
- "XDRI: CreatePbufferSurface handle %d hDrawable %d",
- _eglGetSurfaceHandle(&xdri_surf->Base),
- (int) xdri_surf->hDrawable);
-
- return _eglGetSurfaceHandle(&xdri_surf->Base);
+ return NULL;
}
static EGLBoolean
-xdri_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+xdri_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
{
struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
- if (xdri_surf) {
- _eglUnlinkSurface(&xdri_surf->Base);
- if (!xdri_surf->Base.IsBound) {
- /*
- st_unreference_framebuffer(surf->Framebuffer);
- */
- free(xdri_surf);
- }
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
+
+ if (!_eglIsSurfaceBound(&xdri_surf->Base)) {
+ xdri_surf->driDrawable->destroyDrawable(xdri_surf->driDrawable);
+ free(xdri_surf);
}
+
+ return EGL_TRUE;
}
static EGLBoolean
-xdri_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+xdri_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint buffer)
{
- typedef int (*bind_teximage)(__DRInativeDisplay *dpy,
- __DRIid surface, __DRIscreen *psc,
- int buffer, int target, int format,
- int level, int mipmap);
-
- bind_teximage egl_dri_bind_teximage;
-
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
- struct xdri_egl_context *xdri_ctx = current_context();
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-
- __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
-
- __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
- __DRIscreen *psc = &scrnConf->driScreen;
-
- /* this call just does error checking */
- if (!_eglBindTexImage(drv, dpy, surface, buffer)) {
- return EGL_FALSE;
- }
-
- egl_dri_bind_teximage =
- (bind_teximage) dlsym(NULL, "egl_dri_bind_teximage");
- if (egl_dri_bind_teximage) {
- return egl_dri_bind_teximage(disp->Xdpy, dri_surf, psc,
- buffer,
- xdri_surf->Base.TextureTarget,
- xdri_surf->Base.TextureFormat,
- xdri_surf->Base.MipmapLevel,
- xdri_surf->Base.MipmapTexture);
- }
- else {
- /* fallback path based on glCopyTexImage() */
- /* Get/save currently bound 2D texobj name */
- glGetIntegerv_t glGetIntegerv_func =
- (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
- GLint curTexObj = 0;
- if (glGetIntegerv_func) {
- (*glGetIntegerv_func)(GL_TEXTURE_BINDING_2D, &curTexObj);
- }
- xdri_ctx->bound_tex_object = curTexObj;
- }
-
return EGL_FALSE;
}
static EGLBoolean
-xdri_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+xdri_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
EGLint buffer)
{
- typedef int (*release_teximage)(__DRInativeDisplay *dpy,
- __DRIid surface, __DRIscreen *psc,
- int buffer, int target, int format,
- int level, int mipmap);
- release_teximage egl_dri_release_teximage;
-
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
- struct xdri_egl_context *xdri_ctx = current_context();
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- struct xdri_egl_surface *xdri_surf = lookup_surface(surface);
-
- __DRIid dri_surf = xdri_surf ? xdri_surf->driDrawable : 0;
-
- __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
- __DRIscreen *psc = &scrnConf->driScreen;
-
- /* this call just does error checking */
- if (!_eglReleaseTexImage(drv, dpy, surface, buffer)) {
- return EGL_FALSE;
- }
-
- egl_dri_release_teximage =
- (release_teximage) dlsym(NULL, "egl_dri_release_teximage");
- if (egl_dri_release_teximage) {
- return egl_dri_release_teximage(disp->Xdpy, dri_surf, psc,
- buffer,
- xdri_surf->Base.TextureTarget,
- xdri_surf->Base.TextureFormat,
- xdri_surf->Base.MipmapLevel,
- xdri_surf->Base.MipmapTexture);
- }
- else {
- /* fallback path based on glCopyTexImage() */
- glGetIntegerv_t glGetIntegerv_func =
- (glGetIntegerv_t) dlsym(NULL, "glGetIntegerv");
- glBindTexture_t glBindTexture_func =
- (glBindTexture_t) dlsym(NULL, "glBindTexture");
- glCopyTexImage2D_t glCopyTexImage2D_func =
- (glCopyTexImage2D_t) dlsym(NULL, "glCopyTexImage2D");
- GLint curTexObj;
- GLenum intFormat;
- GLint level, width, height;
-
- if (xdri_surf->Base.TextureFormat == EGL_TEXTURE_RGBA)
- intFormat = GL_RGBA;
- else
- intFormat = GL_RGB;
- level = xdri_surf->Base.MipmapLevel;
- width = xdri_surf->Base.Width >> level;
- height = xdri_surf->Base.Height >> level;
-
- if (width > 0 && height > 0 &&
- glGetIntegerv_func && glBindTexture_func && glCopyTexImage2D_func) {
- glGetIntegerv_func(GL_TEXTURE_BINDING_2D, &curTexObj);
- /* restore texobj from time of eglBindTexImage() call */
- if (curTexObj != xdri_ctx->bound_tex_object)
- glBindTexture_func(GL_TEXTURE_2D, xdri_ctx->bound_tex_object);
- /* copy pbuffer image to texture */
- glCopyTexImage2D_func(GL_TEXTURE_2D,
- level,
- intFormat,
- 0, 0, width, height, 0);
- /* restore current texture */
- if (curTexObj != xdri_ctx->bound_tex_object)
- glBindTexture_func(GL_TEXTURE_2D, curTexObj);
- }
- xdri_ctx->bound_tex_object = -1;
- }
-
return EGL_FALSE;
}
static EGLBoolean
-xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+xdri_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ struct xdri_egl_display *xdri_dpy = lookup_display(dpy);
+ struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
- _eglLog(_EGL_DEBUG, "XDRI: EGL SwapBuffers");
+ xdri_dpy->psc->driScreen->swapBuffers(xdri_surf->driDrawable);
- /* error checking step: */
- if (!_eglSwapBuffers(drv, dpy, draw))
- return EGL_FALSE;
+ return EGL_TRUE;
+}
- {
- struct xdri_egl_surface *xdri_surf = lookup_surface(draw);
- struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
- __GLXscreenConfigs *scrnConf = xdri_drv->glx_priv->screenConfigs;
- __DRIscreen *psc = &scrnConf->driScreen;
- __DRIdrawable * const pdraw = psc->getDrawable(disp->Xdpy,
- xdri_surf->driDrawable,
- psc->private);
-
- if (pdraw)
- pdraw->swapBuffers(disp->Xdpy, pdraw->private);
- else
- _eglLog(_EGL_WARNING, "pdraw is null in SwapBuffers");
- }
- return EGL_TRUE;
+static void
+xdri_Unload(_EGLDriver *drv)
+{
+ struct xdri_egl_driver *xdri_drv = xdri_egl_driver(drv);
+ free(xdri_drv);
}
@@ -1139,15 +546,12 @@ xdri_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
* Create a new _EGLDriver object and init its dispatch table.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *disp, const char *args)
+_eglMain(const char *args)
{
struct xdri_egl_driver *xdri_drv = CALLOC_STRUCT(xdri_egl_driver);
if (!xdri_drv)
return NULL;
- /* Tell libGL to prefer the EGL drivers over regular DRI drivers */
- __glXPreferEGL(1);
-
_eglInitDriverFallbacks(&xdri_drv->Base);
xdri_drv->Base.API.Initialize = xdri_eglInitialize;
xdri_drv->Base.API.Terminate = xdri_eglTerminate;
@@ -1155,6 +559,7 @@ _eglMain(_EGLDisplay *disp, const char *args)
xdri_drv->Base.API.GetProcAddress = xdri_eglGetProcAddress;
xdri_drv->Base.API.CreateContext = xdri_eglCreateContext;
+ xdri_drv->Base.API.DestroyContext = xdri_eglDestroyContext;
xdri_drv->Base.API.MakeCurrent = xdri_eglMakeCurrent;
xdri_drv->Base.API.CreateWindowSurface = xdri_eglCreateWindowSurface;
xdri_drv->Base.API.CreatePbufferSurface = xdri_eglCreatePbufferSurface;
@@ -1163,13 +568,8 @@ _eglMain(_EGLDisplay *disp, const char *args)
xdri_drv->Base.API.ReleaseTexImage = xdri_eglReleaseTexImage;
xdri_drv->Base.API.SwapBuffers = xdri_eglSwapBuffers;
- xdri_drv->Base.ClientAPIsMask = (EGL_OPENGL_BIT |
- EGL_OPENGL_ES_BIT |
- EGL_OPENGL_ES2_BIT |
- EGL_OPENVG_BIT);
xdri_drv->Base.Name = "X/DRI";
-
- _eglLog(_EGL_DEBUG, "XDRI: main(%s)", args);
+ xdri_drv->Base.Unload = xdri_Unload;
return &xdri_drv->Base;
}
diff --git a/src/egl/drivers/xdri/glxinit.c b/src/egl/drivers/xdri/glxinit.c
new file mode 100644
index 0000000000..7775009394
--- /dev/null
+++ b/src/egl/drivers/xdri/glxinit.c
@@ -0,0 +1,626 @@
+/**
+ * GLX initialization. Code based on glxext.c, glx_query.c, and
+ * glcontextmodes.c under src/glx/x11/. The major difference is that no DRI
+ * related code here.
+ *
+ */
+
+#include <assert.h>
+#include <X11/Xlib.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+#include <sys/time.h>
+
+#include "glxinit.h"
+
+typedef struct GLXGenericGetString
+{
+ CARD8 reqType;
+ CARD8 glxCode;
+ CARD16 length B16;
+ CARD32 for_whom B32;
+ CARD32 name B32;
+} xGLXGenericGetStringReq;
+
+#define sz_xGLXGenericGetStringReq 12
+#define X_GLXGenericGetString 0
+
+/* Extension required boiler plate */
+
+static char *__glXExtensionName = GLX_EXTENSION_NAME;
+static XExtensionInfo *__glXExtensionInfo = NULL;
+
+static /* const */ XExtensionHooks __glXExtensionHooks = { NULL };
+static
+XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
+ __glXExtensionName, &__glXExtensionHooks,
+ __GLX_NUMBER_EVENTS, NULL)
+
+static GLint
+_gl_convert_from_x_visual_type(int visualType)
+{
+#define NUM_VISUAL_TYPES 6
+ static const int glx_visual_types[NUM_VISUAL_TYPES] = {
+ GLX_STATIC_GRAY, GLX_GRAY_SCALE,
+ GLX_STATIC_COLOR, GLX_PSEUDO_COLOR,
+ GLX_TRUE_COLOR, GLX_DIRECT_COLOR
+ };
+
+ return ((unsigned) visualType < NUM_VISUAL_TYPES)
+ ? glx_visual_types[visualType] : GLX_NONE;
+}
+
+static __GLcontextModes *
+_gl_context_modes_create(unsigned count, size_t minimum_size)
+{
+ const size_t size = (minimum_size > sizeof(__GLcontextModes))
+ ? minimum_size : sizeof(__GLcontextModes);
+ __GLcontextModes *base = NULL;
+ __GLcontextModes **next;
+ unsigned i;
+
+ next = &base;
+ for (i = 0; i < count; i++) {
+ *next = (__GLcontextModes *) Xmalloc(size);
+ if (*next == NULL) {
+ _gl_context_modes_destroy(base);
+ base = NULL;
+ break;
+ }
+
+ memset(*next, 0, size);
+ (*next)->visualID = GLX_DONT_CARE;
+ (*next)->visualType = GLX_DONT_CARE;
+ (*next)->visualRating = GLX_NONE;
+ (*next)->transparentPixel = GLX_NONE;
+ (*next)->transparentRed = GLX_DONT_CARE;
+ (*next)->transparentGreen = GLX_DONT_CARE;
+ (*next)->transparentBlue = GLX_DONT_CARE;
+ (*next)->transparentAlpha = GLX_DONT_CARE;
+ (*next)->transparentIndex = GLX_DONT_CARE;
+ (*next)->xRenderable = GLX_DONT_CARE;
+ (*next)->fbconfigID = GLX_DONT_CARE;
+ (*next)->swapMethod = GLX_SWAP_UNDEFINED_OML;
+ (*next)->bindToTextureRgb = GLX_DONT_CARE;
+ (*next)->bindToTextureRgba = GLX_DONT_CARE;
+ (*next)->bindToMipmapTexture = GLX_DONT_CARE;
+ (*next)->bindToTextureTargets = GLX_DONT_CARE;
+ (*next)->yInverted = GLX_DONT_CARE;
+
+ next = &((*next)->next);
+ }
+
+ return base;
+}
+
+_X_HIDDEN void
+_gl_context_modes_destroy(__GLcontextModes * modes)
+{
+ while (modes != NULL) {
+ __GLcontextModes *const next = modes->next;
+
+ Xfree(modes);
+ modes = next;
+ }
+}
+
+_X_HIDDEN char *
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
+{
+ xGLXGenericGetStringReq *req;
+ xGLXSingleReply reply;
+ int length;
+ int numbytes;
+ char *buf;
+ CARD32 for_whom = screen;
+ CARD32 glxCode = X_GLXQueryServerString;
+
+
+ LockDisplay(dpy);
+
+
+ /* All of the GLX protocol requests for getting a string from the server
+ * look the same. The exact meaning of the for_whom field is usually
+ * either the screen number (for glXQueryServerString) or the context tag
+ * (for GLXSingle).
+ */
+
+ GetReq(GLXGenericGetString, req);
+ req->reqType = opcode;
+ req->glxCode = glxCode;
+ req->for_whom = for_whom;
+ req->name = name;
+
+ _XReply(dpy, (xReply *) & reply, 0, False);
+
+ length = reply.length * 4;
+ numbytes = reply.size;
+
+ buf = (char *) Xmalloc(numbytes);
+ if (buf != NULL) {
+ _XRead(dpy, buf, numbytes);
+ length -= numbytes;
+ }
+
+ _XEatData(dpy, length);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buf;
+}
+
+/************************************************************************/
+/*
+** Free the per screen configs data as well as the array of
+** __glXScreenConfigs.
+*/
+static void
+FreeScreenConfigs(__GLXdisplayPrivate * priv)
+{
+ __GLXscreenConfigs *psc;
+ GLint i, screens;
+
+ /* Free screen configuration information */
+ psc = priv->screenConfigs;
+ screens = ScreenCount(priv->dpy);
+ for (i = 0; i < screens; i++, psc++) {
+ if (psc->configs) {
+ _gl_context_modes_destroy(psc->configs);
+ psc->configs = NULL; /* NOTE: just for paranoia */
+ }
+ if (psc->visuals) {
+ _gl_context_modes_destroy(psc->visuals);
+ psc->visuals = NULL; /* NOTE: just for paranoia */
+ }
+ Xfree((char *) psc->serverGLXexts);
+ }
+ XFree((char *) priv->screenConfigs);
+ priv->screenConfigs = NULL;
+}
+
+/************************************************************************/
+
+/*
+** Query the version of the GLX extension. This procedure works even if
+** the client extension is not completely set up.
+*/
+static Bool
+QueryVersion(Display * dpy, int opcode, int *major, int *minor)
+{
+ xGLXQueryVersionReq *req;
+ xGLXQueryVersionReply reply;
+
+ /* Send the glXQueryVersion request */
+ LockDisplay(dpy);
+ GetReq(GLXQueryVersion, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXQueryVersion;
+ req->majorVersion = GLX_MAJOR_VERSION;
+ req->minorVersion = GLX_MINOR_VERSION;
+ _XReply(dpy, (xReply *) & reply, 0, False);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ if (reply.majorVersion != GLX_MAJOR_VERSION) {
+ /*
+ ** The server does not support the same major release as this
+ ** client.
+ */
+ return GL_FALSE;
+ }
+ *major = reply.majorVersion;
+ *minor = min(reply.minorVersion, GLX_MINOR_VERSION);
+ return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXInitializeVisualConfigFromTags(__GLcontextModes * config, int count,
+ const INT32 * bp, Bool tagged_only,
+ Bool fbconfig_style_tags)
+{
+ int i;
+
+ if (!tagged_only) {
+ /* Copy in the first set of properties */
+ config->visualID = *bp++;
+
+ config->visualType = _gl_convert_from_x_visual_type(*bp++);
+
+ config->rgbMode = *bp++;
+
+ config->redBits = *bp++;
+ config->greenBits = *bp++;
+ config->blueBits = *bp++;
+ config->alphaBits = *bp++;
+ config->accumRedBits = *bp++;
+ config->accumGreenBits = *bp++;
+ config->accumBlueBits = *bp++;
+ config->accumAlphaBits = *bp++;
+
+ config->doubleBufferMode = *bp++;
+ config->stereoMode = *bp++;
+
+ config->rgbBits = *bp++;
+ config->depthBits = *bp++;
+ config->stencilBits = *bp++;
+ config->numAuxBuffers = *bp++;
+ config->level = *bp++;
+
+ count -= __GLX_MIN_CONFIG_PROPS;
+ }
+
+ /*
+ ** Additional properties may be in a list at the end
+ ** of the reply. They are in pairs of property type
+ ** and property value.
+ */
+
+#define FETCH_OR_SET(tag) \
+ config-> tag = ( fbconfig_style_tags ) ? *bp++ : 1
+
+ for (i = 0; i < count; i += 2) {
+ switch (*bp++) {
+ case GLX_RGBA:
+ FETCH_OR_SET(rgbMode);
+ break;
+ case GLX_BUFFER_SIZE:
+ config->rgbBits = *bp++;
+ break;
+ case GLX_LEVEL:
+ config->level = *bp++;
+ break;
+ case GLX_DOUBLEBUFFER:
+ FETCH_OR_SET(doubleBufferMode);
+ break;
+ case GLX_STEREO:
+ FETCH_OR_SET(stereoMode);
+ break;
+ case GLX_AUX_BUFFERS:
+ config->numAuxBuffers = *bp++;
+ break;
+ case GLX_RED_SIZE:
+ config->redBits = *bp++;
+ break;
+ case GLX_GREEN_SIZE:
+ config->greenBits = *bp++;
+ break;
+ case GLX_BLUE_SIZE:
+ config->blueBits = *bp++;
+ break;
+ case GLX_ALPHA_SIZE:
+ config->alphaBits = *bp++;
+ break;
+ case GLX_DEPTH_SIZE:
+ config->depthBits = *bp++;
+ break;
+ case GLX_STENCIL_SIZE:
+ config->stencilBits = *bp++;
+ break;
+ case GLX_ACCUM_RED_SIZE:
+ config->accumRedBits = *bp++;
+ break;
+ case GLX_ACCUM_GREEN_SIZE:
+ config->accumGreenBits = *bp++;
+ break;
+ case GLX_ACCUM_BLUE_SIZE:
+ config->accumBlueBits = *bp++;
+ break;
+ case GLX_ACCUM_ALPHA_SIZE:
+ config->accumAlphaBits = *bp++;
+ break;
+ case GLX_VISUAL_CAVEAT_EXT:
+ config->visualRating = *bp++;
+ break;
+ case GLX_X_VISUAL_TYPE:
+ config->visualType = *bp++;
+ break;
+ case GLX_TRANSPARENT_TYPE:
+ config->transparentPixel = *bp++;
+ break;
+ case GLX_TRANSPARENT_INDEX_VALUE:
+ config->transparentIndex = *bp++;
+ break;
+ case GLX_TRANSPARENT_RED_VALUE:
+ config->transparentRed = *bp++;
+ break;
+ case GLX_TRANSPARENT_GREEN_VALUE:
+ config->transparentGreen = *bp++;
+ break;
+ case GLX_TRANSPARENT_BLUE_VALUE:
+ config->transparentBlue = *bp++;
+ break;
+ case GLX_TRANSPARENT_ALPHA_VALUE:
+ config->transparentAlpha = *bp++;
+ break;
+ case GLX_VISUAL_ID:
+ config->visualID = *bp++;
+ break;
+ case GLX_DRAWABLE_TYPE:
+ config->drawableType = *bp++;
+ break;
+ case GLX_RENDER_TYPE:
+ config->renderType = *bp++;
+ break;
+ case GLX_X_RENDERABLE:
+ config->xRenderable = *bp++;
+ break;
+ case GLX_FBCONFIG_ID:
+ config->fbconfigID = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_WIDTH:
+ config->maxPbufferWidth = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_HEIGHT:
+ config->maxPbufferHeight = *bp++;
+ break;
+ case GLX_MAX_PBUFFER_PIXELS:
+ config->maxPbufferPixels = *bp++;
+ break;
+ case GLX_OPTIMAL_PBUFFER_WIDTH_SGIX:
+ config->optimalPbufferWidth = *bp++;
+ break;
+ case GLX_OPTIMAL_PBUFFER_HEIGHT_SGIX:
+ config->optimalPbufferHeight = *bp++;
+ break;
+ case GLX_VISUAL_SELECT_GROUP_SGIX:
+ config->visualSelectGroup = *bp++;
+ break;
+ case GLX_SWAP_METHOD_OML:
+ config->swapMethod = *bp++;
+ break;
+ case GLX_SAMPLE_BUFFERS_SGIS:
+ config->sampleBuffers = *bp++;
+ break;
+ case GLX_SAMPLES_SGIS:
+ config->samples = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGB_EXT:
+ config->bindToTextureRgb = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_RGBA_EXT:
+ config->bindToTextureRgba = *bp++;
+ break;
+ case GLX_BIND_TO_MIPMAP_TEXTURE_EXT:
+ config->bindToMipmapTexture = *bp++;
+ break;
+ case GLX_BIND_TO_TEXTURE_TARGETS_EXT:
+ config->bindToTextureTargets = *bp++;
+ break;
+ case GLX_Y_INVERTED_EXT:
+ config->yInverted = *bp++;
+ break;
+ case None:
+ i = count;
+ break;
+ default:
+ break;
+ }
+ }
+
+ config->renderType =
+ (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+
+ config->haveAccumBuffer = ((config->accumRedBits +
+ config->accumGreenBits +
+ config->accumBlueBits +
+ config->accumAlphaBits) > 0);
+ config->haveDepthBuffer = (config->depthBits > 0);
+ config->haveStencilBuffer = (config->stencilBits > 0);
+}
+
+static __GLcontextModes *
+createConfigsFromProperties(Display * dpy, int nvisuals, int nprops,
+ int screen, GLboolean tagged_only)
+{
+ INT32 buf[__GLX_TOTAL_CONFIG], *props;
+ unsigned prop_size;
+ __GLcontextModes *modes, *m;
+ int i;
+
+ if (nprops == 0)
+ return NULL;
+
+ /* FIXME: Is the __GLX_MIN_CONFIG_PROPS test correct for FBconfigs? */
+
+ /* Check number of properties */
+ if (nprops < __GLX_MIN_CONFIG_PROPS || nprops > __GLX_MAX_CONFIG_PROPS)
+ return NULL;
+
+ /* Allocate memory for our config structure */
+ modes = _gl_context_modes_create(nvisuals, sizeof(__GLcontextModes));
+ if (!modes)
+ return NULL;
+
+ prop_size = nprops * __GLX_SIZE_INT32;
+ if (prop_size <= sizeof(buf))
+ props = buf;
+ else
+ props = Xmalloc(prop_size);
+
+ /* Read each config structure and convert it into our format */
+ m = modes;
+ for (i = 0; i < nvisuals; i++) {
+ _XRead(dpy, (char *) props, prop_size);
+ /* Older X servers don't send this so we default it here. */
+ m->drawableType = GLX_WINDOW_BIT;
+ __glXInitializeVisualConfigFromTags(m, nprops, props,
+ tagged_only, GL_TRUE);
+ m->screen = screen;
+ m = m->next;
+ }
+
+ if (props != buf)
+ Xfree(props);
+
+ return modes;
+}
+
+static GLboolean
+getVisualConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+ xGLXGetVisualConfigsReq *req;
+ __GLXscreenConfigs *psc;
+ xGLXGetVisualConfigsReply reply;
+
+ LockDisplay(dpy);
+
+ psc = priv->screenConfigs + screen;
+ psc->visuals = NULL;
+ GetReq(GLXGetVisualConfigs, req);
+ req->reqType = priv->majorOpcode;
+ req->glxCode = X_GLXGetVisualConfigs;
+ req->screen = screen;
+
+ if (!_XReply(dpy, (xReply *) & reply, 0, False))
+ goto out;
+
+ psc->visuals = createConfigsFromProperties(dpy,
+ reply.numVisuals,
+ reply.numProps,
+ screen, GL_FALSE);
+
+ out:
+ UnlockDisplay(dpy);
+ return psc->visuals != NULL;
+}
+
+static GLboolean
+getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
+{
+ xGLXGetFBConfigsReq *fb_req;
+ xGLXGetFBConfigsSGIXReq *sgi_req;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXGetFBConfigsReply reply;
+ __GLXscreenConfigs *psc;
+
+ psc = priv->screenConfigs + screen;
+ psc->serverGLXexts =
+ __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+
+ LockDisplay(dpy);
+
+ psc->configs = NULL;
+ if (atof(priv->serverGLXversion) >= 1.3) {
+ GetReq(GLXGetFBConfigs, fb_req);
+ fb_req->reqType = priv->majorOpcode;
+ fb_req->glxCode = X_GLXGetFBConfigs;
+ fb_req->screen = screen;
+ }
+ else if (strstr(psc->serverGLXexts, "GLX_SGIX_fbconfig") != NULL) {
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXGetFBConfigsSGIXReq +
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ sgi_req = (xGLXGetFBConfigsSGIXReq *) vpreq;
+ sgi_req->reqType = priv->majorOpcode;
+ sgi_req->glxCode = X_GLXVendorPrivateWithReply;
+ sgi_req->vendorCode = X_GLXvop_GetFBConfigsSGIX;
+ sgi_req->screen = screen;
+ }
+ else
+ goto out;
+
+ if (!_XReply(dpy, (xReply *) & reply, 0, False))
+ goto out;
+
+ psc->configs = createConfigsFromProperties(dpy,
+ reply.numFBConfigs,
+ reply.numAttribs * 2,
+ screen, GL_TRUE);
+
+ out:
+ UnlockDisplay(dpy);
+ return psc->configs != NULL;
+}
+
+static GLboolean
+AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
+{
+ __GLXscreenConfigs *psc;
+ GLint i, screens;
+
+ /*
+ ** First allocate memory for the array of per screen configs.
+ */
+ screens = ScreenCount(dpy);
+ psc = (__GLXscreenConfigs *) Xmalloc(screens * sizeof(__GLXscreenConfigs));
+ if (!psc) {
+ return GL_FALSE;
+ }
+ memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
+ priv->screenConfigs = psc;
+
+ priv->serverGLXversion =
+ __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
+ if (priv->serverGLXversion == NULL) {
+ FreeScreenConfigs(priv);
+ return GL_FALSE;
+ }
+
+ for (i = 0; i < screens; i++, psc++) {
+ getFBConfigs(dpy, priv, i);
+ getVisualConfigs(dpy, priv, i);
+ psc->scr = i;
+ psc->dpy = dpy;
+ }
+
+ SyncHandle();
+
+ return GL_TRUE;
+}
+
+_X_HIDDEN void
+__glXRelease(__GLXdisplayPrivate *dpyPriv)
+{
+ FreeScreenConfigs(dpyPriv);
+
+ if (dpyPriv->serverGLXvendor) {
+ Xfree((char *) dpyPriv->serverGLXvendor);
+ dpyPriv->serverGLXvendor = NULL;
+ }
+ if (dpyPriv->serverGLXversion) {
+ Xfree((char *) dpyPriv->serverGLXversion);
+ dpyPriv->serverGLXversion = NULL;
+ }
+
+ Xfree(dpyPriv);
+}
+
+_X_HIDDEN __GLXdisplayPrivate *
+__glXInitialize(Display * dpy)
+{
+ XExtDisplayInfo *info = __glXFindDisplay(dpy);
+ __GLXdisplayPrivate *dpyPriv;
+ int major, minor;
+
+ if (!XextHasExtension(info))
+ return NULL;
+
+ /* See if the versions are compatible */
+ if (!QueryVersion(dpy, info->codes->major_opcode, &major, &minor))
+ return NULL;
+
+ dpyPriv = (__GLXdisplayPrivate *) Xcalloc(1, sizeof(__GLXdisplayPrivate));
+ if (!dpyPriv)
+ return NULL;
+
+ /*
+ ** Init the display private and then read in the screen config
+ ** structures from the server.
+ */
+ dpyPriv->majorOpcode = info->codes->major_opcode;
+ dpyPriv->majorVersion = major;
+ dpyPriv->minorVersion = minor;
+ dpyPriv->dpy = dpy;
+
+ dpyPriv->serverGLXvendor = NULL;
+ dpyPriv->serverGLXversion = NULL;
+
+ if (!AllocAndFetchScreenConfigs(dpy, dpyPriv)) {
+ Xfree(dpyPriv);
+ return NULL;
+ }
+
+ return dpyPriv;
+}
diff --git a/src/egl/drivers/xdri/glxinit.h b/src/egl/drivers/xdri/glxinit.h
new file mode 100644
index 0000000000..57206e627b
--- /dev/null
+++ b/src/egl/drivers/xdri/glxinit.h
@@ -0,0 +1,14 @@
+#ifndef GLXINIT_INCLUDED
+#define GLXINIT_INCLUDED
+
+#include <X11/Xlib.h>
+#include "glxclient.h"
+
+/* this is used by DRI loaders */
+extern void
+_gl_context_modes_destroy(__GLcontextModes * modes);
+
+extern void
+__glXRelease(__GLXdisplayPrivate *dpyPriv);
+
+#endif /* GLXINIT_INCLUDED */
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index 7cab005214..c951b070f1 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -17,13 +17,12 @@ HEADERS = \
egldriver.h \
eglglobals.h \
egllog.h \
- eglhash.h \
eglmisc.h \
eglmode.h \
+ eglmutex.h \
eglscreen.h \
eglstring.h \
- eglsurface.h \
- eglx.h
+ eglsurface.h
SOURCES = \
eglapi.c \
@@ -35,13 +34,11 @@ SOURCES = \
egldriver.c \
eglglobals.c \
egllog.c \
- eglhash.c \
eglmisc.c \
eglmode.c \
eglscreen.c \
eglstring.c \
- eglsurface.c \
- eglx.c
+ eglsurface.c
OBJECTS = $(SOURCES:.c=.o)
@@ -74,6 +71,7 @@ install: default
clean:
-rm -f *.o *.so*
-rm -f core.*
+ -rm -f depend depend.bak
depend: $(SOURCES) $(HEADERS)
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index f0a6f7f935..29617b7aff 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -29,7 +29,6 @@
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -39,7 +38,9 @@
#include "eglglobals.h"
#include "egldriver.h"
#include "eglsurface.h"
-
+#include "eglconfig.h"
+#include "eglscreen.h"
+#include "eglmode.h"
/**
@@ -50,7 +51,6 @@ EGLDisplay EGLAPIENTRY
eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
- _eglInitGlobals();
dpy = _eglFindDisplay(nativeDisplay);
if (!dpy) {
dpy = _eglNewDisplay(nativeDisplay);
@@ -68,232 +68,484 @@ eglGetDisplay(NativeDisplayType nativeDisplay)
EGLBoolean EGLAPIENTRY
eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLDriver *drv;
EGLint major_int, minor_int;
- if (dpy) {
- EGLBoolean retVal;
- _EGLDisplay *dpyPriv = _eglLookupDisplay(dpy);
- if (!dpyPriv) {
- return EGL_FALSE;
- }
- dpyPriv->Driver = _eglOpenDriver(dpyPriv,
- dpyPriv->DriverName,
- dpyPriv->DriverArgs);
- if (!dpyPriv->Driver) {
- return EGL_FALSE;
- }
- /* Initialize the particular driver now */
- retVal = dpyPriv->Driver->API.Initialize(dpyPriv->Driver, dpy,
- &major_int, &minor_int);
-
- dpyPriv->Driver->APImajor = major_int;
- dpyPriv->Driver->APIminor = minor_int;
- snprintf(dpyPriv->Driver->Version, sizeof(dpyPriv->Driver->Version),
- "%d.%d (%s)", major_int, minor_int, dpyPriv->Driver->Name);
-
- /* Update applications version of major and minor if not NULL */
- if((major != NULL) && (minor != NULL))
- {
- *major = major_int;
- *minor = minor_int;
+ if (!disp)
+ return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+ drv = disp->Driver;
+ if (!drv) {
+ drv = _eglOpenDriver(disp);
+ if (!drv)
+ return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
+
+ /* Initialize the particular display now */
+ if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) {
+ _eglCloseDriver(drv, disp);
+ return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__);
}
- return retVal;
+ disp->APImajor = major_int;
+ disp->APIminor = minor_int;
+ snprintf(disp->Version, sizeof(disp->Version),
+ "%d.%d (%s)", major_int, minor_int, drv->Name);
+
+ /* update the global notion of supported APIs */
+ _eglGlobal.ClientAPIsMask |= disp->ClientAPIsMask;
+
+ disp->Driver = drv;
+ } else {
+ major_int = disp->APImajor;
+ minor_int = disp->APIminor;
+ }
+
+ /* Update applications version of major and minor if not NULL */
+ if ((major != NULL) && (minor != NULL)) {
+ *major = major_int;
+ *minor = minor_int;
}
- return EGL_FALSE;
+
+ return EGL_TRUE;
}
EGLBoolean EGLAPIENTRY
eglTerminate(EGLDisplay dpy)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return _eglCloseDriver(drv, dpy);
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLDriver *drv;
+
+ if (!disp)
+ return _eglError(EGL_BAD_DISPLAY, __FUNCTION__);
+
+ drv = disp->Driver;
+ if (drv) {
+ drv->API.Terminate(drv, disp);
+ _eglCloseDriver(drv, disp);
+ disp->Driver = NULL;
+ }
+
+ return EGL_TRUE;
+}
+
+
+/**
+ * A bunch of check functions and declare macros to simply error checking.
+ */
+static INLINE _EGLDriver *
+_eglCheckDisplay(_EGLDisplay *disp, const char *msg)
+{
+ if (!disp) {
+ _eglError(EGL_BAD_DISPLAY, msg);
+ return NULL;
+ }
+ if (!disp->Driver) {
+ _eglError(EGL_NOT_INITIALIZED, msg);
+ return NULL;
+ }
+ return disp->Driver;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckSurface(_EGLDisplay *disp, _EGLSurface *surf, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!surf) {
+ _eglError(EGL_BAD_SURFACE, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckContext(_EGLDisplay *disp, _EGLContext *context, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!context) {
+ _eglError(EGL_BAD_CONTEXT, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!conf) {
+ _eglError(EGL_BAD_CONFIG, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+#define _EGL_DECLARE_DD(dpy) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckDisplay(disp, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLSurface *surf = _eglLookupSurface((surface), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckSurface(disp, surf, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLContext *context = _eglLookupContext((ctx), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckContext(disp, context, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#ifdef EGL_MESA_screen_surface
+
+
+static INLINE _EGLDriver *
+_eglCheckScreen(_EGLDisplay *disp, _EGLScreen *scrn, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!scrn) {
+ _eglError(EGL_BAD_SCREEN_MESA, msg);
+ return NULL;
+ }
+ return drv;
+}
+
+
+static INLINE _EGLDriver *
+_eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg)
+{
+ _EGLDriver *drv = _eglCheckDisplay(disp, msg);
+ if (!drv)
+ return NULL;
+ if (!m) {
+ _eglError(EGL_BAD_MODE_MESA, msg);
+ return NULL;
+ }
+ return drv;
}
+#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLScreen *scrn = _eglLookupScreen((screen), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \
+ _EGLDisplay *disp = _eglLookupDisplay(dpy); \
+ _EGLMode *m = _eglLookupMode((mode), disp); \
+ _EGLDriver *drv; \
+ do { \
+ drv = _eglCheckMode(disp, m, __FUNCTION__); \
+ if (!drv) \
+ return EGL_FALSE; \
+ } while (0)
+
+
+#endif /* EGL_MESA_screen_surface */
+
+
const char * EGLAPIENTRY
eglQueryString(EGLDisplay dpy, EGLint name)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.QueryString(drv, dpy, name);
- else
- return NULL;
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.QueryString(drv, disp, name);
}
EGLBoolean EGLAPIENTRY
-eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglGetConfigs(EGLDisplay dpy, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- /* XXX check drv for null in remaining functions */
- return drv->API.GetConfigs(drv, dpy, configs, config_size, num_config);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.GetConfigs(drv, disp, configs, config_size, num_config);
}
EGLBoolean EGLAPIENTRY
-eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config)
+eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs,
+ EGLint config_size, EGLint *num_config)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ChooseConfig(drv, dpy, attrib_list, configs, config_size, num_config);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.ChooseConfig(drv, disp, attrib_list, configs,
+ config_size, num_config);
}
EGLBoolean EGLAPIENTRY
-eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value)
+eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.GetConfigAttrib(drv, dpy, config, attribute, value);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value);
}
EGLContext EGLAPIENTRY
-eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
-{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateContext(drv, dpy, config, share_list, attrib_list);
+eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list,
+ const EGLint *attrib_list)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLContext *share = _eglLookupContext(share_list, disp);
+ _EGLDriver *drv;
+ _EGLContext *context;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_CONTEXT;
+ if (!share && share_list != EGL_NO_CONTEXT) {
+ _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+ return EGL_NO_CONTEXT;
+ }
+
+ context = drv->API.CreateContext(drv, disp, conf, share, attrib_list);
+ if (context)
+ return _eglLinkContext(context, disp);
+ else
+ return EGL_NO_CONTEXT;
}
EGLBoolean EGLAPIENTRY
eglDestroyContext(EGLDisplay dpy, EGLContext ctx)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.DestroyContext(drv, dpy, ctx);
+ _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+ _eglUnlinkContext(context);
+ return drv->API.DestroyContext(drv, disp, context);
}
EGLBoolean EGLAPIENTRY
-eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx)
+eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read,
+ EGLContext ctx)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.MakeCurrent(drv, dpy, draw, read, ctx);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLContext *context = _eglLookupContext(ctx, disp);
+ _EGLSurface *draw_surf = _eglLookupSurface(draw, disp);
+ _EGLSurface *read_surf = _eglLookupSurface(read, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckDisplay(disp, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+ if (!context && ctx != EGL_NO_CONTEXT)
+ return _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
+ if ((!draw_surf && draw != EGL_NO_SURFACE) ||
+ (!read_surf && read != EGL_NO_SURFACE))
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+
+ return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context);
}
EGLBoolean EGLAPIENTRY
-eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value)
+eglQueryContext(EGLDisplay dpy, EGLContext ctx,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryContext(drv, dpy, ctx, attribute, value);
+ _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx);
+ return drv->API.QueryContext(drv, disp, context, attribute, value);
}
EGLSurface EGLAPIENTRY
-eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config,
+ NativeWindowType window, const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateWindowSurface(drv, dpy, config, window, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLSurface EGLAPIENTRY
-eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config,
+ NativePixmapType pixmap, const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePixmapSurface(drv, dpy, config, pixmap, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLSurface EGLAPIENTRY
-eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePbufferSurface(drv, dpy, config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean EGLAPIENTRY
eglDestroySurface(EGLDisplay dpy, EGLSurface surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.DestroySurface(drv, dpy, surface);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ _eglUnlinkSurface(surf);
+ return drv->API.DestroySurface(drv, disp, surf);
}
-
EGLBoolean EGLAPIENTRY
-eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value)
+eglQuerySurface(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QuerySurface(drv, dpy, surface, attribute, value);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.QuerySurface(drv, disp, surf, attribute, value);
}
-
EGLBoolean EGLAPIENTRY
-eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value)
+eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface,
+ EGLint attribute, EGLint value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SurfaceAttrib(drv, dpy, surface, attribute, value);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value);
}
EGLBoolean EGLAPIENTRY
eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.BindTexImage(drv, dpy, surface, buffer);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.BindTexImage(drv, disp, surf, buffer);
}
EGLBoolean EGLAPIENTRY
eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ReleaseTexImage(drv, dpy, surface, buffer);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.ReleaseTexImage(drv, disp, surf, buffer);
}
EGLBoolean EGLAPIENTRY
eglSwapInterval(EGLDisplay dpy, EGLint interval)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SwapInterval(drv, dpy, interval);
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.SwapInterval(drv, disp, interval);
}
EGLBoolean EGLAPIENTRY
-eglSwapBuffers(EGLDisplay dpy, EGLSurface draw)
+eglSwapBuffers(EGLDisplay dpy, EGLSurface surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.SwapBuffers(drv, dpy, draw);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.SwapBuffers(drv, disp, surf);
}
EGLBoolean EGLAPIENTRY
eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, NativePixmapType target)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CopyBuffers(drv, dpy, surface, target);
+ _EGL_DECLARE_DD_AND_SURFACE(dpy, surface);
+ return drv->API.CopyBuffers(drv, disp, surf, target);
}
EGLBoolean EGLAPIENTRY
eglWaitGL(void)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitGL(drv, dpy);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitGL(drv, disp);
}
EGLBoolean EGLAPIENTRY
eglWaitNative(EGLint engine)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitNative(drv, dpy, engine);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitNative(drv, disp, engine);
}
@@ -421,111 +673,168 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.ChooseModeMESA(drv, dpy, screen, attrib_list, modes, modes_size, num_modes);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list,
+ modes, modes_size, num_modes);
}
EGLBoolean EGLAPIENTRY
-eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode)
+eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes,
+ EGLint mode_size, EGLint *num_mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetModesMESA(drv, dpy, screen, modes, mode_size, num_mode);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode);
}
EGLBoolean EGLAPIENTRY
-eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value)
+eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetModeAttribMESA(drv, dpy, mode, attribute, value);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+ return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value);
}
EGLBoolean EGLAPIENTRY
-eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask)
-{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.CopyContextMESA(drv, dpy, source, dest, mask);
- else
+eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest,
+ EGLint mask)
+{
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLContext *source_context = _eglLookupContext(source, disp);
+ _EGLContext *dest_context = _eglLookupContext(dest, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckContext(disp, source_context, __FUNCTION__);
+ if (!drv || !dest_context) {
+ if (drv)
+ _eglError(EGL_BAD_CONTEXT, __FUNCTION__);
return EGL_FALSE;
+ }
+
+ return drv->API.CopyContextMESA(drv, disp, source_context, dest_context,
+ mask);
}
EGLBoolean
-eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens)
+eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens,
+ EGLint max_screens, EGLint *num_screens)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- if (drv)
- return drv->API.GetScreensMESA(drv, dpy, screens, max_screens, num_screens);
- else
- return EGL_FALSE;
+ _EGL_DECLARE_DD(dpy);
+ return drv->API.GetScreensMESA(drv, disp, screens,
+ max_screens, num_screens);
}
EGLSurface
-eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list)
+eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config,
+ const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreateScreenSurfaceMESA(drv, dpy, config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean
-eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode)
+eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen,
+ EGLSurface surface, EGLModeMESA mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ShowScreenSurfaceMESA(drv, dpy, screen, surface, mode);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLSurface *surf = _eglLookupSurface(surface, disp);
+ _EGLMode *m = _eglLookupMode(mode, disp);
+ _EGLDriver *drv;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+ if (!surf && surface != EGL_NO_SURFACE)
+ return _eglError(EGL_BAD_SURFACE, __FUNCTION__);
+ if (!m && mode != EGL_NO_MODE_MESA)
+ return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__);
+
+ return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m);
}
EGLBoolean
eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.ScreenPositionMESA(drv, dpy, screen, x, y);
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y);
}
EGLBoolean
-eglQueryScreenMESA( EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value)
+eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen,
+ EGLint attribute, EGLint *value)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenMESA(drv, dpy, screen, attribute, value);
+ _EGL_DECLARE_DD_AND_SCREEN(dpy, screen);
+ return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value);
}
EGLBoolean
-eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface)
+eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen,
+ EGLSurface *surface)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenSurfaceMESA(drv, dpy, screen, surface);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE)
+ surf = NULL;
+ if (surface)
+ *surface = _eglGetSurfaceHandle(surf);
+ return (surf != NULL);
}
EGLBoolean
eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryScreenModeMESA(drv, dpy, screen, mode);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp);
+ _EGLDriver *drv;
+ _EGLMode *m;
+
+ drv = _eglCheckScreen(disp, scrn, __FUNCTION__);
+ if (!drv)
+ return EGL_FALSE;
+
+ if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE)
+ m = NULL;
+ if (mode)
+ *mode = m->Handle;
+
+ return (m != NULL);
}
const char *
eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.QueryModeStringMESA(drv, dpy, mode);
+ _EGL_DECLARE_DD_AND_MODE(dpy, mode);
+ return drv->API.QueryModeStringMESA(drv, disp, m);
}
@@ -606,27 +915,37 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype,
EGLClientBuffer buffer, EGLConfig config,
const EGLint *attrib_list)
{
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.CreatePbufferFromClientBuffer(drv, dpy, buftype, buffer,
- config, attrib_list);
+ _EGLDisplay *disp = _eglLookupDisplay(dpy);
+ _EGLConfig *conf = _eglLookupConfig(config, disp);
+ _EGLDriver *drv;
+ _EGLSurface *surf;
+
+ drv = _eglCheckConfig(disp, conf, __FUNCTION__);
+ if (!drv)
+ return EGL_NO_SURFACE;
+
+ surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer,
+ conf, attrib_list);
+ if (surf)
+ return _eglLinkSurface(surf, disp);
+ else
+ return EGL_NO_SURFACE;
}
EGLBoolean
eglReleaseThread(void)
{
- EGLDisplay dpy;
-
- if (_eglIsCurrentThreadDummy())
- return EGL_TRUE;
-
- dpy = eglGetCurrentDisplay();
- if (dpy) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- /* unbind context */
- (void) drv->API.MakeCurrent(drv, dpy, EGL_NO_SURFACE,
- EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ /* unbind current context */
+ if (!_eglIsCurrentThreadDummy()) {
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+ if (disp) {
+ drv = disp->Driver;
+ (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL);
+ }
}
+
_eglDestroyCurrentThread();
return EGL_TRUE;
}
@@ -635,13 +954,17 @@ eglReleaseThread(void)
EGLBoolean
eglWaitClient(void)
{
- EGLDisplay dpy = eglGetCurrentDisplay();
- if (dpy != EGL_NO_DISPLAY) {
- _EGLDriver *drv = _eglLookupDriver(dpy);
- return drv->API.WaitClient(drv, dpy);
- }
- else
- return EGL_FALSE;
+ _EGLDisplay *disp = _eglGetCurrentDisplay();
+ _EGLDriver *drv;
+
+ if (!disp)
+ return EGL_TRUE;
+
+ /* a current display is always initialized */
+ drv = disp->Driver;
+
+ return drv->API.WaitClient(drv, disp);
}
+
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h
index f6163a0c7a..6081e58892 100644
--- a/src/egl/main/eglapi.h
+++ b/src/egl/main/eglapi.h
@@ -12,61 +12,61 @@ typedef void (*_EGLProc)();
*/
/* driver funcs */
-typedef EGLBoolean (*Initialize_t)(_EGLDriver *, EGLDisplay dpy, EGLint *major, EGLint *minor);
-typedef EGLBoolean (*Terminate_t)(_EGLDriver *, EGLDisplay dpy);
+typedef EGLBoolean (*Initialize_t)(_EGLDriver *, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
+typedef EGLBoolean (*Terminate_t)(_EGLDriver *, _EGLDisplay *dpy);
/* config funcs */
-typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
-typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*GetConfigs_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*ChooseConfig_t)(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+typedef EGLBoolean (*GetConfigAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, EGLint attribute, EGLint *value);
/* context funcs */
-typedef EGLContext (*CreateContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
-typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
-typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+typedef _EGLContext *(*CreateContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, _EGLContext *share_list, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroyContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
+typedef EGLBoolean (*MakeCurrent_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
+typedef EGLBoolean (*QueryContext_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
/* surface funcs */
-typedef EGLSurface (*CreateWindowSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePixmapSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-typedef EGLSurface (*CreatePbufferSurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
-typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
-typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
-typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
-typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
-typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+typedef _EGLSurface *(*CreateWindowSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativeWindowType window, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePixmapSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, NativePixmapType pixmap, const EGLint *attrib_list);
+typedef _EGLSurface *(*CreatePbufferSurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*DestroySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
+typedef EGLBoolean (*QuerySurface_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*SurfaceAttrib_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint attribute, EGLint value);
+typedef EGLBoolean (*BindTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*ReleaseTexImage_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, EGLint buffer);
+typedef EGLBoolean (*SwapInterval_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
+typedef EGLBoolean (*SwapBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
+typedef EGLBoolean (*CopyBuffers_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface, NativePixmapType target);
/* misc funcs */
-typedef const char *(*QueryString_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
-typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
+typedef EGLBoolean (*WaitGL_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
typedef _EGLProc (*GetProcAddress_t)(const char *procname);
#ifdef EGL_MESA_screen_surface
-typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
-typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
-typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
-typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-typedef EGLSurface (*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
-typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
-typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
-typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface);
-typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
-typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+typedef EGLBoolean (*ChooseModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
+typedef EGLBoolean (*GetModesMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode);
+typedef EGLBoolean (*GetModeAttribMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*CopyContextMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *source, _EGLContext *dest, EGLint mask);
+typedef EGLBoolean (*GetScreensMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+typedef _EGLSurface *(*CreateScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *config, const EGLint *attrib_list);
+typedef EGLBoolean (*ShowScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
+typedef EGLBoolean (*ScreenPositionMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint x, EGLint y);
+typedef EGLBoolean (*QueryScreenMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, EGLint attribute, EGLint *value);
+typedef EGLBoolean (*QueryScreenSurfaceMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface **surface);
+typedef EGLBoolean (*QueryScreenModeMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLMode **mode);
+typedef const char * (*QueryModeStringMESA_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *mode);
#endif /* EGL_MESA_screen_surface */
#ifdef EGL_VERSION_1_2
-typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, EGLDisplay dpy);
-typedef EGLSurface (*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list);
+typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy);
+typedef _EGLSurface *(*CreatePbufferFromClientBuffer_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLenum buftype, EGLClientBuffer buffer, _EGLConfig *config, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
index 0b19afedfd..6b639b75c6 100644
--- a/src/egl/main/eglcompiler.h
+++ b/src/egl/main/eglcompiler.h
@@ -3,6 +3,39 @@
/**
+ * Get standard integer types
+ */
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
+# include <stdint.h>
+#elif defined(_MSC_VER)
+ typedef __int8 int8_t;
+ typedef unsigned __int8 uint8_t;
+ typedef __int16 int16_t;
+ typedef unsigned __int16 uint16_t;
+# ifndef __eglplatform_h_
+ typedef __int32 int32_t;
+# endif
+ typedef unsigned __int32 uint32_t;
+ typedef __int64 int64_t;
+ typedef unsigned __int64 uint64_t;
+
+# if defined(_WIN64)
+ typedef __int64 intptr_t;
+ typedef unsigned __int64 uintptr_t;
+# else
+ typedef __int32 intptr_t;
+ typedef unsigned __int32 uintptr_t;
+# endif
+
+# define INT64_C(__val) __val##i64
+# define UINT64_C(__val) __val##ui64
+#else
+/* hope the best instead of adding a bunch of ifdef's */
+# include <stdint.h>
+#endif
+
+
+/**
* Function inlining
*/
#if defined(__GNUC__)
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index f2f32585c7..d47b99eed4 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -34,7 +34,7 @@ void
_eglInitConfig(_EGLConfig *config, EGLint id)
{
memset(config, 0, sizeof(*config));
- config->Handle = (EGLConfig) id;
+ config->Handle = (EGLConfig) _eglUIntToPointer((unsigned int) id);
_eglSetConfigAttrib(config, EGL_CONFIG_ID, id);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGB, EGL_DONT_CARE);
_eglSetConfigAttrib(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_DONT_CARE);
@@ -71,10 +71,9 @@ _eglGetConfigHandle(_EGLConfig *config)
* This is the inverse of _eglGetConfigHandle().
*/
_EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config)
+_eglLookupConfig(EGLConfig config, _EGLDisplay *disp)
{
EGLint i;
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
for (i = 0; i < disp->NumConfigs; i++) {
if (disp->Configs[i]->Handle == config) {
return disp->Configs[i];
@@ -319,10 +318,9 @@ _eglCompareConfigs(const void *a, const void *b)
* Typical fallback routine for eglChooseConfig
*/
EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
EGLConfig *configs, EGLint config_size, EGLint *num_configs)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
_EGLConfig **configList, criteria;
EGLint i, count;
@@ -367,10 +365,9 @@ _eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list,
* Fallback for eglGetConfigAttrib.
*/
EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
EGLint attribute, EGLint *value)
{
- const _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
const EGLint k = attribute - FIRST_ATTRIB;
if (k >= 0 && k < MAX_ATTRIBS) {
*value = conf->Attrib[k];
@@ -387,16 +384,9 @@ _eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Fallback for eglGetConfigs.
*/
EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs,
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *disp, EGLConfig *configs,
EGLint config_size, EGLint *num_config)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
-
- if (!drv->Initialized) {
- _eglError(EGL_NOT_INITIALIZED, "eglGetConfigs");
- return EGL_FALSE;
- }
-
if (configs) {
EGLint i;
*num_config = MIN2(disp->NumConfigs, config_size);
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index db1c4c10e0..36ed96ae95 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -34,7 +34,7 @@ _eglGetConfigHandle(_EGLConfig *config);
extern _EGLConfig *
-_eglLookupConfig(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config);
+_eglLookupConfig(EGLConfig config, _EGLDisplay *dpy);
extern _EGLConfig *
@@ -46,15 +46,15 @@ _eglParseConfigAttribs(_EGLConfig *config, const EGLint *attrib_list);
extern EGLBoolean
-_eglChooseConfig(_EGLDriver *drv, EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglChooseConfig(_EGLDriver *drv, _EGLDisplay *dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern EGLBoolean
-_eglGetConfigAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value);
+_eglGetConfigAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglGetConfigs(_EGLDriver *drv, EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
+_eglGetConfigs(_EGLDriver *drv, _EGLDisplay *dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config);
extern void
diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c
index 138dc729e7..c9d00e7982 100644
--- a/src/egl/main/eglconfigutil.c
+++ b/src/egl/main/eglconfigutil.c
@@ -156,6 +156,7 @@ _eglFillInConfigs(_EGLConfig * configs,
{0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000}, /* 8_8_8_8_REV */
};
+#if 0
static const uint32_t masks_table_bgr[8][4] = {
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
@@ -177,6 +178,7 @@ _eglFillInConfigs(_EGLConfig * configs,
{0x00000000, 0x00000000, 0x00000000, 0x00000000},
{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, /* 8_8_8_8_REV */
};
+#endif
static const uint8_t bytes_per_pixel[8] = {
0, 0, 0, 2, 2, 4, 0, 4
diff --git a/src/egl/main/eglcontext.c b/src/egl/main/eglcontext.c
index 9ab4286d3a..b094f49bfc 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -25,11 +25,6 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
return EGL_FALSE;
}
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "_eglInitContext");
- return EGL_FALSE;
- }
-
memset(ctx, 0, sizeof(_EGLContext));
ctx->ClientVersion = 1; /* the default, per EGL spec */
@@ -58,32 +53,25 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
/**
* Just a placeholder/demo function. Real driver will never use this!
*/
-EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- EGLContext share_list, const EGLint *attrib_list)
+_EGLContext *
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
{
#if 0 /* example code */
_EGLContext *context;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
context = (_EGLContext *) calloc(1, sizeof(_EGLContext));
if (!context)
- return EGL_NO_CONTEXT;
+ return NULL;
if (!_eglInitContext(drv, context, conf, attrib_list)) {
free(context);
- return EGL_NO_CONTEXT;
+ return NULL;
}
- return _eglLinkContext(context, _eglLookupDisplay(dpy));
+ return context;
#endif
- return EGL_NO_CONTEXT;
+ return NULL;
}
@@ -91,36 +79,21 @@ _eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
- _EGLContext *context = _eglLookupContext(ctx);
- if (context) {
- _eglUnlinkContext(context);
- if (!context->IsBound)
- free(context);
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
- return EGL_TRUE;
- }
+ if (!_eglIsContextBound(ctx))
+ free(ctx);
+ return EGL_TRUE;
}
EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *c,
EGLint attribute, EGLint *value)
{
- _EGLContext *c = _eglLookupContext(ctx);
-
(void) drv;
(void) dpy;
- if (!c) {
- _eglError(EGL_BAD_CONTEXT, "eglQueryContext");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_CONFIG_ID:
*value = GET_CONFIG_ATTRIB(c->Config, EGL_CONFIG_ID);
@@ -146,13 +119,10 @@ _eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx,
* Then, the driver will do its device-dependent Make-Current stuff.
*/
EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
- EGLSurface r, EGLContext context)
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw,
+ _EGLSurface *read, _EGLContext *ctx)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
- _EGLContext *ctx = _eglLookupContext(context);
- _EGLSurface *draw = _eglLookupSurface(d);
- _EGLSurface *read = _eglLookupSurface(r);
_EGLContext *oldContext = NULL;
_EGLSurface *oldDrawSurface = NULL;
_EGLSurface *oldReadSurface = NULL;
@@ -161,20 +131,17 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
- /* error checking */
if (ctx) {
- if (draw == NULL || read == NULL) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
- if (draw->Config != ctx->Config) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
- if (read->Config != ctx->Config) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
+ /* error checking */
+ if (ctx->Binding && ctx->Binding != t)
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
+ if (draw == NULL || read == NULL)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ if (draw->Config != ctx->Config || read->Config != ctx->Config)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
+ if ((draw->Binding && draw->Binding->Binding != t) ||
+ (read->Binding && read->Binding->Binding != t))
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
#ifdef EGL_VERSION_1_4
/* OpenGL and OpenGL ES are conflicting */
@@ -194,6 +161,8 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
}
else {
+ if (draw != NULL || read != NULL)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
apiIndex = t->CurrentAPIIndex;
}
@@ -201,60 +170,43 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
if (oldContext) {
oldDrawSurface = oldContext->DrawSurface;
oldReadSurface = oldContext->ReadSurface;
- }
+ assert(oldDrawSurface);
+ assert(oldReadSurface);
- /*
- * check if the old context or surfaces need to be deleted
- */
- if (oldDrawSurface != NULL) {
- oldDrawSurface->IsBound = EGL_FALSE;
+ /* break old bindings */
+ t->CurrentContexts[apiIndex] = NULL;
+ oldContext->Binding = NULL;
+ oldContext->DrawSurface = NULL;
+ oldContext->ReadSurface = NULL;
+ oldDrawSurface->Binding = NULL;
+ oldReadSurface->Binding = NULL;
+
+ /*
+ * check if the old context or surfaces need to be deleted
+ */
if (!_eglIsSurfaceLinked(oldDrawSurface)) {
- /* make sure we don't try to rebind a deleted surface */
- if (draw == oldDrawSurface || draw == oldReadSurface) {
- draw = NULL;
- }
- /* really delete surface now */
- drv->API.DestroySurface(drv, dpy, oldDrawSurface->Handle);
+ assert(draw != oldDrawSurface && read != oldDrawSurface);
+ drv->API.DestroySurface(drv, dpy, oldDrawSurface);
}
- }
- if (oldReadSurface != NULL && oldReadSurface != oldDrawSurface) {
- oldReadSurface->IsBound = EGL_FALSE;
- if (!_eglIsSurfaceLinked(oldReadSurface)) {
- /* make sure we don't try to rebind a deleted surface */
- if (read == oldDrawSurface || read == oldReadSurface) {
- read = NULL;
- }
- /* really delete surface now */
- drv->API.DestroySurface(drv, dpy, oldReadSurface->Handle);
+ if (oldReadSurface != oldDrawSurface &&
+ !_eglIsSurfaceLinked(oldReadSurface)) {
+ assert(draw != oldReadSurface && read != oldReadSurface);
+ drv->API.DestroySurface(drv, dpy, oldReadSurface);
}
- }
- if (oldContext != NULL) {
- oldContext->IsBound = EGL_FALSE;
if (!_eglIsContextLinked(oldContext)) {
- /* make sure we don't try to rebind a deleted context */
- if (ctx == oldContext) {
- ctx = NULL;
- }
- /* really delete context now */
- drv->API.DestroyContext(drv, dpy, _eglGetContextHandle(oldContext));
+ assert(ctx != oldContext);
+ drv->API.DestroyContext(drv, dpy, oldContext);
}
}
+ /* build new bindings */
if (ctx) {
- /* check read/draw again, in case we deleted them above */
- if (draw == NULL || read == NULL) {
- _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
- return EGL_FALSE;
- }
+ t->CurrentContexts[apiIndex] = ctx;
+ ctx->Binding = t;
ctx->DrawSurface = draw;
ctx->ReadSurface = read;
- ctx->IsBound = EGL_TRUE;
- draw->IsBound = EGL_TRUE;
- read->IsBound = EGL_TRUE;
- t->CurrentContexts[apiIndex] = ctx;
- }
- else {
- t->CurrentContexts[apiIndex] = NULL;
+ draw->Binding = ctx;
+ read->Binding = ctx;
}
return EGL_TRUE;
diff --git a/src/egl/main/eglcontext.h b/src/egl/main/eglcontext.h
index 2fb28d38b9..647f24488f 100644
--- a/src/egl/main/eglcontext.h
+++ b/src/egl/main/eglcontext.h
@@ -15,12 +15,12 @@ struct _egl_context
_EGLDisplay *Display;
_EGLContext *Next;
- _EGLConfig *Config;
-
+ /* The bound status of the context */
+ _EGLThreadInfo *Binding;
_EGLSurface *DrawSurface;
_EGLSurface *ReadSurface;
- EGLBoolean IsBound;
+ _EGLConfig *Config;
EGLint ClientAPI; /**< EGL_OPENGL_ES_API, EGL_OPENGL_API, EGL_OPENVG_API */
EGLint ClientVersion; /**< 1 = OpenGLES 1.x, 2 = OpenGLES 2.x */
@@ -32,23 +32,34 @@ _eglInitContext(_EGLDriver *drv, _EGLContext *ctx,
_EGLConfig *config, const EGLint *attrib_list);
-extern EGLContext
-_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
+extern _EGLContext *
+_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
extern EGLBoolean
-_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx);
+_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx);
extern EGLBoolean
-_eglQueryContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value);
+_eglQueryContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx);
+_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx);
extern EGLBoolean
_eglCopyContextMESA(_EGLDriver *drv, EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask);
+
+/**
+ * Return true if the context is bound to a thread.
+ */
+static INLINE EGLBoolean
+_eglIsContextBound(_EGLContext *ctx)
+{
+ return (ctx->Binding != NULL);
+}
+
+
#endif /* EGLCONTEXT_INCLUDED */
diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c
index 96152db19f..4431f964f6 100644
--- a/src/egl/main/eglcurrent.c
+++ b/src/egl/main/eglcurrent.c
@@ -3,61 +3,127 @@
#include "eglcurrent.h"
#include "eglcontext.h"
#include "egllog.h"
+#include "eglmutex.h"
+#include "eglglobals.h"
+/* This should be kept in sync with _eglInitThreadInfo() */
+#define _EGL_THREAD_INFO_INITIALIZER \
+ { EGL_SUCCESS, { NULL }, 1 }
+
/* a fallback thread info to guarantee that every thread always has one */
-static _EGLThreadInfo dummy_thread;
+static _EGLThreadInfo dummy_thread = _EGL_THREAD_INFO_INITIALIZER;
#ifdef GLX_USE_TLS
static __thread const _EGLThreadInfo *_egl_TSD;
__attribute__ ((tls_model("initial-exec")));
-static INLINE EGLBoolean _eglInitTSD(void) { return EGL_TRUE; }
-static INLINE void _eglFiniTSD(void) { }
-static INLINE void _eglSetTSD(const _EGLThreadInfo *t) { _egl_TSD = t; }
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+{
+ _egl_TSD = t;
+}
static INLINE _EGLThreadInfo *_eglGetTSD(void)
{
return (_EGLThreadInfo *) _egl_TSD;
}
+static INLINE void _eglFiniTSD(void)
+{
+}
+
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
+{
+ /* TODO destroy TSD */
+ (void) dtor;
+ (void) _eglFiniTSD;
+ return EGL_TRUE;
+}
+
#elif PTHREADS
#include <pthread.h>
+static _EGL_DECLARE_MUTEX(_egl_TSDMutex);
+static EGLBoolean _egl_TSDInitialized;
static pthread_key_t _egl_TSD;
+static void (*_egl_FreeTSD)(_EGLThreadInfo *);
-static INLINE EGLBoolean _eglInitTSD(void)
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
{
- return (pthread_key_create(&_egl_TSD, NULL) == 0);
+ pthread_setspecific(_egl_TSD, (const void *) t);
}
-static INLINE void _eglFiniTSD(void)
+static INLINE _EGLThreadInfo *_eglGetTSD(void)
{
- pthread_key_delete(_egl_TSD);
+ return (_EGLThreadInfo *) pthread_getspecific(_egl_TSD);
}
-static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+static INLINE void _eglFiniTSD(void)
{
- pthread_setspecific(_egl_TSD, (const void *) t);
+ _eglLockMutex(&_egl_TSDMutex);
+ if (_egl_TSDInitialized) {
+ _EGLThreadInfo *t = _eglGetTSD();
+
+ _egl_TSDInitialized = EGL_FALSE;
+ if (t && _egl_FreeTSD)
+ _egl_FreeTSD((void *) t);
+ pthread_key_delete(_egl_TSD);
+ }
+ _eglUnlockMutex(&_egl_TSDMutex);
}
-static INLINE _EGLThreadInfo *_eglGetTSD(void)
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
{
- return (_EGLThreadInfo *) pthread_getspecific(_egl_TSD);
+ if (!_egl_TSDInitialized) {
+ _eglLockMutex(&_egl_TSDMutex);
+
+ /* check again after acquiring lock */
+ if (!_egl_TSDInitialized) {
+ if (pthread_key_create(&_egl_TSD, (void (*)(void *)) dtor) != 0) {
+ _eglUnlockMutex(&_egl_TSDMutex);
+ return EGL_FALSE;
+ }
+ _egl_FreeTSD = dtor;
+ _eglAddAtExitCall(_eglFiniTSD);
+ _egl_TSDInitialized = EGL_TRUE;
+ }
+
+ _eglUnlockMutex(&_egl_TSDMutex);
+ }
+
+ return EGL_TRUE;
}
#else /* PTHREADS */
static const _EGLThreadInfo *_egl_TSD;
+static void (*_egl_FreeTSD)(_EGLThreadInfo *);
-static INLINE EGLBoolean _eglInitTSD(void) { return EGL_TRUE; }
-static INLINE void _eglFiniTSD(void) { }
-static INLINE void _eglSetTSD(const _EGLThreadInfo *t) { _egl_TSD = t; }
+static INLINE void _eglSetTSD(const _EGLThreadInfo *t)
+{
+ _egl_TSD = t;
+}
static INLINE _EGLThreadInfo *_eglGetTSD(void)
{
return (_EGLThreadInfo *) _egl_TSD;
}
+
+static INLINE void _eglFiniTSD(void)
+{
+ if (_egl_FreeTSD && _egl_TSD)
+ _egl_FreeTSD((_EGLThreadInfo *) _egl_TSD);
+}
+
+static INLINE EGLBoolean _eglInitTSD(void (*dtor)(_EGLThreadInfo *))
+{
+ if (!_egl_FreeTSD && dtor) {
+ _egl_FreeTSD = dtor;
+ _eglAddAtExitCall(_eglFiniTSD);
+ }
+ return EGL_TRUE;
+}
+
#endif /* !PTHREADS */
@@ -98,24 +164,17 @@ _eglDestroyThreadInfo(_EGLThreadInfo *t)
/**
- * Initialize "current thread" management.
+ * Make sure TSD is initialized and return current value.
*/
-EGLBoolean
-_eglInitCurrent(void)
+static INLINE _EGLThreadInfo *
+_eglCheckedGetTSD(void)
{
- _eglInitThreadInfo(&dummy_thread);
- return _eglInitTSD();
-}
-
+ if (_eglInitTSD(&_eglDestroyThreadInfo) != EGL_TRUE) {
+ _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
+ return NULL;
+ }
-/**
- * Finish "current thread" management.
- */
-void
-_eglFiniCurrent(void)
-{
- /* TODO trace and release all threads... */
- _eglFiniTSD();
+ return _eglGetTSD();
}
@@ -129,7 +188,7 @@ _eglFiniCurrent(void)
_EGLThreadInfo *
_eglGetCurrentThread(void)
{
- _EGLThreadInfo *t = _eglGetTSD();
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
if (!t) {
t = _eglCreateThreadInfo();
_eglSetTSD(t);
@@ -145,7 +204,7 @@ _eglGetCurrentThread(void)
void
_eglDestroyCurrentThread(void)
{
- _EGLThreadInfo *t = _eglGetTSD();
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
if (t) {
_eglDestroyThreadInfo(t);
_eglSetTSD(NULL);
@@ -162,7 +221,7 @@ _eglDestroyCurrentThread(void)
EGLBoolean
_eglIsCurrentThreadDummy(void)
{
- _EGLThreadInfo *t = _eglGetTSD();
+ _EGLThreadInfo *t = _eglCheckedGetTSD();
return (!t || t == &dummy_thread);
}
diff --git a/src/egl/main/eglcurrent.h b/src/egl/main/eglcurrent.h
index f9fdf7bd0f..8eb241029e 100644
--- a/src/egl/main/eglcurrent.h
+++ b/src/egl/main/eglcurrent.h
@@ -20,14 +20,6 @@ struct _egl_thread_info
};
-extern EGLBoolean
-_eglInitCurrent(void);
-
-
-extern void
-_eglFiniCurrent(void);
-
-
/**
* Return true if a client API enum can be converted to an index.
*/
diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c
index 89de609d0b..896d60dbe1 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -1,4 +1,3 @@
-
/**
* Functions related to EGLDisplay.
*/
@@ -11,8 +10,63 @@
#include "egldisplay.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "eglstring.h"
+#include "eglmutex.h"
+#include "egllog.h"
+
+
+/**
+ * Finish display management.
+ */
+void
+_eglFiniDisplay(void)
+{
+ _EGLDisplay *dpyList, *dpy;
+
+ /* atexit function is called with global mutex locked */
+ dpyList = _eglGlobal.DisplayList;
+ while (dpyList) {
+ /* pop list head */
+ dpy = dpyList;
+ dpyList = dpyList->Next;
+
+ if (dpy->ContextList || dpy->SurfaceList)
+ _eglLog(_EGL_DEBUG, "Display %p is destroyed with resources", dpy);
+
+ free(dpy);
+ }
+ _eglGlobal.DisplayList = NULL;
+}
+
+
+/**
+ * If the first character is '!' we interpret it as specific driver name
+ * (i.e. "!r200" or "!i830"). Whatever follows ':' is interpreted as
+ * arguments.
+ *
+ * The caller may free() the returned driver name.
+ */
+char *
+_eglSplitDisplayString(const char *dpyString, const char **args)
+{
+ char *drv, *p;
+
+ if (!dpyString || dpyString[0] != '!')
+ return NULL;
+ drv = _eglstrdup(dpyString + 1);
+ if (!drv)
+ return NULL;
+
+ p = strchr(dpyString, ':');
+ if (p) {
+ drv[p - dpyString] = '\0';
+ p++;
+ }
+ if (args)
+ *args = p;
+
+ return drv;
+}
/**
@@ -27,11 +81,8 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
_EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay));
if (dpy) {
dpy->NativeDisplay = nativeDisplay;
-#if defined(_EGL_PLATFORM_X)
- dpy->Xdpy = (Display *) nativeDisplay;
-#endif
- dpy->DriverName = _eglChooseDriver(dpy);
+ dpy->DriverName = _eglPreloadDriver(dpy);
if (!dpy->DriverName) {
free(dpy);
return NULL;
@@ -48,14 +99,14 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
EGLDisplay
_eglLinkDisplay(_EGLDisplay *dpy)
{
- EGLuint key;
- key = _eglHashGenKey(_eglGlobal.Displays);
- assert(key);
- /* "link" the display to the hash table */
- _eglHashInsert(_eglGlobal.Displays, key, dpy);
- dpy->Handle = (EGLDisplay) key;
-
- return dpy->Handle;
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ dpy->Next = _eglGlobal.DisplayList;
+ _eglGlobal.DisplayList = dpy;
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
+
+ return (EGLDisplay) dpy;
}
@@ -66,33 +117,25 @@ _eglLinkDisplay(_EGLDisplay *dpy)
void
_eglUnlinkDisplay(_EGLDisplay *dpy)
{
- _eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle);
- dpy->Handle = EGL_NO_DISPLAY;
-}
+ _EGLDisplay *prev;
+ _eglLockMutex(_eglGlobal.Mutex);
-/**
- * Return the handle of a linked display, or EGL_NO_DISPLAY.
- */
-EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display)
-{
- if (display)
- return display->Handle;
- else
- return EGL_NO_DISPLAY;
-}
+ prev = _eglGlobal.DisplayList;
+ if (prev != dpy) {
+ while (prev) {
+ if (prev->Next == dpy)
+ break;
+ prev = prev->Next;
+ }
+ assert(prev);
+ prev->Next = dpy->Next;
+ }
+ else {
+ _eglGlobal.DisplayList = dpy->Next;
+ }
-
-/**
- * Lookup a handle to find the linked display.
- * Return NULL if the handle has no corresponding linked display.
- */
-_EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy)
-{
- EGLuint key = (EGLuint) dpy;
- return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
+ _eglUnlockMutex(_eglGlobal.Mutex);
}
@@ -103,19 +146,21 @@ _eglLookupDisplay(EGLDisplay dpy)
_EGLDisplay *
_eglFindDisplay(NativeDisplayType nativeDisplay)
{
- EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays);
+ _EGLDisplay *dpy;
- /* Walk the hash table. Should switch to list if it is a problem. */
- while (key) {
- _EGLDisplay *dpy = (_EGLDisplay *)
- _eglHashLookup(_eglGlobal.Displays, key);
- assert(dpy);
+ _eglLockMutex(_eglGlobal.Mutex);
- if (dpy->NativeDisplay == nativeDisplay)
+ dpy = _eglGlobal.DisplayList;
+ while (dpy) {
+ if (dpy->NativeDisplay == nativeDisplay) {
+ _eglUnlockMutex(_eglGlobal.Mutex);
return dpy;
- key = _eglHashNextEntry(_eglGlobal.Displays, key);
+ }
+ dpy = dpy->Next;
}
+ _eglUnlockMutex(_eglGlobal.Mutex);
+
return NULL;
}
@@ -124,29 +169,29 @@ _eglFindDisplay(NativeDisplayType nativeDisplay)
* Destroy the contexts and surfaces that are linked to the display.
*/
void
-_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy)
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *display)
{
- _EGLDisplay *display;
_EGLContext *contexts;
_EGLSurface *surfaces;
- display = _eglLookupDisplay(dpy);
- if (!display)
- return;
contexts = display->ContextList;
surfaces = display->SurfaceList;
while (contexts) {
- EGLContext handle = _eglGetContextHandle(contexts);
+ _EGLContext *ctx = contexts;
contexts = contexts->Next;
- drv->API.DestroyContext(drv, dpy, handle);
+
+ _eglUnlinkContext(ctx);
+ drv->API.DestroyContext(drv, display, ctx);
}
assert(!display->ContextList);
while (surfaces) {
- EGLSurface handle = _eglGetSurfaceHandle(surfaces);
+ _EGLSurface *surf = surfaces;
surfaces = surfaces->Next;
- drv->API.DestroySurface(drv, dpy, handle);
+
+ _eglUnlinkSurface(surf);
+ drv->API.DestroySurface(drv, display, surf);
}
assert(!display->SurfaceList);
}
@@ -161,18 +206,15 @@ _eglCleanupDisplay(_EGLDisplay *disp)
{
EGLint i;
- for (i = 0; i < disp->NumConfigs; i++) {
- free(disp->Configs[i]);
+ if (disp->Configs) {
+ for (i = 0; i < disp->NumConfigs; i++)
+ free(disp->Configs[i]);
+ free(disp->Configs);
+ disp->Configs = NULL;
+ disp->NumConfigs = 0;
}
- free(disp->Configs);
- disp->Configs = NULL;
/* XXX incomplete */
-
- free((void *) disp->DriverName);
- disp->DriverName = NULL;
-
- /* driver deletes the _EGLDisplay object */
}
@@ -219,46 +261,16 @@ _eglUnlinkContext(_EGLContext *ctx)
/**
- * Return the handle of a linked context, or EGL_NO_CONTEXT.
- */
-EGLContext
-_eglGetContextHandle(_EGLContext *ctx)
-{
- return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT;
-}
-
-
-/**
- * Lookup a handle to find the linked context.
- * Return NULL if the handle has no corresponding linked context.
- */
-_EGLContext *
-_eglLookupContext(EGLContext ctx)
-{
- _EGLContext *context = (_EGLContext *) ctx;
- return (context && context->Display) ? context : NULL;
-}
-
-
-/**
* Link a surface to a display and return the handle of the link.
* The handle can be passed to client directly.
*/
EGLSurface
_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
{
- EGLuint key;
-
surf->Display = dpy;
surf->Next = dpy->SurfaceList;
dpy->SurfaceList = surf;
-
- key = _eglHashGenKey(_eglGlobal.Surfaces);
- assert(key);
- _eglHashInsert(_eglGlobal.Surfaces, key, surf);
-
- surf->Handle = (EGLSurface) key;
- return surf->Handle;
+ return (EGLSurface) surf;
}
@@ -271,9 +283,6 @@ _eglUnlinkSurface(_EGLSurface *surf)
{
_EGLSurface *prev;
- _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
- surf->Handle = EGL_NO_SURFACE;
-
prev = surf->Display->SurfaceList;
if (prev != surf) {
while (prev) {
@@ -294,27 +303,69 @@ _eglUnlinkSurface(_EGLSurface *surf)
}
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
/**
- * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ * Return EGL_TRUE if the given handle is a valid handle to a display.
*/
-EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *surface)
+EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+ _EGLDisplay *cur;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+ cur = _eglGlobal.DisplayList;
+ while (cur) {
+ if (cur == (_EGLDisplay *) dpy)
+ break;
+ cur = cur->Next;
+ }
+ _eglUnlockMutex(_eglGlobal.Mutex);
+ return (cur != NULL);
+}
+
+
+/**
+ * Return EGL_TRUE if the given handle is a valid handle to a context.
+ */
+EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
{
- if (surface)
- return surface->Handle;
- else
- return EGL_NO_SURFACE;
+ _EGLContext *cur = NULL;
+
+ if (dpy)
+ cur = dpy->ContextList;
+ while (cur) {
+ if (cur == (_EGLContext *) ctx) {
+ assert(cur->Display == dpy);
+ break;
+ }
+ cur = cur->Next;
+ }
+ return (cur != NULL);
}
/**
- * Lookup a handle to find the linked surface.
- * Return NULL if the handle has no corresponding linked surface.
+ * Return EGL_TRUE if the given handle is a valid handle to a surface.
*/
-_EGLSurface *
-_eglLookupSurface(EGLSurface surf)
+EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
{
- _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
- (EGLuint) surf);
- return c;
+ _EGLSurface *cur = NULL;
+
+ if (dpy)
+ cur = dpy->SurfaceList;
+ while (cur) {
+ if (cur == (_EGLSurface *) surf) {
+ assert(cur->Display == dpy);
+ break;
+ }
+ cur = cur->Next;
+ }
+ return (cur != NULL);
}
+
+
+#endif /* !_EGL_SKIP_HANDLE_CHECK */
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 372ed3cd79..6575fdf198 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -1,21 +1,45 @@
#ifndef EGLDISPLAY_INCLUDED
#define EGLDISPLAY_INCLUDED
-#ifdef _EGL_PLATFORM_X
-#include <X11/Xlib.h>
-#endif
-
#include "egltypedefs.h"
+#include "egldefines.h"
+#include "eglcontext.h"
+#include "eglsurface.h"
+
+
+/**
+ * Optional EGL extensions info.
+ */
+struct _egl_extensions
+{
+ EGLBoolean MESA_screen_surface;
+ EGLBoolean MESA_copy_context;
+
+ char String[_EGL_MAX_EXTENSIONS_LEN];
+};
struct _egl_display
{
+ /* used to link displays */
+ _EGLDisplay *Next;
+
EGLNativeDisplayType NativeDisplay;
- EGLDisplay Handle;
const char *DriverName;
- const char *DriverArgs;
_EGLDriver *Driver;
+ void *DriverData; /* private to driver */
+
+ int APImajor, APIminor; /**< as returned by eglInitialize() */
+ char Version[1000]; /**< initialized from APImajor/minor, DriverName */
+
+ /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
+ EGLint ClientAPIsMask;
+ char ClientAPIs[1000]; /**< updated by eglQueryString */
+
+ _EGLExtensions Extensions;
+
+ int LargestPbuffer;
EGLint NumScreens;
_EGLScreen **Screens; /* array [NumScreens] */
@@ -26,12 +50,17 @@ struct _egl_display
/* lists of linked contexts and surface */
_EGLContext *ContextList;
_EGLSurface *SurfaceList;
-#ifdef _EGL_PLATFORM_X
- Display *Xdpy;
-#endif
};
+extern void
+_eglFiniDisplay(void);
+
+
+extern char *
+_eglSplitDisplayString(const char *dpyString, const char **args);
+
+
extern _EGLDisplay *
_eglNewDisplay(NativeDisplayType displayName);
@@ -44,30 +73,12 @@ extern void
_eglUnlinkDisplay(_EGLDisplay *dpy);
-extern EGLDisplay
-_eglGetDisplayHandle(_EGLDisplay *display);
-
-
-extern _EGLDisplay *
-_eglLookupDisplay(EGLDisplay dpy);
-
-
-/**
- * Return true if the display is linked.
- */
-static INLINE EGLBoolean
-_eglIsDisplayLinked(_EGLDisplay *dpy)
-{
- return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
-}
-
-
extern _EGLDisplay *
_eglFindDisplay(NativeDisplayType nativeDisplay);
extern void
-_eglReleaseDisplayResources(_EGLDriver *drv, EGLDisplay dpy);
+_eglReleaseDisplayResources(_EGLDriver *drv, _EGLDisplay *dpy);
extern void
@@ -82,37 +93,149 @@ extern void
_eglUnlinkContext(_EGLContext *ctx);
-extern EGLContext
-_eglGetContextHandle(_EGLContext *ctx);
+extern EGLSurface
+_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+
+extern void
+_eglUnlinkSurface(_EGLSurface *surf);
+
+
+#ifndef _EGL_SKIP_HANDLE_CHECK
+
+
+extern EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy);
+
+
+extern EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy);
+
+
+extern EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy);
+
+
+#else /* !_EGL_SKIP_HANDLE_CHECK */
+
+/* Only do a quick check. This is NOT standard compliant. */
+
+static INLINE EGLBoolean
+_eglCheckDisplayHandle(EGLDisplay dpy)
+{
+ return ((_EGLDisplay *) dpy != NULL);
+}
+
+
+static INLINE EGLBoolean
+_eglCheckContextHandle(EGLContext ctx, _EGLDisplay *dpy)
+{
+ _EGLContext *c = (_EGLContext *) ctx;
+ return (dpy && c && c->Display == dpy);
+}
+
+
+static INLINE EGLBoolean
+_eglCheckSurfaceHandle(EGLSurface surf, _EGLDisplay *dpy)
+{
+ _EGLSurface *s = (_EGLSurface *) surf;
+ return (dpy && s && s->Display == dpy);
+}
-extern _EGLContext *
-_eglLookupContext(EGLContext ctx);
+#endif /* _EGL_SKIP_HANDLE_CHECK */
/**
- * Return true if the context is linked to a display.
+ * Lookup a handle to find the linked display.
+ * Return NULL if the handle has no corresponding linked display.
+ */
+static INLINE _EGLDisplay *
+_eglLookupDisplay(EGLDisplay display)
+{
+ _EGLDisplay *dpy = (_EGLDisplay *) display;
+ if (!_eglCheckDisplayHandle(display))
+ dpy = NULL;
+ return dpy;
+}
+
+
+/**
+ * Return the handle of a linked display, or EGL_NO_DISPLAY.
+ */
+static INLINE EGLDisplay
+_eglGetDisplayHandle(_EGLDisplay *dpy)
+{
+ return (EGLDisplay) ((dpy) ? dpy : EGL_NO_DISPLAY);
+}
+
+
+/**
+ * Return true if the display is linked.
*/
static INLINE EGLBoolean
-_eglIsContextLinked(_EGLContext *ctx)
+_eglIsDisplayLinked(_EGLDisplay *dpy)
{
- return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+ return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY);
}
-extern EGLSurface
-_eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy);
+
+/**
+ * Lookup a handle to find the linked context.
+ * Return NULL if the handle has no corresponding linked context.
+ */
+static INLINE _EGLContext *
+_eglLookupContext(EGLContext context, _EGLDisplay *dpy)
+{
+ _EGLContext *ctx = (_EGLContext *) context;
+ if (!_eglCheckContextHandle(context, dpy))
+ ctx = NULL;
+ return ctx;
+}
-extern void
-_eglUnlinkSurface(_EGLSurface *surf);
+/**
+ * Return the handle of a linked context, or EGL_NO_CONTEXT.
+ */
+static INLINE EGLContext
+_eglGetContextHandle(_EGLContext *ctx)
+{
+ return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT);
+}
-extern EGLSurface
-_eglGetSurfaceHandle(_EGLSurface *);
+/**
+ * Return true if the context is linked to a display.
+ */
+static INLINE EGLBoolean
+_eglIsContextLinked(_EGLContext *ctx)
+{
+ return (EGLBoolean) (_eglGetContextHandle(ctx) != EGL_NO_CONTEXT);
+}
+
+
+/**
+ * Lookup a handle to find the linked surface.
+ * Return NULL if the handle has no corresponding linked surface.
+ */
+static INLINE _EGLSurface *
+_eglLookupSurface(EGLSurface surface, _EGLDisplay *dpy)
+{
+ _EGLSurface *surf = (_EGLSurface *) surface;
+ if (!_eglCheckSurfaceHandle(surf, dpy))
+ surf = NULL;
+ return surf;
+}
-extern _EGLSurface *
-_eglLookupSurface(EGLSurface surf);
+/**
+ * Return the handle of a linked surface, or EGL_NO_SURFACE.
+ */
+static INLINE EGLSurface
+_eglGetSurfaceHandle(_EGLSurface *surf)
+{
+ return (EGLSurface) ((surf && surf->Display) ? surf : EGL_NO_SURFACE);
+}
/**
@@ -125,4 +248,25 @@ _eglIsSurfaceLinked(_EGLSurface *surf)
}
+/**
+ * Cast an unsigned int to a pointer.
+ */
+static INLINE void *
+_eglUIntToPointer(unsigned int v)
+{
+ return (void *) ((uintptr_t) v);
+}
+
+
+/**
+ * Cast a pointer to an unsigned int. The pointer must be one that is
+ * returned by _eglUIntToPointer.
+ */
+static INLINE unsigned int
+_eglPointerToUInt(const void *p)
+{
+ return (unsigned int) ((uintptr_t) p);
+}
+
+
#endif /* EGLDISPLAY_INCLUDED */
diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c
index f2a864cd8a..87786e36bb 100644
--- a/src/egl/main/egldriver.c
+++ b/src/egl/main/egldriver.c
@@ -22,7 +22,6 @@
#if defined(_EGL_PLATFORM_X)
#include <dlfcn.h>
-#include "eglx.h"
#elif defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
#define WINDOWS_STATIC_LINK
@@ -38,7 +37,6 @@
/* XXX Need to decide how to do dynamic name lookup on Windows */
static const char *DefaultDriverName = "TBD";
#endif
- static const char *SysFS = NULL;
typedef HMODULE lib_handle;
static HMODULE
@@ -61,8 +59,7 @@
}
#elif defined(_EGL_PLATFORM_X)
- static const char *DefaultDriverName = ":0";
- static const char *SysFS = "/sys/class";
+ static const char *DefaultDriverName = "egl_softpipe";
typedef void * lib_handle;
@@ -80,142 +77,69 @@
#endif
-/**
- * Given a card number, use sysfs to determine the DRI driver name.
- */
-const char *
-_eglChooseDRMDriver(int card)
-{
-#if 0
- return _eglstrdup("libEGLdri");
-#else
- char path[2000], driverName[2000];
- FILE *f;
- int length;
-
- snprintf(path, sizeof(path), "%s/drm/card%d/dri_library_name", SysFS, card);
-
- f = fopen(path, "r");
- if (!f)
- return NULL;
-
- fgets(driverName, sizeof(driverName), f);
- fclose(f);
-
- if ((length = strlen(driverName)) > 1) {
- /* remove the trailing newline from sysfs */
- driverName[length - 1] = '\0';
- strncat(driverName, "_dri", sizeof(driverName));
- return _eglstrdup(driverName);
- }
- else {
- return NULL;
- }
-#endif
-}
/**
- * XXX this function is totally subject change!!!
- *
- *
- * Determine/return the name of the driver to use for the given _EGLDisplay.
- *
- * Try to be clever and determine if nativeDisplay is an Xlib Display
- * ptr or a string (naming a driver or screen number, etc).
- *
- * If the first character is ':' we interpret it as a screen or card index
- * number (i.e. ":0" or ":1", etc)
- * Else if the first character is '!' we interpret it as specific driver name
- * (i.e. "!r200" or "!i830".
- *
- * Whatever follows ':' is copied and put into dpy->DriverArgs.
- *
- * The caller may free() the returned string.
+ * Choose a driver for a given display.
+ * The caller may free() the returned strings.
*/
-const char *
-_eglChooseDriver(_EGLDisplay *dpy)
+static char *
+_eglChooseDriver(_EGLDisplay *dpy, char **argsRet)
{
- /* Under Windows, the NativeDisplay is an HDC handle, therefore */
- /* it can't be interpreted as a string or a pointer. */
-#if defined(_EGL_PLATFORM_WINDOWS)
- const char *displayString = NULL;
-#else
- const char *displayString = (const char *) dpy->NativeDisplay;
-#endif
- const char *driverName = NULL;
+ char *path = NULL;
+ const char *args = NULL;
+ const char *suffix = NULL;
+ const char *p;
- (void) DefaultDriverName;
+ path = getenv("EGL_DRIVER");
+ if (path)
+ path = _eglstrdup(path);
#if defined(_EGL_PLATFORM_X)
- /* First, if the EGL_DRIVER env var is set, use that */
- driverName = getenv("EGL_DRIVER");
- if (driverName)
- return _eglstrdup(driverName);
-#endif
-
-#if 0
- if (!displayString) {
- /* choose a default */
- displayString = DefaultDriverName;
- }
-#endif
- /* extract default DriverArgs = whatever follows ':' */
- if (displayString &&
- (displayString[0] == '!' ||
- displayString[0] == ':')) {
- const char *args = strchr(displayString, ':');
- if (args)
- dpy->DriverArgs = _eglstrdup(args + 1);
+ if (!path && dpy->NativeDisplay) {
+ /* assume (wrongly!) that the native display is a display string */
+ path = _eglSplitDisplayString((const char *) dpy->NativeDisplay, &args);
}
-
- /* determine driver name now */
- if (displayString && displayString[0] == ':' &&
- (displayString[1] >= '0' && displayString[1] <= '9') &&
- !displayString[2]) {
- int card = atoi(displayString + 1);
- driverName = _eglChooseDRMDriver(card);
- }
- else if (displayString && displayString[0] == '!') {
- /* use user-specified driver name */
- driverName = _eglstrdup(displayString + 1);
- /* truncate driverName at ':' if present */
- {
- char *args = strchr(driverName, ':');
- if (args) {
- *args = 0;
- }
+ suffix = "so";
+#elif defined(_EGL_PLATFORM_WINDOWS)
+ suffix = "dll";
+#endif /* _EGL_PLATFORM_X */
+
+ if (!path)
+ path = _eglstrdup(DefaultDriverName);
+
+ /* append suffix if there isn't */
+ p = strrchr(path, '.');
+ if (!p && suffix) {
+ size_t len = strlen(path);
+ char *tmp = malloc(len + strlen(suffix) + 2);
+ if (tmp) {
+ memcpy(tmp, path, len);
+ tmp[len++] = '.';
+ tmp[len] = '\0';
+ strcat(tmp + len, suffix);
+
+ free(path);
+ path = tmp;
}
}
- else
- {
- /* NativeDisplay is not a string! */
-#if defined(_EGL_PLATFORM_X)
- driverName = _xeglChooseDriver(dpy);
-#else
- driverName = DefaultDriverName;
-#endif
- }
- return driverName;
+ if (argsRet)
+ *argsRet = (args) ? _eglstrdup(args) : NULL;
+
+ return path;
}
/**
- * Open/load the named driver and call its bootstrap function: _eglMain().
- * By the time this function is called, the dpy->DriverName should have
- * been determined.
- *
- * \return new _EGLDriver object.
+ * Open the named driver and find its bootstrap function: _eglMain().
*/
-_EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
+static _EGLMain_t
+_eglOpenLibrary(const char *driverPath, lib_handle *handle)
{
- _EGLDriver *drv;
_EGLMain_t mainFunc;
lib_handle lib;
- char driverFilename[1000];
- assert(driverName);
+ assert(driverPath);
#if defined(_EGL_PLATFORM_WINDOWS)
/* Use static linking on Windows for now */
@@ -224,83 +148,190 @@ _eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args)
mainFunc = (_EGLMain_t)_eglMain;
#else
/* XXX untested */
- sprintf(driverFilename, "%s.dll", driverName);
- _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
- lib = open_library(driverFilename);
+ _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+ lib = open_library(driverPath);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s",
- driverFilename);
+ driverPath);
return NULL;
}
mainFunc = (_EGLMain_t) GetProcAddress(lib, "_eglMain");
#endif
#elif defined(_EGL_PLATFORM_X)
- /* XXX also prepend a directory path??? */
- sprintf(driverFilename, "%s.so", driverName);
- _eglLog(_EGL_DEBUG, "dlopen(%s)", driverFilename);
- lib = open_library(driverFilename);
+ _eglLog(_EGL_DEBUG, "dlopen(%s)", driverPath);
+ lib = open_library(driverPath);
if (!lib) {
_eglLog(_EGL_WARNING, "Could not open %s (%s)",
- driverFilename, dlerror());
+ driverPath, dlerror());
+ if (!getenv("EGL_DRIVER"))
+ _eglLog(_EGL_WARNING,
+ "The driver can be overridden by setting EGL_DRIVER");
return NULL;
}
mainFunc = (_EGLMain_t) dlsym(lib, "_eglMain");
#endif
if (!mainFunc) {
- _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverFilename);
- close_library(lib);
+ _eglLog(_EGL_WARNING, "_eglMain not found in %s", driverPath);
+ if (lib)
+ close_library(lib);
return NULL;
}
- drv = mainFunc(dpy, args);
+ *handle = lib;
+ return mainFunc;
+}
+
+
+/**
+ * Load the named driver. The path and args passed will be
+ * owned by the driver and freed.
+ */
+static _EGLDriver *
+_eglLoadDriver(char *path, char *args)
+{
+ _EGLMain_t mainFunc;
+ lib_handle lib;
+ _EGLDriver *drv = NULL;
+
+ mainFunc = _eglOpenLibrary(path, &lib);
+ if (!mainFunc)
+ return NULL;
+
+ drv = mainFunc(args);
if (!drv) {
- close_library(lib);
+ if (lib)
+ close_library(lib);
return NULL;
}
- /* with a recurvise open you want the inner most handle */
- if (!drv->LibHandle) {
- drv->LibHandle = lib;
- }
- else {
- close_library(lib);
+ if (!drv->Name) {
+ _eglLog(_EGL_WARNING, "Driver loaded from %s has no name", path);
+ drv->Name = "UNNAMED";
}
- /* update the global notion of supported APIs */
- _eglGlobal.ClientAPIsMask |= drv->ClientAPIsMask;
-
- _eglSaveDriver(drv);
+ drv->Path = path;
+ drv->Args = args;
+ drv->LibHandle = lib;
return drv;
}
-EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy)
+/**
+ * Match a display to a preloaded driver.
+ */
+static _EGLDriver *
+_eglMatchDriver(_EGLDisplay *dpy)
+{
+ _EGLDriver *defaultDriver = NULL;
+ EGLint i;
+
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
+
+ /* display specifies a driver */
+ if (dpy->DriverName) {
+ if (strcmp(dpy->DriverName, drv->Name) == 0)
+ return drv;
+ }
+ else if (drv->Probe) {
+ if (drv->Probe(drv, dpy))
+ return drv;
+ }
+ else {
+ if (!defaultDriver)
+ defaultDriver = drv;
+ }
+ }
+
+ return defaultDriver;
+}
+
+
+/**
+ * Load a driver and save it.
+ */
+const char *
+_eglPreloadDriver(_EGLDisplay *dpy)
{
- void *handle = drv->LibHandle;
- EGLBoolean b;
+ char *path, *args;
+ _EGLDriver *drv;
+ EGLint i;
+
+ path = _eglChooseDriver(dpy, &args);
+ if (!path)
+ return NULL;
- _eglLog(_EGL_DEBUG, "Closing %s", drv->Name);
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ drv = _eglGlobal.Drivers[i];
+ if (strcmp(drv->Path, path) == 0) {
+ _eglLog(_EGL_DEBUG, "Driver %s is already preloaded",
+ drv->Name);
+ free(path);
+ if (args)
+ free(args);
+ return drv->Name;
+ }
+ }
- _eglReleaseDisplayResources(drv, dpy);
+ drv = _eglLoadDriver(path, args);
+ if (!drv)
+ return NULL;
- b = drv->API.Terminate(drv, dpy);
+ _eglGlobal.Drivers[_eglGlobal.NumDrivers++] = drv;
+
+ return drv->Name;
+}
+
+
+/**
+ * Open a preloaded driver.
+ */
+_EGLDriver *
+_eglOpenDriver(_EGLDisplay *dpy)
+{
+ _EGLDriver *drv = _eglMatchDriver(dpy);
+ return drv;
+}
- close_library(handle);
- return b;
+/**
+ * Close a preloaded driver.
+ */
+EGLBoolean
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy)
+{
+ return EGL_TRUE;
}
/**
- * Save the given driver pointer in the list of all known drivers.
+ * Unload preloaded drivers.
*/
void
-_eglSaveDriver(_EGLDriver *drv)
+_eglUnloadDrivers(void)
{
- _eglGlobal.Drivers[ _eglGlobal.NumDrivers++ ] = drv;
+ EGLint i;
+ for (i = 0; i < _eglGlobal.NumDrivers; i++) {
+ _EGLDriver *drv = _eglGlobal.Drivers[i];
+ lib_handle handle = drv->LibHandle;
+
+ if (drv->Path)
+ free((char *) drv->Path);
+ if (drv->Args)
+ free((char *) drv->Args);
+
+ /* destroy driver */
+ if (drv->Unload)
+ drv->Unload(drv);
+
+ if (handle)
+ close_library(handle);
+ _eglGlobal.Drivers[i] = NULL;
+ }
+
+ _eglGlobal.NumDrivers = 0;
}
diff --git a/src/egl/main/egldriver.h b/src/egl/main/egldriver.h
index 4066c6ec1d..6c848eb35e 100644
--- a/src/egl/main/egldriver.h
+++ b/src/egl/main/egldriver.h
@@ -4,19 +4,6 @@
#include "egltypedefs.h"
#include "eglapi.h"
-#include "egldefines.h"
-
-
-/**
- * Optional EGL extensions info.
- */
-struct _egl_extensions
-{
- EGLBoolean MESA_screen_surface;
- EGLBoolean MESA_copy_context;
-
- char String[_EGL_MAX_EXTENSIONS_LEN];
-};
/**
@@ -24,46 +11,37 @@ struct _egl_extensions
*/
struct _egl_driver
{
- EGLBoolean Initialized; /**< set by driver after initialized */
-
void *LibHandle; /**< dlopen handle */
+ const char *Path; /**< path to this driver */
+ const char *Args; /**< args to load this driver */
const char *Name; /**< name of this driver */
-
- int APImajor, APIminor; /**< as returned by eglInitialize() */
- char Version[1000]; /**< initialized from APImajor/minor, Name */
-
- /** Bitmask of supported APIs (EGL_xx_BIT) set by the driver during init */
- EGLint ClientAPIsMask;
+ /**< probe a display to see if it is supported */
+ EGLBoolean (*Probe)(_EGLDriver *drv, _EGLDisplay *dpy);
+ /**< called before dlclose to release this driver */
+ void (*Unload)(_EGLDriver *drv);
_EGLAPI API; /**< EGL API dispatch table */
-
- _EGLExtensions Extensions;
-
- int LargestPbuffer;
};
-extern _EGLDriver *_eglMain(_EGLDisplay *dpy, const char *args);
+extern _EGLDriver *_eglMain(const char *args);
extern const char *
-_eglChooseDRMDriver(int card);
-
-extern const char *
-_eglChooseDriver(_EGLDisplay *dpy);
+_eglPreloadDriver(_EGLDisplay *dpy);
extern _EGLDriver *
-_eglOpenDriver(_EGLDisplay *dpy, const char *driverName, const char *args);
+_eglOpenDriver(_EGLDisplay *dpy);
extern EGLBoolean
-_eglCloseDriver(_EGLDriver *drv, EGLDisplay dpy);
+_eglCloseDriver(_EGLDriver *drv, _EGLDisplay *dpy);
-extern void
-_eglSaveDriver(_EGLDriver *drv);
+void
+_eglUnloadDrivers(void);
extern _EGLDriver *
diff --git a/src/egl/main/eglglobals.c b/src/egl/main/eglglobals.c
index 55de394ef5..3ae4c1ad3a 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,41 +1,56 @@
#include <stdlib.h>
+#include <assert.h>
#include "eglglobals.h"
+#include "egldriver.h"
#include "egllog.h"
+#include "eglmutex.h"
-struct _egl_global _eglGlobal =
-{
- EGL_FALSE
-};
-/**
- * Init the fields in the _eglGlobal struct
- * May be safely called more than once.
- */
-void
-_eglInitGlobals(void)
+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
+
+
+static _EGL_DECLARE_MUTEX(_eglGlobalMutex);
+struct _egl_global _eglGlobal =
{
- if (!_eglGlobal.Initialized) {
- _eglGlobal.Displays = _eglNewHashTable();
- _eglGlobal.Surfaces = _eglNewHashTable();
- _eglGlobal.FreeScreenHandle = 1;
- _eglGlobal.Initialized = EGL_TRUE;
+ &_eglGlobalMutex, /* Mutex */
+ NULL, /* DisplayList */
+ 1, /* FreeScreenHandle */
+ 0x0, /* ClientAPIsMask */
+ 0, /* NumDrivers */
+ { NULL }, /* Drivers */
+ 2, /* NumAtExitCalls */
+ { /* AtExitCalls */
+ _eglFiniDisplay,
+ _eglUnloadDrivers
+ },
+};
- _eglGlobal.ClientAPIsMask = 0x0;
- if (!_eglInitCurrent())
- _eglLog(_EGL_FATAL, "failed to initialize \"current\" system");
- }
+static void
+_eglAtExit(void)
+{
+ EGLint i;
+ for (i = _eglGlobal.NumAtExitCalls - 1; i >= 0; i--)
+ _eglGlobal.AtExitCalls[i]();
}
-/**
- * Should call this via an atexit handler.
- */
void
-_eglDestroyGlobals(void)
+_eglAddAtExitCall(void (*func)(void))
{
- _eglFiniCurrent();
- /* XXX TODO walk over table entries, deleting each */
- _eglDeleteHashTable(_eglGlobal.Displays);
- _eglDeleteHashTable(_eglGlobal.Surfaces);
+ if (func) {
+ static EGLBoolean registered = EGL_FALSE;
+
+ _eglLockMutex(_eglGlobal.Mutex);
+
+ if (!registered) {
+ atexit(_eglAtExit);
+ registered = EGL_TRUE;
+ }
+
+ assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls));
+ _eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func;
+
+ _eglUnlockMutex(_eglGlobal.Mutex);
+ }
}
diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h
index a9443cfbdd..58511076d4 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -2,8 +2,9 @@
#define EGLGLOBALS_INCLUDED
#include "egltypedefs.h"
-#include "eglhash.h"
+#include "egldisplay.h"
#include "eglcurrent.h"
+#include "eglmutex.h"
/**
@@ -11,21 +12,21 @@
*/
struct _egl_global
{
- EGLBoolean Initialized;
+ _EGLMutex *Mutex;
- /* these are private to egldisplay.c */
- _EGLHashtable *Displays;
- _EGLHashtable *Surfaces;
+ /* the list of all displays */
+ _EGLDisplay *DisplayList;
EGLScreenMESA FreeScreenHandle;
/* bitmaks of supported APIs (supported by _some_ driver) */
EGLint ClientAPIsMask;
- char ClientAPIs[1000]; /**< updated by eglQueryString */
-
EGLint NumDrivers;
_EGLDriver *Drivers[10];
+
+ EGLint NumAtExitCalls;
+ void (*AtExitCalls[10])(void);
};
@@ -33,11 +34,7 @@ extern struct _egl_global _eglGlobal;
extern void
-_eglInitGlobals(void);
-
-
-extern void
-_eglDestroyGlobals(void);
+_eglAddAtExitCall(void (*func)(void));
#endif /* EGLGLOBALS_INCLUDED */
diff --git a/src/egl/main/eglhash.c b/src/egl/main/eglhash.c
deleted file mode 100644
index 8e3da2e906..0000000000
--- a/src/egl/main/eglhash.c
+++ /dev/null
@@ -1,347 +0,0 @@
-/**
- * \file hash.c
- * Generic hash table.
- *
- * This code taken from Mesa and adapted.
- */
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include "eglhash.h"
-
-
-#define TABLE_SIZE 1023 /**< Size of lookup table/array */
-
-#define HASH_FUNC(K) ((K) % TABLE_SIZE)
-
-
-/*
- * Unfinished mutex stuff
- */
-
-typedef int _EGLMutex;
-
-static void
-_eglInitMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglDestroyMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglLockMutex(_EGLMutex m)
-{
-}
-
-static void
-_eglUnlockMutex(_EGLMutex m)
-{
-}
-
-
-
-typedef struct _egl_hashentry _EGLHashentry;
-
-struct _egl_hashentry
-{
- EGLuint Key; /**< the entry's key */
- void *Data; /**< the entry's data */
- _EGLHashentry *Next; /**< pointer to next entry */
-};
-
-
-struct _egl_hashtable
-{
- _EGLHashentry *Table[TABLE_SIZE]; /**< the lookup table */
- EGLuint MaxKey; /**< highest key inserted so far */
- _EGLMutex Mutex; /**< mutual exclusion lock */
-};
-
-
-/**
- * Create a new hash table.
- *
- * \return pointer to a new, empty hash table.
- */
-_EGLHashtable *
-_eglNewHashTable(void)
-{
- _EGLHashtable *table = (_EGLHashtable *) calloc(1, sizeof(_EGLHashtable));
- if (table) {
- _eglInitMutex(table->Mutex);
- table->MaxKey = 1;
- }
- return table;
-}
-
-
-
-/**
- * Delete a hash table.
- * Frees each entry on the hash table and then the hash table structure itself.
- * Note that the caller should have already traversed the table and deleted
- * the objects in the table (i.e. We don't free the entries' data pointer).
- *
- * \param table the hash table to delete.
- */
-void
-_eglDeleteHashTable(_EGLHashtable *table)
-{
- EGLuint i;
- assert(table);
- for (i = 0; i < TABLE_SIZE; i++) {
- _EGLHashentry *entry = table->Table[i];
- while (entry) {
- _EGLHashentry *next = entry->Next;
- free(entry);
- entry = next;
- }
- }
- _eglDestroyMutex(table->Mutex);
- free(table);
-}
-
-
-
-/**
- * Lookup an entry in the hash table.
- *
- * \param table the hash table.
- * \param key the key.
- *
- * \return pointer to user's data or NULL if key not in table
- */
-void *
-_eglHashLookup(const _EGLHashtable *table, EGLuint key)
-{
- EGLuint pos;
- const _EGLHashentry *entry;
-
- assert(table);
-
- if (!key)
- return NULL;
-
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- return entry->Data;
- }
- entry = entry->Next;
- }
- return NULL;
-}
-
-
-
-/**
- * Insert a key/pointer pair into the hash table.
- * If an entry with this key already exists we'll replace the existing entry.
- *
- * \param table the hash table.
- * \param key the key (not zero).
- * \param data pointer to user data.
- */
-void
-_eglHashInsert(_EGLHashtable *table, EGLuint key, void *data)
-{
- /* search for existing entry with this key */
- EGLuint pos;
- _EGLHashentry *entry;
-
- assert(table);
- assert(key);
-
- _eglLockMutex(table->Mutex);
-
- if (key > table->MaxKey)
- table->MaxKey = key;
-
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- /* replace entry's data */
- entry->Data = data;
- _eglUnlockMutex(table->Mutex);
- return;
- }
- entry = entry->Next;
- }
-
- /* alloc and insert new table entry */
- entry = (_EGLHashentry *) malloc(sizeof(_EGLHashentry));
- entry->Key = key;
- entry->Data = data;
- entry->Next = table->Table[pos];
- table->Table[pos] = entry;
-
- _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Remove an entry from the hash table.
- *
- * \param table the hash table.
- * \param key key of entry to remove.
- *
- * While holding the hash table's lock, searches the entry with the matching
- * key and unlinks it.
- */
-void
-_eglHashRemove(_EGLHashtable *table, EGLuint key)
-{
- EGLuint pos;
- _EGLHashentry *entry, *prev;
-
- assert(table);
- assert(key);
-
- _eglLockMutex(table->Mutex);
-
- pos = HASH_FUNC(key);
- prev = NULL;
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- /* found it! */
- if (prev) {
- prev->Next = entry->Next;
- }
- else {
- table->Table[pos] = entry->Next;
- }
- free(entry);
- _eglUnlockMutex(table->Mutex);
- return;
- }
- prev = entry;
- entry = entry->Next;
- }
-
- _eglUnlockMutex(table->Mutex);
-}
-
-
-
-/**
- * Get the key of the "first" entry in the hash table.
- *
- * This is used in the course of deleting all display lists when
- * a context is destroyed.
- *
- * \param table the hash table
- *
- * \return key for the "first" entry in the hash table.
- *
- * While holding the lock, walks through all table positions until finding
- * the first entry of the first non-empty one.
- */
-EGLuint
-_eglHashFirstEntry(_EGLHashtable *table)
-{
- EGLuint pos;
- assert(table);
- _eglLockMutex(table->Mutex);
- for (pos = 0; pos < TABLE_SIZE; pos++) {
- if (table->Table[pos]) {
- _eglUnlockMutex(table->Mutex);
- return table->Table[pos]->Key;
- }
- }
- _eglUnlockMutex(table->Mutex);
- return 0;
-}
-
-
-/**
- * Given a hash table key, return the next key. This is used to walk
- * over all entries in the table. Note that the keys returned during
- * walking won't be in any particular order.
- * \return next hash key or 0 if end of table.
- */
-EGLuint
-_eglHashNextEntry(const _EGLHashtable *table, EGLuint key)
-{
- const _EGLHashentry *entry;
- EGLuint pos;
-
- assert(table);
- assert(key);
-
- /* Find the entry with given key */
- pos = HASH_FUNC(key);
- entry = table->Table[pos];
- while (entry) {
- if (entry->Key == key) {
- break;
- }
- entry = entry->Next;
- }
-
- if (!entry) {
- /* the key was not found, we can't find next entry */
- return 0;
- }
-
- if (entry->Next) {
- /* return next in linked list */
- return entry->Next->Key;
- }
- else {
- /* look for next non-empty table slot */
- pos++;
- while (pos < TABLE_SIZE) {
- if (table->Table[pos]) {
- return table->Table[pos]->Key;
- }
- pos++;
- }
- return 0;
- }
-}
-
-
-/**
- * Dump contents of hash table for debugging.
- *
- * \param table the hash table.
- */
-void
-_eglHashPrint(const _EGLHashtable *table)
-{
- EGLuint i;
- assert(table);
- for (i = 0; i < TABLE_SIZE; i++) {
- const _EGLHashentry *entry = table->Table[i];
- while (entry) {
- printf("%u %p\n", entry->Key, entry->Data);
- entry = entry->Next;
- }
- }
-}
-
-
-
-/**
- * Return a new, unused hash key.
- */
-EGLuint
-_eglHashGenKey(_EGLHashtable *table)
-{
- EGLuint k;
-
- _eglLockMutex(table->Mutex);
- k = table->MaxKey;
- table->MaxKey++;
- _eglUnlockMutex(table->Mutex);
- return k;
-}
-
diff --git a/src/egl/main/eglhash.h b/src/egl/main/eglhash.h
deleted file mode 100644
index 1d6db9598c..0000000000
--- a/src/egl/main/eglhash.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * \file eglhash.h
- * Generic hash table.
- */
-
-
-#ifndef EGLHASH_INCLUDED
-#define EGLHASH_INCLUDED
-
-
-/* XXX move this? */
-typedef unsigned int EGLuint;
-
-
-typedef struct _egl_hashtable _EGLHashtable;
-
-
-extern _EGLHashtable *_eglNewHashTable(void);
-
-extern void _eglDeleteHashTable(_EGLHashtable *table);
-
-extern void *_eglHashLookup(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashInsert(_EGLHashtable *table, EGLuint key, void *data);
-
-extern void _eglHashRemove(_EGLHashtable *table, EGLuint key);
-
-extern EGLuint _eglHashFirstEntry(_EGLHashtable *table);
-
-extern EGLuint _eglHashNextEntry(const _EGLHashtable *table, EGLuint key);
-
-extern void _eglHashPrint(const _EGLHashtable *table);
-
-extern EGLuint _eglHashGenKey(_EGLHashtable *table);
-
-extern void _egltest_hash_functions(void);
-
-
-#endif /* EGLHASH_INCLUDED */
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index b5bdc3ea4b..b37213faf1 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -35,6 +35,7 @@
#include <string.h>
#include "eglglobals.h"
#include "eglmisc.h"
+#include "egldisplay.h"
/**
@@ -42,42 +43,47 @@
* the driver's Extensions string.
*/
static void
-_eglUpdateExtensionsString(_EGLDriver *drv)
+_eglUpdateExtensionsString(_EGLDisplay *dpy)
{
- drv->Extensions.String[0] = 0;
+ char *exts = dpy->Extensions.String;
- if (drv->Extensions.MESA_screen_surface)
- strcat(drv->Extensions.String, "EGL_MESA_screen_surface ");
- if (drv->Extensions.MESA_copy_context)
- strcat(drv->Extensions.String, "EGL_MESA_copy_context ");
- assert(strlen(drv->Extensions.String) < _EGL_MAX_EXTENSIONS_LEN);
+ if (exts[0])
+ return;
+
+ if (dpy->Extensions.MESA_screen_surface)
+ strcat(exts, "EGL_MESA_screen_surface ");
+ if (dpy->Extensions.MESA_copy_context)
+ strcat(exts, "EGL_MESA_copy_context ");
+ assert(strlen(exts) < _EGL_MAX_EXTENSIONS_LEN);
}
static void
-_eglUpdateAPIsString(_EGLDriver *drv)
+_eglUpdateAPIsString(_EGLDisplay *dpy)
{
- _eglGlobal.ClientAPIs[0] = 0;
+ char *apis = dpy->ClientAPIs;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL ");
+ if (apis[0] || !dpy->ClientAPIsMask)
+ return;
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_BIT)
+ strcat(apis, "OpenGL ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENGL_ES2_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenGL_ES2 ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES_BIT)
+ strcat(apis, "OpenGL_ES ");
- if (_eglGlobal.ClientAPIsMask & EGL_OPENVG_BIT)
- strcat(_eglGlobal.ClientAPIs, "OpenVG ");
+ if (dpy->ClientAPIsMask & EGL_OPENGL_ES2_BIT)
+ strcat(apis, "OpenGL_ES2 ");
- assert(strlen(_eglGlobal.ClientAPIs) < sizeof(_eglGlobal.ClientAPIs));
-}
+ if (dpy->ClientAPIsMask & EGL_OPENVG_BIT)
+ strcat(apis, "OpenVG ");
+ assert(strlen(apis) < sizeof(dpy->ClientAPIs));
+}
const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name)
{
(void) drv;
(void) dpy;
@@ -85,14 +91,14 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
case EGL_VENDOR:
return _EGL_VENDOR_STRING;
case EGL_VERSION:
- return drv->Version;
+ return dpy->Version;
case EGL_EXTENSIONS:
- _eglUpdateExtensionsString(drv);
- return drv->Extensions.String;
+ _eglUpdateExtensionsString(dpy);
+ return dpy->Extensions.String;
#ifdef EGL_VERSION_1_2
case EGL_CLIENT_APIS:
- _eglUpdateAPIsString(drv);
- return _eglGlobal.ClientAPIs;
+ _eglUpdateAPIsString(dpy);
+ return dpy->ClientAPIs;
#endif
default:
_eglError(EGL_BAD_PARAMETER, "eglQueryString");
@@ -102,7 +108,7 @@ _eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name)
EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy)
{
/* just a placeholder */
(void) drv;
@@ -112,7 +118,7 @@ _eglWaitGL(_EGLDriver *drv, EGLDisplay dpy)
EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine)
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine)
{
/* just a placeholder */
(void) drv;
diff --git a/src/egl/main/eglmisc.h b/src/egl/main/eglmisc.h
index 4e2a40ea99..a15c839be2 100644
--- a/src/egl/main/eglmisc.h
+++ b/src/egl/main/eglmisc.h
@@ -33,15 +33,15 @@
extern const char *
-_eglQueryString(_EGLDriver *drv, EGLDisplay dpy, EGLint name);
+_eglQueryString(_EGLDriver *drv, _EGLDisplay *dpy, EGLint name);
extern EGLBoolean
-_eglWaitGL(_EGLDriver *drv, EGLDisplay dpy);
+_eglWaitGL(_EGLDriver *drv, _EGLDisplay *dpy);
extern EGLBoolean
-_eglWaitNative(_EGLDriver *drv, EGLDisplay dpy, EGLint engine);
+_eglWaitNative(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine);
#endif /* EGLMISC_INCLUDED */
diff --git a/src/egl/main/eglmode.c b/src/egl/main/eglmode.c
index 786432234b..0f3ba6e5c0 100644
--- a/src/egl/main/eglmode.c
+++ b/src/egl/main/eglmode.c
@@ -34,9 +34,8 @@ my_strdup(const char *s)
* or null if non-existant.
*/
_EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode)
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *disp)
{
- const _EGLDisplay *disp = _eglLookupDisplay(dpy);
EGLint scrnum;
/* loop over all screens on the display */
@@ -272,19 +271,13 @@ _eglCompareModes(const void *a, const void *b)
* Called via eglChooseModeMESA API function.
*/
EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
_EGLMode **modeList, min;
EGLint i, count;
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglChooseModeMESA");
- return EGL_FALSE;
- }
-
if (!_eglParseModeAttribs(&min, attrib_list)) {
/* error code will have been recorded */
return EGL_FALSE;
@@ -326,16 +319,9 @@ _eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Called via eglGetModesMESA() API function.
*/
EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglGetModesMESA");
- return EGL_FALSE;
- }
-
if (modes) {
EGLint i;
*num_modes = MIN2(scrn->NumModes, modes_size);
@@ -356,17 +342,11 @@ _eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Query an attribute of a mode.
*/
EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLModeMESA mode, EGLint attribute, EGLint *value)
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLMode *m, EGLint attribute, EGLint *value)
{
- _EGLMode *m = _eglLookupMode(dpy, mode);
EGLint v;
- if (!m) {
- _eglError(EGL_BAD_MODE_MESA, "eglGetModeAttribMESA");
- return EGL_FALSE;
- }
-
v = getModeAttrib(m, attribute);
if (v < 0) {
_eglError(EGL_BAD_ATTRIBUTE, "eglGetModeAttribMESA");
@@ -382,13 +362,8 @@ _eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy,
* This is the default function called by eglQueryModeStringMESA().
*/
const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode)
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m)
{
- _EGLMode *m = _eglLookupMode(dpy, mode);
- if (!m) {
- _eglError(EGL_BAD_MODE_MESA, "eglQueryModeStringMESA");
- return NULL;
- }
return m->Name;
}
diff --git a/src/egl/main/eglmode.h b/src/egl/main/eglmode.h
index 52d4875676..af7c2c56d3 100644
--- a/src/egl/main/eglmode.h
+++ b/src/egl/main/eglmode.h
@@ -26,7 +26,7 @@ struct _egl_mode
extern _EGLMode *
-_eglLookupMode(EGLDisplay dpy, EGLModeMESA mode);
+_eglLookupMode(EGLModeMESA mode, _EGLDisplay *dpy);
extern _EGLMode *
@@ -35,23 +35,23 @@ _eglAddNewMode(_EGLScreen *screen, EGLint width, EGLint height,
extern EGLBoolean
-_eglChooseModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglChooseModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
const EGLint *attrib_list, EGLModeMESA *modes,
EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
-_eglGetModesMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglGetModesMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes);
extern EGLBoolean
-_eglGetModeAttribMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode,
+_eglGetModeAttribMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m,
EGLint attribute, EGLint *value);
extern const char *
-_eglQueryModeStringMESA(_EGLDriver *drv, EGLDisplay dpy, EGLModeMESA mode);
+_eglQueryModeStringMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLMode *m);
#endif /* EGLMODE_INCLUDED */
diff --git a/src/egl/main/eglmutex.h b/src/egl/main/eglmutex.h
new file mode 100644
index 0000000000..29faba0f24
--- /dev/null
+++ b/src/egl/main/eglmutex.h
@@ -0,0 +1,52 @@
+#ifndef EGLMUTEX_INCLUDED
+#define EGLMUTEX_INCLUDED
+
+#include "eglcompiler.h"
+
+#ifdef PTHREADS
+#include <pthread.h>
+
+typedef pthread_mutex_t _EGLMutex;
+
+static INLINE void _eglInitMutex(_EGLMutex *m)
+{
+ pthread_mutex_init(m, NULL);
+}
+
+static INLINE void
+_eglDestroyMutex(_EGLMutex *m)
+{
+ pthread_mutex_destroy(m);
+}
+
+static INLINE void
+_eglLockMutex(_EGLMutex *m)
+{
+ pthread_mutex_lock(m);
+}
+
+static INLINE void
+_eglUnlockMutex(_EGLMutex *m)
+{
+ pthread_mutex_unlock(m);
+}
+
+#define _EGL_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define _EGL_DECLARE_MUTEX(m) \
+ _EGLMutex m = _EGL_MUTEX_INITIALIZER
+
+#else
+
+typedef int _EGLMutex;
+static INLINE void _eglInitMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglDestroyMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglLockMutex(_EGLMutex *m) { (void) m; }
+static INLINE void _eglUnlockMutex(_EGLMutex *m) { (void) m; }
+
+#define _EGL_MUTEX_INITIALIZER 0
+#define _EGL_DECLARE_MUTEX(m) \
+ _EGLMutex m = _EGL_MUTEX_INITIALIZER
+
+#endif
+
+#endif /* EGLMUTEX_INCLUDED */
diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c
index b6bde65e8b..14a1e9f8fe 100644
--- a/src/egl/main/eglscreen.c
+++ b/src/egl/main/eglscreen.c
@@ -52,13 +52,9 @@ _eglInitScreen(_EGLScreen *screen)
* Given a public screen handle, return the internal _EGLScreen object.
*/
_EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen)
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *display)
{
EGLint i;
- _EGLDisplay *display = _eglLookupDisplay(dpy);
-
- if (!display)
- return NULL;
for (i = 0; i < display->NumScreens; i++) {
if (display->Screens[i]->Handle == screen)
@@ -89,17 +85,11 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen)
EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *display, EGLScreenMESA *screens,
EGLint max_screens, EGLint *num_screens)
{
- _EGLDisplay *display = _eglLookupDisplay(dpy);
EGLint n;
- if (!display) {
- _eglError(EGL_BAD_DISPLAY, "eglGetScreensMESA");
- return EGL_FALSE;
- }
-
if (display->NumScreens > max_screens) {
n = max_screens;
}
@@ -122,33 +112,26 @@ _eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens,
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateScreenSurfaceMESA");
- return EGL_NO_SURFACE;
- }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
if (!_eglInitSurface(drv, surf, EGL_SCREEN_BIT_MESA,
conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
@@ -160,28 +143,15 @@ _eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* this with code that _really_ shows the surface.
*/
EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface surface,
- EGLModeMESA m)
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface *surf,
+ _EGLMode *mode)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- _EGLMode *mode = _eglLookupMode(dpy, m);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglShowSurfaceMESA");
- return EGL_FALSE;
- }
- if (!mode && (m != EGL_NO_MODE_MESA )) {
- _eglError(EGL_BAD_MODE_MESA, "eglShowSurfaceMESA");
- return EGL_FALSE;
- }
-
- if (surface == EGL_NO_SURFACE) {
+ if (!surf) {
scrn->CurrentSurface = NULL;
}
else {
- _EGLSurface *surf = _eglLookupSurface(surface);
- if (!surf || surf->Type != EGL_SCREEN_BIT_MESA) {
+ if (surf->Type != EGL_SCREEN_BIT_MESA) {
_eglError(EGL_BAD_SURFACE, "eglShowSurfaceMESA");
return EGL_FALSE;
}
@@ -206,18 +176,10 @@ _eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
* this with code that _really_ sets the mode.
*/
EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
- EGLModeMESA mode)
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+ _EGLMode *m)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglScreenModeMESA");
- return EGL_FALSE;
- }
-
- scrn->CurrentMode = _eglLookupMode(dpy, mode);
-
+ scrn->CurrentMode = m;
return EGL_TRUE;
}
@@ -226,15 +188,9 @@ _eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
* Set a screen's surface origin.
*/
EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLint x, EGLint y)
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, EGLint x, EGLint y)
{
- _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglScreenPositionMESA");
- return EGL_FALSE;
- }
-
scrn->OriginX = x;
scrn->OriginY = y;
@@ -246,14 +202,10 @@ _eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy,
* Query a screen's current surface.
*/
EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface *surface)
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface **surf)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (scrn->CurrentSurface)
- *surface = scrn->CurrentSurface->Handle;
- else
- *surface = EGL_NO_SURFACE;
+ *surf = scrn->CurrentSurface;
return EGL_TRUE;
}
@@ -262,29 +214,18 @@ _eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
* Query a screen's current mode.
*/
EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
- EGLModeMESA *mode)
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
+ _EGLMode **m)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
- if (scrn->CurrentMode)
- *mode = scrn->CurrentMode->Handle;
- else
- *mode = EGL_NO_MODE_MESA;
+ *m = scrn->CurrentMode;
return EGL_TRUE;
}
EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen,
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn,
EGLint attribute, EGLint *value)
{
- const _EGLScreen *scrn = _eglLookupScreen(dpy, screen);
-
- if (!scrn) {
- _eglError(EGL_BAD_SCREEN_MESA, "eglQueryScreenMESA");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_SCREEN_POSITION_MESA:
value[0] = scrn->OriginX;
diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h
index 833439b410..8860a2aa7f 100644
--- a/src/egl/main/eglscreen.h
+++ b/src/egl/main/eglscreen.h
@@ -35,7 +35,7 @@ _eglInitScreen(_EGLScreen *screen);
extern _EGLScreen *
-_eglLookupScreen(EGLDisplay dpy, EGLScreenMESA screen);
+_eglLookupScreen(EGLScreenMESA screen, _EGLDisplay *dpy);
extern void
@@ -43,40 +43,40 @@ _eglAddScreen(_EGLDisplay *display, _EGLScreen *screen);
extern EGLBoolean
-_eglGetScreensMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
+_eglGetScreensMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens);
-extern EGLSurface
-_eglCreateScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
extern EGLBoolean
-_eglShowScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA mode);
+_eglShowScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLSurface *surf, _EGLMode *m);
extern EGLBoolean
-_eglScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA mode);
+_eglScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode *m);
extern EGLBoolean
-_eglScreenPositionMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y);
+_eglScreenPositionMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint x, EGLint y);
extern EGLBoolean
-_eglQueryDisplayMESA(_EGLDriver *drv, EGLDisplay dpy, EGLint attribute, EGLint *value);
+_eglQueryDisplayMESA(_EGLDriver *drv, _EGLDisplay *dpy, EGLint attribute, EGLint *value);
extern EGLBoolean
-_eglQueryScreenSurfaceMESA(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen, EGLSurface *surface);
+_eglQueryScreenSurfaceMESA(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *scrn, _EGLSurface **surface);
extern EGLBoolean
-_eglQueryScreenModeMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode);
+_eglQueryScreenModeMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, _EGLMode **m);
extern EGLBoolean
-_eglQueryScreenMESA(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value);
+_eglQueryScreenMESA(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *scrn, EGLint attribute, EGLint *value);
extern void
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 9821e63628..e7a1a8329e 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -11,7 +11,6 @@
#include "eglconfig.h"
#include "egldriver.h"
#include "eglglobals.h"
-#include "eglhash.h"
#include "egllog.h"
#include "eglsurface.h"
@@ -26,7 +25,8 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
{
const char *func;
EGLint width = 0, height = 0, largest = 0;
- EGLint texFormat = 0, texTarget = 0, mipmapTex = 0;
+ EGLint texFormat = EGL_NO_TEXTURE, texTarget = EGL_NO_TEXTURE;
+ EGLint mipmapTex = EGL_FALSE;
EGLint renderBuffer = EGL_BACK_BUFFER;
#ifdef EGL_VERSION_1_2
EGLint colorspace = EGL_COLORSPACE_sRGB;
@@ -210,22 +210,15 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- /* Basically just do error checking here. Drivers have to do the
- * actual buffer swap.
- */
- _EGLSurface *surface = _eglLookupSurface(draw);
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapBuffers");
- return EGL_FALSE;
- }
+ /* Drivers have to do the actual buffer swap. */
return EGL_TRUE;
}
EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf,
NativePixmapType target)
{
/* copy surface to native pixmap */
@@ -235,14 +228,9 @@ _eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface,
EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint *value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglQuerySurface");
- return EGL_FALSE;
- }
switch (attribute) {
case EGL_WIDTH:
*value = surface->Width;
@@ -254,7 +242,7 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
*value = GET_CONFIG_ATTRIB(surface->Config, EGL_CONFIG_ID);
return EGL_TRUE;
case EGL_LARGEST_PBUFFER:
- *value = drv->LargestPbuffer;
+ *value = dpy->LargestPbuffer;
return EGL_TRUE;
case EGL_SURFACE_TYPE:
*value = surface->Type;
@@ -311,96 +299,75 @@ _eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateWindowSurface");
- return EGL_NO_SURFACE;
- }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
if (!_eglInitSurface(drv, surf, EGL_WINDOW_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
NativePixmapType pixmap, const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePixmapSurface");
- return EGL_NO_SURFACE;
- }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
if (!_eglInitSurface(drv, surf, EGL_PIXMAP_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+ return surf;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
#if 0 /* THIS IS JUST EXAMPLE CODE */
_EGLSurface *surf;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
- }
surf = (_EGLSurface *) calloc(1, sizeof(_EGLSurface));
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
if (!_eglInitSurface(drv, surf, EGL_PBUFFER_BIT, conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- return _eglLinkSurface(surf, _eglLookupDisplay(dpy));
+ return NULL;
#endif
- return EGL_NO_SURFACE;
+ return NULL;
}
@@ -408,19 +375,11 @@ _eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
* Default fallback routine - drivers should usually override this.
*/
EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf)
{
- _EGLSurface *surf = _eglLookupSurface(surface);
- if (surf) {
- _eglUnlinkSurface(surf);
- if (!surf->IsBound)
- free(surf);
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
- }
+ if (!_eglIsSurfaceBound(surf))
+ free(surf);
+ return EGL_TRUE;
}
@@ -428,16 +387,9 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
* Default fallback routine - drivers might override this.
*/
EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint attribute, EGLint value)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
-
- if (surface == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSurfaceAttrib");
- return EGL_FALSE;
- }
-
switch (attribute) {
case EGL_MIPMAP_LEVEL:
surface->MipmapLevel = value;
@@ -451,15 +403,14 @@ _eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
{
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+ if (surface->Type != EGL_PBUFFER_BIT) {
_eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
@@ -481,15 +432,14 @@ _eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
EGLint buffer)
{
/* Just do basic error checking and return success/fail.
* Drivers must implement the real stuff.
*/
- _EGLSurface *surface = _eglLookupSurface(surf);
- if (!surface || surface->Type != EGL_PBUFFER_BIT) {
+ if (surface->Type != EGL_PBUFFER_BIT) {
_eglError(EGL_BAD_SURFACE, "eglBindTexImage");
return EGL_FALSE;
}
@@ -516,14 +466,11 @@ _eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surf,
EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval)
{
_EGLSurface *surf = _eglGetCurrentSurface(EGL_DRAW);
- if (surf == NULL) {
- _eglError(EGL_BAD_SURFACE, "eglSwapInterval");
- return EGL_FALSE;
- }
- surf->SwapInterval = interval;
+ if (surf)
+ surf->SwapInterval = interval;
return EGL_TRUE;
}
@@ -533,17 +480,17 @@ _eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval)
/**
* Example function - drivers should do a proper implementation.
*/
-EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+_EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum buftype, EGLClientBuffer buffer,
- EGLConfig config, const EGLint *attrib_list)
+ _EGLConfig *conf, const EGLint *attrib_list)
{
if (buftype != EGL_OPENVG_IMAGE) {
_eglError(EGL_BAD_PARAMETER, "eglCreatePbufferFromClientBuffer");
- return EGL_NO_SURFACE;
+ return NULL;
}
- return EGL_NO_SURFACE;
+ return NULL;
}
#endif /* EGL_VERSION_1_2 */
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index f9413eb9d7..f6d44b5922 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -13,14 +13,13 @@ struct _egl_surface
/* Managed by EGLDisplay for linking */
_EGLDisplay *Display;
_EGLSurface *Next;
- EGLSurface Handle;
- _EGLConfig *Config;
-
- /* May need reference counting here */
- EGLBoolean IsBound;
+ /* The bound status of the surface */
+ _EGLContext *Binding;
EGLBoolean BoundToTexture;
+ _EGLConfig *Config;
+
EGLint Type; /* one of EGL_WINDOW_BIT, EGL_PIXMAP_BIT or EGL_PBUFFER_BIT */
EGLint Width, Height;
EGLint TextureFormat, TextureTarget;
@@ -47,58 +46,69 @@ _eglInitSurface(_EGLDriver *drv, _EGLSurface *surf, EGLint type,
extern EGLBoolean
-_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
extern EGLBoolean
-_eglCopyBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, NativePixmapType target);
+_eglCopyBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, NativePixmapType target);
extern EGLBoolean
-_eglQuerySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value);
+_eglQuerySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint *value);
-extern EGLSurface
-_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
-extern EGLSurface
-_eglCreatePixmapSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePixmapSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
-extern EGLSurface
-_eglCreatePbufferSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
+extern _EGLSurface *
+_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
extern EGLBoolean
-_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
+_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf);
extern EGLBoolean
-_eglSurfaceAttrib(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value);
+_eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
extern EGLBoolean
-_eglBindTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
extern EGLBoolean
-_eglReleaseTexImage(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface, EGLint buffer);
+_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
extern EGLBoolean
-_eglSwapInterval(_EGLDriver *drv, EGLDisplay dpy, EGLint interval);
+_eglSwapInterval(_EGLDriver *drv, _EGLDisplay *dpy, EGLint interval);
#ifdef EGL_VERSION_1_2
-extern EGLSurface
-_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
+extern _EGLSurface *
+_eglCreatePbufferFromClientBuffer(_EGLDriver *drv, _EGLDisplay *dpy,
EGLenum buftype, EGLClientBuffer buffer,
- EGLConfig config, const EGLint *attrib_list);
+ _EGLConfig *conf, const EGLint *attrib_list);
#endif /* EGL_VERSION_1_2 */
+/**
+ * Return true if the surface is bound to a thread.
+ * A surface bound to a texutre is not considered bound by
+ * this function.
+ */
+static INLINE EGLBoolean
+_eglIsSurfaceBound(_EGLSurface *surf)
+{
+ return (surf->Binding != NULL);
+}
+
#endif /* EGLSURFACE_INCLUDED */
diff --git a/src/egl/main/egltypedefs.h b/src/egl/main/egltypedefs.h
index 0a770dec0c..4461440b9b 100644
--- a/src/egl/main/egltypedefs.h
+++ b/src/egl/main/egltypedefs.h
@@ -29,7 +29,7 @@ typedef struct _egl_surface _EGLSurface;
typedef struct _egl_thread_info _EGLThreadInfo;
-typedef _EGLDriver *(*_EGLMain_t)(_EGLDisplay *dpy, const char *args);
+typedef _EGLDriver *(*_EGLMain_t)(const char *args);
#endif /* EGLTYPEDEFS_INCLUDED */
diff --git a/src/egl/main/eglx.c b/src/egl/main/eglx.c
deleted file mode 100644
index 50acc3a24f..0000000000
--- a/src/egl/main/eglx.c
+++ /dev/null
@@ -1,100 +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.
- *
- **************************************************************************/
-
-
-/**
- * X-specific EGL code.
- *
- * Any glue code needed to make EGL work with X is placed in this file.
- */
-
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <X11/Xlib.h>
-
-#include "egldriver.h"
-#include "egllog.h"
-#include "eglstring.h"
-#include "eglx.h"
-
-
-static const char *DefaultGLXDriver = "egl_glx";
-static const char *DefaultSoftDriver = "egl_softpipe";
-
-
-/**
- * Given an X Display ptr (at dpy->Xdpy) try to determine the appropriate
- * device driver. Return its name.
- *
- * This boils down to whether to use the egl_glx.so driver which will
- * load a DRI driver or the egl_softpipe.so driver that'll do software
- * rendering on Xlib.
- */
-const char *
-_xeglChooseDriver(_EGLDisplay *dpy)
-{
-#ifdef _EGL_PLATFORM_X
- _XPrivDisplay xdpy;
- int screen;
- const char *driverName;
-
- assert(dpy);
-
- if (!dpy->Xdpy) {
- dpy->Xdpy = XOpenDisplay(NULL);
- if (!dpy->Xdpy) {
- /* can't open X display -> can't use X-based driver */
- return NULL;
- }
- }
- xdpy = (_XPrivDisplay) dpy->Xdpy;
-
- assert(dpy->Xdpy);
-
- screen = DefaultScreen(dpy->Xdpy);
-
- /* See if we can choose a DRI/DRM driver */
- driverName = _eglChooseDRMDriver(screen);
- if (driverName) {
- free((void *) driverName);
- driverName = _eglstrdup(DefaultGLXDriver);
- }
- else {
- driverName = _eglstrdup(DefaultSoftDriver);
- }
-
- _eglLog(_EGL_DEBUG, "_xeglChooseDriver: %s", driverName);
-
- return driverName;
-#else
- return NULL;
-#endif
-}
-
-
diff --git a/src/egl/main/eglx.h b/src/egl/main/eglx.h
deleted file mode 100644
index 4323d55838..0000000000
--- a/src/egl/main/eglx.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#ifndef EGLX_INCLUDED
-#define EGLX_INCLUDED
-
-
-#include "egldisplay.h"
-
-
-extern const char *
-_xeglChooseDriver(_EGLDisplay *dpy);
-
-
-#endif /* EGLX_INCLUDED */
diff --git a/src/gallium/Makefile.template b/src/gallium/Makefile.template
index 98487d43bd..63983c5220 100644
--- a/src/gallium/Makefile.template
+++ b/src/gallium/Makefile.template
@@ -31,8 +31,8 @@ INCLUDES = \
default: depend lib$(LIBNAME).a
-lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
- $(MKLIB) -o $(LIBNAME) -static $(OBJECTS)
+lib$(LIBNAME).a: $(OBJECTS) $(EXTRA_OBJECTS) Makefile $(TOP)/src/gallium/Makefile.template
+ $(MKLIB) -o $(LIBNAME) -static $(OBJECTS) $(EXTRA_OBJECTS)
depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
rm -f depend
@@ -41,7 +41,7 @@ depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
# Emacs tags
tags:
- etags `find . -name \*.[ch]` `find ../include`
+ etags `find . -name \*.[ch]` `find $(TOP)/src/gallium/include -name \*.h`
# Remove .o and backup files
clean:
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index 32b7c2980a..89c69d7205 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -31,6 +31,7 @@ for driver in env['drivers']:
SConscript('state_trackers/python/SConscript')
SConscript('state_trackers/glx/xlib/SConscript')
SConscript('state_trackers/dri/SConscript')
+SConscript('state_trackers/xorg/SConscript')
if platform == 'windows':
SConscript('state_trackers/wgl/SConscript')
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 2e3f5b2fc0..1c6d657297 100644
--- a/src/gallium/auxiliary/draw/draw_pipe.c
+++ b/src/gallium/auxiliary/draw/draw_pipe.c
@@ -158,6 +158,60 @@ static void do_triangle( struct draw_context *draw,
+#define QUAD(i0,i1,i2,i3) \
+ do_triangle( draw, \
+ ( DRAW_PIPE_RESET_STIPPLE | \
+ DRAW_PIPE_EDGE_FLAG_0 | \
+ DRAW_PIPE_EDGE_FLAG_2 ), \
+ verts + stride * elts[i0], \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i3]); \
+ do_triangle( draw, \
+ ( DRAW_PIPE_EDGE_FLAG_0 | \
+ DRAW_PIPE_EDGE_FLAG_1 ), \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i2], \
+ verts + stride * elts[i3])
+
+#define TRIANGLE(flags,i0,i1,i2) \
+ do_triangle( draw, \
+ elts[i0], /* flags */ \
+ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * elts[i1], \
+ verts + stride * elts[i2])
+
+#define LINE(flags,i0,i1) \
+ do_line( draw, \
+ elts[i0], \
+ verts + stride * (elts[i0] & ~DRAW_PIPE_FLAG_MASK), \
+ verts + stride * elts[i1])
+
+#define POINT(i0) \
+ do_point( draw, \
+ verts + stride * elts[i0] )
+
+#define FUNC pipe_run
+#define ARGS \
+ struct draw_context *draw, \
+ unsigned prim, \
+ struct vertex_header *vertices, \
+ unsigned stride, \
+ const ushort *elts
+
+#define LOCAL_VARS \
+ char *verts = (char *)vertices; \
+ boolean flatfirst = (draw->rasterizer->flatshade && \
+ draw->rasterizer->flatshade_first); \
+ unsigned i; \
+ ushort flags
+
+#define FLUSH
+
+#include "draw_pt_decompose.h"
+#undef ARGS
+#undef LOCAL_VARS
+
+
/* Code to run the pipeline on a fairly arbitary collection of vertices.
*
@@ -178,34 +232,12 @@ void draw_pipeline_run( struct draw_context *draw,
unsigned count )
{
char *verts = (char *)vertices;
- unsigned i;
draw->pipeline.verts = verts;
draw->pipeline.vertex_stride = stride;
draw->pipeline.vertex_count = vertex_count;
- switch (prim) {
- case PIPE_PRIM_POINTS:
- for (i = 0; i < count; i++)
- do_point( draw,
- verts + stride * elts[i] );
- break;
- case PIPE_PRIM_LINES:
- for (i = 0; i+1 < count; i += 2)
- do_line( draw,
- elts[i+0], /* flags */
- verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
- verts + stride * elts[i+1]);
- break;
- case PIPE_PRIM_TRIANGLES:
- for (i = 0; i+2 < count; i += 3)
- do_triangle( draw,
- elts[i+0], /* flags */
- verts + stride * (elts[i+0] & ~DRAW_PIPE_FLAG_MASK),
- verts + stride * elts[i+1],
- verts + stride * elts[i+2]);
- break;
- }
+ pipe_run(draw, prim, vertices, stride, elts, count);
draw->pipeline.verts = NULL;
draw->pipeline.vertex_count = 0;
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 014d8c7346..7d76a7dbf3 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
@@ -28,6 +28,30 @@
/* Authors: Keith Whitwell <keith@tungstengraphics.com>
*/
+/**
+ * Notes on wide points and sprite mode:
+ *
+ * In wide point/sprite mode we effectively need to convert each incoming
+ * vertex into four outgoing vertices specifying the corners of a quad.
+ * Since we don't (yet) have geometry shaders, we have to handle this here
+ * in the draw module.
+ *
+ * For sprites, it also means that this is where we have to handle texcoords
+ * for the vertices of the quad. OpenGL's GL_COORD_REPLACE state specifies
+ * if/how enabled texcoords are automatically generated for sprites. We pass
+ * that info through gallium in the pipe_rasterizer_state::sprite_coord_mode
+ * array.
+ *
+ * Additionally, GLSL's gl_PointCoord fragment attribute has to be handled
+ * here as well. This is basically an additional texture/generic attribute
+ * that varies .x from 0 to 1 horizontally across the point and varies .y
+ * vertically from 0 to 1 down the sprite.
+ *
+ * With geometry shaders, the state tracker could create a GS to do
+ * most/all of this.
+ */
+
+
#include "util/u_math.h"
#include "util/u_memory.h"
#include "pipe/p_defines.h"
@@ -52,7 +76,7 @@ struct widepoint_stage {
int psize_slot;
- int point_coord_fs_input; /**< input for pointcoord (and fog) */
+ int point_coord_fs_input; /**< input for pointcoord */
};
@@ -64,8 +88,6 @@ widepoint_stage( struct draw_stage *stage )
}
-
-
/**
* Set the vertex texcoords for sprite mode.
* Coords may be left untouched or set to a right-side-up or upside-down
@@ -89,10 +111,12 @@ static void set_texcoords(const struct widepoint_stage *wide,
}
if (wide->point_coord_fs_input >= 0) {
- /* put gl_PointCoord into extra vertex output's zw components */
- uint k = wide->stage.draw->extra_vp_outputs.slot;
- v->data[k][2] = tc[0];
- v->data[k][3] = tc[1];
+ /* put gl_PointCoord into the extra vertex slot */
+ uint slot = wide->stage.draw->extra_vp_outputs.slot;
+ v->data[slot][0] = tc[0];
+ v->data[slot][1] = tc[1];
+ v->data[slot][2] = 0.0F;
+ v->data[slot][3] = 1.0F;
}
}
@@ -182,10 +206,10 @@ static void widepoint_point( struct draw_stage *stage,
static int
-find_fog_input_attrib(struct draw_context *draw)
+find_pntc_input_attrib(struct draw_context *draw)
{
- /* Scan the fragment program's input decls to find the fogcoord
- * attribute. The z/w components will store the point coord.
+ /* Scan the fragment program's input decls to find the pointcoord
+ * attribute. The xy components will store the point coord.
*/
return 0; /* XXX fix this */
}
@@ -229,8 +253,8 @@ static void widepoint_first_point( struct draw_stage *stage,
}
wide->num_texcoords = j;
- /* find fragment shader PointCoord/Fog input */
- wide->point_coord_fs_input = find_fog_input_attrib(draw);
+ /* find fragment shader PointCoord input */
+ wide->point_coord_fs_input = find_pntc_input_attrib(draw);
/* setup extra vp output (point coord implemented as a texcoord) */
draw->extra_vp_outputs.semantic_name = TGSI_SEMANTIC_GENERIC;
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index 727977bc3a..b3535c0e48 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -119,7 +119,7 @@ draw_create_vs_llvm(struct draw_context *draw,
vs->base.create_varient = draw_vs_varient_generic;
vs->base.run_linear = vs_llvm_run_linear;
vs->base.delete = vs_llvm_delete;
- vs->machine = &draw->vs.machine;
+ vs->machine = draw->vs.machine;
{
struct gallivm_ir *ir = gallivm_ir_new(GALLIVM_VS);
diff --git a/src/gallium/auxiliary/gallivm/instructionssoa.cpp b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
index 2d2af3085e..721b7d2d83 100644
--- a/src/gallium/auxiliary/gallivm/instructionssoa.cpp
+++ b/src/gallium/auxiliary/gallivm/instructionssoa.cpp
@@ -128,7 +128,7 @@ void InstructionsSoa::createFunctionMap()
m_functionsMap[TGSI_OPCODE_DP4] = "dp4";
m_functionsMap[TGSI_OPCODE_MIN] = "min";
m_functionsMap[TGSI_OPCODE_MAX] = "max";
- m_functionsMap[TGSI_OPCODE_POWER] = "pow";
+ m_functionsMap[TGSI_OPCODE_POW] = "pow";
m_functionsMap[TGSI_OPCODE_LIT] = "lit";
m_functionsMap[TGSI_OPCODE_RSQ] = "rsq";
m_functionsMap[TGSI_OPCODE_SLT] = "slt";
@@ -311,7 +311,7 @@ std::vector<llvm::Value*> InstructionsSoa::mul(const std::vector<llvm::Value*> i
std::vector<llvm::Value*> InstructionsSoa::pow(const std::vector<llvm::Value*> in1,
const std::vector<llvm::Value*> in2)
{
- llvm::Function *func = function(TGSI_OPCODE_POWER);
+ llvm::Function *func = function(TGSI_OPCODE_POW);
return callBuiltin(func, in1, in2);
}
diff --git a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
index 9c8f89d520..bf84401e11 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -338,7 +338,7 @@ translate_instruction(llvm::Module *module,
out = instr->sub(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_LERP: {
+ case TGSI_OPCODE_LRP: {
out = instr->lerp(inputs[0], inputs[1], inputs[2]);
}
break;
@@ -350,17 +350,11 @@ translate_instruction(llvm::Module *module,
out = instr->cnd0(inputs[0], inputs[1], inputs[2]);
}
break;
- case TGSI_OPCODE_DOT2ADD: {
+ case TGSI_OPCODE_DP2A: {
out = instr->dot2add(inputs[0], inputs[1], inputs[2]);
}
break;
- case TGSI_OPCODE_INDEX:
- break;
- case TGSI_OPCODE_NEGATE: {
- out = instr->neg(inputs[0]);
- }
- break;
- case TGSI_OPCODE_FRAC: {
+ case TGSI_OPCODE_FRC: {
out = instr->frc(inputs[0]);
}
break;
@@ -368,30 +362,28 @@ translate_instruction(llvm::Module *module,
out = instr->clamp(inputs[0]);
}
break;
- case TGSI_OPCODE_FLOOR: {
+ case TGSI_OPCODE_FLR: {
out = instr->floor(inputs[0]);
}
break;
case TGSI_OPCODE_ROUND:
break;
- case TGSI_OPCODE_EXPBASE2: {
+ case TGSI_OPCODE_EX2: {
out = instr->ex2(inputs[0]);
}
break;
- case TGSI_OPCODE_LOGBASE2: {
+ case TGSI_OPCODE_LG2: {
out = instr->lg2(inputs[0]);
}
break;
- case TGSI_OPCODE_POWER: {
+ case TGSI_OPCODE_POW: {
out = instr->pow(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_CROSSPRODUCT: {
+ case TGSI_OPCODE_XPD: {
out = instr->cross(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- break;
case TGSI_OPCODE_ABS: {
out = instr->abs(inputs[0]);
}
@@ -524,7 +516,7 @@ translate_instruction(llvm::Module *module,
return; //just update the state
}
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
break;
case TGSI_OPCODE_REP:
break;
@@ -540,7 +532,7 @@ translate_instruction(llvm::Module *module,
return; //just update the state
}
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
break;
case TGSI_OPCODE_ENDREP:
break;
@@ -582,7 +574,7 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_ENDPRIM:
break;
- case TGSI_OPCODE_BGNLOOP2: {
+ case TGSI_OPCODE_BGNLOOP: {
instr->beginLoop();
storage->setCurrentBlock(instr->currentBlock());
return;
@@ -595,7 +587,7 @@ translate_instruction(llvm::Module *module,
return;
}
break;
- case TGSI_OPCODE_ENDLOOP2: {
+ case TGSI_OPCODE_ENDLOOP: {
instr->endLoop();
storage->setCurrentBlock(instr->currentBlock());
return;
@@ -619,14 +611,6 @@ translate_instruction(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_M4X3:
- break;
- case TGSI_OPCODE_M3X4:
- break;
- case TGSI_OPCODE_M3X3:
- break;
- case TGSI_OPCODE_M3X2:
- break;
case TGSI_OPCODE_CALLNZ:
break;
case TGSI_OPCODE_IFC:
@@ -780,44 +764,38 @@ translate_instructionir(llvm::Module *module,
out = instr->sub(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_LERP: {
+ case TGSI_OPCODE_LRP: {
}
break;
case TGSI_OPCODE_CND:
break;
case TGSI_OPCODE_CND0:
break;
- case TGSI_OPCODE_DOT2ADD:
+ case TGSI_OPCODE_DP2A:
break;
- case TGSI_OPCODE_INDEX:
- break;
- case TGSI_OPCODE_NEGATE:
- break;
- case TGSI_OPCODE_FRAC: {
+ case TGSI_OPCODE_FRC: {
}
break;
case TGSI_OPCODE_CLAMP:
break;
- case TGSI_OPCODE_FLOOR: {
+ case TGSI_OPCODE_FLR: {
}
break;
case TGSI_OPCODE_ROUND:
break;
- case TGSI_OPCODE_EXPBASE2: {
+ case TGSI_OPCODE_EX2: {
}
break;
- case TGSI_OPCODE_LOGBASE2: {
+ case TGSI_OPCODE_LG2: {
}
break;
- case TGSI_OPCODE_POWER: {
+ case TGSI_OPCODE_POW: {
out = instr->pow(inputs[0], inputs[1]);
}
break;
- case TGSI_OPCODE_CROSSPRODUCT: {
+ case TGSI_OPCODE_XPD: {
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- break;
case TGSI_OPCODE_ABS: {
out = instr->abs(inputs[0]);
}
@@ -912,7 +890,7 @@ translate_instructionir(llvm::Module *module,
case TGSI_OPCODE_IF: {
}
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
break;
case TGSI_OPCODE_REP:
break;
@@ -922,7 +900,7 @@ translate_instructionir(llvm::Module *module,
case TGSI_OPCODE_ENDIF: {
}
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
break;
case TGSI_OPCODE_ENDREP:
break;
@@ -963,13 +941,13 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_ENDPRIM:
break;
- case TGSI_OPCODE_BGNLOOP2: {
+ case TGSI_OPCODE_BGNLOOP: {
}
break;
case TGSI_OPCODE_BGNSUB: {
}
break;
- case TGSI_OPCODE_ENDLOOP2: {
+ case TGSI_OPCODE_ENDLOOP: {
}
break;
case TGSI_OPCODE_ENDSUB: {
@@ -985,14 +963,6 @@ translate_instructionir(llvm::Module *module,
break;
case TGSI_OPCODE_NOP:
break;
- case TGSI_OPCODE_M4X3:
- break;
- case TGSI_OPCODE_M3X4:
- break;
- case TGSI_OPCODE_M3X3:
- break;
- case TGSI_OPCODE_M3X2:
- break;
case TGSI_OPCODE_NRM4:
break;
case TGSI_OPCODE_CALLNZ:
diff --git a/src/gallium/auxiliary/tgsi/Makefile b/src/gallium/auxiliary/tgsi/Makefile
index b4900e8dba..5f0a580b09 100644
--- a/src/gallium/auxiliary/tgsi/Makefile
+++ b/src/gallium/auxiliary/tgsi/Makefile
@@ -16,6 +16,7 @@ C_SOURCES = \
tgsi_sse2.c \
tgsi_text.c \
tgsi_transform.c \
+ tgsi_ureg.c \
tgsi_util.c
include ../../Makefile.template
diff --git a/src/gallium/auxiliary/tgsi/SConscript b/src/gallium/auxiliary/tgsi/SConscript
index 8200cce42f..b6bc2924f0 100644
--- a/src/gallium/auxiliary/tgsi/SConscript
+++ b/src/gallium/auxiliary/tgsi/SConscript
@@ -16,6 +16,7 @@ tgsi = env.ConvenienceLibrary(
'tgsi_sse2.c',
'tgsi_text.c',
'tgsi_transform.c',
+ 'tgsi_ureg.c',
'tgsi_util.c',
])
diff --git a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
index a3f4947c73..eb492076b7 100644
--- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
+++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
@@ -187,11 +187,7 @@ TGSI Instruction Specification
1.2.6 CND0 - Condition Zero
- dst.x = (src2.x >= 0.0) ? src0.x : src1.x
- dst.y = (src2.y >= 0.0) ? src0.y : src1.y
- dst.z = (src2.z >= 0.0) ? src0.z : src1.z
- dst.w = (src2.w >= 0.0) ? src0.w : src1.w
-
+ Removed. Use (CMP src2, src1, src0) instead.
1.2.7 DOT2ADD - 2-component Dot Product And Add
@@ -665,9 +661,18 @@ TGSI Instruction Specification
TBD
-1.9.8 LOOP - Loop
+1.9.8 BGNFOR - Begin a For-Loop
- TBD
+ dst.x = floor(src.x)
+ dst.y = floor(src.y)
+ dst.z = floor(src.z)
+
+ if (dst.y <= 0)
+ pc = [matching ENDFOR] + 1
+ endif
+
+ Note: The destination must be a loop register.
+ The source must be a constant register.
1.9.9 REP - Repeat
@@ -685,9 +690,16 @@ TGSI Instruction Specification
TBD
-1.9.12 ENDLOOP - End Loop
+1.9.12 ENDFOR - End a For-Loop
- TBD
+ dst.x = dst.x + dst.z
+ dst.y = dst.y - 1.0
+
+ if (dst.y > 0)
+ pc = [matching BGNFOR instruction] + 1
+ endif
+
+ Note: The destination must be a loop register.
1.9.13 ENDREP - End Repeat
@@ -840,7 +852,7 @@ TGSI Instruction Specification
----------
-1.13.1 BGNLOOP2 - Begin Loop
+1.13.1 BGNLOOP - Begin a Loop
TBD
@@ -850,7 +862,7 @@ TGSI Instruction Specification
TBD
-1.13.3 ENDLOOP2 - End Loop
+1.13.3 ENDLOOP - End a Loop
TBD
@@ -1015,12 +1027,12 @@ TGSI Instruction Specification
1.18.1 EXPP - Approximate Exponential Base 2
- Alias for EXP.
+ Use EXP. See also 1.19.3.
1.18.2 LOGP - Logarithm Base 2
- Alias for LG2.
+ Use LOG. See also 1.19.4.
1.19 vs_2_0
@@ -1037,6 +1049,16 @@ TGSI Instruction Specification
Alias for ARR.
+1.19.3 EXPP - Approximate Exponential Base 2
+
+ Use EX2.
+
+
+1.19.4 LOGP - Logarithm Base 2
+
+ Use LG2.
+
+
2 Explanation of symbols used
==============================
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index 010d501c60..e0cfc54420 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -482,6 +482,8 @@ tgsi_default_full_instruction( void )
full_instruction.FullSrcRegisters[i] = tgsi_default_full_src_register();
}
+ full_instruction.Flags = 0x0;
+
return full_instruction;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index e1cd8479cb..111d95b666 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -33,12 +33,20 @@
#include "tgsi_info.h"
#include "tgsi_iterate.h"
+
+/** Number of spaces to indent for IF/LOOP/etc */
+static const int indent_spaces = 3;
+
+
struct dump_ctx
{
struct tgsi_iterate_context iter;
uint instno;
+ int indent;
+ uint indentation;
+
void (*printf)(struct dump_ctx *ctx, const char *format, ...);
};
@@ -82,7 +90,7 @@ static const char *processor_type_names[] =
"GEOM"
};
-static const char *file_names[] =
+static const char *file_names[TGSI_FILE_COUNT] =
{
"NULL",
"CONST",
@@ -91,7 +99,8 @@ static const char *file_names[] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static const char *interpolate_names[] =
@@ -334,13 +343,19 @@ iter_instruction(
{
struct dump_ctx *ctx = (struct dump_ctx *) iter;
uint instno = ctx->instno++;
-
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info( inst->Instruction.Opcode );
uint i;
boolean first_reg = TRUE;
INSTID( instno );
TXT( ": " );
- TXT( tgsi_get_opcode_info( inst->Instruction.Opcode )->mnemonic );
+
+ ctx->indent -= info->pre_dedent;
+ for(i = 0; (int)i < ctx->indent; ++i)
+ TXT( " " );
+ ctx->indent += info->post_indent;
+
+ TXT( info->mnemonic );
switch (inst->Instruction.Saturate) {
case TGSI_SAT_NONE:
@@ -472,14 +487,22 @@ iter_instruction(
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_IF:
case TGSI_OPCODE_ELSE:
- case TGSI_OPCODE_BGNLOOP2:
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
+ case TGSI_OPCODE_ENDLOOP:
case TGSI_OPCODE_CAL:
TXT( " :" );
UID( inst->InstructionExtLabel.Label );
break;
}
+ /* update indentation */
+ if (inst->Instruction.Opcode == TGSI_OPCODE_IF ||
+ inst->Instruction.Opcode == TGSI_OPCODE_ELSE ||
+ inst->Instruction.Opcode == TGSI_OPCODE_BGNFOR ||
+ inst->Instruction.Opcode == TGSI_OPCODE_BGNLOOP) {
+ ctx->indentation += indent_spaces;
+ }
+
EOL();
return TRUE;
@@ -493,7 +516,9 @@ tgsi_dump_instruction(
struct dump_ctx ctx;
ctx.instno = instno;
+ ctx.indent = 0;
ctx.printf = dump_ctx_printf;
+ ctx.indentation = 0;
iter_instruction( &ctx.iter, (struct tgsi_full_instruction *)inst );
}
@@ -525,7 +550,9 @@ tgsi_dump(
ctx.iter.epilog = NULL;
ctx.instno = 0;
+ ctx.indent = 0;
ctx.printf = dump_ctx_printf;
+ ctx.indentation = 0;
tgsi_iterate_shader( tokens, &ctx.iter );
}
@@ -577,7 +604,9 @@ tgsi_dump_str(
ctx.base.iter.epilog = NULL;
ctx.base.instno = 0;
+ ctx.base.indent = 0;
ctx.base.printf = &str_dump_ctx_printf;
+ ctx.base.indentation = 0;
ctx.str = str;
ctx.str[0] = 0;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
index c944760ca6..4a9c02b141 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
@@ -69,7 +69,7 @@ static const char *TGSI_TOKEN_TYPES[] =
"TOKEN_TYPE_INSTRUCTION"
};
-static const char *TGSI_FILES[] =
+static const char *TGSI_FILES[TGSI_FILE_COUNT] =
{
"FILE_NULL",
"FILE_CONSTANT",
@@ -78,7 +78,8 @@ static const char *TGSI_FILES[] =
"FILE_TEMPORARY",
"FILE_SAMPLER",
"FILE_ADDRESS",
- "FILE_IMMEDIATE"
+ "FILE_IMMEDIATE",
+ "FILE_LOOP"
};
static const char *TGSI_INTERPOLATES[] =
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index b193fd7a0a..c79c56debd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -62,6 +62,9 @@
#define FAST_MATH 1
+/** for tgsi_full_instruction::Flags */
+#define SOA_DEPENDENCY_FLAG 0x1
+
#define TILE_TOP_LEFT 0
#define TILE_TOP_RIGHT 1
#define TILE_BOTTOM_LEFT 2
@@ -182,7 +185,7 @@ print_temp(const struct tgsi_exec_machine *mach, uint index)
* MOV t3, t2;
* The second instruction will have the wrong value for t0 if executed as-is.
*/
-static boolean
+boolean
tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst)
{
uint i, chan;
@@ -328,19 +331,24 @@ tgsi_exec_machine_bind_shader(
* sizeof(struct tgsi_full_instruction));
maxInstructions += 10;
}
- memcpy(instructions + numInstructions,
- &parse.FullToken.FullInstruction,
- sizeof(instructions[0]));
-#if 0
if (tgsi_check_soa_dependencies(&parse.FullToken.FullInstruction)) {
- debug_printf("SOA dependency in instruction:\n");
- tgsi_dump_instruction(&parse.FullToken.FullInstruction,
- numInstructions);
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ parse.FullToken.FullInstruction.Flags = SOA_DEPENDENCY_FLAG;
+ /* XXX we only handle SOA dependencies properly for MOV/SWZ
+ * at this time!
+ */
+ if (opcode != TGSI_OPCODE_MOV && opcode != TGSI_OPCODE_SWZ) {
+ debug_printf("Warning: SOA dependency in instruction"
+ " is not handled:\n");
+ tgsi_dump_instruction(&parse.FullToken.FullInstruction,
+ numInstructions);
+ }
}
-#else
- (void) tgsi_check_soa_dependencies;
-#endif
+
+ memcpy(instructions + numInstructions,
+ &parse.FullToken.FullInstruction,
+ sizeof(instructions[0]));
numInstructions++;
break;
@@ -375,15 +383,9 @@ tgsi_exec_machine_create( void )
if (!mach)
goto fail;
- mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
+ memset(mach, 0, sizeof(*mach));
- mach->Samplers = NULL;
- mach->Consts = NULL;
- mach->Tokens = NULL;
- mach->Primitives = NULL;
- mach->InterpCoefs = NULL;
- mach->Instructions = NULL;
- mach->Declarations = NULL;
+ mach->Addrs = &mach->Temps[TGSI_EXEC_TEMP_ADDR];
/* Setup constants. */
for( i = 0; i < 4; i++ ) {
@@ -2030,9 +2032,23 @@ exec_instruction(
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
- FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
- FETCH( &r[0], 0, chan_index );
- STORE( &r[0], 0, chan_index );
+ if (inst->Flags & SOA_DEPENDENCY_FLAG) {
+ /* Do all fetches into temp regs, then do all stores to avoid
+ * intermediate/accidental clobbering. This could be done all the
+ * time for MOV but for other instructions we'll need more temps...
+ */
+ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+ FETCH( &r[chan_index], 0, chan_index );
+ }
+ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+ STORE( &r[chan_index], 0, chan_index );
+ }
+ }
+ else {
+ FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
+ FETCH( &r[0], 0, chan_index );
+ STORE( &r[0], 0, chan_index );
+ }
}
break;
@@ -2313,16 +2329,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_CND0:
- FOR_EACH_ENABLED_CHANNEL(*inst, chan_index) {
- FETCH(&r[0], 0, chan_index);
- FETCH(&r[1], 1, chan_index);
- FETCH(&r[2], 2, chan_index);
- micro_le(&r[0], &mach->Temps[TEMP_0_I].xyzw[TEMP_0_C], &r[2], &r[0], &r[1]);
- STORE(&r[0], 0, chan_index);
- }
- break;
-
case TGSI_OPCODE_DP2A:
FETCH( &r[0], 0, CHAN_X );
FETCH( &r[1], 1, CHAN_X );
@@ -2341,16 +2347,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_INDEX:
- /* XXX: considered for removal */
- assert (0);
- break;
-
- case TGSI_OPCODE_NEGATE:
- /* XXX: considered for removal */
- assert (0);
- break;
-
case TGSI_OPCODE_FRC:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
@@ -2454,11 +2450,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- /* XXX: considered for removal */
- assert (0);
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
@@ -2765,19 +2756,32 @@ exec_instruction(
if (mach->ExecMask) {
/* do the call */
- /* push the Cond, Loop, Cont stacks */
+ /* First, record the depths of the execution stacks.
+ * This is important for deeply nested/looped return statements.
+ * We have to unwind the stacks by the correct amount. For a
+ * real code generator, we could determine the number of entries
+ * to pop off each stack with simple static analysis and avoid
+ * implementing this data structure at run time.
+ */
+ mach->CallStack[mach->CallStackTop].CondStackTop = mach->CondStackTop;
+ mach->CallStack[mach->CallStackTop].LoopStackTop = mach->LoopStackTop;
+ mach->CallStack[mach->CallStackTop].ContStackTop = mach->ContStackTop;
+ /* note that PC was already incremented above */
+ mach->CallStack[mach->CallStackTop].ReturnAddr = *pc;
+
+ mach->CallStackTop++;
+
+ /* Second, push the Cond, Loop, Cont, Func stacks */
assert(mach->CondStackTop < TGSI_EXEC_MAX_COND_NESTING);
mach->CondStack[mach->CondStackTop++] = mach->CondMask;
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
-
assert(mach->FuncStackTop < TGSI_EXEC_MAX_CALL_NESTING);
mach->FuncStack[mach->FuncStackTop++] = mach->FuncMask;
- /* note that PC was already incremented above */
- mach->CallStack[mach->CallStackTop++] = *pc;
+ /* Finally, jump to the subroutine */
*pc = inst->InstructionExtLabel.Label;
}
break;
@@ -2794,18 +2798,24 @@ exec_instruction(
*pc = -1;
return;
}
- *pc = mach->CallStack[--mach->CallStackTop];
- /* pop the Cond, Loop, Cont stacks */
- assert(mach->CondStackTop > 0);
- mach->CondMask = mach->CondStack[--mach->CondStackTop];
- assert(mach->LoopStackTop > 0);
- mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
- assert(mach->ContStackTop > 0);
- mach->ContMask = mach->ContStack[--mach->ContStackTop];
+ assert(mach->CallStackTop > 0);
+ mach->CallStackTop--;
+
+ mach->CondStackTop = mach->CallStack[mach->CallStackTop].CondStackTop;
+ mach->CondMask = mach->CondStack[mach->CondStackTop];
+
+ mach->LoopStackTop = mach->CallStack[mach->CallStackTop].LoopStackTop;
+ mach->LoopMask = mach->LoopStack[mach->LoopStackTop];
+
+ mach->ContStackTop = mach->CallStack[mach->CallStackTop].ContStackTop;
+ mach->ContMask = mach->ContStack[mach->ContStackTop];
+
assert(mach->FuncStackTop > 0);
mach->FuncMask = mach->FuncStack[--mach->FuncStackTop];
+ *pc = mach->CallStack[mach->CallStackTop].ReturnAddr;
+
UPDATE_EXEC_MASK(mach);
}
break;
@@ -3102,26 +3112,81 @@ exec_instruction(
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
+ assert(mach->LoopCounterStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ for (chan_index = 0; chan_index < 3; chan_index++) {
+ FETCH( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[chan_index], 0, chan_index );
+ }
+ STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
+ ++mach->LoopCounterStackTop;
/* fall-through (for now) */
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
assert(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
assert(mach->ContStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
+ assert(mach->LoopLabelStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
+ mach->LoopLabelStack[mach->LoopLabelStackTop++] = *pc - 1;
+ break;
+
+ case TGSI_OPCODE_ENDFOR:
+ assert(mach->LoopCounterStackTop > 0);
+ micro_sub( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
+ &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X],
+ &mach->Temps[TEMP_1_I].xyzw[TEMP_1_C] );
+ /* update LoopMask */
+ if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[0] <= 0) {
+ mach->LoopMask &= ~0x1;
+ }
+ if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[1] <= 0 ) {
+ mach->LoopMask &= ~0x2;
+ }
+ if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[2] <= 0 ) {
+ mach->LoopMask &= ~0x4;
+ }
+ if( mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_X].f[3] <= 0 ) {
+ mach->LoopMask &= ~0x8;
+ }
+ micro_add( &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
+ &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Y],
+ &mach->LoopCounterStack[mach->LoopCounterStackTop - 1].xyzw[CHAN_Z]);
+ assert(mach->LoopLabelStackTop > 0);
+ inst = mach->Instructions + mach->LoopLabelStack[mach->LoopLabelStackTop - 1];
+ STORE( &mach->LoopCounterStack[mach->LoopCounterStackTop].xyzw[CHAN_Y], 0, CHAN_X );
+ /* Restore ContMask, but don't pop */
+ assert(mach->ContStackTop > 0);
+ mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
+ UPDATE_EXEC_MASK(mach);
+ if (mach->ExecMask) {
+ /* repeat loop: jump to instruction just past BGNLOOP */
+ assert(mach->LoopLabelStackTop > 0);
+ *pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
+ }
+ else {
+ /* exit loop: pop LoopMask */
+ assert(mach->LoopStackTop > 0);
+ mach->LoopMask = mach->LoopStack[--mach->LoopStackTop];
+ /* pop ContMask */
+ assert(mach->ContStackTop > 0);
+ mach->ContMask = mach->ContStack[--mach->ContStackTop];
+ assert(mach->LoopLabelStackTop > 0);
+ --mach->LoopLabelStackTop;
+ assert(mach->LoopCounterStackTop > 0);
+ --mach->LoopCounterStackTop;
+ }
+ UPDATE_EXEC_MASK(mach);
break;
-
+
case TGSI_OPCODE_ENDLOOP:
- /* fall-through (for now at least) */
- case TGSI_OPCODE_ENDLOOP2:
/* Restore ContMask, but don't pop */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
UPDATE_EXEC_MASK(mach);
if (mach->ExecMask) {
/* repeat loop: jump to instruction just past BGNLOOP */
- *pc = inst->InstructionExtLabel.Label + 1;
+ assert(mach->LoopLabelStackTop > 0);
+ *pc = mach->LoopLabelStack[mach->LoopLabelStackTop - 1] + 1;
}
else {
/* exit loop: pop LoopMask */
@@ -3130,6 +3195,8 @@ exec_instruction(
/* pop ContMask */
assert(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[--mach->ContStackTop];
+ assert(mach->LoopLabelStackTop > 0);
+ --mach->LoopLabelStackTop;
}
UPDATE_EXEC_MASK(mach);
break;
@@ -3197,7 +3264,6 @@ tgsi_exec_machine_run( struct tgsi_exec_machine *mach )
mach->FuncMask = 0xf;
mach->ExecMask = 0xf;
- mach->CondStackTop = 0; /* temporarily subvert this assertion */
assert(mach->CondStackTop == 0);
assert(mach->LoopStackTop == 0);
assert(mach->ContStackTop == 0);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.h b/src/gallium/auxiliary/tgsi/tgsi_exec.h
index 8a9100f4c3..c72f76809d 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.h
@@ -186,6 +186,17 @@ struct tgsi_exec_labels
*/
#define TGSI_EXEC_MAX_CONST_BUFFER 4096
+
+/** function call/activation record */
+struct tgsi_call_record
+{
+ uint CondStackTop;
+ uint LoopStackTop;
+ uint ContStackTop;
+ uint ReturnAddr;
+};
+
+
/**
* Run-time virtual machine state for executing TGSI shader.
*/
@@ -232,6 +243,14 @@ struct tgsi_exec_machine
uint LoopStack[TGSI_EXEC_MAX_LOOP_NESTING];
int LoopStackTop;
+ /** Loop label stack */
+ uint LoopLabelStack[TGSI_EXEC_MAX_LOOP_NESTING];
+ int LoopLabelStackTop;
+
+ /** Loop counter stack (x = count, y = current, z = step) */
+ struct tgsi_exec_vector LoopCounterStack[TGSI_EXEC_MAX_LOOP_NESTING];
+ int LoopCounterStackTop;
+
/** Loop continue mask stack (see comments in tgsi_exec.c) */
uint ContStack[TGSI_EXEC_MAX_LOOP_NESTING];
int ContStackTop;
@@ -241,7 +260,7 @@ struct tgsi_exec_machine
int FuncStackTop;
/** Function call stack for saving/restoring the program counter */
- uint CallStack[TGSI_EXEC_MAX_CALL_NESTING];
+ struct tgsi_call_record CallStack[TGSI_EXEC_MAX_CALL_NESTING];
int CallStackTop;
struct tgsi_full_instruction *Instructions;
@@ -272,6 +291,14 @@ tgsi_exec_machine_run(
struct tgsi_exec_machine *mach );
+void
+tgsi_exec_machine_free_data(struct tgsi_exec_machine *mach);
+
+
+boolean
+tgsi_check_soa_dependencies(const struct tgsi_full_instruction *inst);
+
+
static INLINE void
tgsi_set_kill_mask(struct tgsi_exec_machine *mach, unsigned mask)
{
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 29b8115560..17af4cb7ad 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -31,125 +31,125 @@
static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{
- { 1, 1, 0, 0, "ARL", TGSI_OPCODE_ARL },
- { 1, 1, 0, 0, "MOV", TGSI_OPCODE_MOV },
- { 1, 1, 0, 0, "LIT", TGSI_OPCODE_LIT },
- { 1, 1, 0, 0, "RCP", TGSI_OPCODE_RCP },
- { 1, 1, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
- { 1, 1, 0, 0, "EXP", TGSI_OPCODE_EXP },
- { 1, 1, 0, 0, "LOG", TGSI_OPCODE_LOG },
- { 1, 2, 0, 0, "MUL", TGSI_OPCODE_MUL },
- { 1, 2, 0, 0, "ADD", TGSI_OPCODE_ADD },
- { 1, 2, 0, 0, "DP3", TGSI_OPCODE_DP3 },
- { 1, 2, 0, 0, "DP4", TGSI_OPCODE_DP4 },
- { 1, 2, 0, 0, "DST", TGSI_OPCODE_DST },
- { 1, 2, 0, 0, "MIN", TGSI_OPCODE_MIN },
- { 1, 2, 0, 0, "MAX", TGSI_OPCODE_MAX },
- { 1, 2, 0, 0, "SLT", TGSI_OPCODE_SLT },
- { 1, 2, 0, 0, "SGE", TGSI_OPCODE_SGE },
- { 1, 3, 0, 0, "MAD", TGSI_OPCODE_MAD },
- { 1, 2, 0, 0, "SUB", TGSI_OPCODE_SUB },
- { 1, 3, 0, 0, "LRP", TGSI_OPCODE_LRP },
- { 1, 3, 0, 0, "CND", TGSI_OPCODE_CND },
- { 1, 3, 0, 0, "CND0", TGSI_OPCODE_CND0 },
- { 1, 3, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
- { 1, 2, 0, 0, "INDEX", TGSI_OPCODE_INDEX },
- { 1, 1, 0, 0, "NEGATE", TGSI_OPCODE_NEGATE },
- { 1, 1, 0, 0, "FRC", TGSI_OPCODE_FRC },
- { 1, 3, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
- { 1, 1, 0, 0, "FLR", TGSI_OPCODE_FLR },
- { 1, 1, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
- { 1, 1, 0, 0, "EX2", TGSI_OPCODE_EX2 },
- { 1, 1, 0, 0, "LG2", TGSI_OPCODE_LG2 },
- { 1, 2, 0, 0, "POW", TGSI_OPCODE_POW },
- { 1, 2, 0, 0, "XPD", TGSI_OPCODE_XPD },
- { 1, 2, 0, 0, "M4X4", TGSI_OPCODE_MULTIPLYMATRIX },
- { 1, 1, 0, 0, "ABS", TGSI_OPCODE_ABS },
- { 1, 1, 0, 0, "RCC", TGSI_OPCODE_RCC },
- { 1, 2, 0, 0, "DPH", TGSI_OPCODE_DPH },
- { 1, 1, 0, 0, "COS", TGSI_OPCODE_COS },
- { 1, 1, 0, 0, "DDX", TGSI_OPCODE_DDX },
- { 1, 1, 0, 0, "DDY", TGSI_OPCODE_DDY },
- { 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
- { 1, 1, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
- { 1, 1, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
- { 1, 1, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
- { 1, 1, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
- { 1, 2, 0, 0, "RFL", TGSI_OPCODE_RFL },
- { 1, 2, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
- { 1, 2, 0, 0, "SFL", TGSI_OPCODE_SFL },
- { 1, 2, 0, 0, "SGT", TGSI_OPCODE_SGT },
- { 1, 1, 0, 0, "SIN", TGSI_OPCODE_SIN },
- { 1, 2, 0, 0, "SLE", TGSI_OPCODE_SLE },
- { 1, 2, 0, 0, "SNE", TGSI_OPCODE_SNE },
- { 1, 2, 0, 0, "STR", TGSI_OPCODE_STR },
- { 1, 2, 1, 0, "TEX", TGSI_OPCODE_TEX },
- { 1, 4, 1, 0, "TXD", TGSI_OPCODE_TXD },
- { 1, 2, 1, 0, "TXP", TGSI_OPCODE_TXP },
- { 1, 1, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
- { 1, 1, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
- { 1, 1, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
- { 1, 1, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
- { 1, 3, 0, 0, "X2D", TGSI_OPCODE_X2D },
- { 1, 1, 0, 0, "ARA", TGSI_OPCODE_ARA },
- { 1, 1, 0, 0, "ARR", TGSI_OPCODE_ARR },
- { 0, 1, 0, 0, "BRA", TGSI_OPCODE_BRA },
- { 0, 0, 0, 1, "CAL", TGSI_OPCODE_CAL },
- { 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
- { 1, 1, 0, 0, "SSG", TGSI_OPCODE_SSG },
- { 1, 3, 0, 0, "CMP", TGSI_OPCODE_CMP },
- { 1, 1, 0, 0, "SCS", TGSI_OPCODE_SCS },
- { 1, 2, 1, 0, "TXB", TGSI_OPCODE_TXB },
- { 1, 1, 0, 0, "NRM", TGSI_OPCODE_NRM },
- { 1, 2, 0, 0, "DIV", TGSI_OPCODE_DIV },
- { 1, 2, 0, 0, "DP2", TGSI_OPCODE_DP2 },
- { 1, 2, 1, 0, "TXL", TGSI_OPCODE_TXL },
- { 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
- { 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
- { 0, 0, 0, 0, "LOOP", TGSI_OPCODE_LOOP },
- { 0, 1, 0, 0, "REP", TGSI_OPCODE_REP },
- { 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE },
- { 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF },
- { 0, 0, 0, 0, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
- { 0, 0, 0, 0, "ENDREP", TGSI_OPCODE_ENDREP },
- { 0, 1, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
- { 1, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
- { 1, 1, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
- { 1, 1, 0, 0, "I2F", TGSI_OPCODE_I2F },
- { 1, 1, 0, 0, "NOT", TGSI_OPCODE_NOT },
- { 1, 1, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
- { 1, 2, 0, 0, "SHL", TGSI_OPCODE_SHL },
- { 1, 2, 0, 0, "SHR", TGSI_OPCODE_SHR },
- { 1, 2, 0, 0, "AND", TGSI_OPCODE_AND },
- { 1, 2, 0, 0, "OR", TGSI_OPCODE_OR },
- { 1, 2, 0, 0, "MOD", TGSI_OPCODE_MOD },
- { 1, 2, 0, 0, "XOR", TGSI_OPCODE_XOR },
- { 1, 3, 0, 0, "SAD", TGSI_OPCODE_SAD },
- { 1, 2, 1, 0, "TXF", TGSI_OPCODE_TXF },
- { 1, 2, 1, 0, "TXQ", TGSI_OPCODE_TXQ },
- { 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
- { 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
- { 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
- { 0, 0, 0, 1, "BGNLOOP2", TGSI_OPCODE_BGNLOOP2 },
- { 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB },
- { 0, 0, 0, 1, "ENDLOOP2", TGSI_OPCODE_ENDLOOP2 },
- { 0, 0, 0, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
- { 1, 1, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
- { 1, 1, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
- { 1, 1, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
- { 1, 1, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
- { 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
- { 1, 2, 0, 0, "M4X3", TGSI_OPCODE_M4X3 },
- { 1, 2, 0, 0, "M3X4", TGSI_OPCODE_M3X4 },
- { 1, 2, 0, 0, "M3X3", TGSI_OPCODE_M3X3 },
- { 1, 2, 0, 0, "M3X2", TGSI_OPCODE_M3X2 },
- { 1, 1, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
- { 0, 1, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
- { 0, 1, 0, 0, "IFC", TGSI_OPCODE_IFC },
- { 0, 1, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
- { 0, 1, 0, 0, "KIL", TGSI_OPCODE_KIL },
- { 0, 0, 0, 0, "END", TGSI_OPCODE_END },
- { 1, 1, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
+ { 1, 1, 0, 0, 0, 0, "ARL", TGSI_OPCODE_ARL },
+ { 1, 1, 0, 0, 0, 0, "MOV", TGSI_OPCODE_MOV },
+ { 1, 1, 0, 0, 0, 0, "LIT", TGSI_OPCODE_LIT },
+ { 1, 1, 0, 0, 0, 0, "RCP", TGSI_OPCODE_RCP },
+ { 1, 1, 0, 0, 0, 0, "RSQ", TGSI_OPCODE_RSQ },
+ { 1, 1, 0, 0, 0, 0, "EXP", TGSI_OPCODE_EXP },
+ { 1, 1, 0, 0, 0, 0, "LOG", TGSI_OPCODE_LOG },
+ { 1, 2, 0, 0, 0, 0, "MUL", TGSI_OPCODE_MUL },
+ { 1, 2, 0, 0, 0, 0, "ADD", TGSI_OPCODE_ADD },
+ { 1, 2, 0, 0, 0, 0, "DP3", TGSI_OPCODE_DP3 },
+ { 1, 2, 0, 0, 0, 0, "DP4", TGSI_OPCODE_DP4 },
+ { 1, 2, 0, 0, 0, 0, "DST", TGSI_OPCODE_DST },
+ { 1, 2, 0, 0, 0, 0, "MIN", TGSI_OPCODE_MIN },
+ { 1, 2, 0, 0, 0, 0, "MAX", TGSI_OPCODE_MAX },
+ { 1, 2, 0, 0, 0, 0, "SLT", TGSI_OPCODE_SLT },
+ { 1, 2, 0, 0, 0, 0, "SGE", TGSI_OPCODE_SGE },
+ { 1, 3, 0, 0, 0, 0, "MAD", TGSI_OPCODE_MAD },
+ { 1, 2, 0, 0, 0, 0, "SUB", TGSI_OPCODE_SUB },
+ { 1, 3, 0, 0, 0, 0, "LRP", TGSI_OPCODE_LRP },
+ { 1, 3, 0, 0, 0, 0, "CND", TGSI_OPCODE_CND },
+ { 0, 0, 0, 0, 0, 0, "", 20 }, /* removed */
+ { 1, 3, 0, 0, 0, 0, "DP2A", TGSI_OPCODE_DP2A },
+ { 0, 0, 0, 0, 0, 0, "", 22 }, /* removed */
+ { 0, 0, 0, 0, 0, 0, "", 23 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, "FRC", TGSI_OPCODE_FRC },
+ { 1, 3, 0, 0, 0, 0, "CLAMP", TGSI_OPCODE_CLAMP },
+ { 1, 1, 0, 0, 0, 0, "FLR", TGSI_OPCODE_FLR },
+ { 1, 1, 0, 0, 0, 0, "ROUND", TGSI_OPCODE_ROUND },
+ { 1, 1, 0, 0, 0, 0, "EX2", TGSI_OPCODE_EX2 },
+ { 1, 1, 0, 0, 0, 0, "LG2", TGSI_OPCODE_LG2 },
+ { 1, 2, 0, 0, 0, 0, "POW", TGSI_OPCODE_POW },
+ { 1, 2, 0, 0, 0, 0, "XPD", TGSI_OPCODE_XPD },
+ { 0, 0, 0, 0, 0, 0, "", 32 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, "ABS", TGSI_OPCODE_ABS },
+ { 1, 1, 0, 0, 0, 0, "RCC", TGSI_OPCODE_RCC },
+ { 1, 2, 0, 0, 0, 0, "DPH", TGSI_OPCODE_DPH },
+ { 1, 1, 0, 0, 0, 0, "COS", TGSI_OPCODE_COS },
+ { 1, 1, 0, 0, 0, 0, "DDX", TGSI_OPCODE_DDX },
+ { 1, 1, 0, 0, 0, 0, "DDY", TGSI_OPCODE_DDY },
+ { 0, 0, 0, 0, 0, 0, "KILP", TGSI_OPCODE_KILP },
+ { 1, 1, 0, 0, 0, 0, "PK2H", TGSI_OPCODE_PK2H },
+ { 1, 1, 0, 0, 0, 0, "PK2US", TGSI_OPCODE_PK2US },
+ { 1, 1, 0, 0, 0, 0, "PK4B", TGSI_OPCODE_PK4B },
+ { 1, 1, 0, 0, 0, 0, "PK4UB", TGSI_OPCODE_PK4UB },
+ { 1, 2, 0, 0, 0, 0, "RFL", TGSI_OPCODE_RFL },
+ { 1, 2, 0, 0, 0, 0, "SEQ", TGSI_OPCODE_SEQ },
+ { 1, 2, 0, 0, 0, 0, "SFL", TGSI_OPCODE_SFL },
+ { 1, 2, 0, 0, 0, 0, "SGT", TGSI_OPCODE_SGT },
+ { 1, 1, 0, 0, 0, 0, "SIN", TGSI_OPCODE_SIN },
+ { 1, 2, 0, 0, 0, 0, "SLE", TGSI_OPCODE_SLE },
+ { 1, 2, 0, 0, 0, 0, "SNE", TGSI_OPCODE_SNE },
+ { 1, 2, 0, 0, 0, 0, "STR", TGSI_OPCODE_STR },
+ { 1, 2, 1, 0, 0, 0, "TEX", TGSI_OPCODE_TEX },
+ { 1, 4, 1, 0, 0, 0, "TXD", TGSI_OPCODE_TXD },
+ { 1, 2, 1, 0, 0, 0, "TXP", TGSI_OPCODE_TXP },
+ { 1, 1, 0, 0, 0, 0, "UP2H", TGSI_OPCODE_UP2H },
+ { 1, 1, 0, 0, 0, 0, "UP2US", TGSI_OPCODE_UP2US },
+ { 1, 1, 0, 0, 0, 0, "UP4B", TGSI_OPCODE_UP4B },
+ { 1, 1, 0, 0, 0, 0, "UP4UB", TGSI_OPCODE_UP4UB },
+ { 1, 3, 0, 0, 0, 0, "X2D", TGSI_OPCODE_X2D },
+ { 1, 1, 0, 0, 0, 0, "ARA", TGSI_OPCODE_ARA },
+ { 1, 1, 0, 0, 0, 0, "ARR", TGSI_OPCODE_ARR },
+ { 0, 1, 0, 0, 0, 0, "BRA", TGSI_OPCODE_BRA },
+ { 0, 0, 0, 1, 0, 0, "CAL", TGSI_OPCODE_CAL },
+ { 0, 0, 0, 0, 0, 0, "RET", TGSI_OPCODE_RET },
+ { 1, 1, 0, 0, 0, 0, "SSG", TGSI_OPCODE_SSG },
+ { 1, 3, 0, 0, 0, 0, "CMP", TGSI_OPCODE_CMP },
+ { 1, 1, 0, 0, 0, 0, "SCS", TGSI_OPCODE_SCS },
+ { 1, 2, 1, 0, 0, 0, "TXB", TGSI_OPCODE_TXB },
+ { 1, 1, 0, 0, 0, 0, "NRM", TGSI_OPCODE_NRM },
+ { 1, 2, 0, 0, 0, 0, "DIV", TGSI_OPCODE_DIV },
+ { 1, 2, 0, 0, 0, 0, "DP2", TGSI_OPCODE_DP2 },
+ { 1, 2, 1, 0, 0, 0, "TXL", TGSI_OPCODE_TXL },
+ { 0, 0, 0, 0, 0, 0, "BRK", TGSI_OPCODE_BRK },
+ { 0, 1, 0, 1, 0, 1, "IF", TGSI_OPCODE_IF },
+ { 1, 1, 0, 0, 0, 1, "BGNFOR", TGSI_OPCODE_BGNFOR },
+ { 0, 1, 0, 0, 0, 1, "REP", TGSI_OPCODE_REP },
+ { 0, 0, 0, 1, 1, 1, "ELSE", TGSI_OPCODE_ELSE },
+ { 0, 0, 0, 0, 1, 0, "ENDIF", TGSI_OPCODE_ENDIF },
+ { 1, 0, 0, 0, 1, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
+ { 0, 0, 0, 0, 1, 0, "ENDREP", TGSI_OPCODE_ENDREP },
+ { 0, 1, 0, 0, 0, 0, "PUSHA", TGSI_OPCODE_PUSHA },
+ { 1, 0, 0, 0, 0, 0, "POPA", TGSI_OPCODE_POPA },
+ { 1, 1, 0, 0, 0, 0, "CEIL", TGSI_OPCODE_CEIL },
+ { 1, 1, 0, 0, 0, 0, "I2F", TGSI_OPCODE_I2F },
+ { 1, 1, 0, 0, 0, 0, "NOT", TGSI_OPCODE_NOT },
+ { 1, 1, 0, 0, 0, 0, "TRUNC", TGSI_OPCODE_TRUNC },
+ { 1, 2, 0, 0, 0, 0, "SHL", TGSI_OPCODE_SHL },
+ { 1, 2, 0, 0, 0, 0, "SHR", TGSI_OPCODE_SHR },
+ { 1, 2, 0, 0, 0, 0, "AND", TGSI_OPCODE_AND },
+ { 1, 2, 0, 0, 0, 0, "OR", TGSI_OPCODE_OR },
+ { 1, 2, 0, 0, 0, 0, "MOD", TGSI_OPCODE_MOD },
+ { 1, 2, 0, 0, 0, 0, "XOR", TGSI_OPCODE_XOR },
+ { 1, 3, 0, 0, 0, 0, "SAD", TGSI_OPCODE_SAD },
+ { 1, 2, 1, 0, 0, 0, "TXF", TGSI_OPCODE_TXF },
+ { 1, 2, 1, 0, 0, 0, "TXQ", TGSI_OPCODE_TXQ },
+ { 0, 0, 0, 0, 0, 0, "CONT", TGSI_OPCODE_CONT },
+ { 0, 0, 0, 0, 0, 0, "EMIT", TGSI_OPCODE_EMIT },
+ { 0, 0, 0, 0, 0, 0, "ENDPRIM", TGSI_OPCODE_ENDPRIM },
+ { 0, 0, 0, 1, 0, 1, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
+ { 0, 0, 0, 0, 0, 1, "BGNSUB", TGSI_OPCODE_BGNSUB },
+ { 0, 0, 0, 1, 1, 0, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
+ { 0, 0, 0, 0, 1, 0, "ENDSUB", TGSI_OPCODE_ENDSUB },
+ { 1, 1, 0, 0, 0, 0, "NOISE1", TGSI_OPCODE_NOISE1 },
+ { 1, 1, 0, 0, 0, 0, "NOISE2", TGSI_OPCODE_NOISE2 },
+ { 1, 1, 0, 0, 0, 0, "NOISE3", TGSI_OPCODE_NOISE3 },
+ { 1, 1, 0, 0, 0, 0, "NOISE4", TGSI_OPCODE_NOISE4 },
+ { 0, 0, 0, 0, 0, 0, "NOP", TGSI_OPCODE_NOP },
+ { 0, 0, 0, 0, 0, 0, "", 108 }, /* removed */
+ { 0, 0, 0, 0, 0, 0, "", 109 }, /* removed */
+ { 0, 0, 0, 0, 0, 0, "", 110 }, /* removed */
+ { 0, 0, 0, 0, 0, 0, "", 111 }, /* removed */
+ { 1, 1, 0, 0, 0, 0, "NRM4", TGSI_OPCODE_NRM4 },
+ { 0, 1, 0, 0, 0, 0, "CALLNZ", TGSI_OPCODE_CALLNZ },
+ { 0, 1, 0, 0, 0, 0, "IFC", TGSI_OPCODE_IFC },
+ { 0, 1, 0, 0, 0, 0, "BREAKC", TGSI_OPCODE_BREAKC },
+ { 0, 1, 0, 0, 0, 0, "KIL", TGSI_OPCODE_KIL },
+ { 0, 0, 0, 0, 0, 0, "END", TGSI_OPCODE_END },
+ { 1, 1, 0, 0, 0, 0, "SWZ", TGSI_OPCODE_SWZ }
};
const struct tgsi_opcode_info *
@@ -170,3 +170,12 @@ tgsi_get_opcode_info( uint opcode )
assert( 0 );
return NULL;
}
+
+
+const char *
+tgsi_get_opcode_name( uint opcode )
+{
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info(opcode);
+ return info->mnemonic;
+}
+
diff --git a/src/gallium/auxiliary/tgsi/tgsi_info.h b/src/gallium/auxiliary/tgsi/tgsi_info.h
index 16577598bb..74713c3b98 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.h
@@ -36,10 +36,12 @@ extern "C" {
struct tgsi_opcode_info
{
- uint num_dst;
- uint num_src;
- boolean is_tex;
- boolean is_branch;
+ unsigned num_dst:3;
+ unsigned num_src:3;
+ unsigned is_tex:1;
+ unsigned is_branch:1;
+ int pre_dedent:2;
+ int post_indent:2;
const char *mnemonic;
uint opcode;
};
@@ -47,6 +49,10 @@ struct tgsi_opcode_info
const struct tgsi_opcode_info *
tgsi_get_opcode_info( uint opcode );
+const char *
+tgsi_get_opcode_name( uint opcode );
+
+
#if defined __cplusplus
}
#endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
new file mode 100644
index 0000000000..e7bcf4bf75
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -0,0 +1,172 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+#ifndef OP12_TEX
+#define OP12_TEX(a) OP12(a)
+#endif
+
+#ifndef OP14_TEX
+#define OP14_TEX(a) OP14(a)
+#endif
+
+#ifndef OP00_LBL
+#define OP00_LBL(a) OP00(a)
+#endif
+
+#ifndef OP01_LBL
+#define OP01_LBL(a) OP01(a)
+#endif
+
+OP11(ARL)
+OP11(MOV)
+OP11(LIT)
+OP11(RCP)
+OP11(RSQ)
+OP11(EXP)
+OP11(LOG)
+OP12(MUL)
+OP12(ADD)
+OP12(DP3)
+OP12(DP4)
+OP12(DST)
+OP12(MIN)
+OP12(MAX)
+OP12(SLT)
+OP12(SGE)
+OP13(MAD)
+OP12(SUB)
+OP13(LRP)
+OP13(CND)
+OP13(DP2A)
+OP11(FRC)
+OP13(CLAMP)
+OP11(FLR)
+OP11(ROUND)
+OP11(EX2)
+OP11(LG2)
+OP12(POW)
+OP12(XPD)
+OP11(ABS)
+OP11(RCC)
+OP12(DPH)
+OP11(COS)
+OP11(DDX)
+OP11(DDY)
+OP00(KILP)
+OP11(PK2H)
+OP11(PK2US)
+OP11(PK4B)
+OP11(PK4UB)
+OP12(RFL)
+OP12(SEQ)
+OP12(SFL)
+OP12(SGT)
+OP11(SIN)
+OP12(SLE)
+OP12(SNE)
+OP12(STR)
+OP12_TEX(TEX)
+OP14_TEX(TXD)
+OP12_TEX(TXP)
+OP11(UP2H)
+OP11(UP2US)
+OP11(UP4B)
+OP11(UP4UB)
+OP13(X2D)
+OP11(ARA)
+OP11(ARR)
+OP01(BRA)
+OP00_LBL(CAL)
+OP00(RET)
+OP11(SSG)
+OP13(CMP)
+OP11(SCS)
+OP12_TEX(TXB)
+OP11(NRM)
+OP12(DIV)
+OP12(DP2)
+OP12_TEX(TXL)
+OP00(BRK)
+OP01_LBL(IF)
+OP11(BGNFOR)
+OP01(REP)
+OP00_LBL(ELSE)
+OP00(ENDIF)
+OP10(ENDFOR)
+OP00(ENDREP)
+OP01(PUSHA)
+OP10(POPA)
+OP11(CEIL)
+OP11(I2F)
+OP11(NOT)
+OP11(TRUNC)
+OP12(SHL)
+OP12(SHR)
+OP12(AND)
+OP12(OR)
+OP12(MOD)
+OP12(XOR)
+OP13(SAD)
+OP12_TEX(TXF)
+OP12_TEX(TXQ)
+OP00(CONT)
+OP00(EMIT)
+OP00(ENDPRIM)
+OP00_LBL(BGNLOOP)
+OP00(BGNSUB)
+OP00_LBL(ENDLOOP)
+OP00(ENDSUB)
+OP11(NOISE1)
+OP11(NOISE2)
+OP11(NOISE3)
+OP11(NOISE4)
+OP00(NOP)
+OP11(NRM4)
+OP01(CALLNZ)
+OP01(IFC)
+OP01(BREAKC)
+OP01(KIL)
+OP00(END)
+OP11(SWZ)
+
+
+#undef OP00
+#undef OP01
+#undef OP10
+#undef OP11
+#undef OP12
+#undef OP13
+
+#ifdef OP14
+#undef OP14
+#endif
+
+#undef OP00_LBL
+#undef OP01_LBL
+
+#undef OP12_TEX
+#undef OP14_TEX
+
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index 1035bda1a8..a26ee5ba86 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -87,6 +87,7 @@ struct tgsi_full_instruction
struct tgsi_instruction_ext_texture InstructionExtTexture;
struct tgsi_full_dst_register FullDstRegisters[TGSI_FULL_MAX_DST_REGISTERS];
struct tgsi_full_src_register FullSrcRegisters[TGSI_FULL_MAX_SRC_REGISTERS];
+ uint Flags; /**< user-defined usage */
};
union tgsi_full_token
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index fddf54460a..4b1c7d4e01 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -38,6 +38,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_sse.h"
+#include "tgsi/tgsi_info.h"
#include "tgsi/tgsi_parse.h"
#include "tgsi/tgsi_util.h"
#include "tgsi_dump.h"
@@ -619,17 +620,17 @@ emit_unaryop(struct gen_context *gen, struct tgsi_full_instruction *inst)
ppc_vandc(gen->f, v1, v0, bit31_vec); /* v1 = v0 & ~bit31 */
}
break;
- case TGSI_OPCODE_FLOOR:
+ case TGSI_OPCODE_FLR:
ppc_vrfim(gen->f, v1, v0); /* v1 = floor(v0) */
break;
- case TGSI_OPCODE_FRAC:
+ case TGSI_OPCODE_FRC:
ppc_vrfim(gen->f, v1, v0); /* tmp = floor(v0) */
ppc_vsubfp(gen->f, v1, v0, v1); /* v1 = v0 - v1 */
break;
- case TGSI_OPCODE_EXPBASE2:
+ case TGSI_OPCODE_EX2:
ppc_vexptefp(gen->f, v1, v0); /* v1 = 2^v0 */
break;
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_LG2:
/* XXX this may be broken! */
ppc_vlogefp(gen->f, v1, v0); /* v1 = log2(v0) */
break;
@@ -1107,14 +1108,23 @@ static int
emit_instruction(struct gen_context *gen,
struct tgsi_full_instruction *inst)
{
+
+ /* we don't handle saturation/clamping yet */
+ if (inst->Instruction.Saturate != TGSI_SAT_NONE)
+ return 0;
+
+ /* need to use extra temps to fix SOA dependencies : */
+ if (tgsi_check_soa_dependencies(inst))
+ return FALSE;
+
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_MOV:
case TGSI_OPCODE_SWZ:
case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_FLOOR:
- case TGSI_OPCODE_FRAC:
- case TGSI_OPCODE_EXPBASE2:
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_FLR:
+ case TGSI_OPCODE_FRC:
+ case TGSI_OPCODE_EX2:
+ case TGSI_OPCODE_LG2:
emit_unaryop(gen, inst);
break;
case TGSI_OPCODE_RSQ:
@@ -1317,8 +1327,10 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
ok = emit_instruction(&gen, &parse.FullToken.FullInstruction);
if (!ok) {
- debug_printf("failed to translate tgsi opcode %d to PPC (%s)\n",
- parse.FullToken.FullInstruction.Instruction.Opcode,
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ debug_printf("failed to translate tgsi opcode %d (%s) to PPC (%s)\n",
+ opcode,
+ tgsi_get_opcode_name(opcode),
parse.FullHeader.Processor.Processor == TGSI_PROCESSOR_VERTEX ?
"vertex shader" : "fragment shader");
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 6f1f5c2b4b..53e13b30e6 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sanity.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
@@ -131,7 +131,7 @@ is_register_used(
return (ctx->regs_used[file][index / BITS_IN_REG_FLAG] & (1 << (index % BITS_IN_REG_FLAG))) ? TRUE : FALSE;
}
-static const char *file_names[] =
+static const char *file_names[TGSI_FILE_COUNT] =
{
"NULL",
"CONST",
@@ -140,7 +140,8 @@ static const char *file_names[] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static boolean
@@ -198,10 +199,10 @@ iter_instruction(
}
if (info->num_dst != inst->Instruction.NumDstRegs) {
- report_error( ctx, "Invalid number of destination operands, should be %u", info->num_dst );
+ report_error( ctx, "%s: Invalid number of destination operands, should be %u", info->mnemonic, info->num_dst );
}
if (info->num_src != inst->Instruction.NumSrcRegs) {
- report_error( ctx, "Invalid number of source operands, should be %u", info->num_src );
+ report_error( ctx, "%s: Invalid number of source operands, should be %u", info->mnemonic, info->num_src );
}
/* Check destination and source registers' validity.
@@ -234,9 +235,29 @@ iter_instruction(
index,
"indirect",
FALSE );
- if (file != TGSI_FILE_ADDRESS || index != 0)
- report_warning( ctx, "Indirect register not ADDR[0]" );
+ if (!(file == TGSI_FILE_ADDRESS || file == TGSI_FILE_LOOP) || index != 0) {
+ report_warning(ctx, "Indirect register neither ADDR[0] nor LOOP[0]");
+ }
+ }
+ }
+
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_BGNFOR:
+ case TGSI_OPCODE_ENDFOR:
+ if (inst->FullDstRegisters[0].DstRegister.File != TGSI_FILE_LOOP ||
+ inst->FullDstRegisters[0].DstRegister.Index != 0) {
+ report_error(ctx, "Destination register must be LOOP[0]");
+ }
+ break;
+ }
+
+ switch (inst->Instruction.Opcode) {
+ case TGSI_OPCODE_BGNFOR:
+ if (inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_CONSTANT &&
+ inst->FullSrcRegisters[0].SrcRegister.File != TGSI_FILE_IMMEDIATE) {
+ report_error(ctx, "Source register file must be either CONST or IMM");
}
+ break;
}
ctx->num_instructions++;
@@ -337,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 ca45e94c7a..52263ff883 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 c535788819..0db4481a3d 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 2c1a75bc81..8a7ee0c7e4 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 a2d4627da9..501fc05e72 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -36,10 +36,12 @@
#if defined(PIPE_ARCH_SSE)
#include "util/u_sse.h"
#endif
+#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"
@@ -1359,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(
@@ -1387,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 )\
@@ -1467,15 +1482,15 @@ emit_tex( struct x86_function *func,
switch (inst->InstructionExtTexture.Texture) {
case TGSI_TEXTURE_1D:
- case TGSI_TEXTURE_SHADOW1D:
count = 1;
break;
case TGSI_TEXTURE_2D:
case TGSI_TEXTURE_RECT:
- case TGSI_TEXTURE_SHADOW2D:
- case TGSI_TEXTURE_SHADOWRECT:
count = 2;
break;
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
case TGSI_TEXTURE_3D:
case TGSI_TEXTURE_CUBE:
count = 3;
@@ -1759,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;
@@ -2080,10 +2097,6 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_CND0:
- return 0;
- break;
-
case TGSI_OPCODE_DP2A:
FETCH( func, *inst, 0, 0, CHAN_X ); /* xmm0 = src[0].x */
FETCH( func, *inst, 1, 1, CHAN_X ); /* xmm1 = src[1].x */
@@ -2099,14 +2112,6 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_INDEX:
- return 0;
- break;
-
- case TGSI_OPCODE_NEGATE:
- return 0;
- break;
-
case TGSI_OPCODE_FRC:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
@@ -2206,10 +2211,6 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- return 0;
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
@@ -2543,7 +2544,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
return 0;
break;
@@ -2559,7 +2560,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
return 0;
break;
@@ -2929,11 +2930,29 @@ tgsi_emit_sse2(
&parse.FullToken.FullInstruction );
if (!ok) {
- debug_printf("failed to translate tgsi opcode %d to SSE (%s)\n",
- parse.FullToken.FullInstruction.Instruction.Opcode,
+ uint opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ debug_printf("failed to translate tgsi opcode %d (%s) to SSE (%s)\n",
+ opcode,
+ tgsi_get_opcode_name(opcode),
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_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index bfcbc40982..d438450b1e 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_text.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_text.c
@@ -231,7 +231,8 @@ static const char *file_names[TGSI_FILE_COUNT] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static boolean
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
new file mode 100644
index 0000000000..654426a903
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -0,0 +1,1077 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE, INC AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#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"
+
+union tgsi_any_token {
+ struct tgsi_version version;
+ struct tgsi_header header;
+ struct tgsi_processor processor;
+ struct tgsi_token token;
+ struct tgsi_declaration decl;
+ struct tgsi_declaration_range decl_range;
+ struct tgsi_declaration_semantic decl_semantic;
+ struct tgsi_immediate imm;
+ union tgsi_immediate_data imm_data;
+ struct tgsi_instruction insn;
+ struct tgsi_instruction_ext_nv insn_ext_nv;
+ struct tgsi_instruction_ext_label insn_ext_label;
+ struct tgsi_instruction_ext_texture insn_ext_texture;
+ struct tgsi_instruction_ext_predicate insn_ext_predicate;
+ struct tgsi_src_register src;
+ struct tgsi_src_register_ext_swz src_ext_swz;
+ struct tgsi_src_register_ext_mod src_ext_mod;
+ struct tgsi_dimension dim;
+ struct tgsi_dst_register dst;
+ struct tgsi_dst_register_ext_concode dst_ext_code;
+ struct tgsi_dst_register_ext_modulate dst_ext_mod;
+ struct tgsi_dst_register_ext_predicate dst_ext_pred;
+ unsigned value;
+};
+
+
+struct ureg_tokens {
+ union tgsi_any_token *tokens;
+ unsigned size;
+ unsigned order;
+ unsigned count;
+};
+
+#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
+
+#define DOMAIN_DECL 0
+#define DOMAIN_INSN 1
+
+struct ureg_program
+{
+ unsigned processor;
+ struct pipe_context *pipe;
+
+ struct {
+ unsigned semantic_name;
+ unsigned semantic_index;
+ unsigned interp;
+ } fs_input[UREG_MAX_INPUT];
+ unsigned nr_fs_inputs;
+
+ unsigned vs_inputs[UREG_MAX_INPUT/32];
+
+ struct {
+ unsigned semantic_name;
+ unsigned semantic_index;
+ } output[UREG_MAX_OUTPUT];
+ unsigned nr_outputs;
+
+ struct {
+ float v[4];
+ unsigned nr;
+ } immediate[UREG_MAX_IMMEDIATE];
+ unsigned nr_immediates;
+
+ struct ureg_src sampler[PIPE_MAX_SAMPLERS];
+ unsigned nr_samplers;
+
+ unsigned temps_active[UREG_MAX_TEMP / 32];
+ unsigned nr_temps;
+
+ struct {
+ unsigned first;
+ unsigned last;
+ } constant_range[UREG_MAX_CONSTANT_RANGE];
+ unsigned nr_constant_ranges;
+
+ unsigned nr_addrs;
+ unsigned nr_instructions;
+
+ struct ureg_tokens domain[2];
+};
+
+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;
+}
+
+
+static void tokens_expand( struct ureg_tokens *tokens,
+ unsigned count )
+{
+ unsigned old_size = tokens->size * sizeof(unsigned);
+
+ if (tokens->tokens == error_tokens)
+ goto fail;
+
+ while (tokens->count + count > tokens->size) {
+ tokens->size = (1 << ++tokens->order);
+ }
+
+ tokens->tokens = REALLOC(tokens->tokens,
+ old_size,
+ tokens->size * sizeof(unsigned));
+ if (tokens->tokens == NULL)
+ goto fail;
+
+ return;
+
+fail:
+ tokens_error(tokens);
+}
+
+static void set_bad( struct ureg_program *ureg )
+{
+ tokens_error(&ureg->domain[0]);
+}
+
+
+
+static union tgsi_any_token *get_tokens( struct ureg_program *ureg,
+ unsigned domain,
+ unsigned count )
+{
+ struct ureg_tokens *tokens = &ureg->domain[domain];
+ union tgsi_any_token *result;
+
+ if (tokens->count + count > tokens->size)
+ tokens_expand(tokens, count);
+
+ result = &tokens->tokens[tokens->count];
+ tokens->count += count;
+ return result;
+}
+
+
+static union tgsi_any_token *retrieve_token( struct ureg_program *ureg,
+ unsigned domain,
+ unsigned nr )
+{
+ if (ureg->domain[domain].tokens == error_tokens)
+ return &error_tokens[0];
+
+ return &ureg->domain[domain].tokens[nr];
+}
+
+
+
+static INLINE struct ureg_dst
+ureg_dst_register( unsigned file,
+ unsigned index )
+{
+ struct ureg_dst dst;
+
+ dst.File = file;
+ dst.WriteMask = TGSI_WRITEMASK_XYZW;
+ dst.Indirect = 0;
+ dst.IndirectIndex = 0;
+ dst.IndirectSwizzle = 0;
+ dst.Saturate = 0;
+ dst.Index = index;
+ dst.Pad1 = 0;
+ dst.Pad2 = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src_register( unsigned file,
+ unsigned index )
+{
+ struct ureg_src src;
+
+ src.File = file;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Pad = 0;
+ src.Indirect = 0;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
+ src.Absolute = 0;
+ src.Index = index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+
+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_fs_inputs; i++) {
+ if (ureg->fs_input[i].semantic_name == name &&
+ ureg->fs_input[i].semantic_index == index)
+ goto out;
+ }
+
+ 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 );
+ }
+
+out:
+ return ureg_src_register( TGSI_FILE_INPUT, i );
+}
+
+
+struct ureg_src
+ureg_DECL_vs_input( struct ureg_program *ureg,
+ unsigned index )
+{
+ assert(ureg->processor == TGSI_PROCESSOR_VERTEX);
+
+ ureg->vs_inputs[index/32] |= 1 << (index % 32);
+ return ureg_src_register( TGSI_FILE_INPUT, index );
+}
+
+
+struct ureg_dst
+ureg_DECL_output( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_outputs; i++) {
+ if (ureg->output[i].semantic_name == name &&
+ ureg->output[i].semantic_index == index)
+ goto out;
+ }
+
+ if (ureg->nr_outputs < UREG_MAX_OUTPUT) {
+ ureg->output[i].semantic_name = name;
+ ureg->output[i].semantic_index = index;
+ ureg->nr_outputs++;
+ }
+ else {
+ set_bad( ureg );
+ }
+
+out:
+ return ureg_dst_register( TGSI_FILE_OUTPUT, i );
+}
+
+
+/* Returns a new constant register. Keep track of which have been
+ * referred to so that we can emit decls later.
+ *
+ * There is nothing in this code to bind this constant to any tracked
+ * 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,
+ unsigned index )
+{
+ 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 );
+}
+
+
+/* Allocate a new temporary. Temporaries greater than UREG_MAX_TEMP
+ * are legal, but will not be released.
+ */
+struct ureg_dst ureg_DECL_temporary( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ for (i = 0; i < UREG_MAX_TEMP; i += 32) {
+ int bit = ffs(~ureg->temps_active[i/32]);
+ if (bit != 0) {
+ i += bit - 1;
+ goto out;
+ }
+ }
+
+ /* No reusable temps, so allocate a new one:
+ */
+ i = ureg->nr_temps++;
+
+out:
+ if (i < UREG_MAX_TEMP)
+ ureg->temps_active[i/32] |= 1 << (i % 32);
+
+ if (i >= ureg->nr_temps)
+ ureg->nr_temps = i + 1;
+
+ return ureg_dst_register( TGSI_FILE_TEMPORARY, i );
+}
+
+
+void ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp )
+{
+ if(tmp.File == TGSI_FILE_TEMPORARY)
+ if (tmp.Index < UREG_MAX_TEMP)
+ ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32));
+}
+
+
+/* Allocate a new address register.
+ */
+struct ureg_dst ureg_DECL_address( struct ureg_program *ureg )
+{
+ if (ureg->nr_addrs < UREG_MAX_ADDR)
+ return ureg_dst_register( TGSI_FILE_ADDRESS, ureg->nr_addrs++ );
+
+ assert( 0 );
+ return ureg_dst_register( TGSI_FILE_ADDRESS, 0 );
+}
+
+/* Allocate a new sampler.
+ */
+struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg,
+ unsigned nr )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_samplers; i++)
+ if (ureg->sampler[i].Index == nr)
+ return ureg->sampler[i];
+
+ if (i < PIPE_MAX_SAMPLERS) {
+ ureg->sampler[i] = ureg_src_register( TGSI_FILE_SAMPLER, nr );
+ ureg->nr_samplers++;
+ return ureg->sampler[i];
+ }
+
+ assert( 0 );
+ return ureg->sampler[0];
+}
+
+
+
+
+static int match_or_expand_immediate( const float *v,
+ unsigned nr,
+ float *v2,
+ unsigned *nr2,
+ unsigned *swizzle )
+{
+ unsigned i, j;
+
+ *swizzle = 0;
+
+ for (i = 0; i < nr; i++) {
+ boolean found = FALSE;
+
+ for (j = 0; j < *nr2 && !found; j++) {
+ if (v[i] == v2[j]) {
+ *swizzle |= j << (i * 2);
+ found = TRUE;
+ }
+ }
+
+ if (!found) {
+ if (*nr2 >= 4)
+ return FALSE;
+
+ v2[*nr2] = v[i];
+ *swizzle |= *nr2 << (i * 2);
+ (*nr2)++;
+ }
+ }
+
+ return TRUE;
+}
+
+
+
+
+struct ureg_src ureg_DECL_immediate( struct ureg_program *ureg,
+ const float *v,
+ unsigned nr )
+{
+ unsigned i, j;
+ unsigned swizzle;
+
+ /* Could do a first pass where we examine all existing immediates
+ * without expanding.
+ */
+
+ for (i = 0; i < ureg->nr_immediates; i++) {
+ if (match_or_expand_immediate( v,
+ nr,
+ ureg->immediate[i].v,
+ &ureg->immediate[i].nr,
+ &swizzle ))
+ goto out;
+ }
+
+ if (ureg->nr_immediates < UREG_MAX_IMMEDIATE) {
+ i = ureg->nr_immediates++;
+ if (match_or_expand_immediate( v,
+ nr,
+ ureg->immediate[i].v,
+ &ureg->immediate[i].nr,
+ &swizzle ))
+ goto out;
+ }
+
+ set_bad( ureg );
+
+out:
+ /* Make sure that all referenced elements are from this immediate.
+ * Has the effect of making size-one immediates into scalars.
+ */
+ for (j = nr; j < 4; j++)
+ swizzle |= (swizzle & 0x3) << (j * 2);
+
+ return ureg_swizzle( ureg_src_register( TGSI_FILE_IMMEDIATE, i ),
+ (swizzle >> 0) & 0x3,
+ (swizzle >> 2) & 0x3,
+ (swizzle >> 4) & 0x3,
+ (swizzle >> 6) & 0x3);
+}
+
+
+void
+ureg_emit_src( struct ureg_program *ureg,
+ struct ureg_src src )
+{
+ unsigned size = (1 +
+ (src.Absolute ? 1 : 0) +
+ (src.Indirect ? 1 : 0));
+
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
+ unsigned n = 0;
+
+ assert(src.File != TGSI_FILE_NULL);
+ assert(src.File != TGSI_FILE_OUTPUT);
+ assert(src.File < TGSI_FILE_COUNT);
+
+ out[n].value = 0;
+ out[n].src.File = src.File;
+ out[n].src.SwizzleX = src.SwizzleX;
+ out[n].src.SwizzleY = src.SwizzleY;
+ out[n].src.SwizzleZ = src.SwizzleZ;
+ out[n].src.SwizzleW = src.SwizzleW;
+ out[n].src.Index = src.Index;
+ out[n].src.Negate = src.Negate;
+ n++;
+
+ if (src.Absolute) {
+ out[0].src.Extended = 1;
+ out[0].src.Negate = 0;
+ out[n].value = 0;
+ out[n].src_ext_mod.Type = TGSI_SRC_REGISTER_EXT_TYPE_MOD;
+ out[n].src_ext_mod.Absolute = 1;
+ out[n].src_ext_mod.Negate = src.Negate;
+ n++;
+ }
+
+ if (src.Indirect) {
+ out[0].src.Indirect = 1;
+ out[n].value = 0;
+ out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.SwizzleX = src.IndirectSwizzle;
+ out[n].src.SwizzleY = src.IndirectSwizzle;
+ out[n].src.SwizzleZ = src.IndirectSwizzle;
+ out[n].src.SwizzleW = src.IndirectSwizzle;
+ out[n].src.Index = src.IndirectIndex;
+ n++;
+ }
+
+ assert(n == size);
+}
+
+
+void
+ureg_emit_dst( struct ureg_program *ureg,
+ struct ureg_dst dst )
+{
+ unsigned size = (1 +
+ (dst.Indirect ? 1 : 0));
+
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_INSN, size );
+ unsigned n = 0;
+
+ assert(dst.File != TGSI_FILE_NULL);
+ assert(dst.File != TGSI_FILE_CONSTANT);
+ assert(dst.File != TGSI_FILE_INPUT);
+ assert(dst.File != TGSI_FILE_SAMPLER);
+ assert(dst.File != TGSI_FILE_IMMEDIATE);
+ assert(dst.File < TGSI_FILE_COUNT);
+
+ out[n].value = 0;
+ out[n].dst.File = dst.File;
+ out[n].dst.WriteMask = dst.WriteMask;
+ out[n].dst.Indirect = dst.Indirect;
+ out[n].dst.Index = dst.Index;
+ n++;
+
+ if (dst.Indirect) {
+ out[n].value = 0;
+ out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.SwizzleX = dst.IndirectSwizzle;
+ out[n].src.SwizzleY = dst.IndirectSwizzle;
+ out[n].src.SwizzleZ = dst.IndirectSwizzle;
+ out[n].src.SwizzleW = dst.IndirectSwizzle;
+ out[n].src.Index = dst.IndirectIndex;
+ n++;
+ }
+
+ assert(n == size);
+}
+
+
+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,
+ unsigned opcode,
+ boolean saturate,
+ unsigned num_dst,
+ unsigned num_src )
+{
+ 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;
+ out[0].insn.NrTokens = 0;
+ out[0].insn.Opcode = opcode;
+ out[0].insn.Saturate = saturate;
+ out[0].insn.NumDstRegs = num_dst;
+ out[0].insn.NumSrcRegs = num_src;
+ out[0].insn.Padding = 0;
+ out[0].insn.Extended = 0;
+
+ ureg->nr_instructions++;
+
+ return ureg->domain[DOMAIN_INSN].count - 1;
+}
+
+
+void
+ureg_emit_label(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned *label_token )
+{
+ union tgsi_any_token *out, *insn;
+
+ if(!label_token)
+ return;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
+
+ insn->insn.Extended = 1;
+
+ out[0].value = 0;
+ out[0].insn_ext_label.Type = TGSI_INSTRUCTION_EXT_TYPE_LABEL;
+
+ *label_token = ureg->domain[DOMAIN_INSN].count - 1;
+}
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg )
+{
+ return ureg->nr_instructions;
+}
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+ unsigned label_token,
+ unsigned instruction_number )
+{
+ union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, label_token );
+
+ assert(out->insn_ext_label.Type == TGSI_INSTRUCTION_EXT_TYPE_LABEL);
+ out->insn_ext_label.Label = instruction_number;
+}
+
+
+void
+ureg_emit_texture(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned target )
+{
+ union tgsi_any_token *out, *insn;
+
+ out = get_tokens( ureg, DOMAIN_INSN, 1 );
+ insn = retrieve_token( ureg, DOMAIN_INSN, insn_token );
+
+ insn->insn.Extended = 1;
+
+ out[0].value = 0;
+ out[0].insn_ext_texture.Type = TGSI_INSTRUCTION_EXT_TYPE_TEXTURE;
+ out[0].insn_ext_texture.Texture = target;
+}
+
+
+void
+ureg_fixup_insn_size(struct ureg_program *ureg,
+ unsigned insn )
+{
+ union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_INSN, insn );
+
+ assert(out->insn.Type == TGSI_TOKEN_TYPE_INSTRUCTION);
+ out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
+}
+
+
+void
+ureg_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ 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 );
+
+ 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_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,
+ unsigned file,
+ unsigned index,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 );
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 3;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = TGSI_WRITEMASK_XYZW; /* FIXME! */
+ out[0].decl.Interpolate = interp;
+ out[0].decl.Semantic = 1;
+
+ out[1].value = 0;
+ out[1].decl_range.First =
+ out[1].decl_range.Last = index;
+
+ out[2].value = 0;
+ out[2].decl_semantic.SemanticName = semantic_name;
+ out[2].decl_semantic.SemanticIndex = semantic_index;
+
+}
+
+
+static void emit_decl_range( struct ureg_program *ureg,
+ unsigned file,
+ unsigned first,
+ unsigned count )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 2 );
+
+ out[0].value = 0;
+ out[0].decl.Type = TGSI_TOKEN_TYPE_DECLARATION;
+ out[0].decl.NrTokens = 2;
+ out[0].decl.File = file;
+ out[0].decl.UsageMask = 0xf;
+ out[0].decl.Interpolate = TGSI_INTERPOLATE_CONSTANT;
+ out[0].decl.Semantic = 0;
+
+ out[1].value = 0;
+ out[1].decl_range.First = first;
+ out[1].decl_range.Last = first + count - 1;
+}
+
+static void emit_immediate( struct ureg_program *ureg,
+ const float *v )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 5 );
+
+ out[0].value = 0;
+ out[0].imm.Type = TGSI_TOKEN_TYPE_IMMEDIATE;
+ out[0].imm.NrTokens = 5;
+ out[0].imm.DataType = TGSI_IMM_FLOAT32;
+ out[0].imm.Padding = 0;
+ out[0].imm.Extended = 0;
+
+ out[1].imm_data.Float = v[0];
+ out[2].imm_data.Float = v[1];
+ out[3].imm_data.Float = v[2];
+ out[4].imm_data.Float = v[3];
+}
+
+
+
+
+static void emit_decls( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ 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++) {
+ emit_decl( ureg,
+ TGSI_FILE_OUTPUT,
+ i,
+ ureg->output[i].semantic_name,
+ ureg->output[i].semantic_index,
+ TGSI_INTERPOLATE_CONSTANT );
+ }
+
+ for (i = 0; i < ureg->nr_samplers; i++) {
+ emit_decl_range( ureg,
+ TGSI_FILE_SAMPLER,
+ ureg->sampler[i].Index, 1 );
+ }
+
+ 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) {
+ emit_decl_range( ureg,
+ TGSI_FILE_TEMPORARY,
+ 0, ureg->nr_temps );
+ }
+
+ if (ureg->nr_addrs) {
+ emit_decl_range( ureg,
+ TGSI_FILE_ADDRESS,
+ 0, ureg->nr_addrs );
+ }
+
+ for (i = 0; i < ureg->nr_immediates; i++) {
+ emit_immediate( ureg,
+ ureg->immediate[i].v );
+ }
+}
+
+/* Append the instruction tokens onto the declarations to build a
+ * contiguous stream suitable to send to the driver.
+ */
+static void copy_instructions( struct ureg_program *ureg )
+{
+ unsigned nr_tokens = ureg->domain[DOMAIN_INSN].count;
+ union tgsi_any_token *out = get_tokens( ureg,
+ DOMAIN_DECL,
+ nr_tokens );
+
+ memcpy(out,
+ ureg->domain[DOMAIN_INSN].tokens,
+ nr_tokens * sizeof out[0] );
+}
+
+
+static void
+fixup_header_size(struct ureg_program *ureg)
+{
+ union tgsi_any_token *out = retrieve_token( ureg, DOMAIN_DECL, 1 );
+
+ out->header.BodySize = ureg->domain[DOMAIN_DECL].count - 3;
+}
+
+
+static void
+emit_header( struct ureg_program *ureg )
+{
+ union tgsi_any_token *out = get_tokens( ureg, DOMAIN_DECL, 3 );
+
+ out[0].version.MajorVersion = 1;
+ out[0].version.MinorVersion = 1;
+ out[0].version.Padding = 0;
+
+ out[1].header.HeaderSize = 2;
+ out[1].header.BodySize = 0;
+
+ out[2].processor.Processor = ureg->processor;
+ out[2].processor.Padding = 0;
+}
+
+
+const struct tgsi_token *ureg_finalize( struct ureg_program *ureg )
+{
+ const struct tgsi_token *tokens;
+
+ emit_header( ureg );
+ emit_decls( ureg );
+ copy_instructions( ureg );
+ fixup_header_size( ureg );
+
+ if (ureg->domain[0].tokens == error_tokens ||
+ ureg->domain[1].tokens == error_tokens) {
+ debug_printf("%s: error in generated shader\n", __FUNCTION__);
+ assert(0);
+ return NULL;
+ }
+
+ tokens = &ureg->domain[DOMAIN_DECL].tokens[0].token;
+
+ if (0) {
+ debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
+ 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;
+}
+
+
+void *ureg_create_shader( struct ureg_program *ureg,
+ struct pipe_context *pipe )
+{
+ struct pipe_shader_state state;
+
+ state.tokens = ureg_finalize(ureg);
+ if(!state.tokens)
+ return NULL;
+
+ if (ureg->processor == TGSI_PROCESSOR_VERTEX)
+ return pipe->create_vs_state( pipe, &state );
+ else
+ return pipe->create_fs_state( pipe, &state );
+}
+
+
+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 )
+{
+ struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
+ if (ureg == NULL)
+ return NULL;
+
+ ureg->processor = processor;
+ return ureg;
+}
+
+
+void ureg_destroy( struct ureg_program *ureg )
+{
+ unsigned i;
+
+ for (i = 0; i < Elements(ureg->domain); i++) {
+ if (ureg->domain[i].tokens &&
+ ureg->domain[i].tokens != error_tokens)
+ FREE(ureg->domain[i].tokens);
+ }
+
+ FREE(ureg);
+}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.h b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
new file mode 100644
index 0000000000..f04f443b9e
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -0,0 +1,619 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE, INC 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 TGSI_UREG_H
+#define TGSI_UREG_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_shader_tokens.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ureg_program;
+
+/* Almost a tgsi_src_register, but we need to pull in the Absolute
+ * flag from the _ext token. Indirect flag always implies ADDR[0].
+ */
+struct ureg_src
+{
+ unsigned File : 4; /* TGSI_FILE_ */
+ unsigned SwizzleX : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleY : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleZ : 2; /* TGSI_SWIZZLE_ */
+ unsigned SwizzleW : 2; /* TGSI_SWIZZLE_ */
+ unsigned Pad : 1; /* BOOL */
+ unsigned Indirect : 1; /* BOOL */
+ unsigned Absolute : 1; /* BOOL */
+ int Index : 16; /* SINT */
+ unsigned Negate : 1; /* BOOL */
+ int IndirectIndex : 16; /* SINT */
+ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
+};
+
+/* Very similar to a tgsi_dst_register, removing unsupported fields
+ * and adding a Saturate flag. It's easier to push saturate into the
+ * destination register than to try and create a _SAT varient of each
+ * instruction function.
+ */
+struct ureg_dst
+{
+ unsigned File : 4; /* TGSI_FILE_ */
+ unsigned WriteMask : 4; /* TGSI_WRITEMASK_ */
+ unsigned Indirect : 1; /* BOOL */
+ unsigned Saturate : 1; /* BOOL */
+ int Index : 16; /* SINT */
+ unsigned Pad1 : 5;
+ unsigned Pad2 : 1; /* BOOL */
+ int IndirectIndex : 16; /* SINT */
+ int IndirectSwizzle : 2; /* TGSI_SWIZZLE_ */
+};
+
+struct pipe_context;
+
+struct ureg_program *
+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 * );
+
+
+/***********************************************************************
+ * Convenience routine:
+ */
+static INLINE void *
+ureg_create_shader_and_destroy( struct ureg_program *p,
+ struct pipe_context *pipe )
+{
+ void *result = ureg_create_shader( p, pipe );
+ ureg_destroy( p );
+ return result;
+}
+
+
+
+/***********************************************************************
+ * Build shader declarations:
+ */
+
+struct ureg_src
+ureg_DECL_fs_input( struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index,
+ unsigned interp_mode );
+
+struct ureg_src
+ureg_DECL_vs_input( struct ureg_program *,
+ unsigned index );
+
+struct ureg_dst
+ureg_DECL_output( struct ureg_program *,
+ unsigned semantic_name,
+ unsigned semantic_index );
+
+struct ureg_src
+ureg_DECL_immediate( struct ureg_program *,
+ const float *v,
+ unsigned nr );
+
+struct ureg_src
+ureg_DECL_constant( struct ureg_program *,
+ unsigned index );
+
+struct ureg_dst
+ureg_DECL_temporary( struct ureg_program * );
+
+void
+ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp );
+
+struct ureg_dst
+ureg_DECL_address( struct ureg_program * );
+
+/* Supply an index to the sampler declaration as this is the hook to
+ * the external pipe_sampler state. Users of this function probably
+ * don't want just any sampler, but a specific one which they've set
+ * up state for in the context.
+ */
+struct ureg_src
+ureg_DECL_sampler( struct ureg_program *,
+ unsigned index );
+
+
+static INLINE struct ureg_src
+ureg_imm4f( struct ureg_program *ureg,
+ float a, float b,
+ float c, float d)
+{
+ float v[4];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ v[3] = d;
+ return ureg_DECL_immediate( ureg, v, 4 );
+}
+
+static INLINE struct ureg_src
+ureg_imm3f( struct ureg_program *ureg,
+ float a, float b,
+ float c)
+{
+ float v[3];
+ v[0] = a;
+ v[1] = b;
+ v[2] = c;
+ return ureg_DECL_immediate( ureg, v, 3 );
+}
+
+static INLINE struct ureg_src
+ureg_imm2f( struct ureg_program *ureg,
+ float a, float b)
+{
+ float v[2];
+ v[0] = a;
+ v[1] = b;
+ return ureg_DECL_immediate( ureg, v, 2 );
+}
+
+static INLINE struct ureg_src
+ureg_imm1f( struct ureg_program *ureg,
+ float a)
+{
+ float v[1];
+ v[0] = a;
+ return ureg_DECL_immediate( ureg, v, 1 );
+}
+
+/***********************************************************************
+ * Functions for patching up labels
+ */
+
+
+/* Will return a number which can be used in a label to point to the
+ * next instruction to be emitted.
+ */
+unsigned
+ureg_get_instruction_number( struct ureg_program *ureg );
+
+
+/* Patch a given label (expressed as a token number) to point to a
+ * given instruction (expressed as an instruction number).
+ *
+ * Labels are obtained from instruction emitters, eg ureg_CAL().
+ * Instruction numbers are obtained from ureg_get_instruction_number(),
+ * above.
+ */
+void
+ureg_fixup_label(struct ureg_program *ureg,
+ unsigned label_token,
+ unsigned instruction_number );
+
+
+/* Generic instruction emitter. Use if you need to pass the opcode as
+ * a parameter, rather than using the emit_OP() varients below.
+ */
+void
+ureg_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ const struct ureg_dst *dst,
+ unsigned nr_dst,
+ const struct ureg_src *src,
+ 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:
+ */
+
+unsigned
+ureg_emit_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ boolean saturate,
+ unsigned num_dst,
+ unsigned num_src );
+
+void
+ureg_emit_label(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned *label_token );
+
+void
+ureg_emit_texture(struct ureg_program *ureg,
+ unsigned insn_token,
+ unsigned target );
+
+void
+ureg_emit_dst( struct ureg_program *ureg,
+ struct ureg_dst dst );
+
+void
+ureg_emit_src( struct ureg_program *ureg,
+ struct ureg_src src );
+
+void
+ureg_fixup_insn_size(struct ureg_program *ureg,
+ unsigned insn );
+
+
+#define OP00( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP01( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_src src ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP00_LBL( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ unsigned *label_token ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 0 ); \
+ ureg_emit_label( ureg, insn, label_token ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP01_LBL( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_src src, \
+ unsigned *label_token ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, FALSE, 0, 1 ); \
+ ureg_emit_label( ureg, insn, label_token ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP10( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 0 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
+#define OP11( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 1 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP12( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP12_TEX( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ unsigned target, \
+ struct ureg_src src0, \
+ struct ureg_src src1 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 2 ); \
+ ureg_emit_texture( ureg, insn, target ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP13( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 3 ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+#define OP14_TEX( op ) \
+static INLINE void ureg_##op( struct ureg_program *ureg, \
+ struct ureg_dst dst, \
+ unsigned target, \
+ struct ureg_src src0, \
+ struct ureg_src src1, \
+ struct ureg_src src2, \
+ struct ureg_src src3 ) \
+{ \
+ unsigned opcode = TGSI_OPCODE_##op; \
+ unsigned insn = ureg_emit_insn( ureg, opcode, dst.Saturate, 1, 4 ); \
+ ureg_emit_texture( ureg, insn, target ); \
+ ureg_emit_dst( ureg, dst ); \
+ ureg_emit_src( ureg, src0 ); \
+ ureg_emit_src( ureg, src1 ); \
+ ureg_emit_src( ureg, src2 ); \
+ ureg_emit_src( ureg, src3 ); \
+ ureg_fixup_insn_size( ureg, insn ); \
+}
+
+
+/* Use a template include to generate a correctly-typed ureg_OP()
+ * function for each TGSI opcode:
+ */
+#include "tgsi_opcode_tmp.h"
+
+
+/***********************************************************************
+ * Inline helpers for manipulating register structs:
+ */
+static INLINE struct ureg_src
+ureg_negate( struct ureg_src reg )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Negate ^= 1;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_abs( struct ureg_src reg )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Absolute = 1;
+ reg.Negate = 0;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_swizzle( struct ureg_src reg,
+ int x, int y, int z, int w )
+{
+ unsigned swz = ( (reg.SwizzleX << 0) |
+ (reg.SwizzleY << 2) |
+ (reg.SwizzleZ << 4) |
+ (reg.SwizzleW << 6));
+
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(x < 4);
+ assert(y < 4);
+ assert(z < 4);
+ assert(w < 4);
+
+ reg.SwizzleX = (swz >> (x*2)) & 0x3;
+ reg.SwizzleY = (swz >> (y*2)) & 0x3;
+ reg.SwizzleZ = (swz >> (z*2)) & 0x3;
+ reg.SwizzleW = (swz >> (w*2)) & 0x3;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_scalar( struct ureg_src reg, int x )
+{
+ return ureg_swizzle(reg, x, x, x, x);
+}
+
+static INLINE struct ureg_dst
+ureg_writemask( struct ureg_dst reg,
+ unsigned writemask )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.WriteMask &= writemask;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_saturate( struct ureg_dst reg )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ reg.Saturate = 1;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_dst_indirect( struct ureg_dst reg, struct ureg_src addr )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(addr.File == TGSI_FILE_ADDRESS);
+ reg.Indirect = 1;
+ reg.IndirectIndex = addr.Index;
+ reg.IndirectSwizzle = addr.SwizzleX;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_src_indirect( struct ureg_src reg, struct ureg_src addr )
+{
+ assert(reg.File != TGSI_FILE_NULL);
+ assert(addr.File == TGSI_FILE_ADDRESS);
+ reg.Indirect = 1;
+ reg.IndirectIndex = addr.Index;
+ reg.IndirectSwizzle = addr.SwizzleX;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_dst( struct ureg_src src )
+{
+ struct ureg_dst dst;
+
+ dst.File = src.File;
+ dst.WriteMask = TGSI_WRITEMASK_XYZW;
+ dst.Indirect = src.Indirect;
+ dst.IndirectIndex = src.IndirectIndex;
+ dst.IndirectSwizzle = src.IndirectSwizzle;
+ dst.Saturate = 0;
+ dst.Index = src.Index;
+ dst.Pad1 = 0;
+ dst.Pad2 = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src( struct ureg_dst dst )
+{
+ struct ureg_src src;
+
+ src.File = dst.File;
+ src.SwizzleX = TGSI_SWIZZLE_X;
+ src.SwizzleY = TGSI_SWIZZLE_Y;
+ src.SwizzleZ = TGSI_SWIZZLE_Z;
+ src.SwizzleW = TGSI_SWIZZLE_W;
+ src.Pad = 0;
+ src.Indirect = dst.Indirect;
+ src.IndirectIndex = dst.IndirectIndex;
+ src.IndirectSwizzle = dst.IndirectSwizzle;
+ src.Absolute = 0;
+ src.Index = dst.Index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+static INLINE struct ureg_dst
+ureg_dst_undef( void )
+{
+ struct ureg_dst dst;
+
+ dst.File = TGSI_FILE_NULL;
+ dst.WriteMask = 0;
+ dst.Indirect = 0;
+ dst.IndirectIndex = 0;
+ dst.IndirectSwizzle = 0;
+ dst.Saturate = 0;
+ dst.Index = 0;
+ dst.Pad1 = 0;
+ dst.Pad2 = 0;
+
+ return dst;
+}
+
+static INLINE struct ureg_src
+ureg_src_undef( void )
+{
+ struct ureg_src src;
+
+ src.File = TGSI_FILE_NULL;
+ src.SwizzleX = 0;
+ src.SwizzleY = 0;
+ src.SwizzleZ = 0;
+ src.SwizzleW = 0;
+ src.Pad = 0;
+ src.Indirect = 0;
+ src.IndirectIndex = 0;
+ src.IndirectSwizzle = 0;
+ src.Absolute = 0;
+ src.Index = 0;
+ src.Negate = 0;
+
+ return src;
+}
+
+static INLINE boolean
+ureg_src_is_undef( struct ureg_src src )
+{
+ return src.File == TGSI_FILE_NULL;
+}
+
+static INLINE boolean
+ureg_dst_is_undef( struct ureg_dst dst )
+{
+ return dst.File == TGSI_FILE_NULL;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/auxiliary/tgsi/tgsi_util.h b/src/gallium/auxiliary/tgsi/tgsi_util.h
index 7877f34558..21eb656327 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_util.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_util.h
@@ -32,6 +32,10 @@
extern "C" {
#endif
+struct tgsi_src_register;
+struct tgsi_src_register_ext_swz;
+struct tgsi_full_src_register;
+
void *
tgsi_align_128bit(
void *unaligned );
diff --git a/src/gallium/auxiliary/util/.gitignore b/src/gallium/auxiliary/util/.gitignore
new file mode 100644
index 0000000000..29c586c9b5
--- /dev/null
+++ b/src/gallium/auxiliary/util/.gitignore
@@ -0,0 +1,2 @@
+u_format_access.c
+u_format_table.c
diff --git a/src/gallium/auxiliary/util/Makefile b/src/gallium/auxiliary/util/Makefile
index 6a8eb73e84..ae8d330a78 100644
--- a/src/gallium/auxiliary/util/Makefile
+++ b/src/gallium/auxiliary/util/Makefile
@@ -5,11 +5,15 @@ LIBNAME = util
C_SOURCES = \
u_debug.c \
+ u_debug_dump.c \
u_debug_symbol.c \
u_debug_stack.c \
u_blit.c \
u_cache.c \
u_draw_quad.c \
+ u_format.c \
+ u_format_access.c \
+ u_format_table.c \
u_gen_mipmap.c \
u_handle_table.c \
u_hash_table.c \
@@ -32,3 +36,9 @@ C_SOURCES = \
u_simple_screen.c
include ../../Makefile.template
+
+u_format_table.c: u_format_table.py u_format_parse.py u_format.csv
+ python u_format_table.py u_format.csv > $@
+
+u_format_access.c: u_format_access.py u_format_parse.py u_format.csv
+ python u_format_access.py u_format.csv > $@
diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript
index fb142eebca..28a5ab4256 100644
--- a/src/gallium/auxiliary/util/SConscript
+++ b/src/gallium/auxiliary/util/SConscript
@@ -1,5 +1,23 @@
Import('*')
+env.Clone()
+
+env.Append(CPPPATH = ['.'])
+
+env.CodeGenerate(
+ target = 'u_format_table.c',
+ script = 'u_format_table.py',
+ source = ['u_format.csv'],
+ command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
+env.CodeGenerate(
+ target = 'u_format_access.c',
+ script = 'u_format_access.py',
+ source = ['u_format.csv'],
+ command = 'python $SCRIPT $SOURCE > $TARGET'
+)
+
util = env.ConvenienceLibrary(
target = 'util',
source = [
@@ -7,11 +25,15 @@ util = env.ConvenienceLibrary(
'u_blit.c',
'u_cache.c',
'u_debug.c',
+ 'u_debug_dump.c',
'u_debug_memory.c',
'u_debug_profile.c',
'u_debug_stack.c',
'u_debug_symbol.c',
'u_draw_quad.c',
+ 'u_format.c',
+ 'u_format_access.c',
+ 'u_format_table.c',
'u_gen_mipmap.c',
'u_handle_table.c',
'u_hash.c',
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 414cf91025..c516317d70 100644
--- a/src/gallium/auxiliary/util/u_blit.c
+++ b/src/gallium/auxiliary/util/u_blit.c
@@ -45,6 +45,7 @@
#include "util/u_math.h"
#include "util/u_memory.h"
#include "util/u_simple_shaders.h"
+#include "util/u_surface.h"
#include "cso_cache/cso_context.h"
@@ -61,7 +62,7 @@ struct blit_state
struct pipe_viewport_state viewport;
void *vs;
- void *fs;
+ void *fs[TGSI_WRITEMASK_XYZW + 1];
struct pipe_buffer *vbuf; /**< quad vertices */
unsigned vbuf_slot;
@@ -124,7 +125,7 @@ util_create_blit(struct pipe_context *pipe, struct cso_context *cso)
}
/* fragment shader */
- ctx->fs = util_make_fragment_tex_shader(pipe);
+ ctx->fs[TGSI_WRITEMASK_XYZW] = util_make_fragment_tex_shader(pipe);
ctx->vbuf = NULL;
/* init vertex data that doesn't change */
@@ -145,9 +146,13 @@ void
util_destroy_blit(struct blit_state *ctx)
{
struct pipe_context *pipe = ctx->pipe;
+ unsigned i;
pipe->delete_vs_state(pipe, ctx->vs);
- pipe->delete_fs_state(pipe, ctx->fs);
+
+ for (i = 0; i < Elements(ctx->fs); i++)
+ if (ctx->fs[i])
+ pipe->delete_fs_state(pipe, ctx->fs[i]);
pipe_buffer_reference(&ctx->vbuf, NULL);
@@ -155,7 +160,11 @@ util_destroy_blit(struct blit_state *ctx)
}
-static unsigned get_next_slot( struct blit_state *ctx )
+/**
+ * Get offset of next free slot in vertex buffer for quad vertices.
+ */
+static unsigned
+get_next_slot( struct blit_state *ctx )
{
const unsigned max_slots = 4096 / sizeof ctx->vertices;
@@ -173,7 +182,6 @@ static unsigned get_next_slot( struct blit_state *ctx )
}
-
/**
* Setup vertex data for the textured quad we'll draw.
* Note: y=0=top
@@ -260,20 +268,50 @@ setup_vertex_data_tex(struct blit_state *ctx,
return offset;
}
+
+
+/**
+ * \return TRUE if two regions overlap, FALSE otherwise
+ */
+static boolean
+regions_overlap(int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1)
+{
+ if (MAX2(srcX0, srcX1) < MIN2(dstX0, dstX1))
+ return FALSE; /* src completely left of dst */
+
+ if (MAX2(dstX0, dstX1) < MIN2(srcX0, srcX1))
+ return FALSE; /* dst completely left of src */
+
+ if (MAX2(srcY0, srcY1) < MIN2(dstY0, dstY1))
+ return FALSE; /* src completely above dst */
+
+ if (MAX2(dstY0, dstY1) < MIN2(srcY0, srcY1))
+ return FALSE; /* dst completely above src */
+
+ return TRUE; /* some overlap */
+}
+
+
/**
* Copy pixel block from src surface to dst surface.
* Overlapping regions are acceptable.
+ * Flipping and stretching are supported.
+ * XXX what about clipping???
* XXX need some control over blitting Z and/or stencil.
*/
void
-util_blit_pixels(struct blit_state *ctx,
- struct pipe_surface *src,
- int srcX0, int srcY0,
- int srcX1, int srcY1,
- struct pipe_surface *dst,
- int dstX0, int dstY0,
- int dstX1, int dstY1,
- float z, uint filter)
+util_blit_pixels_writemask(struct blit_state *ctx,
+ struct pipe_surface *src,
+ int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ struct pipe_surface *dst,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1,
+ float z, uint filter,
+ uint writemask)
{
struct pipe_context *pipe = ctx->pipe;
struct pipe_screen *screen = pipe->screen;
@@ -285,10 +323,41 @@ util_blit_pixels(struct blit_state *ctx,
const int srcLeft = MIN2(srcX0, srcX1);
const int srcTop = MIN2(srcY0, srcY1);
unsigned offset;
+ boolean overlap;
assert(filter == PIPE_TEX_MIPFILTER_NEAREST ||
filter == PIPE_TEX_MIPFILTER_LINEAR);
+ assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_SAMPLER, 0));
+ assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
+
+ /* do the regions overlap? */
+ overlap = util_same_surface(src, dst) &&
+ regions_overlap(srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1);
+
+ /*
+ * Check for simple case: no format conversion, no flipping, no stretching,
+ * no overlapping.
+ * Filter mode should not matter since there's no stretching.
+ */
+ if (dst->format == src->format &&
+ srcX0 < srcX1 &&
+ dstX0 < dstX1 &&
+ srcY0 < srcY1 &&
+ dstY0 < dstY1 &&
+ (dstX1 - dstX0) == (srcX1 - srcX0) &&
+ (dstY1 - dstY0) == (srcY1 - srcY0) &&
+ !overlap) {
+ pipe->surface_copy(pipe,
+ dst, dstX0, dstY0, /* dest */
+ src, srcX0, srcY0, /* src */
+ srcW, srcH); /* size */
+ return;
+ }
+
if (srcLeft != srcX0) {
/* left-right flip */
int tmp = dstX0;
@@ -303,20 +372,6 @@ util_blit_pixels(struct blit_state *ctx,
dstY1 = tmp;
}
- assert(screen->is_format_supported(screen, src->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER, 0));
- assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_SAMPLER, 0));
-
- if(dst->format == src->format && (dstX1 - dstX0) == srcW && (dstY1 - dstY0) == srcH) {
- /* FIXME: this will most surely fail for overlapping rectangles */
- pipe->surface_copy(pipe,
- dst, dstX0, dstY0, /* dest */
- src, srcX0, srcY0, /* src */
- srcW, srcH); /* size */
- return;
- }
-
assert(screen->is_format_supported(screen, dst->format, PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_RENDER_TARGET, 0));
@@ -376,8 +431,11 @@ util_blit_pixels(struct blit_state *ctx,
/* texture */
cso_set_sampler_textures(ctx->cso, 1, &tex);
+ if (ctx->fs[writemask] == NULL)
+ ctx->fs[writemask] = util_make_fragment_tex_shader_writemask(pipe, writemask);
+
/* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[writemask]);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */
@@ -412,6 +470,27 @@ util_blit_pixels(struct blit_state *ctx,
}
+void
+util_blit_pixels(struct blit_state *ctx,
+ struct pipe_surface *src,
+ int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ struct pipe_surface *dst,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1,
+ float z, uint filter )
+{
+ util_blit_pixels_writemask( ctx, src,
+ srcX0, srcY0,
+ srcX1, srcY1,
+ dst,
+ dstX0, dstY0,
+ dstX1, dstY1,
+ z, filter,
+ TGSI_WRITEMASK_XYZW );
+}
+
+
/* Release vertex buffer at end of frame to avoid synchronous
* rendering.
*/
@@ -485,7 +564,7 @@ util_blit_pixels_tex(struct blit_state *ctx,
cso_set_sampler_textures(ctx->cso, 1, &tex);
/* shaders */
- cso_set_fragment_shader_handle(ctx->cso, ctx->fs);
+ cso_set_fragment_shader_handle(ctx->cso, ctx->fs[TGSI_WRITEMASK_XYZW]);
cso_set_vertex_shader_handle(ctx->cso, ctx->vs);
/* drawing dest */
diff --git a/src/gallium/auxiliary/util/u_blit.h b/src/gallium/auxiliary/util/u_blit.h
index c35beceda8..a102021529 100644
--- a/src/gallium/auxiliary/util/u_blit.h
+++ b/src/gallium/auxiliary/util/u_blit.h
@@ -60,6 +60,17 @@ util_blit_pixels(struct blit_state *ctx,
int dstX1, int dstY1,
float z, uint filter);
+void
+util_blit_pixels_writemask(struct blit_state *ctx,
+ struct pipe_surface *src,
+ int srcX0, int srcY0,
+ int srcX1, int srcY1,
+ struct pipe_surface *dst,
+ int dstX0, int dstY0,
+ int dstX1, int dstY1,
+ float z, uint filter,
+ uint writemask);
+
extern void
util_blit_pixels_tex(struct blit_state *ctx,
struct pipe_texture *tex,
diff --git a/src/gallium/auxiliary/util/u_debug.h b/src/gallium/auxiliary/util/u_debug.h
index d42b65ce28..b82e7cb4d4 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,12 +87,16 @@ _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, ...)
{
@@ -101,6 +110,7 @@ debug_printf(const char *format, ...)
#endif
}
+#endif /* !PIPE_OS_HAIKU */
/*
* ... isn't portable so we need to pass arguments in parentheses.
diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_debug_dump.c
new file mode 100644
index 0000000000..6bdecde048
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_debug_dump.c
@@ -0,0 +1,189 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_memory.h"
+#include "util/u_debug.h"
+#include "util/u_debug_dump.h"
+
+
+#define DEBUG_DUMP_INVALID_NAME "<invalid>"
+
+
+#if 0
+static const char *
+debug_dump_strip_prefix(const char *name,
+ const char *prefix)
+{
+ const char *stripped;
+ assert(name);
+ assert(prefix);
+ stripped = name;
+ while(*prefix) {
+ if(*stripped != *prefix)
+ return name;
+
+ ++stripped;
+ ++prefix;
+ }
+ return stripped;
+}
+#endif
+
+static const char *
+debug_dump_enum_continuous(unsigned value,
+ unsigned num_names,
+ const char **names)
+{
+ if (value >= num_names)
+ return DEBUG_DUMP_INVALID_NAME;
+ return names[value];
+}
+
+
+#define DEFINE_DEBUG_DUMP_CONTINUOUS(_name) \
+ const char * \
+ debug_dump_##_name(unsigned value, boolean shortened) \
+ { \
+ if(shortened) \
+ return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_short_names), debug_dump_##_name##_short_names); \
+ else \
+ return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_names), debug_dump_##_name##_names); \
+ }
+
+
+static const char *
+debug_dump_blend_factor_names[] = {
+ DEBUG_DUMP_INVALID_NAME, /* 0x0 */
+ "PIPE_BLENDFACTOR_ONE",
+ "PIPE_BLENDFACTOR_SRC_COLOR",
+ "PIPE_BLENDFACTOR_SRC_ALPHA",
+ "PIPE_BLENDFACTOR_DST_ALPHA",
+ "PIPE_BLENDFACTOR_DST_COLOR",
+ "PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE",
+ "PIPE_BLENDFACTOR_CONST_COLOR",
+ "PIPE_BLENDFACTOR_CONST_ALPHA",
+ "PIPE_BLENDFACTOR_SRC1_COLOR",
+ "PIPE_BLENDFACTOR_SRC1_ALPHA",
+ DEBUG_DUMP_INVALID_NAME, /* 0x0b */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0c */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0d */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0e */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0f */
+ DEBUG_DUMP_INVALID_NAME, /* 0x10 */
+ "PIPE_BLENDFACTOR_ZERO",
+ "PIPE_BLENDFACTOR_INV_SRC_COLOR",
+ "PIPE_BLENDFACTOR_INV_SRC_ALPHA",
+ "PIPE_BLENDFACTOR_INV_DST_ALPHA",
+ "PIPE_BLENDFACTOR_INV_DST_COLOR",
+ DEBUG_DUMP_INVALID_NAME, /* 0x16 */
+ "PIPE_BLENDFACTOR_INV_CONST_COLOR",
+ "PIPE_BLENDFACTOR_INV_CONST_ALPHA",
+ "PIPE_BLENDFACTOR_INV_SRC1_COLOR",
+ "PIPE_BLENDFACTOR_INV_SRC1_ALPHA"
+};
+
+static const char *
+debug_dump_blend_factor_short_names[] = {
+ DEBUG_DUMP_INVALID_NAME, /* 0x0 */
+ "one",
+ "src_color",
+ "src_alpha",
+ "dst_alpha",
+ "dst_color",
+ "src_alpha_saturate",
+ "const_color",
+ "const_alpha",
+ "src1_color",
+ "src1_alpha",
+ DEBUG_DUMP_INVALID_NAME, /* 0x0b */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0c */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0d */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0e */
+ DEBUG_DUMP_INVALID_NAME, /* 0x0f */
+ DEBUG_DUMP_INVALID_NAME, /* 0x10 */
+ "zero",
+ "inv_src_color",
+ "inv_src_alpha",
+ "inv_dst_alpha",
+ "inv_dst_color",
+ DEBUG_DUMP_INVALID_NAME, /* 0x16 */
+ "inv_const_color",
+ "inv_const_alpha",
+ "inv_src1_color",
+ "inv_src1_alpha"
+};
+
+DEFINE_DEBUG_DUMP_CONTINUOUS(blend_factor)
+
+
+static const char *
+debug_dump_blend_func_names[] = {
+ "PIPE_BLEND_ADD",
+ "PIPE_BLEND_SUBTRACT",
+ "PIPE_BLEND_REVERSE_SUBTRACT",
+ "PIPE_BLEND_MIN",
+ "PIPE_BLEND_MAX"
+};
+
+static const char *
+debug_dump_blend_func_short_names[] = {
+ "add",
+ "sub",
+ "rev_sub",
+ "min",
+ "max"
+};
+
+DEFINE_DEBUG_DUMP_CONTINUOUS(blend_func)
+
+
+static const char *
+debug_dump_func_names[] = {
+ "PIPE_FUNC_NEVER",
+ "PIPE_FUNC_LESS",
+ "PIPE_FUNC_EQUAL",
+ "PIPE_FUNC_LEQUAL",
+ "PIPE_FUNC_GREATER",
+ "PIPE_FUNC_NOTEQUAL",
+ "PIPE_FUNC_GEQUAL",
+ "PIPE_FUNC_ALWAYS"
+};
+
+static const char *
+debug_dump_func_short_names[] = {
+ "never",
+ "less",
+ "equal",
+ "less_equal",
+ "greater",
+ "not_equal",
+ "greater_equal",
+ "always"
+};
+
+DEFINE_DEBUG_DUMP_CONTINUOUS(func)
diff --git a/src/gallium/auxiliary/util/u_debug_dump.h b/src/gallium/auxiliary/util/u_debug_dump.h
new file mode 100644
index 0000000000..102935559c
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_debug_dump.h
@@ -0,0 +1,65 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Dump data in human/machine readable format.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef U_DEBUG_DUMP_H_
+#define U_DEBUG_DUMP_H_
+
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+const char *
+debug_dump_blend_factor(unsigned value, boolean shortened);
+
+const char *
+debug_dump_blend_func(unsigned value, boolean shortened);
+
+const char *
+debug_dump_func(unsigned value, boolean shortened);
+
+
+/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* U_DEBUG_H_ */
diff --git a/src/gallium/auxiliary/util/u_fifo.h b/src/gallium/auxiliary/util/u_fifo.h
new file mode 100644
index 0000000000..9e007de1ad
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_fifo.h
@@ -0,0 +1,94 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef U_FIFO_H
+#define U_FIFO_H
+
+#include "util/u_memory.h"
+
+struct util_fifo
+{
+ size_t head;
+ size_t tail;
+ size_t num;
+ size_t size;
+};
+
+static INLINE struct util_fifo *
+u_fifo_create(size_t size)
+{
+ struct util_fifo *fifo;
+ fifo = MALLOC(sizeof(*fifo) + size * sizeof(void*));
+
+ fifo->head = 0;
+ fifo->tail = 0;
+ fifo->num = 0;
+ fifo->size = size;
+
+ return fifo;
+}
+
+static INLINE boolean
+u_fifo_add(struct util_fifo *fifo, void *ptr)
+{
+ void **array = (void**)&fifo[1];
+ if (fifo->num >= fifo->size)
+ return FALSE;
+
+ if (++fifo->head >= fifo->size)
+ fifo->head = 0;
+
+ array[fifo->head] = ptr;
+
+ ++fifo->num;
+
+ return TRUE;
+}
+
+static INLINE boolean
+u_fifo_pop(struct util_fifo *fifo, void **ptr)
+{
+ void **array = (void**)&fifo[1];
+
+ if (!fifo->num)
+ return FALSE;
+
+ if (++fifo->tail >= fifo->size)
+ fifo->tail = 0;
+
+ *ptr = array[fifo->tail];
+
+ ++fifo->num;
+
+ return TRUE;
+}
+
+static INLINE void
+u_fifo_destroy(struct util_fifo *fifo)
+{
+ FREE(fifo);
+}
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_format.c b/src/gallium/auxiliary/util/u_format.c
new file mode 100644
index 0000000000..98ea13b60b
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format.c
@@ -0,0 +1,46 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Vmware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "u_format.h"
+
+
+const struct util_format_description *
+util_format_description(enum pipe_format format)
+{
+ const struct util_format_description *desc = util_format_description_table;
+
+ while(TRUE) {
+ if(desc->format == format)
+ return desc;
+
+ if(desc->format == PIPE_FORMAT_NONE)
+ return NULL;
+
+ ++desc;
+ };
+}
diff --git a/src/gallium/auxiliary/util/u_format.csv b/src/gallium/auxiliary/util/u_format.csv
new file mode 100644
index 0000000000..f1bf94f17d
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format.csv
@@ -0,0 +1,99 @@
+PIPE_FORMAT_A8R8G8B8_UNORM , arith , 1, 1, un8 , un8 , un8 , un8 , zyxw, rgb
+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, 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
+PIPE_FORMAT_L8_UNORM , arith , 1, 1, un8 , , , , xxx1, rgb
+PIPE_FORMAT_A8_UNORM , arith , 1, 1, un8 , , , , 000x, rgb
+PIPE_FORMAT_I8_UNORM , arith , 1, 1, un8 , , , , xxxx, rgb
+PIPE_FORMAT_A8L8_UNORM , arith , 1, 1, un8 , un8 , , , xxxy, rgb
+PIPE_FORMAT_L16_UNORM , arith , 1, 1, un16, , , , xxx1, rgb
+PIPE_FORMAT_Z16_UNORM , array , 1, 1, un16, , , , x___, zs
+PIPE_FORMAT_Z32_UNORM , array , 1, 1, un32, , , , x___, zs
+PIPE_FORMAT_Z32_FLOAT , array , 1, 1, f32 , , , , x___, zs
+PIPE_FORMAT_S8Z24_UNORM , arith , 1, 1, un24, un8 , , , xy__, zs
+PIPE_FORMAT_Z24S8_UNORM , arith , 1, 1, un8 , un24, , , yx__, zs
+PIPE_FORMAT_X8Z24_UNORM , arith , 1, 1, un24, un8 , , , x___, zs
+PIPE_FORMAT_Z24X8_UNORM , arith , 1, 1, un8 , un24, , , y___, zs
+PIPE_FORMAT_S8_UNORM , array , 1, 1, un8 , , , , _x__, zs
+PIPE_FORMAT_R64_FLOAT , array , 1, 1, f64 , , , , x001, rgb
+PIPE_FORMAT_R64G64_FLOAT , array , 1, 1, f64 , f64 , , , xy01, rgb
+PIPE_FORMAT_R64G64B64_FLOAT , array , 1, 1, f64 , f64 , f64 , , xyz1, rgb
+PIPE_FORMAT_R64G64B64A64_FLOAT , array , 1, 1, f64 , f64 , f64 , f64 , xyzw, rgb
+PIPE_FORMAT_R32_FLOAT , array , 1, 1, f32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_FLOAT , array , 1, 1, f32 , f32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_FLOAT , array , 1, 1, f32 , f32 , f32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_FLOAT , array , 1, 1, f32 , f32 , f32 , f32 , xyzw, rgb
+PIPE_FORMAT_R32_UNORM , array , 1, 1, un32, , , , x001, rgb
+PIPE_FORMAT_R32G32_UNORM , array , 1, 1, un32, un32, , , xy01, rgb
+PIPE_FORMAT_R32G32B32_UNORM , array , 1, 1, un32, un32, un32, , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_UNORM , array , 1, 1, un32, un32, un32, un32, xyzw, rgb
+PIPE_FORMAT_R32_USCALED , array , 1, 1, u32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_USCALED , array , 1, 1, u32 , u32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_USCALED , array , 1, 1, u32 , u32 , u32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_USCALED , array , 1, 1, u32 , u32 , u32 , u32 , xyzw, rgb
+PIPE_FORMAT_R32_SNORM , array , 1, 1, sn32, , , , x001, rgb
+PIPE_FORMAT_R32G32_SNORM , array , 1, 1, sn32, sn32, , , xy01, rgb
+PIPE_FORMAT_R32G32B32_SNORM , array , 1, 1, sn32, sn32, sn32, , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_SNORM , array , 1, 1, sn32, sn32, sn32, sn32, xyzw, rgb
+PIPE_FORMAT_R32_SSCALED , array , 1, 1, s32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_SSCALED , array , 1, 1, s32 , s32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_SSCALED , array , 1, 1, s32 , s32 , s32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_SSCALED , array , 1, 1, s32 , s32 , s32 , s32 , xyzw, rgb
+PIPE_FORMAT_R16_UNORM , array , 1, 1, un16, , , , x001, rgb
+PIPE_FORMAT_R16G16_UNORM , array , 1, 1, un16, un16, , , xy01, rgb
+PIPE_FORMAT_R16G16B16_UNORM , array , 1, 1, un16, un16, un16, , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_UNORM , array , 1, 1, un16, un16, un16, un16, xyzw, rgb
+PIPE_FORMAT_R16_USCALED , array , 1, 1, u16 , , , , x001, rgb
+PIPE_FORMAT_R16G16_USCALED , array , 1, 1, u16 , u16 , , , xy01, rgb
+PIPE_FORMAT_R16G16B16_USCALED , array , 1, 1, u16 , u16 , u16 , , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_USCALED , array , 1, 1, u16 , u16 , u16 , u16 , xyzw, rgb
+PIPE_FORMAT_R16_SNORM , array , 1, 1, sn16, , , , x001, rgb
+PIPE_FORMAT_R16G16_SNORM , array , 1, 1, sn16, sn16, , , xy01, rgb
+PIPE_FORMAT_R16G16B16_SNORM , array , 1, 1, sn16, sn16, sn16, , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_SNORM , array , 1, 1, sn16, sn16, sn16, sn16, xyzw, rgb
+PIPE_FORMAT_R16_SSCALED , array , 1, 1, s16 , , , , x001, rgb
+PIPE_FORMAT_R16G16_SSCALED , array , 1, 1, s16 , s16 , , , xy01, rgb
+PIPE_FORMAT_R16G16B16_SSCALED , array , 1, 1, s16 , s16 , s16 , , xyz1, rgb
+PIPE_FORMAT_R16G16B16A16_SSCALED , array , 1, 1, s16 , s16 , s16 , s16 , xyzw, rgb
+PIPE_FORMAT_R8_UNORM , array , 1, 1, un8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_UNORM , array , 1, 1, un8 , un8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_UNORM , array , 1, 1, un8 , un8 , un8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , xyzw, rgb
+PIPE_FORMAT_R8G8B8X8_UNORM , array , 1, 1, un8 , un8 , un8 , un8 , xyz1, rgb
+PIPE_FORMAT_R8_USCALED , array , 1, 1, u8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_USCALED , array , 1, 1, u8 , u8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_USCALED , array , 1, 1, u8 , u8 , u8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_USCALED , array , 1, 1, u8 , u8 , u8 , u8 , xyzw, rgb
+PIPE_FORMAT_R8G8B8X8_USCALED , array , 1, 1, u8 , u8 , u8 , u8 , xyz1, rgb
+PIPE_FORMAT_R8_SNORM , array , 1, 1, sn8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_SNORM , array , 1, 1, sn8 , sn8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyzw, rgb
+PIPE_FORMAT_R8G8B8X8_SNORM , array , 1, 1, sn8 , sn8 , sn8 , sn8 , xyz1, rgb
+PIPE_FORMAT_B6G5R5_SNORM , arith , 1, 1, sn5 , sn5 , sn6 , , zyx1, rgb
+PIPE_FORMAT_A8B8G8R8_SNORM , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyxw, rgb
+PIPE_FORMAT_X8B8G8R8_SNORM , arith , 1, 1, sn8 , sn8 , sn8 , sn8 , zyx1, rgb
+PIPE_FORMAT_R8_SSCALED , array , 1, 1, s8 , , , , x001, rgb
+PIPE_FORMAT_R8G8_SSCALED , array , 1, 1, s8 , s8 , , , xy01, rgb
+PIPE_FORMAT_R8G8B8_SSCALED , array , 1, 1, s8 , s8 , s8 , , xyz1, rgb
+PIPE_FORMAT_R8G8B8A8_SSCALED , array , 1, 1, s8 , s8 , s8 , s8 , xyzw, rgb
+PIPE_FORMAT_R8G8B8X8_SSCALED , array , 1, 1, s8 , s8 , s8 , s8 , xyz1, rgb
+PIPE_FORMAT_R32_FIXED , array , 1, 1, h32 , , , , x001, rgb
+PIPE_FORMAT_R32G32_FIXED , array , 1, 1, h32 , h32 , , , xy01, rgb
+PIPE_FORMAT_R32G32B32_FIXED , array , 1, 1, h32 , h32 , h32 , , xyz1, rgb
+PIPE_FORMAT_R32G32B32A32_FIXED , array , 1, 1, h32 , h32 , h32 , h32 , xyzw, rgb
+PIPE_FORMAT_L8_SRGB , arith , 1, 1, u8 , , , , xxx1, srgb
+PIPE_FORMAT_A8L8_SRGB , arith , 1, 1, u8 , u8 , , , xxxy, srgb
+PIPE_FORMAT_R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , , xyz1, srgb
+PIPE_FORMAT_R8G8B8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , xyzw, srgb
+PIPE_FORMAT_R8G8B8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , xyz1, srgb
+PIPE_FORMAT_A8R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , wxyz, srgb
+PIPE_FORMAT_X8R8G8B8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , 1xyz, srgb
+PIPE_FORMAT_B8G8R8A8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyxw, srgb
+PIPE_FORMAT_B8G8R8X8_SRGB , arith , 1, 1, u8 , u8 , u8 , u8 , zyx1, srgb
+PIPE_FORMAT_X8UB8UG8SR8S_NORM , arith , 1, 1, sn8 , sn8 , un8 , x8 , 1zyx, rgb
+PIPE_FORMAT_B6UG5SR5S_NORM , arith , 1, 1, sn5 , sn5 , un6 , , xyz1, rgb
diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h
new file mode 100644
index 0000000000..7b5b7fcda5
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format.h
@@ -0,0 +1,138 @@
+/**************************************************************************
+ *
+ * Copyright 2009 Vmware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef U_FORMAT_H
+#define U_FORMAT_H
+
+
+#include "pipe/p_format.h"
+
+
+enum util_format_layout {
+ UTIL_FORMAT_LAYOUT_SCALAR = 0,
+ UTIL_FORMAT_LAYOUT_ARITH = 1,
+ UTIL_FORMAT_LAYOUT_ARRAY = 2,
+ UTIL_FORMAT_LAYOUT_YUV = 3,
+ UTIL_FORMAT_LAYOUT_DXT = 4
+};
+
+
+struct util_format_block
+{
+ /** Block width in pixels */
+ unsigned width;
+
+ /** Block height in pixels */
+ unsigned height;
+
+ /** Block size in bytes */
+ unsigned bits;
+};
+
+
+enum util_format_type {
+ UTIL_FORMAT_TYPE_VOID = 0,
+ UTIL_FORMAT_TYPE_UNSIGNED = 1,
+ UTIL_FORMAT_TYPE_SIGNED = 2,
+ UTIL_FORMAT_TYPE_FIXED = 3,
+ UTIL_FORMAT_TYPE_FLOAT = 4
+};
+
+
+enum util_format_swizzle {
+ UTIL_FORMAT_SWIZZLE_X = 0,
+ UTIL_FORMAT_SWIZZLE_Y = 1,
+ UTIL_FORMAT_SWIZZLE_Z = 2,
+ UTIL_FORMAT_SWIZZLE_W = 3,
+ UTIL_FORMAT_SWIZZLE_0 = 4,
+ UTIL_FORMAT_SWIZZLE_1 = 5,
+ UTIL_FORMAT_SWIZZLE_NONE = 6
+};
+
+
+enum util_format_colorspace {
+ UTIL_FORMAT_COLORSPACE_RGB = 0,
+ UTIL_FORMAT_COLORSPACE_SRGB = 1,
+ UTIL_FORMAT_COLORSPACE_YUV = 2,
+ UTIL_FORMAT_COLORSPACE_ZS = 3,
+};
+
+
+struct util_format_channel_description
+{
+ unsigned type:6;
+ unsigned normalized:1;
+ unsigned size:9;
+};
+
+
+struct util_format_description
+{
+ enum pipe_format format;
+ const char *name;
+ struct util_format_block block;
+ enum util_format_layout layout;
+ struct util_format_channel_description channel[4];
+ unsigned char swizzle[4];
+ enum util_format_colorspace colorspace;
+};
+
+
+extern const struct util_format_description
+util_format_description_table[];
+
+
+const struct util_format_description *
+util_format_description(enum pipe_format format);
+
+
+void
+util_format_read_4f(enum pipe_format format,
+ float *dst, unsigned dst_stride,
+ const void *src, unsigned src_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_write_4f(enum pipe_format format,
+ const float *src, unsigned src_stride,
+ void *dst, unsigned dst_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_read_4ub(enum pipe_format format,
+ uint8_t *dst, unsigned dst_stride,
+ const void *src, unsigned src_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+void
+util_format_write_4ub(enum pipe_format format,
+ const uint8_t *src, unsigned src_stride,
+ void *dst, unsigned dst_stride,
+ unsigned x, unsigned y, unsigned w, unsigned h);
+
+#endif /* ! U_FORMAT_H */
diff --git a/src/gallium/auxiliary/util/u_format_access.py b/src/gallium/auxiliary/util/u_format_access.py
new file mode 100644
index 0000000000..eeb1a9657f
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_access.py
@@ -0,0 +1,498 @@
+#!/usr/bin/env python
+
+'''
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Pixel format accessor functions.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+'''
+
+
+import sys
+
+from u_format_parse import *
+
+
+def short_name(format):
+ '''Make up a short norm for a format, suitable to be used as suffix in
+ function names.'''
+
+ name = format.name
+ if name.startswith('PIPE_FORMAT_'):
+ name = name[len('PIPE_FORMAT_'):]
+ name = name.lower()
+ return name
+
+
+def is_format_supported(format):
+ '''Determines whether we actually have the plumbing necessary to generate the
+ to read/write to/from this format.'''
+
+ # FIXME: Ideally we would support any format combination here.
+
+ # XXX: It should be straightforward to support srgb
+ if format.colorspace not in ('rgb', 'zs'):
+ return False
+
+ if format.layout not in (ARITH, ARRAY):
+ return False
+
+ for i in range(4):
+ type = format.in_types[i]
+ if type.kind not in (VOID, UNSIGNED, FLOAT):
+ return False
+
+ # We can only read a color from a depth/stencil format if the depth channel is present
+ if format.colorspace == 'zs' and format.out_swizzle[0] == SWIZZLE_NONE:
+ return False
+
+ return True
+
+
+def native_type(format):
+ '''Get the native appropriate for a format.'''
+
+ if format.layout == ARITH:
+ # For arithmetic pixel formats return the integer type that matches the whole pixel
+ return 'uint%u_t' % format.block_size()
+ elif format.layout == ARRAY:
+ # For array pixel formats return the integer type that matches the color channel
+ type = format.in_types[0]
+ if type.kind == UNSIGNED:
+ return 'uint%u_t' % type.size
+ elif type.kind == SIGNED:
+ return 'int%u_t' % type.size
+ elif type.kind == FLOAT:
+ if type.size == 32:
+ return 'float'
+ elif type.size == 64:
+ return 'double'
+ else:
+ assert False
+ else:
+ assert False
+ else:
+ assert False
+
+
+def intermediate_native_type(bits, sign):
+ '''Find a native type adequate to hold intermediate results of the request bit size.'''
+
+ bytes = 4 # don't use anything smaller than 32bits
+ while bytes * 8 < bits:
+ bytes *= 2
+ bits = bytes*8
+
+ if sign:
+ return 'int%u_t' % bits
+ else:
+ return 'uint%u_t' % bits
+
+
+def get_one_shift(type):
+ '''Get the number of the bit that matches unity for this type.'''
+ if type.kind == 'FLOAT':
+ assert False
+ if not type.norm:
+ return 0
+ if type.kind == UNSIGNED:
+ return type.size
+ if type.kind == SIGNED:
+ return type.size - 1
+ if type.kind == FIXED:
+ return type.size / 2
+ assert False
+
+
+def get_one(type):
+ '''Get the value of unity for this type.'''
+ if type.kind == 'FLOAT' or not type.norm:
+ return 1
+ else:
+ return (1 << get_one_shift(type)) - 1
+
+
+def generate_clamp():
+ '''Code generate the clamping functions for each type.
+
+ We don't use a macro so that arguments with side effects,
+ like *src_pixel++ are correctly handled.
+ '''
+
+ for suffix, native_type in [
+ ('', 'double'),
+ ('f', 'float'),
+ ('ui', 'unsigned int'),
+ ('si', 'int'),
+ ]:
+ print 'static INLINE %s' % native_type
+ print 'clamp%s(%s value, %s lbound, %s ubound)' % (suffix, native_type, native_type, native_type)
+ print '{'
+ print ' if(value < lbound)'
+ print ' return lbound;'
+ print ' if(value > ubound)'
+ print ' return ubound;'
+ print ' return value;'
+ print '}'
+ print
+
+
+def clamp_expr(src_type, dst_type, dst_native_type, value):
+ '''Generate the expression to clamp the value in the source type to the
+ destination type range.'''
+
+ if src_type == dst_type:
+ return value
+
+ # Pick the approriate clamp function
+ if src_type.kind == FLOAT:
+ if src_type.size == 32:
+ func = 'clampf'
+ elif src_type.size == 64:
+ func = 'clamp'
+ else:
+ assert False
+ elif src_type.kind == UNSIGNED:
+ func = 'clampui'
+ elif src_type.kind == SIGNED:
+ func = 'clampsi'
+ else:
+ assert False
+
+ # Clamp floats to [-1, 1] or [0, 1] range
+ if src_type.kind == FLOAT and dst_type.norm:
+ max = 1
+ if src_type.sign and dst_type.sign:
+ min = -1
+ else:
+ min = 0
+ return '%s(%s, %s, %s)' % (func, value, min, max)
+
+ # FIXME: Also clamp scaled values
+
+ return value
+
+
+def conversion_expr(src_type, dst_type, dst_native_type, value):
+ '''Generate the expression to convert a value between two types.'''
+
+ if src_type == dst_type:
+ return value
+
+ if src_type.kind == FLOAT and dst_type.kind == FLOAT:
+ return '(%s)%s' % (dst_native_type, value)
+
+ if not src_type.norm and not dst_type.norm:
+ return '(%s)%s' % (dst_native_type, value)
+
+ value = clamp_expr(src_type, dst_type, dst_native_type, value)
+
+ if dst_type.kind == FLOAT:
+ if src_type.norm:
+ one = get_one(src_type)
+ if src_type.size <= 23:
+ scale = '(1.0f/0x%x)' % one
+ else:
+ # bigger than single precision mantissa, use double
+ scale = '(1.0/0x%x)' % one
+ value = '(%s * %s)' % (value, scale)
+ return '(%s)%s' % (dst_native_type, value)
+
+ if src_type.kind == FLOAT:
+ if dst_type.norm:
+ dst_one = get_one(dst_type)
+ if dst_type.size <= 23:
+ scale = '0x%x' % dst_one
+ else:
+ # bigger than single precision mantissa, use double
+ scale = '(double)0x%x' % dst_one
+ value = '(%s * %s)' % (value, scale)
+ return '(%s)%s' % (dst_native_type, value)
+
+ if src_type.kind == dst_type.kind:
+ src_one = get_one(src_type)
+ dst_one = get_one(dst_type)
+
+ if src_one > dst_one and src_type.norm and dst_type.norm:
+ # We can just bitshift
+ src_shift = get_one_shift(src_type)
+ dst_shift = get_one_shift(dst_type)
+ value = '(%s >> %s)' % (value, src_shift - dst_shift)
+ else:
+ # We need to rescale using an intermediate type big enough to hold the multiplication of both
+ tmp_native_type = intermediate_native_type(src_type.size + dst_type.size, src_type.sign and dst_type.sign)
+ value = '(%s)%s' % (tmp_native_type, value)
+ value = '%s * 0x%x / 0x%x' % (value, dst_one, src_one)
+ value = '(%s)%s' % (dst_native_type, value)
+ return value
+
+ assert False
+
+
+def generate_format_read(format, dst_type, dst_native_type, dst_suffix):
+ '''Generate the function to read pixels from a particular format'''
+
+ name = short_name(format)
+
+ src_native_type = native_type(format)
+
+ print 'static void'
+ print 'util_format_%s_read_%s(%s *dst, unsigned dst_stride, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, dst_suffix, dst_native_type)
+ print '{'
+ print ' unsigned x, y;'
+ print ' const uint8_t *src_row = src + y0*src_stride;'
+ print ' %s *dst_row = dst;' % dst_native_type
+ print ' for (y = 0; y < h; ++y) {'
+ print ' const %s *src_pixel = (const %s *)(src_row + x0*%u);' % (src_native_type, src_native_type, format.stride())
+ print ' %s *dst_pixel = dst_row;' %dst_native_type
+ print ' for (x = 0; x < w; ++x) {'
+
+ names = ['']*4
+ if format.colorspace == 'rgb':
+ for i in range(4):
+ swizzle = format.out_swizzle[i]
+ if swizzle < 4:
+ names[swizzle] += 'rgba'[i]
+ elif format.colorspace == 'zs':
+ swizzle = format.out_swizzle[0]
+ if swizzle < 4:
+ names[swizzle] = 'z'
+ else:
+ assert False
+ else:
+ assert False
+
+ if format.layout == ARITH:
+ print ' %s pixel = *src_pixel++;' % src_native_type
+ shift = 0;
+ for i in range(4):
+ src_type = format.in_types[i]
+ width = src_type.size
+ if names[i]:
+ value = 'pixel'
+ mask = (1 << width) - 1
+ if shift:
+ value = '(%s >> %u)' % (value, shift)
+ if shift + width < format.block_size():
+ value = '(%s & 0x%x)' % (value, mask)
+ value = conversion_expr(src_type, dst_type, dst_native_type, value)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ shift += width
+ elif format.layout == ARRAY:
+ for i in range(4):
+ src_type = format.in_types[i]
+ if names[i]:
+ value = '(*src_pixel++)'
+ value = conversion_expr(src_type, dst_type, dst_native_type, value)
+ print ' %s %s = %s;' % (dst_native_type, names[i], value)
+ else:
+ assert False
+
+ for i in range(4):
+ if format.colorspace == 'rgb':
+ swizzle = format.out_swizzle[i]
+ if swizzle < 4:
+ value = names[swizzle]
+ elif swizzle == SWIZZLE_0:
+ value = '0'
+ elif swizzle == SWIZZLE_1:
+ value = '1'
+ else:
+ assert False
+ elif format.colorspace == 'zs':
+ if i < 3:
+ value = 'z'
+ else:
+ value = '1'
+ else:
+ assert False
+ print ' *dst_pixel++ = %s; /* %s */' % (value, 'rgba'[i])
+
+ print ' }'
+ print ' src_row += src_stride;'
+ print ' dst_row += dst_stride/sizeof(%s);' % dst_native_type
+ print ' }'
+ print '}'
+ print
+
+
+def generate_format_write(format, src_type, src_native_type, src_suffix):
+ '''Generate the function to write pixels to a particular format'''
+
+ name = short_name(format)
+
+ dst_native_type = native_type(format)
+
+ print 'static void'
+ print 'util_format_%s_write_%s(const %s *src, unsigned src_stride, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h)' % (name, src_suffix, src_native_type)
+ print '{'
+ print ' unsigned x, y;'
+ print ' uint8_t *dst_row = dst + y0*dst_stride;'
+ print ' const %s *src_row = src;' % src_native_type
+ print ' for (y = 0; y < h; ++y) {'
+ print ' %s *dst_pixel = (%s *)(dst_row + x0*%u);' % (dst_native_type, dst_native_type, format.stride())
+ print ' const %s *src_pixel = src_row;' %src_native_type
+ print ' for (x = 0; x < w; ++x) {'
+
+ inv_swizzle = [None]*4
+ if format.colorspace == 'rgb':
+ for i in range(4):
+ swizzle = format.out_swizzle[i]
+ if swizzle < 4:
+ inv_swizzle[swizzle] = i
+ elif format.colorspace == 'zs':
+ swizzle = format.out_swizzle[0]
+ if swizzle < 4:
+ inv_swizzle[swizzle] = 0
+ else:
+ assert False
+
+ if format.layout == ARITH:
+ print ' %s pixel = 0;' % dst_native_type
+ shift = 0;
+ for i in range(4):
+ dst_type = format.in_types[i]
+ width = dst_type.size
+ if inv_swizzle[i] is not None:
+ value = 'src_pixel[%u]' % inv_swizzle[i]
+ value = conversion_expr(src_type, dst_type, dst_native_type, value)
+ if shift:
+ value = '(%s << %u)' % (value, shift)
+ print ' pixel |= %s;' % value
+ shift += width
+ print ' *dst_pixel++ = pixel;'
+ elif format.layout == ARRAY:
+ for i in range(4):
+ dst_type = format.in_types[i]
+ if inv_swizzle[i] is not None:
+ value = 'src_pixel[%u]' % inv_swizzle[i]
+ value = conversion_expr(src_type, dst_type, dst_native_type, value)
+ print ' *dst_pixel++ = %s;' % value
+ else:
+ assert False
+ print ' src_pixel += 4;'
+
+ print ' }'
+ print ' dst_row += dst_stride;'
+ print ' src_row += src_stride/sizeof(%s);' % src_native_type
+ print ' }'
+ print '}'
+ print
+
+
+def generate_read(formats, dst_type, dst_native_type, dst_suffix):
+ '''Generate the dispatch function to read pixels from any format'''
+
+ for format in formats:
+ if is_format_supported(format):
+ generate_format_read(format, dst_type, dst_native_type, dst_suffix)
+
+ print 'void'
+ print 'util_format_read_%s(enum pipe_format format, %s *dst, unsigned dst_stride, const void *src, unsigned src_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (dst_suffix, dst_native_type)
+ print '{'
+ print ' void (*func)(%s *dst, unsigned dst_stride, const uint8_t *src, unsigned src_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % dst_native_type
+ print ' switch(format) {'
+ for format in formats:
+ if is_format_supported(format):
+ print ' case %s:' % format.name
+ print ' func = &util_format_%s_read_%s;' % (short_name(format), dst_suffix)
+ print ' break;'
+ print ' default:'
+ print ' debug_printf("unsupported format\\n");'
+ print ' return;'
+ print ' }'
+ print ' func(dst, dst_stride, (const uint8_t *)src, src_stride, x, y, w, h);'
+ print '}'
+ print
+
+
+def generate_write(formats, src_type, src_native_type, src_suffix):
+ '''Generate the dispatch function to write pixels to any format'''
+
+ for format in formats:
+ if is_format_supported(format):
+ generate_format_write(format, src_type, src_native_type, src_suffix)
+
+ print 'void'
+ print 'util_format_write_%s(enum pipe_format format, const %s *src, unsigned src_stride, void *dst, unsigned dst_stride, unsigned x, unsigned y, unsigned w, unsigned h)' % (src_suffix, src_native_type)
+
+ print '{'
+ print ' void (*func)(const %s *src, unsigned src_stride, uint8_t *dst, unsigned dst_stride, unsigned x0, unsigned y0, unsigned w, unsigned h);' % src_native_type
+ print ' switch(format) {'
+ for format in formats:
+ if is_format_supported(format):
+ print ' case %s:' % format.name
+ print ' func = &util_format_%s_write_%s;' % (short_name(format), src_suffix)
+ print ' break;'
+ print ' default:'
+ print ' debug_printf("unsupported format\\n");'
+ print ' return;'
+ print ' }'
+ print ' func(src, src_stride, (uint8_t *)dst, dst_stride, x, y, w, h);'
+ print '}'
+ print
+
+
+def main():
+ formats = []
+ for arg in sys.argv[1:]:
+ formats.extend(parse(arg))
+
+ print '/* This file is autogenerated by u_format_access.py from u_format.csv. Do not edit directly. */'
+ print
+ # This will print the copyright message on the top of this file
+ print __doc__.strip()
+ print
+ print '#include "pipe/p_compiler.h"'
+ print '#include "u_format.h"'
+ print '#include "u_math.h"'
+ print
+
+ generate_clamp()
+
+ type = Type(FLOAT, False, 32)
+ native_type = 'float'
+ suffix = '4f'
+
+ generate_read(formats, type, native_type, suffix)
+ generate_write(formats, type, native_type, suffix)
+
+ type = Type(UNSIGNED, True, 8)
+ native_type = 'uint8_t'
+ suffix = '4ub'
+
+ generate_read(formats, type, native_type, suffix)
+ generate_write(formats, type, native_type, suffix)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
new file mode 100755
index 0000000000..493aff7112
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -0,0 +1,141 @@
+#!/usr/bin/env python
+
+'''
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+'''
+
+
+import sys
+
+
+VOID, UNSIGNED, SIGNED, FIXED, FLOAT = range(5)
+
+SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W, SWIZZLE_0, SWIZZLE_1, SWIZZLE_NONE, = range(7)
+
+ARITH = 'arith'
+ARRAY = 'array'
+
+
+class Type:
+ '''Describe the type of a color channel.'''
+
+ def __init__(self, kind, norm, size):
+ self.kind = kind
+ self.norm = norm
+ self.size = size
+ self.sign = kind in (SIGNED, FIXED, FLOAT)
+
+ def __str__(self):
+ s = str(self.kind)
+ if self.norm:
+ s += 'n'
+ s += str(self.size)
+ return s
+
+ def __eq__(self, other):
+ return self.kind == other.kind and self.norm == other.norm and self.size == other.size
+
+
+class Format:
+ '''Describe a pixel format.'''
+
+ def __init__(self, name, layout, block_width, block_height, in_types, out_swizzle, colorspace):
+ self.name = name
+ self.layout = layout
+ self.block_width = block_width
+ self.block_height = block_height
+ self.in_types = in_types
+ self.out_swizzle = out_swizzle
+ self.name = name
+ self.colorspace = colorspace
+
+ def __str__(self):
+ return self.name
+
+ def block_size(self):
+ size = 0
+ for type in self.in_types:
+ size += type.size
+ return size
+
+ def stride(self):
+ return self.block_size()/8
+
+
+_kind_parse_map = {
+ '': VOID,
+ 'x': VOID,
+ 'u': UNSIGNED,
+ 's': SIGNED,
+ 'h': FIXED,
+ 'f': FLOAT,
+}
+
+_swizzle_parse_map = {
+ 'x': SWIZZLE_X,
+ 'y': SWIZZLE_Y,
+ 'z': SWIZZLE_Z,
+ 'w': SWIZZLE_W,
+ '0': SWIZZLE_0,
+ '1': SWIZZLE_1,
+ '_': SWIZZLE_NONE,
+}
+
+def parse(filename):
+ '''Parse the format descrition in CSV format in terms of the
+ Type and Format classes above.'''
+
+ stream = open(filename)
+ formats = []
+ for line in stream:
+ line = line.rstrip()
+ fields = [field.strip() for field in line.split(',')]
+ name = fields[0]
+ layout = fields[1]
+ block_width, block_height = map(int, fields[2:4])
+ in_types = []
+ for field in fields[4:8]:
+ if field:
+ kind = _kind_parse_map[field[0]]
+ if field[1] == 'n':
+ norm = True
+ size = int(field[2:])
+ else:
+ norm = False
+ size = int(field[1:])
+ else:
+ kind = VOID
+ norm = False
+ size = 0
+ in_type = Type(kind, norm, size)
+ in_types.append(in_type)
+ out_swizzle = [_swizzle_parse_map[swizzle] for swizzle in fields[8]]
+ colorspace = fields[9]
+ formats.append(Format(name, layout, block_width, block_height, in_types, out_swizzle, colorspace))
+ return formats
+
diff --git a/src/gallium/auxiliary/util/u_format_table.py b/src/gallium/auxiliary/util/u_format_table.py
new file mode 100755
index 0000000000..8834568e8e
--- /dev/null
+++ b/src/gallium/auxiliary/util/u_format_table.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python
+
+'''
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+'''
+
+
+import sys
+
+from u_format_parse import *
+
+
+def layout_map(layout):
+ return 'UTIL_FORMAT_LAYOUT_' + str(layout).upper()
+
+
+def colorspace_map(colorspace):
+ return 'UTIL_FORMAT_COLORSPACE_' + str(colorspace).upper()
+
+
+colorspace_channels_map = {
+ 'rgb': 'rgba',
+ 'rgba': 'rgba',
+ 'zs': 'zs',
+ 'yuv': ['y1', 'y2', 'u', 'v'],
+ 'dxt': []
+}
+
+
+kind_map = {
+ VOID: "UTIL_FORMAT_TYPE_VOID",
+ UNSIGNED: "UTIL_FORMAT_TYPE_UNSIGNED",
+ SIGNED: "UTIL_FORMAT_TYPE_SIGNED",
+ FIXED: "UTIL_FORMAT_TYPE_FIXED",
+ FLOAT: "UTIL_FORMAT_TYPE_FLOAT",
+}
+
+
+def bool_map(value):
+ if value:
+ return "TRUE"
+ else:
+ return "FALSE"
+
+
+swizzle_map = {
+ SWIZZLE_X: "UTIL_FORMAT_SWIZZLE_X",
+ SWIZZLE_Y: "UTIL_FORMAT_SWIZZLE_Y",
+ SWIZZLE_Z: "UTIL_FORMAT_SWIZZLE_Z",
+ SWIZZLE_W: "UTIL_FORMAT_SWIZZLE_W",
+ SWIZZLE_0: "UTIL_FORMAT_SWIZZLE_0",
+ SWIZZLE_1: "UTIL_FORMAT_SWIZZLE_1",
+ SWIZZLE_NONE: "UTIL_FORMAT_SWIZZLE_NONE",
+}
+
+
+def write_format_table(formats):
+ print '/* This file is autogenerated by u_format_table.py from u_format.csv. Do not edit directly. */'
+ print
+ # This will print the copyright message on the top of this file
+ print __doc__.strip()
+ print
+ print '#include "u_format.h"'
+ print
+ print 'const struct util_format_description'
+ print 'util_format_description_table[] = '
+ print "{"
+ for format in formats:
+ print " {"
+ print " %s," % (format.name,)
+ print " \"%s\"," % (format.name,)
+ print " {%u, %u, %u}, /* block */" % (format.block_width, format.block_height, format.block_size())
+ print " %s," % (layout_map(format.layout),)
+ print " {"
+ for i in range(4):
+ type = format.in_types[i]
+ if i < 3:
+ sep = ","
+ else:
+ sep = ""
+ print " {%s, %s, %u}%s /* %s */" % (kind_map[type.kind], bool_map(type.norm), type.size, sep, "xyzw"[i])
+ print " },"
+ print " {"
+ for i in range(4):
+ swizzle = format.out_swizzle[i]
+ if i < 3:
+ sep = ","
+ else:
+ sep = ""
+ try:
+ comment = layout_channels_map[format.layout][i]
+ except:
+ comment = 'ignored'
+ print " %s%s /* %s */" % (swizzle_map[swizzle], sep, comment)
+ print " },"
+ print " %s," % (colorspace_map(format.colorspace),)
+ print " },"
+ print " {"
+ print " PIPE_FORMAT_NONE,"
+ print " \"PIPE_FORMAT_NONE\","
+ print " {0, 0, 0},"
+ print " 0,"
+ print " {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}},"
+ print " {0, 0, 0, 0},"
+ print " 0"
+ print " },"
+ print "};"
+
+
+def main():
+
+ formats = []
+ for arg in sys.argv[1:]:
+ formats.extend(parse(arg))
+ write_format_table(formats)
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index ca797486a0..f06c0e463d 100644
--- a/src/gallium/auxiliary/util/u_gen_mipmap.c
+++ b/src/gallium/auxiliary/util/u_gen_mipmap.c
@@ -46,10 +46,6 @@
#include "util/u_gen_mipmap.h"
#include "util/u_simple_shaders.h"
-#include "tgsi/tgsi_build.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
-
#include "cso_cache/cso_context.h"
@@ -921,11 +917,19 @@ static void
format_to_type_comps(enum pipe_format pformat,
enum dtype *datatype, uint *comps)
{
+ /* XXX I think this could be implemented in terms of the pf_*() functions */
switch (pformat) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_B8G8R8A8_UNORM:
case PIPE_FORMAT_B8G8R8X8_UNORM:
+ case PIPE_FORMAT_R8G8B8A8_SRGB:
+ case PIPE_FORMAT_R8G8B8X8_SRGB:
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ case PIPE_FORMAT_X8R8G8B8_SRGB:
+ case PIPE_FORMAT_B8G8R8A8_SRGB:
+ case PIPE_FORMAT_B8G8R8X8_SRGB:
+ case PIPE_FORMAT_R8G8B8_SRGB:
*datatype = DTYPE_UBYTE;
*comps = 4;
return;
@@ -942,12 +946,14 @@ format_to_type_comps(enum pipe_format pformat,
*comps = 3;
return;
case PIPE_FORMAT_L8_UNORM:
+ case PIPE_FORMAT_L8_SRGB:
case PIPE_FORMAT_A8_UNORM:
case PIPE_FORMAT_I8_UNORM:
*datatype = DTYPE_UBYTE;
*comps = 1;
return;
case PIPE_FORMAT_A8L8_UNORM:
+ case PIPE_FORMAT_A8L8_SRGB:
*datatype = DTYPE_UBYTE;
*comps = 2;
return;
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index 163522d3ef..cd6a9fcc09 100644
--- a/src/gallium/auxiliary/util/u_math.h
+++ b/src/gallium/auxiliary/util/u_math.h
@@ -53,11 +53,11 @@ __inline double ceil(double val)
{
double ceil_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
ceil_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
ceil_val = (long) val + 1;
}
else {
@@ -73,11 +73,11 @@ __inline double floor(double val)
{
double floor_val;
- if((val - (long) val) == 0) {
+ if ((val - (long) val) == 0) {
floor_val = val;
}
else {
- if(val > 0) {
+ if (val > 0) {
floor_val = (long) val;
}
else {
@@ -189,7 +189,10 @@ static INLINE double log2( double x )
extern float pow2_table[POW2_TABLE_SIZE];
-
+/**
+ * Initialize math module. This should be called before using any
+ * other functions in this module.
+ */
extern void
util_init_math(void);
@@ -216,23 +219,24 @@ util_fast_exp2(float x)
int32_t ipart;
float fpart, mpart;
union fi epart;
-
+
if(x > 129.00000f)
return 3.402823466e+38f;
-
- if(x < -126.99999f)
+
+ if (x < -126.99999f)
return 0.0f;
ipart = (int32_t) x;
fpart = x - (float) ipart;
-
+
/* same as
* epart.f = (float) (1 << ipart)
- * but faster and without integer overflow for ipart > 31 */
+ * but faster and without integer overflow for ipart > 31
+ */
epart.i = (ipart + 127 ) << 23;
-
+
mpart = pow2_table[POW2_TABLE_OFFSET + (int)(fpart * POW2_TABLE_SCALE)];
-
+
return epart.f * mpart;
}
@@ -254,6 +258,9 @@ util_fast_exp(float x)
extern float log2_table[LOG2_TABLE_SIZE];
+/**
+ * Fast approximation to log2(x).
+ */
static INLINE float
util_fast_log2(float x)
{
@@ -267,6 +274,9 @@ util_fast_log2(float x)
}
+/**
+ * Fast approximation to x^y.
+ */
static INLINE float
util_fast_pow(float x, float y)
{
@@ -282,7 +292,6 @@ util_is_power_of_two( unsigned v )
}
-
/**
* Floor(x), returned as int.
*/
@@ -292,8 +301,8 @@ util_ifloor(float f)
int ai, bi;
double af, bf;
union fi u;
- af = (3 << 22) + 0.5 + (double)f;
- bf = (3 << 22) + 0.5 - (double)f;
+ af = (3 << 22) + 0.5 + (double) f;
+ bf = (3 << 22) + 0.5 - (double) f;
u.f = (float) af; ai = u.i;
u.f = (float) bf; bi = u.i;
return (ai - bi) >> 1;
@@ -313,9 +322,9 @@ util_iround(float f)
#elif defined(PIPE_CC_MSVC) && defined(PIPE_ARCH_X86)
int r;
_asm {
- fld f
- fistp r
- }
+ fld f
+ fistp r
+ }
return r;
#else
if (f >= 0.0f)
@@ -340,15 +349,27 @@ util_is_inf_or_nan(float x)
/**
+ * Test whether x is a power of two.
+ */
+static INLINE boolean
+util_is_pot(unsigned x)
+{
+ return (x & (x - 1)) == 0;
+}
+
+
+/**
* 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 )
{
unsigned long i;
- if(_BitScanForward(&i, u))
+ if (_BitScanForward(&i, u))
return i + 1;
else
return 0;
@@ -359,7 +380,7 @@ unsigned ffs( unsigned u )
{
unsigned i;
- if( u == 0 ) {
+ if (u == 0) {
return 0;
}
@@ -373,6 +394,10 @@ unsigned ffs( unsigned u )
#define ffs __builtin_ffs
#endif
+#ifdef __MINGW32__
+#define ffs __builtin_ffs
+#endif
+
/* Could also binary search for the highest bit.
*/
@@ -398,7 +423,10 @@ fui( float f )
}
-
+/**
+ * Convert ubyte to float in [0, 1].
+ * XXX a 256-entry lookup table would be slightly faster.
+ */
static INLINE float
ubyte_to_float(ubyte ub)
{
@@ -429,7 +457,23 @@ float_to_ubyte(float f)
}
+/**
+ * Calc log base 2
+ */
+static INLINE unsigned
+util_logbase2(unsigned n)
+{
+ unsigned log2 = 0;
+ while (n >>= 1)
+ ++log2;
+ return log2;
+}
+
+/**
+ * Clamp X to [MIN, MAX].
+ * This is a macro to allow float, int, uint, etc. types.
+ */
#define CLAMP( X, MIN, MAX ) ( (X)<(MIN) ? (MIN) : ((X)>(MAX) ? (MAX) : (X)) )
#define MIN2( A, B ) ( (A)<(B) ? (A) : (B) )
@@ -442,6 +486,11 @@ align(int value, int alignment)
return (value + alignment - 1) & ~(alignment - 1);
}
+static INLINE unsigned
+minify(unsigned value)
+{
+ return MAX2(1, value >> 1);
+}
#ifndef COPY_4V
#define COPY_4V( DST, SRC ) \
diff --git a/src/gallium/auxiliary/util/u_memory.h b/src/gallium/auxiliary/util/u_memory.h
index 0b18d043ad..c3f8c91833 100644
--- a/src/gallium/auxiliary/util/u_memory.h
+++ b/src/gallium/auxiliary/util/u_memory.h
@@ -100,8 +100,14 @@ ExFreePool(void *P);
#define MALLOC( SIZE ) malloc( SIZE )
#define CALLOC( COUNT, SIZE ) calloc( COUNT, SIZE )
#define FREE( PTR ) free( PTR )
-#define REALLOC( OLDPTR, OLDSIZE, NEWSIZE ) realloc( OLDPTR, NEWSIZE )
+static INLINE void *
+_REALLOC( void *old_ptr, unsigned old_size, unsigned new_size )
+{
+ (void) old_size;
+ return realloc(old_ptr, new_size);
+}
+#define REALLOC( a, b, c ) _REALLOC( a, b, c )
#endif
diff --git a/src/gallium/auxiliary/util/u_mm.c b/src/gallium/auxiliary/util/u_mm.c
index 151a480d34..4b75d4ba1d 100644
--- a/src/gallium/auxiliary/util/u_mm.c
+++ b/src/gallium/auxiliary/util/u_mm.c
@@ -33,30 +33,32 @@
void
u_mmDumpMemInfo(const struct mem_block *heap)
{
- debug_printf("Memory heap %p:\n", (void *)heap);
+ debug_printf("Memory heap %p:\n", (void *) heap);
if (heap == 0) {
debug_printf(" heap == 0\n");
- } else {
+ }
+ else {
const struct mem_block *p;
- for(p = heap->next; p != heap; p = p->next) {
- debug_printf(" Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
- p->free ? 'F':'.',
- p->reserved ? 'R':'.');
+ for (p = heap->next; p != heap; p = p->next) {
+ debug_printf(" Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
}
debug_printf("\nFree list:\n");
- for(p = heap->next_free; p != heap; p = p->next_free) {
- debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n",p->ofs,p->size,
- p->free ? 'F':'.',
- p->reserved ? 'R':'.');
+ for (p = heap->next_free; p != heap; p = p->next_free) {
+ debug_printf(" FREE Offset:%08x, Size:%08x, %c%c\n", p->ofs, p->size,
+ p->free ? 'F':'.',
+ p->reserved ? 'R':'.');
}
}
debug_printf("End of memory blocks\n");
}
+
struct mem_block *
u_mmInit(int ofs, int size)
{
diff --git a/src/gallium/auxiliary/util/u_mm.h b/src/gallium/auxiliary/util/u_mm.h
index ce20e48763..6b158aae6e 100644
--- a/src/gallium/auxiliary/util/u_mm.h
+++ b/src/gallium/auxiliary/util/u_mm.h
@@ -84,7 +84,7 @@ extern struct mem_block *u_mmFindBlock(struct mem_block *heap, int start);
extern void u_mmDestroy(struct mem_block *mmInit);
/**
- * For debuging purpose.
+ * For debugging purposes.
*/
extern void u_mmDumpMemInfo(const struct mem_block *mmInit);
diff --git a/src/gallium/auxiliary/util/u_network.c b/src/gallium/auxiliary/util/u_network.c
index 07d804ecdb..bc4b758406 100644
--- a/src/gallium/auxiliary/util/u_network.c
+++ b/src/gallium/auxiliary/util/u_network.c
@@ -6,7 +6,7 @@
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# include <winsock2.h>
# include <windows.h>
-#elif defined(PIPE_OS_LINUX)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
# include <sys/socket.h>
# include <netinet/in.h>
# include <unistd.h>
@@ -54,7 +54,7 @@ u_socket_close(int s)
if (s < 0)
return;
-#if defined(PIPE_OS_LINUX)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
shutdown(s, SHUT_RDWR);
close(s);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_USER)
@@ -169,7 +169,7 @@ u_socket_listen_on_port(uint16_t portnum)
void
u_socket_block(int s, boolean block)
{
-#if defined(PIPE_OS_LINUX)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
int old = fcntl(s, F_GETFL, 0);
if (old == -1)
return;
diff --git a/src/gallium/auxiliary/util/u_network.h b/src/gallium/auxiliary/util/u_network.h
index 14d3884427..8c778f492c 100644
--- a/src/gallium/auxiliary/util/u_network.h
+++ b/src/gallium/auxiliary/util/u_network.h
@@ -6,7 +6,7 @@
#if defined(PIPE_SUBSYSTEM_WINDOWS_USER)
# define PIPE_HAVE_SOCKETS
-#elif defined(PIPE_OS_LINUX)
+#elif defined(PIPE_OS_LINUX) || defined(PIPE_OS_HAIKU)
# define PIPE_HAVE_SOCKETS
#endif
diff --git a/src/gallium/auxiliary/util/u_rect.c b/src/gallium/auxiliary/util/u_rect.c
index 74259d453b..9866b6fc8a 100644
--- a/src/gallium/auxiliary/util/u_rect.c
+++ b/src/gallium/auxiliary/util/u_rect.c
@@ -43,7 +43,7 @@
* src_pitch may be negative to do vertical flip of pixels from source.
*/
void
-pipe_copy_rect(ubyte * dst,
+util_copy_rect(ubyte * dst,
const struct pipe_format_block *block,
unsigned dst_stride,
unsigned dst_x,
@@ -91,7 +91,7 @@ pipe_copy_rect(ubyte * dst,
}
void
-pipe_fill_rect(ubyte * dst,
+util_fill_rect(ubyte * dst,
const struct pipe_format_block *block,
unsigned dst_stride,
unsigned dst_x,
@@ -204,7 +204,7 @@ util_surface_copy(struct pipe_context *pipe,
if (src_map && dst_map) {
/* If do_flip, invert src_y position and pass negative src stride */
- pipe_copy_rect(dst_map,
+ util_copy_rect(dst_map,
&dst_trans->block,
dst_trans->stride,
0, 0,
@@ -263,7 +263,7 @@ util_surface_fill(struct pipe_context *pipe,
case 1:
case 2:
case 4:
- pipe_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
+ util_fill_rect(dst_map, &dst_trans->block, dst_trans->stride,
0, 0, width, height, value);
break;
case 8:
diff --git a/src/gallium/auxiliary/util/u_rect.h b/src/gallium/auxiliary/util/u_rect.h
index 59e842e16d..daa50834d3 100644
--- a/src/gallium/auxiliary/util/u_rect.h
+++ b/src/gallium/auxiliary/util/u_rect.h
@@ -42,13 +42,13 @@ struct pipe_surface;
extern void
-pipe_copy_rect(ubyte * dst, const struct pipe_format_block *block,
+util_copy_rect(ubyte * dst, const struct pipe_format_block *block,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
unsigned width, unsigned height, const ubyte * src,
int src_stride, unsigned src_x, int src_y);
extern void
-pipe_fill_rect(ubyte * dst, const struct pipe_format_block *block,
+util_fill_rect(ubyte * dst, const struct pipe_format_block *block,
unsigned dst_stride, unsigned dst_x, unsigned dst_y,
unsigned width, unsigned height, uint32_t value);
diff --git a/src/gallium/auxiliary/util/u_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 8114b53cd0..5238299015 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;
@@ -65,12 +64,12 @@ pass_surface_buffer_create(struct pipe_screen *screen,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_buffer *buffer =
- screen->winsys->surface_buffer_create(screen->winsys,
- width, height,
- format, usage, stride);
+ screen->winsys->surface_buffer_create(screen->winsys, width, height,
+ format, usage, tex_usage, stride);
buffer->screen = screen;
@@ -82,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
@@ -105,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
@@ -114,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
@@ -123,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
@@ -132,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;
@@ -151,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 e519c354d2..0d706f9449 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -34,17 +34,9 @@
#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_build.h"
-#include "tgsi/tgsi_dump.h"
-#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_ureg.h"
@@ -58,93 +50,29 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
const uint *semantic_indexes)
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[100];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_VERTEX;
- uint ti, i;
-
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
+ struct ureg_program *ureg;
+ uint i;
- ti = 3;
+ ureg = ureg_create( TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
- /* declare inputs */
for (i = 0; i < num_attribs; i++) {
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
-
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = semantic_names[i];
- decl.Semantic.SemanticIndex = semantic_indexes[i];
-
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = i;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ src = ureg_DECL_vs_input( ureg, i );
+
+ dst = ureg_DECL_output( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ ureg_MOV( ureg, dst, src );
}
- /* declare outputs */
- for (i = 0; i < num_attribs; i++) {
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = semantic_names[i];
- decl.Semantic.SemanticIndex = semantic_indexes[i];
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = i;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
- }
+ ureg_END( ureg );
- /* emit MOV instructions */
- for (i = 0; i < num_attribs; i++) {
- /* MOVE out[i], in[i]; */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_MOV;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = i;
- inst.Instruction.NumSrcRegs = 1;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = i;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
- }
-
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
-
- return pipe->create_vs_state(pipe, &shader);
+ return ureg_create_shader_and_destroy( ureg, pipe );
}
@@ -152,108 +80,46 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
/**
* Make simple fragment texture shader:
- * TEX OUT[0], IN[0], SAMP[0], 2D;
+ * IMM {0,0,0,1} // (if writemask != 0xf)
+ * MOV OUT[0], IMM[0] // (if writemask != 0xf)
+ * TEX OUT[0].writemask, IN[0], SAMP[0], 2D;
* END;
*/
void *
-util_make_fragment_tex_shader(struct pipe_context *pipe)
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+ unsigned writemask )
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[100];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_FRAGMENT;
- uint ti;
-
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out;
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg, 0 );
- ti = 3;
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
- /* declare TEX[0] input */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
- /* XXX this could be linear... */
- decl.Declaration.Interpolate = TGSI_INTERPOLATE_PERSPECTIVE;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_GENERIC;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
- /* declare color[0] output */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
+ ureg_TEX( ureg, out, TGSI_TEXTURE_2D, tex, sampler );
+ ureg_END( ureg );
- /* declare sampler */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_SAMPLER;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* TEX instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_TEX;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = 0;
- inst.Instruction.NumSrcRegs = 2;
- inst.InstructionExtTexture.Texture = TGSI_TEXTURE_2D;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = 0;
- inst.FullSrcRegisters[1].SrcRegister.File = TGSI_FILE_SAMPLER;
- inst.FullSrcRegisters[1].SrcRegister.Index = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
-
- return pipe->create_fs_state(pipe, &shader);
+ return ureg_create_shader_and_destroy( ureg, pipe );
}
-
+void *
+util_make_fragment_tex_shader(struct pipe_context *pipe )
+{
+ return util_make_fragment_tex_shader_writemask( pipe,
+ TGSI_WRITEMASK_XYZW );
+}
@@ -263,87 +129,23 @@ util_make_fragment_tex_shader(struct pipe_context *pipe)
void *
util_make_fragment_passthrough_shader(struct pipe_context *pipe)
{
- struct pipe_shader_state shader;
- struct tgsi_token tokens[40];
- struct tgsi_header *header;
- struct tgsi_processor *processor;
- struct tgsi_full_declaration decl;
- struct tgsi_full_instruction inst;
- const uint procType = TGSI_PROCESSOR_FRAGMENT;
- uint ti;
-
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
-
- header = (struct tgsi_header *) &tokens[1];
- *header = tgsi_build_header();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
-
- ti = 3;
-
- /* declare input */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_INPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
- /* declare output */
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_OUTPUT;
- decl.Declaration.Semantic = 1;
- decl.Semantic.SemanticName = TGSI_SEMANTIC_COLOR;
- decl.Semantic.SemanticIndex = 0;
- decl.DeclarationRange.First =
- decl.DeclarationRange.Last = 0;
- ti += tgsi_build_full_declaration(&decl,
- &tokens[ti],
- header,
- Elements(tokens) - ti);
-
-
- /* MOVE out[0], in[0]; */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_MOV;
- inst.Instruction.NumDstRegs = 1;
- inst.FullDstRegisters[0].DstRegister.File = TGSI_FILE_OUTPUT;
- inst.FullDstRegisters[0].DstRegister.Index = 0;
- inst.Instruction.NumSrcRegs = 1;
- inst.FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_INPUT;
- inst.FullSrcRegisters[0].SrcRegister.Index = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
+ struct ureg_program *ureg;
+ struct ureg_src src;
+ struct ureg_dst dst;
- /* END instruction */
- inst = tgsi_default_full_instruction();
- inst.Instruction.Opcode = TGSI_OPCODE_END;
- inst.Instruction.NumDstRegs = 0;
- inst.Instruction.NumSrcRegs = 0;
- ti += tgsi_build_full_instruction(&inst,
- &tokens[ti],
- header,
- Elements(tokens) - ti );
+ ureg = ureg_create( TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
- assert(ti < Elements(tokens));
+ src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
+ dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
- shader.tokens = tokens;
+ ureg_MOV( ureg, dst, src );
+ ureg_END( ureg );
- return pipe->create_fs_state(pipe, &shader);
+ return ureg_create_shader_and_destroy( ureg, pipe );
}
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.h b/src/gallium/auxiliary/util/u_simple_shaders.h
index 6f8d96af9b..d2e80d6eb4 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.h
+++ b/src/gallium/auxiliary/util/u_simple_shaders.h
@@ -50,6 +50,10 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
extern void *
+util_make_fragment_tex_shader_writemask(struct pipe_context *pipe,
+ unsigned writemask );
+
+extern void *
util_make_fragment_tex_shader(struct pipe_context *pipe);
diff --git a/src/gallium/auxiliary/util/u_stream_stdc.c b/src/gallium/auxiliary/util/u_stream_stdc.c
index d8f648e5dd..5cd05b2904 100644
--- a/src/gallium/auxiliary/util/u_stream_stdc.c
+++ b/src/gallium/auxiliary/util/u_stream_stdc.c
@@ -32,7 +32,7 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_HAIKU)
#include <stdio.h>
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index a5b73cfc20..ce84ed7ad0 100644
--- a/src/gallium/auxiliary/util/u_surface.h
+++ b/src/gallium/auxiliary/util/u_surface.h
@@ -37,6 +37,23 @@ struct pipe_texture;
struct pipe_surface;
+/**
+ * Are s1 and s2 the same surface?
+ * Surfaces are basically views into textures so check if the two surfaces
+ * name the same part of the same texture.
+ */
+static INLINE boolean
+util_same_surface(const struct pipe_surface *s1, const struct pipe_surface *s2)
+{
+ return (s1->texture == s2->texture &&
+ s1->face == s2->face &&
+ s1->level == s2->level &&
+ s1->zslice == s2->zslice);
+}
+
+
+
+
extern boolean
util_create_rgba_surface(struct pipe_screen *screen,
uint width, uint height,
diff --git a/src/gallium/auxiliary/util/u_tile.c b/src/gallium/auxiliary/util/u_tile.c
index a0c8ed88f7..0d6489c26e 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -62,7 +62,7 @@ pipe_get_tile_raw(struct pipe_transfer *pt,
if(!src)
return;
- pipe_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
+ util_copy_rect(dst, &pt->block, dst_stride, 0, 0, w, h, src, pt->stride, x, y);
screen->transfer_unmap(screen, pt);
}
@@ -90,7 +90,7 @@ pipe_put_tile_raw(struct pipe_transfer *pt,
if(!dst)
return;
- pipe_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
+ util_copy_rect(dst, &pt->block, pt->stride, x, y, w, h, src, src_stride, 0, 0);
screen->transfer_unmap(screen, pt);
}
@@ -153,7 +153,7 @@ a8r8g8b8_put_tile_rgba(unsigned *dst,
}
-/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
+/*** PIPE_FORMAT_X8R8G8B8_UNORM ***/
static void
x8r8g8b8_get_tile_rgba(const unsigned *src,
@@ -170,7 +170,7 @@ x8r8g8b8_get_tile_rgba(const unsigned *src,
pRow[0] = ubyte_to_float((pixel >> 16) & 0xff);
pRow[1] = ubyte_to_float((pixel >> 8) & 0xff);
pRow[2] = ubyte_to_float((pixel >> 0) & 0xff);
- pRow[3] = ubyte_to_float(0xff);
+ pRow[3] = 1.0F;
}
p += dst_stride;
}
@@ -394,6 +394,52 @@ r5g6b5_put_tile_rgba(ushort *dst,
+/*** PIPE_FORMAT_R8G8B8_UNORM ***/
+
+static void
+r8g8b8_get_tile_rgba(const ubyte *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ pRow[0] = ubyte_to_float(src[0]);
+ pRow[1] = ubyte_to_float(src[1]);
+ pRow[2] = ubyte_to_float(src[2]);
+ pRow[3] = 1.0f;
+ src += 3;
+ }
+ p += dst_stride;
+ }
+}
+
+
+static void
+r8g8b8_put_tile_rgba(ubyte *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ dst[0] = float_to_ubyte(pRow[0]);
+ dst[1] = float_to_ubyte(pRow[1]);
+ dst[2] = float_to_ubyte(pRow[2]);
+ dst += 3;
+ }
+ p += src_stride;
+ }
+}
+
+
+
/*** PIPE_FORMAT_Z16_UNORM ***/
/**
@@ -596,6 +642,184 @@ r16g16b16a16_put_tile_rgba(short *dst,
}
+/*** PIPE_FORMAT_R8G8B8A8_SRGB ***/
+
+/**
+ * Convert an 8-bit sRGB value from non-linear space to a
+ * linear RGB value in [0, 1].
+ * Implemented with a 256-entry lookup table.
+ */
+static INLINE float
+srgb_to_linear(ubyte cs8)
+{
+ static float table[256];
+ static boolean tableReady = FALSE;
+ if (!tableReady) {
+ /* compute lookup table now */
+ uint i;
+ for (i = 0; i < 256; i++) {
+ const float cs = ubyte_to_float(i);
+ if (cs <= 0.04045) {
+ table[i] = cs / 12.92f;
+ }
+ else {
+ table[i] = (float) powf((cs + 0.055) / 1.055, 2.4);
+ }
+ }
+ tableReady = TRUE;
+ }
+ return table[cs8];
+}
+
+
+/**
+ * Convert linear float in [0,1] to an srgb ubyte value in [0,255].
+ * XXX this hasn't been tested (render to srgb surface).
+ * XXX this needs optimization.
+ */
+static INLINE ubyte
+linear_to_srgb(float cl)
+{
+ if (cl >= 1.0F)
+ return 255;
+ else if (cl >= 0.0031308F)
+ return float_to_ubyte(1.055F * powf(cl, 0.41666F) - 0.055F);
+ else if (cl > 0.0F)
+ return float_to_ubyte(12.92F * cl);
+ else
+ return 0.0;
+}
+
+
+static void
+a8r8g8b8_srgb_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ const unsigned pixel = *src++;
+ pRow[0] = srgb_to_linear((pixel >> 16) & 0xff);
+ pRow[1] = srgb_to_linear((pixel >> 8) & 0xff);
+ pRow[2] = srgb_to_linear((pixel >> 0) & 0xff);
+ pRow[3] = ubyte_to_float((pixel >> 24) & 0xff);
+ }
+ p += dst_stride;
+ }
+}
+
+static void
+a8r8g8b8_srgb_put_tile_rgba(unsigned *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ unsigned r, g, b, a;
+ r = linear_to_srgb(pRow[0]);
+ g = linear_to_srgb(pRow[1]);
+ b = linear_to_srgb(pRow[2]);
+ a = float_to_ubyte(pRow[3]);
+ *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ p += src_stride;
+ }
+}
+
+
+/*** PIPE_FORMAT_A8L8_SRGB ***/
+
+static void
+a8l8_srgb_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ ushort p = *src++;
+ pRow[0] =
+ pRow[1] =
+ pRow[2] = srgb_to_linear(p & 0xff);
+ pRow[3] = ubyte_to_float(p >> 8);
+ }
+ p += dst_stride;
+ }
+}
+
+static void
+a8l8_srgb_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ unsigned r, a;
+ r = linear_to_srgb(pRow[0]);
+ a = float_to_ubyte(pRow[3]);
+ *dst++ = (a << 8) | r;
+ }
+ p += src_stride;
+ }
+}
+
+
+/*** PIPE_FORMAT_L8_SRGB ***/
+
+static void
+l8_srgb_get_tile_rgba(const ubyte *src,
+ unsigned w, unsigned h,
+ float *p,
+ unsigned dst_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ float *pRow = p;
+ for (j = 0; j < w; j++, src++, pRow += 4) {
+ pRow[0] =
+ pRow[1] =
+ pRow[2] = srgb_to_linear(*src);
+ pRow[3] = 1.0;
+ }
+ p += dst_stride;
+ }
+}
+
+static void
+l8_srgb_put_tile_rgba(ubyte *dst,
+ unsigned w, unsigned h,
+ const float *p,
+ unsigned src_stride)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ const float *pRow = p;
+ for (j = 0; j < w; j++, pRow += 4) {
+ unsigned r;
+ r = linear_to_srgb(pRow[0]);
+ *dst++ = (ubyte) r;
+ }
+ p += src_stride;
+ }
+}
+
/*** PIPE_FORMAT_I8_UNORM ***/
@@ -928,6 +1152,9 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_R5G6B5_UNORM:
r5g6b5_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ r8g8b8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
+ break;
case PIPE_FORMAT_L8_UNORM:
l8_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
break;
@@ -946,6 +1173,15 @@ pipe_tile_raw_to_rgba(enum pipe_format format,
case PIPE_FORMAT_R16G16B16A16_SNORM:
r16g16b16a16_get_tile_rgba((short *) src, w, h, dst, dst_stride);
break;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ a8r8g8b8_srgb_get_tile_rgba((unsigned *) src, w, h, dst, dst_stride);
+ break;
+ case PIPE_FORMAT_A8L8_SRGB:
+ a8l8_srgb_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
+ break;
+ case PIPE_FORMAT_L8_SRGB:
+ l8_srgb_get_tile_rgba((ubyte *) src, w, h, dst, dst_stride);
+ break;
case PIPE_FORMAT_Z16_UNORM:
z16_get_tile_rgba((ushort *) src, w, h, dst, dst_stride);
break;
@@ -1035,6 +1271,9 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_R5G6B5_UNORM:
r5g6b5_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
break;
+ case PIPE_FORMAT_R8G8B8_UNORM:
+ r8g8b8_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
+ break;
case PIPE_FORMAT_R8G8B8A8_UNORM:
assert(0);
break;
@@ -1059,6 +1298,15 @@ pipe_put_tile_rgba(struct pipe_transfer *pt,
case PIPE_FORMAT_R16G16B16A16_SNORM:
r16g16b16a16_put_tile_rgba((short *) packed, w, h, p, src_stride);
break;
+ case PIPE_FORMAT_A8R8G8B8_SRGB:
+ a8r8g8b8_srgb_put_tile_rgba((unsigned *) packed, w, h, p, src_stride);
+ break;
+ case PIPE_FORMAT_A8L8_SRGB:
+ a8l8_srgb_put_tile_rgba((ushort *) packed, w, h, p, src_stride);
+ break;
+ case PIPE_FORMAT_L8_SRGB:
+ l8_srgb_put_tile_rgba((ubyte *) packed, w, h, p, src_stride);
+ break;
case PIPE_FORMAT_Z16_UNORM:
/*z16_put_tile_rgba((ushort *) packed, w, h, p, src_stride);*/
break;
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 5268cbf79c..b958a98635 100644
--- a/src/gallium/auxiliary/util/u_time.c
+++ b/src/gallium/auxiliary/util/u_time.c
@@ -35,7 +35,7 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
#include <sys/time.h>
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
#include <windows.h>
@@ -77,7 +77,7 @@ util_time_get_frequency(void)
void
util_time_get(struct util_time *t)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
gettimeofday(&t->tv, NULL);
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY)
LONGLONG temp;
@@ -102,7 +102,7 @@ util_time_add(const struct util_time *t1,
int64_t usecs,
struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
t2->tv.tv_sec = t1->tv.tv_sec + usecs / 1000000;
t2->tv.tv_usec = t1->tv.tv_usec + usecs % 1000000;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
@@ -124,7 +124,7 @@ int64_t
util_time_diff(const struct util_time *t1,
const struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
return (t2->tv.tv_usec - t1->tv.tv_usec) +
(t2->tv.tv_sec - t1->tv.tv_sec)*1000000;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
@@ -144,7 +144,7 @@ util_time_micros( void )
util_time_get(&t1);
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
return t1.tv.tv_usec + t1.tv.tv_sec*1000000LL;
#elif defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) || defined(PIPE_SUBSYSTEM_WINDOWS_USER) || defined(PIPE_SUBSYSTEM_WINDOWS_CE)
util_time_get_frequency();
@@ -166,7 +166,7 @@ static INLINE int
util_time_compare(const struct util_time *t1,
const struct util_time *t2)
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
if (t1->tv.tv_sec < t2->tv.tv_sec)
return -1;
else if(t1->tv.tv_sec > t2->tv.tv_sec)
diff --git a/src/gallium/auxiliary/util/u_time.h b/src/gallium/auxiliary/util/u_time.h
index 6bca6077a2..a6189a247b 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -38,11 +38,16 @@
#include "pipe/p_config.h"
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE)
#include <time.h> /* timeval */
#include <unistd.h> /* usleep */
#endif
+#if defined(PIPE_OS_HAIKU)
+#include <sys/time.h> /* timeval */
+#include <unistd.h>
+#endif
+
#include "pipe/p_compiler.h"
@@ -58,7 +63,7 @@ extern "C" {
*/
struct util_time
{
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
struct timeval tv;
#else
int64_t counter;
@@ -89,7 +94,7 @@ util_time_timeout(const struct util_time *start,
const struct util_time *end,
const struct util_time *curr);
-#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS)
+#if defined(PIPE_OS_LINUX) || defined(PIPE_OS_BSD) || defined(PIPE_OS_SOLARIS) || defined(PIPE_OS_APPLE) || defined(PIPE_OS_HAIKU)
#define util_time_sleep usleep
#else
void
diff --git a/src/gallium/auxiliary/util/u_timed_winsys.c b/src/gallium/auxiliary/util/u_timed_winsys.c
index 77b2a3a1c8..178acdca4d 100644
--- a/src/gallium/auxiliary/util/u_timed_winsys.c
+++ b/src/gallium/auxiliary/util/u_timed_winsys.c
@@ -212,13 +212,14 @@ timed_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_winsys *backend = timed_winsys(winsys)->backend;
uint64_t start = time_start();
struct pipe_buffer *ret = backend->surface_buffer_create( backend, width, height,
- format, usage, stride );
+ format, usage, tex_usage, stride );
time_finish(winsys, start, 7, __FUNCTION__);
diff --git a/src/gallium/auxiliary/util/u_upload_mgr.c b/src/gallium/auxiliary/util/u_upload_mgr.c
index c90425f3e5..eb635c9f14 100644
--- a/src/gallium/auxiliary/util/u_upload_mgr.c
+++ b/src/gallium/auxiliary/util/u_upload_mgr.c
@@ -123,21 +123,25 @@ static enum pipe_error
u_upload_alloc_buffer( struct u_upload_mgr *upload,
unsigned min_size )
{
+ unsigned size;
+
/* Release old buffer, if present:
*/
u_upload_flush( upload );
/* Allocate a new one:
*/
- upload->size = align(MAX2(upload->default_size, min_size), 4096);
+ size = align(MAX2(upload->default_size, min_size), 4096);
upload->buffer = pipe_buffer_create( upload->screen,
upload->alignment,
upload->usage | PIPE_BUFFER_USAGE_CPU_WRITE,
- upload->size );
+ size );
if (upload->buffer == NULL)
goto fail;
+ upload->size = size;
+
upload->offset = 0;
return 0;
diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h
index 1f6860da11..d5f5c7bbba 100644
--- a/src/gallium/drivers/cell/common.h
+++ b/src/gallium/drivers/cell/common.h
@@ -327,7 +327,7 @@ struct cell_command_sampler
opcode_t opcode; /**< CELL_CMD_STATE_SAMPLER */
uint unit;
struct pipe_sampler_state state;
- uint32_t pad_[1];
+ uint32_t pad_[2];
};
diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
index 7cd5656a7e..312621fd53 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
@@ -1767,7 +1767,7 @@ emit_instruction(struct codegen *gen,
case TGSI_OPCODE_MAD:
return emit_MAD(gen, inst);
case TGSI_OPCODE_LERP:
- return emit_LERP(gen, inst);
+ return emit_LRP(gen, inst);
case TGSI_OPCODE_DP3:
return emit_DP3(gen, inst);
case TGSI_OPCODE_DP4:
@@ -1810,9 +1810,9 @@ emit_instruction(struct codegen *gen,
return emit_function_call(gen, inst, "spu_sin", 1, TRUE);
case TGSI_OPCODE_POW:
return emit_function_call(gen, inst, "spu_pow", 2, TRUE);
- case TGSI_OPCODE_EXPBASE2:
+ case TGSI_OPCODE_EX2:
return emit_function_call(gen, inst, "spu_exp2", 1, TRUE);
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_LG2:
return emit_function_call(gen, inst, "spu_log2", 1, TRUE);
case TGSI_OPCODE_TEX:
/* fall-through for now */
@@ -1834,9 +1834,9 @@ emit_instruction(struct codegen *gen,
case TGSI_OPCODE_ENDIF:
return emit_ENDIF(gen, inst);
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
return emit_BGNLOOP(gen, inst);
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP:
return emit_ENDLOOP(gen, inst);
case TGSI_OPCODE_BRK:
return emit_BRK(gen, inst);
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index bd48ce7005..d185c6b849 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/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index e26594448f..6a63a0e6ce 100644
--- a/src/gallium/drivers/cell/ppu/cell_texture.c
+++ b/src/gallium/drivers/cell/ppu/cell_texture.c
@@ -44,13 +44,6 @@
-static unsigned
-minify(unsigned d)
-{
- return MAX2(1, d>>1);
-}
-
-
static void
cell_texture_layout(struct cell_texture *ct)
{
@@ -424,7 +417,8 @@ cell_transfer_map(struct pipe_screen *screen, struct pipe_transfer *transfer)
if (!ctrans->map)
return NULL; /* out of memory */
- if (transfer->usage & PIPE_TRANSFER_READ) {
+ if (transfer->usage == PIPE_TRANSFER_READ ||
+ transfer->usage == PIPE_TRANSFER_READ_WRITE) {
/* need to untwiddle the texture to make a linear version */
const uint bpp = pf_get_size(ct->base.format);
if (bpp == 4) {
@@ -465,7 +459,8 @@ cell_transfer_unmap(struct pipe_screen *screen,
PIPE_BUFFER_USAGE_CPU_READ);
}
- if (transfer->usage & PIPE_TRANSFER_WRITE) {
+ if (transfer->usage == PIPE_TRANSFER_WRITE ||
+ transfer->usage == PIPE_TRANSFER_READ_WRITE) {
/* The user wrote new texture data into the mapped buffer.
* We need to convert the new linear data into the twiddled/tiled format.
*/
diff --git a/src/gallium/drivers/cell/spu/spu_exec.c b/src/gallium/drivers/cell/spu/spu_exec.c
index e27df2dfb3..0eaae2e451 100644
--- a/src/gallium/drivers/cell/spu/spu_exec.c
+++ b/src/gallium/drivers/cell/spu/spu_exec.c
@@ -952,7 +952,6 @@ exec_instruction(
break;
case TGSI_OPCODE_RCP:
- /* TGSI_OPCODE_RECIP */
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q);
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -961,7 +960,6 @@ exec_instruction(
break;
case TGSI_OPCODE_RSQ:
- /* TGSI_OPCODE_RECIPSQRT */
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_sqrt(r[0].q);
r[0].q = micro_div(mach->Temps[TEMP_1_I].xyzw[TEMP_1_C].q, r[0].q);
@@ -1115,7 +1113,6 @@ exec_instruction(
break;
case TGSI_OPCODE_MAD:
- /* TGSI_OPCODE_MADD */
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
FETCH( &r[1], 1, chan_index );
@@ -1136,8 +1133,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LERP:
- /* TGSI_OPCODE_LRP */
+ case TGSI_OPCODE_LRP:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
FETCH(&r[1], 1, chan_index);
@@ -1154,25 +1150,11 @@ exec_instruction(
ASSERT (0);
break;
- case TGSI_OPCODE_CND0:
+ case TGSI_OPCODE_DP2A:
ASSERT (0);
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
- ASSERT (0);
- break;
-
- case TGSI_OPCODE_INDEX:
- ASSERT (0);
- break;
-
- case TGSI_OPCODE_NEGATE:
- ASSERT (0);
- break;
-
- case TGSI_OPCODE_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
r[0].q = micro_frc(r[0].q);
@@ -1184,8 +1166,7 @@ exec_instruction(
ASSERT (0);
break;
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
r[0].q = micro_flr(r[0].q);
@@ -1201,8 +1182,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH(&r[0], 0, CHAN_X);
r[0].q = micro_pow(mach->Temps[TEMP_2_I].xyzw[TEMP_2_C].q, r[0].q);
@@ -1212,8 +1192,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( &r[0], 0, CHAN_X );
r[0].q = micro_lg2(r[0].q);
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -1221,8 +1200,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_POWER:
- /* TGSI_OPCODE_POW */
+ case TGSI_OPCODE_POW:
FETCH(&r[0], 0, CHAN_X);
FETCH(&r[1], 1, CHAN_X);
@@ -1233,7 +1211,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
+ case TGSI_OPCODE_XPD:
/* TGSI_OPCODE_XPD */
FETCH(&r[0], 0, CHAN_Y);
FETCH(&r[1], 1, CHAN_Z);
@@ -1275,10 +1253,6 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_MULTIPLYMATRIX:
- ASSERT (0);
- break;
-
case TGSI_OPCODE_ABS:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH(&r[0], 0, chan_index);
@@ -1780,9 +1754,9 @@ exec_instruction(
mach->Primitives[mach->Temps[TEMP_PRIMITIVE_I].xyzw[TEMP_PRIMITIVE_C].u[0]] = 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
/* fall-through (for now) */
- case TGSI_OPCODE_BGNLOOP2:
+ case TGSI_OPCODE_BGNLOOP:
/* push LoopMask and ContMasks */
ASSERT(mach->LoopStackTop < TGSI_EXEC_MAX_LOOP_NESTING);
mach->LoopStack[mach->LoopStackTop++] = mach->LoopMask;
@@ -1790,9 +1764,9 @@ exec_instruction(
mach->ContStack[mach->ContStackTop++] = mach->ContMask;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
/* fall-through (for now at least) */
- case TGSI_OPCODE_ENDLOOP2:
+ case TGSI_OPCODE_ENDLOOP:
/* Restore ContMask, but don't pop */
ASSERT(mach->ContStackTop > 0);
mach->ContMask = mach->ContStack[mach->ContStackTop - 1];
diff --git a/src/gallium/drivers/i915simple/Makefile b/src/gallium/drivers/i915simple/Makefile
index 8870b39866..fb533c1796 100644
--- a/src/gallium/drivers/i915simple/Makefile
+++ b/src/gallium/drivers/i915simple/Makefile
@@ -5,6 +5,7 @@ LIBNAME = i915simple
C_SOURCES = \
i915_blit.c \
+ i915_buffer.c \
i915_clear.c \
i915_flush.c \
i915_context.c \
diff --git a/src/gallium/drivers/i915simple/SConscript b/src/gallium/drivers/i915simple/SConscript
index 2366e1247f..778c4ed0fd 100644
--- a/src/gallium/drivers/i915simple/SConscript
+++ b/src/gallium/drivers/i915simple/SConscript
@@ -6,6 +6,7 @@ i915simple = env.ConvenienceLibrary(
target = 'i915simple',
source = [
'i915_blit.c',
+ 'i915_buffer.c',
'i915_clear.c',
'i915_context.c',
'i915_debug.c',
diff --git a/src/gallium/drivers/i915simple/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h
index a433cf054d..b813784723 100644
--- a/src/gallium/drivers/i915simple/i915_batch.h
+++ b/src/gallium/drivers/i915simple/i915_batch.h
@@ -28,89 +28,20 @@
#ifndef I915_BATCH_H
#define I915_BATCH_H
-#include "i915_winsys.h"
+#include "intel_batchbuffer.h"
-struct i915_batchbuffer
-{
- struct pipe_buffer *buffer;
- struct i915_winsys *winsys;
+#define BEGIN_BATCH(dwords, relocs) \
+ (intel_batchbuffer_check(i915->batch, dwords, relocs))
- unsigned char *map;
- unsigned char *ptr;
+#define OUT_BATCH(dword) \
+ intel_batchbuffer_dword(i915->batch, dword)
- size_t size;
- size_t actual_size;
+#define OUT_RELOC(buf, usage, offset) \
+ intel_batchbuffer_reloc(i915->batch, buf, usage, offset)
- size_t relocs;
- size_t max_relocs;
-};
-
-static INLINE boolean
-i915_batchbuffer_check( struct i915_batchbuffer *batch,
- size_t dwords,
- size_t relocs )
-{
- /** TODO JB: Check relocs */
- return dwords * 4 <= batch->size - (batch->ptr - batch->map);
-}
-
-static INLINE size_t
-i915_batchbuffer_space( struct i915_batchbuffer *batch )
-{
- return batch->size - (batch->ptr - batch->map);
-}
-
-static INLINE void
-i915_batchbuffer_dword( struct i915_batchbuffer *batch,
- unsigned dword )
-{
- if (i915_batchbuffer_space(batch) < 4)
- return;
-
- *(unsigned *)batch->ptr = dword;
- batch->ptr += 4;
-}
-
-static INLINE void
-i915_batchbuffer_write( struct i915_batchbuffer *batch,
- void *data,
- size_t size )
-{
- if (i915_batchbuffer_space(batch) < size)
- return;
-
- memcpy(data, batch->ptr, size);
- batch->ptr += size;
-}
-
-static INLINE void
-i915_batchbuffer_reloc( struct i915_batchbuffer *batch,
- struct pipe_buffer *buffer,
- size_t flags,
- size_t offset )
-{
- batch->winsys->batch_reloc( batch->winsys, buffer, flags, offset );
-}
-
-static INLINE void
-i915_batchbuffer_flush( struct i915_batchbuffer *batch,
- struct pipe_fence_handle **fence )
-{
- batch->winsys->batch_flush( batch->winsys, fence );
-}
-
-#define BEGIN_BATCH( dwords, relocs ) \
- (i915_batchbuffer_check( i915->batch, dwords, relocs ))
-
-#define OUT_BATCH( dword ) \
- i915_batchbuffer_dword( i915->batch, dword )
-
-#define OUT_RELOC( buf, flags, delta ) \
- i915_batchbuffer_reloc( i915->batch, buf, flags, delta )
-
-#define FLUSH_BATCH(fence) do { \
- i915->winsys->batch_flush( i915->winsys, fence ); \
- i915->hardware_dirty = ~0; \
+#define FLUSH_BATCH(fence) do { \
+ intel_batchbuffer_flush(i915->batch, fence); \
+ i915->hardware_dirty = ~0; \
} while (0)
#endif
diff --git a/src/gallium/drivers/i915simple/i915_blit.c b/src/gallium/drivers/i915simple/i915_blit.c
index 448a4708ce..83dfc33528 100644
--- a/src/gallium/drivers/i915simple/i915_blit.c
+++ b/src/gallium/drivers/i915simple/i915_blit.c
@@ -26,8 +26,6 @@
**************************************************************************/
-#include "i915_context.h"
-#include "i915_winsys.h"
#include "i915_blit.h"
#include "i915_reg.h"
#include "i915_batch.h"
@@ -37,33 +35,33 @@
void
i915_fill_blit(struct i915_context *i915,
- unsigned cpp,
- unsigned short dst_pitch,
- struct pipe_buffer *dst_buffer,
- unsigned dst_offset,
- short x, short y,
- short w, short h,
- unsigned color)
+ unsigned cpp,
+ unsigned short dst_pitch,
+ struct intel_buffer *dst_buffer,
+ unsigned dst_offset,
+ short x, short y,
+ short w, short h,
+ unsigned color)
{
unsigned BR13, CMD;
I915_DBG(i915,
- "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
- __FUNCTION__,
- dst_buffer, dst_pitch, dst_offset, x, y, w, h);
+ "%s dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+ __FUNCTION__,
+ dst_buffer, dst_pitch, dst_offset, x, y, w, h);
switch (cpp) {
case 1:
case 2:
case 3:
BR13 = (((int) dst_pitch) & 0xffff) |
- (0xF0 << 16) | (1 << 24);
+ (0xF0 << 16) | (1 << 24);
CMD = XY_COLOR_BLT_CMD;
break;
case 4:
BR13 = (((int) dst_pitch) & 0xffff) |
- (0xF0 << 16) | (1 << 24) | (1 << 25);
+ (0xF0 << 16) | (1 << 24) | (1 << 25);
CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
XY_COLOR_BLT_WRITE_RGB);
break;
@@ -79,25 +77,24 @@ i915_fill_blit(struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((y << 16) | x);
OUT_BATCH(((y + h) << 16) | (x + w));
- OUT_RELOC( dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset);
+ OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
OUT_BATCH(color);
FLUSH_BATCH(NULL);
}
-
void
-i915_copy_blit( struct i915_context *i915,
- unsigned do_flip,
- unsigned cpp,
- unsigned short src_pitch,
- struct pipe_buffer *src_buffer,
- unsigned src_offset,
- unsigned short dst_pitch,
- struct pipe_buffer *dst_buffer,
- unsigned dst_offset,
- short src_x, short src_y,
- short dst_x, short dst_y,
- short w, short h )
+i915_copy_blit(struct i915_context *i915,
+ unsigned do_flip,
+ unsigned cpp,
+ unsigned short src_pitch,
+ struct intel_buffer *src_buffer,
+ unsigned src_offset,
+ unsigned short dst_pitch,
+ struct intel_buffer *dst_buffer,
+ unsigned dst_offset,
+ short src_x, short src_y,
+ short dst_x, short dst_y,
+ short w, short h)
{
unsigned CMD, BR13;
int dst_y2 = dst_y + h;
@@ -105,32 +102,30 @@ i915_copy_blit( struct i915_context *i915,
I915_DBG(i915,
- "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
- __FUNCTION__,
- src_buffer, src_pitch, src_offset, src_x, src_y,
- dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
+ "%s src:buf(%p)/%d+%d %d,%d dst:buf(%p)/%d+%d %d,%d sz:%dx%d\n",
+ __FUNCTION__,
+ src_buffer, src_pitch, src_offset, src_x, src_y,
+ dst_buffer, dst_pitch, dst_offset, dst_x, dst_y, w, h);
switch (cpp) {
case 1:
case 2:
case 3:
BR13 = (((int) dst_pitch) & 0xffff) |
- (0xCC << 16) | (1 << 24);
+ (0xCC << 16) | (1 << 24);
CMD = XY_SRC_COPY_BLT_CMD;
break;
case 4:
BR13 = (((int) dst_pitch) & 0xffff) |
- (0xCC << 16) | (1 << 24) | (1 << 25);
- CMD =
- (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
- XY_SRC_COPY_BLT_WRITE_RGB);
+ (0xCC << 16) | (1 << 24) | (1 << 25);
+ CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
+ XY_SRC_COPY_BLT_WRITE_RGB);
break;
default:
return;
}
- if (dst_y2 < dst_y ||
- dst_x2 < dst_x) {
+ if (dst_y2 < dst_y || dst_x2 < dst_x) {
return;
}
@@ -140,7 +135,6 @@ i915_copy_blit( struct i915_context *i915,
*/
assert (dst_pitch > 0 && src_pitch > 0);
-
if (!BEGIN_BATCH(8, 2)) {
FLUSH_BATCH(NULL);
assert(BEGIN_BATCH(8, 2));
@@ -149,11 +143,9 @@ i915_copy_blit( struct i915_context *i915,
OUT_BATCH(BR13);
OUT_BATCH((dst_y << 16) | dst_x);
OUT_BATCH((dst_y2 << 16) | dst_x2);
- OUT_RELOC(dst_buffer, I915_BUFFER_ACCESS_WRITE, dst_offset);
+ OUT_RELOC(dst_buffer, INTEL_USAGE_2D_TARGET, dst_offset);
OUT_BATCH((src_y << 16) | src_x);
OUT_BATCH(((int) src_pitch & 0xffff));
- OUT_RELOC(src_buffer, I915_BUFFER_ACCESS_READ, src_offset);
+ OUT_RELOC(src_buffer, INTEL_USAGE_2D_SOURCE, src_offset);
FLUSH_BATCH(NULL);
}
-
-
diff --git a/src/gallium/drivers/i915simple/i915_blit.h b/src/gallium/drivers/i915simple/i915_blit.h
index 0bb3453861..8ce3220cfd 100644
--- a/src/gallium/drivers/i915simple/i915_blit.h
+++ b/src/gallium/drivers/i915simple/i915_blit.h
@@ -32,24 +32,24 @@
extern void i915_copy_blit(struct i915_context *i915,
unsigned do_flip,
- unsigned cpp,
- unsigned short src_pitch,
- struct pipe_buffer *src_buffer,
- unsigned src_offset,
- unsigned short dst_pitch,
- struct pipe_buffer *dst_buffer,
- unsigned dst_offset,
- short srcx, short srcy,
- short dstx, short dsty,
- short w, short h );
+ unsigned cpp,
+ unsigned short src_pitch,
+ struct intel_buffer *src_buffer,
+ unsigned src_offset,
+ unsigned short dst_pitch,
+ struct intel_buffer *dst_buffer,
+ unsigned dst_offset,
+ short srcx, short srcy,
+ short dstx, short dsty,
+ short w, short h);
extern void i915_fill_blit(struct i915_context *i915,
- unsigned cpp,
- unsigned short dst_pitch,
- struct pipe_buffer *dst_buffer,
- unsigned dst_offset,
- short x, short y,
- short w, short h, unsigned color);
+ unsigned cpp,
+ unsigned short dst_pitch,
+ struct intel_buffer *dst_buffer,
+ unsigned dst_offset,
+ short x, short y,
+ short w, short h, unsigned color);
#endif
diff --git a/src/gallium/drivers/i915simple/i915_buffer.c b/src/gallium/drivers/i915simple/i915_buffer.c
new file mode 100644
index 0000000000..effeba1297
--- /dev/null
+++ b/src/gallium/drivers/i915simple/i915_buffer.c
@@ -0,0 +1,136 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_memory.h"
+#include "i915_screen.h"
+#include "i915_buffer.h"
+
+struct intel_buffer;
+
+struct i915_buffer
+{
+ struct pipe_buffer base;
+
+ struct intel_buffer *ibuf; /** hw buffer */
+
+ void *data; /**< user and malloc data */
+ boolean own; /**< we own the data incase of malloc */
+};
+
+static INLINE struct i915_buffer *
+i915_buffer(struct pipe_buffer *buffer)
+{
+ return (struct i915_buffer *)buffer;
+}
+
+static struct pipe_buffer *
+i915_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
+
+ if (!buf)
+ return NULL;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->base.alignment = alignment;
+ buf->base.screen = screen;
+ buf->base.usage = usage;
+ buf->base.size = size;
+ buf->data = MALLOC(size);
+ buf->own = TRUE;
+
+ if (!buf->data)
+ goto err;
+
+ return &buf->base;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+static struct pipe_buffer *
+i915_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct i915_buffer *buf = CALLOC_STRUCT(i915_buffer);
+
+ if (!buf)
+ return NULL;
+
+ pipe_reference_init(&buf->base.reference, 1);
+ buf->base.alignment = 0;
+ buf->base.screen = screen;
+ buf->base.usage = 0;
+ buf->base.size = bytes;
+ buf->data = ptr;
+ buf->own = FALSE;
+
+ return &buf->base;
+}
+
+static void *
+i915_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buffer,
+ unsigned usage)
+{
+ struct i915_buffer *buf = i915_buffer(buffer);
+ assert(!buf->ibuf);
+ return buf->data;
+}
+
+static void
+i915_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buffer)
+{
+ struct i915_buffer *buf = i915_buffer(buffer);
+ assert(!buf->ibuf);
+}
+
+static void
+i915_buffer_destroy(struct pipe_buffer *buffer)
+{
+ struct i915_buffer *buf = i915_buffer(buffer);
+ assert(!buf->ibuf);
+
+ if (buf->own)
+ FREE(buf->data);
+ FREE(buf);
+}
+
+void i915_init_screen_buffer_functions(struct i915_screen *screen)
+{
+ screen->base.buffer_create = i915_buffer_create;
+ screen->base.user_buffer_create = i915_user_buffer_create;
+ screen->base.buffer_map = i915_buffer_map;
+ screen->base.buffer_map_range = NULL;
+ screen->base.buffer_flush_mapped_range = NULL;
+ screen->base.buffer_unmap = i915_buffer_unmap;
+ screen->base.buffer_destroy = i915_buffer_destroy;
+}
diff --git a/src/gallium/drivers/i915simple/i915_buffer.h b/src/gallium/drivers/i915simple/i915_buffer.h
new file mode 100644
index 0000000000..80fda7c62f
--- /dev/null
+++ b/src/gallium/drivers/i915simple/i915_buffer.h
@@ -0,0 +1,31 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef I915_BUFFER_H
+#define I915_BUFFER_H
+
+void i915_init_screen_buffer_functions(struct i915_screen *screen);
+
+#endif
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index ccf9bb31fb..e745f3342d 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -26,8 +26,8 @@
**************************************************************************/
#include "i915_context.h"
-#include "i915_winsys.h"
#include "i915_state.h"
+#include "i915_screen.h"
#include "i915_batch.h"
#include "i915_texture.h"
#include "i915_reg.h"
@@ -40,66 +40,58 @@
#include "pipe/p_screen.h"
-static void i915_destroy( struct pipe_context *pipe )
-{
- struct i915_context *i915 = i915_context( pipe );
-
- draw_destroy( i915->draw );
-
- if(i915->winsys->destroy)
- i915->winsys->destroy(i915->winsys);
-
- FREE( i915 );
-}
+/*
+ * Draw functions
+ */
static boolean
i915_draw_range_elements(struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned min_index,
- unsigned max_index,
- unsigned prim, unsigned start, unsigned count)
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned prim, unsigned start, unsigned count)
{
- struct i915_context *i915 = i915_context( pipe );
+ struct i915_context *i915 = i915_context(pipe);
struct draw_context *draw = i915->draw;
unsigned i;
if (i915->dirty)
- i915_update_derived( i915 );
+ i915_update_derived(i915);
/*
* Map vertex buffers
*/
for (i = 0; i < i915->num_vertex_buffers; i++) {
- void *buf
- = pipe_buffer_map(pipe->screen,
- i915->vertex_buffer[i].buffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *buf = pipe_buffer_map(pipe->screen, i915->vertex_buffer[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_vertex_buffer(draw, i, buf);
}
- /* Map index buffer, if present */
+
+ /*
+ * Map index buffer, if present
+ */
if (indexBuffer) {
- void *mapped_indexes
- = pipe_buffer_map(pipe->screen, indexBuffer,
- PIPE_BUFFER_USAGE_CPU_READ);
+ void *mapped_indexes = pipe_buffer_map(pipe->screen, indexBuffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
draw_set_mapped_element_buffer_range(draw, indexSize,
- min_index,
- max_index,
- mapped_indexes);
- }
- else {
- /* no index/element buffer */
+ min_index,
+ max_index,
+ mapped_indexes);
+ } else {
draw_set_mapped_element_buffer(draw, 0, NULL);
}
draw_set_mapped_constant_buffer(draw,
i915->current.constants[PIPE_SHADER_VERTEX],
- ( i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
- 4 * sizeof(float) ));
+ (i915->current.num_user_constants[PIPE_SHADER_VERTEX] *
+ 4 * sizeof(float)));
- /* draw! */
+ /*
+ * Do the drawing
+ */
draw_arrays(i915->draw, prim, start, count);
/*
@@ -109,6 +101,7 @@ i915_draw_range_elements(struct pipe_context *pipe,
pipe_buffer_unmap(pipe->screen, i915->vertex_buffer[i].buffer);
draw_set_mapped_vertex_buffer(draw, i, NULL);
}
+
if (indexBuffer) {
pipe_buffer_unmap(pipe->screen, indexBuffer);
draw_set_mapped_element_buffer_range(draw, 0, start, start + count - 1, NULL);
@@ -118,51 +111,88 @@ i915_draw_range_elements(struct pipe_context *pipe,
}
static boolean
-i915_draw_elements( struct pipe_context *pipe,
- struct pipe_buffer *indexBuffer,
- unsigned indexSize,
- unsigned prim, unsigned start, unsigned count)
+i915_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned prim, unsigned start, unsigned count)
{
- return i915_draw_range_elements( pipe, indexBuffer,
- indexSize,
- 0, 0xffffffff,
- prim, start, count );
+ return i915_draw_range_elements(pipe, indexBuffer,
+ indexSize,
+ 0, 0xffffffff,
+ prim, start, count);
}
-static boolean i915_draw_arrays( struct pipe_context *pipe,
- unsigned prim, unsigned start, unsigned count)
+static boolean
+i915_draw_arrays(struct pipe_context *pipe,
+ unsigned prim, unsigned start, unsigned count)
{
return i915_draw_elements(pipe, NULL, 0, prim, start, count);
}
+/*
+ * Is referenced functions
+ */
+
+
static unsigned int
-i915_is_texture_referenced( struct pipe_context *pipe,
- struct pipe_texture *texture,
- unsigned face, unsigned level)
+i915_is_texture_referenced(struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
{
/**
- * FIXME: Optimize.
+ * FIXME: Return the corrent result. We can't alays return referenced
+ * since it causes a double flush within the vbo module.
*/
-
+#if 0
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+#else
+ return 0;
+#endif
}
static unsigned int
-i915_is_buffer_referenced( struct pipe_context *pipe,
- struct pipe_buffer *buf)
+i915_is_buffer_referenced(struct pipe_context *pipe,
+ struct pipe_buffer *buf)
{
/**
- * FIXME: Optimize.
+ * FIXME: Return the corrent result. We can't alays return referenced
+ * since it causes a double flush within the vbo module.
*/
-
+#if 0
return PIPE_REFERENCED_FOR_READ | PIPE_REFERENCED_FOR_WRITE;
+#else
+ return 0;
+#endif
}
-struct pipe_context *i915_create_context( struct pipe_screen *screen,
- struct pipe_winsys *pipe_winsys,
- struct i915_winsys *i915_winsys )
+/*
+ * Generic context functions
+ */
+
+
+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);
+}
+
+struct pipe_context *
+i915_create_context(struct pipe_screen *screen)
{
struct i915_context *i915;
@@ -170,21 +200,20 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
if (i915 == NULL)
return NULL;
- i915->winsys = i915_winsys;
- i915->pipe.winsys = pipe_winsys;
- i915->pipe.screen = screen;
+ i915->iws = i915_screen(screen)->iws;
+ i915->base.winsys = NULL;
+ i915->base.screen = screen;
- i915->pipe.destroy = i915_destroy;
+ i915->base.destroy = i915_destroy;
- i915->pipe.clear = i915_clear;
+ i915->base.clear = i915_clear;
+ i915->base.draw_arrays = i915_draw_arrays;
+ i915->base.draw_elements = i915_draw_elements;
+ i915->base.draw_range_elements = i915_draw_range_elements;
- i915->pipe.draw_arrays = i915_draw_arrays;
- i915->pipe.draw_elements = i915_draw_elements;
- i915->pipe.draw_range_elements = i915_draw_range_elements;
-
- i915->pipe.is_texture_referenced = i915_is_texture_referenced;
- i915->pipe.is_buffer_referenced = i915_is_buffer_referenced;
+ i915->base.is_texture_referenced = i915_is_texture_referenced;
+ i915->base.is_buffer_referenced = i915_is_buffer_referenced;
/*
* Create drawing context and plug our rendering stage into it.
@@ -193,27 +222,23 @@ struct pipe_context *i915_create_context( struct pipe_screen *screen,
assert(i915->draw);
if (!debug_get_bool_option("I915_NO_VBUF", FALSE)) {
draw_set_rasterize_stage(i915->draw, i915_draw_vbuf_stage(i915));
- }
- else {
+ } else {
draw_set_rasterize_stage(i915->draw, i915_draw_render_stage(i915));
}
i915_init_surface_functions(i915);
i915_init_state_functions(i915);
i915_init_flush_functions(i915);
- i915_init_texture_functions(i915);
- draw_install_aaline_stage(i915->draw, &i915->pipe);
- draw_install_aapoint_stage(i915->draw, &i915->pipe);
+ draw_install_aaline_stage(i915->draw, &i915->base);
+ draw_install_aapoint_stage(i915->draw, &i915->base);
i915->dirty = ~0;
i915->hardware_dirty = ~0;
/* Batch stream debugging is a bit hacked up at the moment:
*/
- i915->batch = i915_winsys->batch_get(i915_winsys);
- i915->batch->winsys = i915_winsys;
+ i915->batch = i915->iws->batchbuffer_create(i915->iws);
- return &i915->pipe;
+ return &i915->base;
}
-
diff --git a/src/gallium/drivers/i915simple/i915_context.h b/src/gallium/drivers/i915simple/i915_context.h
index b6983ba86e..234b441ce6 100644
--- a/src/gallium/drivers/i915simple/i915_context.h
+++ b/src/gallium/drivers/i915simple/i915_context.h
@@ -38,6 +38,11 @@
#include "tgsi/tgsi_scan.h"
+struct intel_winsys;
+struct intel_buffer;
+struct intel_batchbuffer;
+
+
#define I915_TEX_UNITS 8
#define I915_DYNAMIC_MODES4 0
@@ -182,7 +187,6 @@ struct i915_sampler_state {
unsigned maxlod;
};
-
struct i915_texture {
struct pipe_texture base;
@@ -192,7 +196,8 @@ struct i915_texture {
unsigned depth_stride; /* per-image on i945? */
unsigned total_nblocksy;
- unsigned tiled;
+ unsigned sw_tiled; /**< tiled with software flags */
+ unsigned hw_tiled; /**< tiled with hardware fences */
unsigned nr_images[PIPE_MAX_TEXTURE_LEVELS];
@@ -206,15 +211,15 @@ struct i915_texture {
/* The data is held here:
*/
- struct pipe_buffer *buffer;
+ struct intel_buffer *buffer;
};
-struct i915_batchbuffer;
-
struct i915_context
{
- struct pipe_context pipe;
- struct i915_winsys *winsys;
+ struct pipe_context base;
+
+ struct intel_winsys *iws;
+
struct draw_context *draw;
/* The most recent drawing state as set by the driver:
@@ -243,10 +248,10 @@ struct i915_context
unsigned num_vertex_elements;
unsigned num_vertex_buffers;
- struct i915_batchbuffer *batch;
+ struct intel_batchbuffer *batch;
/** Vertex buffer */
- struct pipe_buffer *vbo;
+ struct intel_buffer *vbo;
size_t vbo_offset;
unsigned vbo_flushed;
diff --git a/src/gallium/drivers/i915simple/i915_debug.c b/src/gallium/drivers/i915simple/i915_debug.c
index e08582efab..ce92d1af9a 100644
--- a/src/gallium/drivers/i915simple/i915_debug.c
+++ b/src/gallium/drivers/i915simple/i915_debug.c
@@ -27,7 +27,6 @@
#include "i915_reg.h"
#include "i915_context.h"
-#include "i915_winsys.h"
#include "i915_debug.h"
#include "i915_batch.h"
#include "pipe/internal/p_winsys_screen.h"
@@ -864,7 +863,7 @@ static boolean i915_debug_packet( struct debug_stream *stream )
void
-i915_dump_batchbuffer( struct i915_batchbuffer *batch )
+i915_dump_batchbuffer( struct intel_batchbuffer *batch )
{
struct debug_stream stream;
unsigned *start = (unsigned*)batch->map;
diff --git a/src/gallium/drivers/i915simple/i915_debug.h b/src/gallium/drivers/i915simple/i915_debug.h
index 16ca7277c7..dd9b86e17b 100644
--- a/src/gallium/drivers/i915simple/i915_debug.h
+++ b/src/gallium/drivers/i915simple/i915_debug.h
@@ -104,9 +104,9 @@ I915_DBG(
#endif
-struct i915_batchbuffer;
+struct intel_batchbuffer;
-void i915_dump_batchbuffer( struct i915_batchbuffer *i915 );
+void i915_dump_batchbuffer( struct intel_batchbuffer *i915 );
void i915_debug_init( struct i915_context *i915 );
diff --git a/src/gallium/drivers/i915simple/i915_flush.c b/src/gallium/drivers/i915simple/i915_flush.c
index 472e0ab774..1582168eba 100644
--- a/src/gallium/drivers/i915simple/i915_flush.c
+++ b/src/gallium/drivers/i915simple/i915_flush.c
@@ -45,6 +45,7 @@ static void i915_flush( struct pipe_context *pipe,
draw_flush(i915->draw);
+#if 0
/* Do we need to emit an MI_FLUSH command to flush the hardware
* caches?
*/
@@ -63,6 +64,13 @@ static void i915_flush( struct pipe_context *pipe,
}
OUT_BATCH( flush );
}
+#endif
+
+#if 0
+ if (i915->batch->map == i915->batch->ptr) {
+ return;
+ }
+#endif
/* If there are no flags, just flush pending commands to hardware:
*/
@@ -74,5 +82,5 @@ static void i915_flush( struct pipe_context *pipe,
void i915_init_flush_functions( struct i915_context *i915 )
{
- i915->pipe.flush = i915_flush;
+ i915->base.flush = i915_flush;
}
diff --git a/src/gallium/drivers/i915simple/i915_prim_emit.c b/src/gallium/drivers/i915simple/i915_prim_emit.c
index 8f1f58b2dd..d9a5c40ab9 100644
--- a/src/gallium/drivers/i915simple/i915_prim_emit.c
+++ b/src/gallium/drivers/i915simple/i915_prim_emit.c
@@ -32,7 +32,6 @@
#include "util/u_pack_color.h"
#include "i915_context.h"
-#include "i915_winsys.h"
#include "i915_reg.h"
#include "i915_state.h"
#include "i915_batch.h"
diff --git a/src/gallium/drivers/i915simple/i915_prim_vbuf.c b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
index 9bdd91f288..b3a7774fd6 100644
--- a/src/gallium/drivers/i915simple/i915_prim_vbuf.c
+++ b/src/gallium/drivers/i915simple/i915_prim_vbuf.c
@@ -42,13 +42,12 @@
#include "draw/draw_vbuf.h"
#include "util/u_debug.h"
#include "pipe/p_inlines.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "util/u_math.h"
#include "util/u_memory.h"
+#include "util/u_fifo.h"
#include "i915_context.h"
#include "i915_reg.h"
-#include "i915_winsys.h"
#include "i915_batch.h"
#include "i915_state.h"
@@ -59,7 +58,7 @@
struct i915_vbuf_render {
struct vbuf_render base;
- struct i915_context *i915;
+ struct i915_context *i915;
/** Vertex size in bytes */
size_t vertex_size;
@@ -74,12 +73,17 @@ struct i915_vbuf_render {
unsigned fallback;
/* Stuff for the vbo */
- struct pipe_buffer *vbo;
+ struct intel_buffer *vbo;
size_t vbo_size;
size_t vbo_offset;
void *vbo_ptr;
- size_t vbo_alloc_size;
size_t vbo_max_used;
+
+ /* stuff for the pool */
+ struct util_fifo *pool_fifo;
+ unsigned pool_used;
+ unsigned pool_buffer_size;
+ boolean pool_not_used;
};
@@ -87,56 +91,93 @@ struct i915_vbuf_render {
* Basically a cast wrapper.
*/
static INLINE struct i915_vbuf_render *
-i915_vbuf_render( struct vbuf_render *render )
+i915_vbuf_render(struct vbuf_render *render)
{
assert(render);
return (struct i915_vbuf_render *)render;
}
-
static const struct vertex_info *
-i915_vbuf_render_get_vertex_info( struct vbuf_render *render )
+i915_vbuf_render_get_vertex_info(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
if (i915->dirty) {
/* make sure we have up to date vertex layout */
- i915_update_derived( i915 );
+ i915_update_derived(i915);
}
return &i915->current.vertex_info;
}
+static boolean
+i915_vbuf_render_reserve(struct i915_vbuf_render *i915_render, size_t size)
+{
+ struct i915_context *i915 = i915_render->i915;
+
+ if (i915_render->vbo_size < size + i915_render->vbo_offset)
+ return FALSE;
+
+ if (i915->vbo_flushed)
+ return FALSE;
+
+ return TRUE;
+}
+
+static void
+i915_vbuf_render_new_buf(struct i915_vbuf_render *i915_render, size_t size)
+{
+ struct i915_context *i915 = i915_render->i915;
+ struct intel_winsys *iws = i915->iws;
+
+ if (i915_render->vbo) {
+ if (i915_render->pool_not_used)
+ iws->buffer_destroy(iws, i915_render->vbo);
+ else
+ u_fifo_add(i915_render->pool_fifo, i915_render->vbo);
+ i915_render->vbo = NULL;
+ }
+
+ i915->vbo_flushed = 0;
+
+ i915_render->vbo_size = MAX2(size, i915_render->pool_buffer_size);
+ i915_render->vbo_offset = 0;
+
+ if (i915_render->vbo_size != i915_render->pool_buffer_size) {
+ i915_render->pool_not_used = TRUE;
+ i915_render->vbo = iws->buffer_create(iws, i915_render->vbo_size, 64,
+ INTEL_NEW_VERTEX);
+ } else {
+ i915_render->pool_not_used = FALSE;
+
+ if (i915_render->pool_used >= 2) {
+ FLUSH_BATCH(NULL);
+ i915->vbo_flushed = 0;
+ i915_render->pool_used = 0;
+ }
+ u_fifo_pop(i915_render->pool_fifo, (void**)&i915_render->vbo);
+ }
+}
static boolean
-i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
- ushort vertex_size,
- ushort nr_vertices )
+i915_vbuf_render_allocate_vertices(struct vbuf_render *render,
+ ushort vertex_size,
+ ushort nr_vertices)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct pipe_screen *screen = i915->pipe.screen;
size_t size = (size_t)vertex_size * (size_t)nr_vertices;
/* FIXME: handle failure */
assert(!i915->vbo);
- if (i915_render->vbo_size > size + i915_render->vbo_offset && !i915->vbo_flushed) {
- } else {
- i915->vbo_flushed = 0;
- if (i915_render->vbo)
- pipe_buffer_reference(&i915_render->vbo, NULL);
- }
+ if (!i915_vbuf_render_reserve(i915_render, size)) {
- if (!i915_render->vbo) {
- i915_render->vbo_size = MAX2(size, i915_render->vbo_alloc_size);
- i915_render->vbo_offset = 0;
- i915_render->vbo = pipe_buffer_create(screen,
- 64,
- I915_BUFFER_USAGE_LIT_VERTEX,
- i915_render->vbo_size);
+ if (i915->vbo_flushed)
+ i915_render->pool_used = 0;
+ i915_vbuf_render_new_buf(i915_render, size);
}
i915_render->vertex_size = vertex_size;
@@ -149,40 +190,37 @@ i915_vbuf_render_allocate_vertices( struct vbuf_render *render,
return TRUE;
}
-
static void *
-i915_vbuf_render_map_vertices( struct vbuf_render *render )
+i915_vbuf_render_map_vertices(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct pipe_screen *screen = i915->pipe.screen;
+ struct intel_winsys *iws = i915->iws;
if (i915->vbo_flushed)
debug_printf("%s bad vbo flush occured stalling on hw\n");
- i915_render->vbo_ptr = pipe_buffer_map(screen,
- i915_render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
+ i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
return (unsigned char *)i915_render->vbo_ptr + i915->vbo_offset;
}
static void
-i915_vbuf_render_unmap_vertices( struct vbuf_render *render,
- ushort min_index,
- ushort max_index )
+i915_vbuf_render_unmap_vertices(struct vbuf_render *render,
+ ushort min_index,
+ ushort max_index)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
- struct pipe_screen *screen = i915->pipe.screen;
+ struct intel_winsys *iws = i915->iws;
i915_render->vbo_max_used = MAX2(i915_render->vbo_max_used, i915_render->vertex_size * (max_index + 1));
- pipe_buffer_unmap(screen, i915_render->vbo);
+ iws->buffer_unmap(iws, i915_render->vbo);
}
static boolean
-i915_vbuf_render_set_primitive( struct vbuf_render *render,
- unsigned prim )
+i915_vbuf_render_set_primitive(struct vbuf_render *render,
+ unsigned prim)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
i915_render->prim = prim;
@@ -234,15 +272,13 @@ i915_vbuf_render_set_primitive( struct vbuf_render *render,
}
}
-
-
/**
* Used for fallbacks in draw_arrays
*/
static void
-draw_arrays_generate_indices( struct vbuf_render *render,
- unsigned start, uint nr,
- unsigned type )
+draw_arrays_generate_indices(struct vbuf_render *render,
+ unsigned start, uint nr,
+ unsigned type)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@@ -251,29 +287,29 @@ draw_arrays_generate_indices( struct vbuf_render *render,
switch(type) {
case 0:
for (i = start; i+1 < end; i += 2)
- OUT_BATCH( (i+0) | (i+1) << 16 );
+ OUT_BATCH((i+0) | (i+1) << 16);
if (i < end)
- OUT_BATCH( i );
+ OUT_BATCH(i);
break;
case PIPE_PRIM_LINE_LOOP:
if (nr >= 2) {
- for (i = start + 1; i < end; i++)
- OUT_BATCH( (i-0) | (i+0) << 16 );
- OUT_BATCH( (i-0) | ( start) << 16 );
+ for (i = start + 1; i < end; i++)
+ OUT_BATCH((i-0) | (i+0) << 16);
+ OUT_BATCH((i-0) | ( start) << 16);
}
break;
case PIPE_PRIM_QUADS:
for (i = start; i + 3 < end; i += 4) {
- OUT_BATCH( (i+0) | (i+1) << 16 );
- OUT_BATCH( (i+3) | (i+1) << 16 );
- OUT_BATCH( (i+2) | (i+3) << 16 );
+ OUT_BATCH((i+0) | (i+1) << 16);
+ OUT_BATCH((i+3) | (i+1) << 16);
+ OUT_BATCH((i+2) | (i+3) << 16);
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = start; i + 3 < end; i += 2) {
- OUT_BATCH( (i+0) | (i+1) << 16 );
- OUT_BATCH( (i+3) | (i+2) << 16 );
- OUT_BATCH( (i+0) | (i+3) << 16 );
+ OUT_BATCH((i+0) | (i+1) << 16);
+ OUT_BATCH((i+3) | (i+2) << 16);
+ OUT_BATCH((i+0) | (i+3) << 16);
}
break;
default:
@@ -282,16 +318,16 @@ draw_arrays_generate_indices( struct vbuf_render *render,
}
static unsigned
-draw_arrays_calc_nr_indices( uint nr, unsigned type )
+draw_arrays_calc_nr_indices(uint nr, unsigned type)
{
switch (type) {
case 0:
return nr;
case PIPE_PRIM_LINE_LOOP:
if (nr >= 2)
- return nr * 2;
+ return nr * 2;
else
- return 0;
+ return 0;
case PIPE_PRIM_QUADS:
return (nr / 4) * 6;
case PIPE_PRIM_QUAD_STRIP:
@@ -303,64 +339,64 @@ draw_arrays_calc_nr_indices( uint nr, unsigned type )
}
static void
-draw_arrays_fallback( struct vbuf_render *render,
- unsigned start,
- uint nr )
+draw_arrays_fallback(struct vbuf_render *render,
+ unsigned start,
+ uint nr)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
unsigned nr_indices;
if (i915->dirty)
- i915_update_derived( i915 );
+ i915_update_derived(i915);
if (i915->hardware_dirty)
- i915_emit_hardware_state( i915 );
+ i915_emit_hardware_state(i915);
- nr_indices = draw_arrays_calc_nr_indices( nr, i915_render->fallback );
+ nr_indices = draw_arrays_calc_nr_indices(nr, i915_render->fallback);
if (!nr_indices)
return;
- if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+ if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived( i915 );
- i915_emit_hardware_state( i915 );
+ i915_update_derived(i915);
+ i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
- if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
- assert(0);
- goto out;
+ if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
+ assert(0);
+ goto out;
}
}
- OUT_BATCH( _3DPRIMITIVE |
- PRIM_INDIRECT |
- i915_render->hwprim |
- PRIM_INDIRECT_ELTS |
- nr_indices );
+ OUT_BATCH(_3DPRIMITIVE |
+ PRIM_INDIRECT |
+ i915_render->hwprim |
+ PRIM_INDIRECT_ELTS |
+ nr_indices);
- draw_arrays_generate_indices( render, start, nr, i915_render->fallback );
+ draw_arrays_generate_indices(render, start, nr, i915_render->fallback);
out:
return;
}
static void
-i915_vbuf_render_draw_arrays( struct vbuf_render *render,
- unsigned start,
- uint nr )
+i915_vbuf_render_draw_arrays(struct vbuf_render *render,
+ unsigned start,
+ uint nr)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
if (i915_render->fallback) {
- draw_arrays_fallback( render, start, nr );
+ draw_arrays_fallback(render, start, nr);
return;
}
/* JB: TODO submit direct cmds */
- draw_arrays_fallback( render, start, nr );
+ draw_arrays_fallback(render, start, nr);
}
/**
@@ -368,10 +404,10 @@ i915_vbuf_render_draw_arrays( struct vbuf_render *render,
* If type is zero normal operation assumed.
*/
static void
-draw_generate_indices( struct vbuf_render *render,
- const ushort *indices,
- uint nr_indices,
- unsigned type )
+draw_generate_indices(struct vbuf_render *render,
+ const ushort *indices,
+ uint nr_indices,
+ unsigned type)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@@ -380,31 +416,31 @@ draw_generate_indices( struct vbuf_render *render,
switch(type) {
case 0:
for (i = 0; i + 1 < nr_indices; i += 2) {
- OUT_BATCH( indices[i] | indices[i+1] << 16 );
+ OUT_BATCH(indices[i] | indices[i+1] << 16);
}
if (i < nr_indices) {
- OUT_BATCH( indices[i] );
+ OUT_BATCH(indices[i]);
}
break;
case PIPE_PRIM_LINE_LOOP:
if (nr_indices >= 2) {
- for (i = 1; i < nr_indices; i++)
- OUT_BATCH( indices[i-1] | indices[i] << 16 );
- OUT_BATCH( indices[i-1] | indices[0] << 16 );
+ for (i = 1; i < nr_indices; i++)
+ OUT_BATCH(indices[i-1] | indices[i] << 16);
+ OUT_BATCH(indices[i-1] | indices[0] << 16);
}
break;
case PIPE_PRIM_QUADS:
for (i = 0; i + 3 < nr_indices; i += 4) {
- OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
- OUT_BATCH( indices[i+3] | indices[i+1] << 16 );
- OUT_BATCH( indices[i+2] | indices[i+3] << 16 );
+ OUT_BATCH(indices[i+0] | indices[i+1] << 16);
+ OUT_BATCH(indices[i+3] | indices[i+1] << 16);
+ OUT_BATCH(indices[i+2] | indices[i+3] << 16);
}
break;
case PIPE_PRIM_QUAD_STRIP:
for (i = 0; i + 3 < nr_indices; i += 2) {
- OUT_BATCH( indices[i+0] | indices[i+1] << 16 );
- OUT_BATCH( indices[i+3] | indices[i+2] << 16 );
- OUT_BATCH( indices[i+0] | indices[i+3] << 16 );
+ OUT_BATCH(indices[i+0] | indices[i+1] << 16);
+ OUT_BATCH(indices[i+3] | indices[i+2] << 16);
+ OUT_BATCH(indices[i+0] | indices[i+3] << 16);
}
break;
default:
@@ -414,16 +450,16 @@ draw_generate_indices( struct vbuf_render *render,
}
static unsigned
-draw_calc_nr_indices( uint nr_indices, unsigned type )
+draw_calc_nr_indices(uint nr_indices, unsigned type)
{
switch (type) {
case 0:
return nr_indices;
case PIPE_PRIM_LINE_LOOP:
if (nr_indices >= 2)
- return nr_indices * 2;
+ return nr_indices * 2;
else
- return 0;
+ return 0;
case PIPE_PRIM_QUADS:
return (nr_indices / 4) * 6;
case PIPE_PRIM_QUAD_STRIP:
@@ -435,9 +471,9 @@ draw_calc_nr_indices( uint nr_indices, unsigned type )
}
static void
-i915_vbuf_render_draw( struct vbuf_render *render,
- const ushort *indices,
- uint nr_indices)
+i915_vbuf_render_draw(struct vbuf_render *render,
+ const ushort *indices,
+ uint nr_indices)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@@ -445,48 +481,47 @@ i915_vbuf_render_draw( struct vbuf_render *render,
save_nr_indices = nr_indices;
- nr_indices = draw_calc_nr_indices( nr_indices, i915_render->fallback );
+ nr_indices = draw_calc_nr_indices(nr_indices, i915_render->fallback);
if (!nr_indices)
return;
if (i915->dirty)
- i915_update_derived( i915 );
+ i915_update_derived(i915);
if (i915->hardware_dirty)
- i915_emit_hardware_state( i915 );
+ i915_emit_hardware_state(i915);
- if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
+ if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
FLUSH_BATCH(NULL);
/* Make sure state is re-emitted after a flush:
*/
- i915_update_derived( i915 );
- i915_emit_hardware_state( i915 );
+ i915_update_derived(i915);
+ i915_emit_hardware_state(i915);
i915->vbo_flushed = 1;
- if (!BEGIN_BATCH( 1 + (nr_indices + 1)/2, 1 )) {
- assert(0);
- goto out;
+ if (!BEGIN_BATCH(1 + (nr_indices + 1)/2, 1)) {
+ assert(0);
+ goto out;
}
}
- OUT_BATCH( _3DPRIMITIVE |
- PRIM_INDIRECT |
- i915_render->hwprim |
- PRIM_INDIRECT_ELTS |
- nr_indices );
- draw_generate_indices( render,
- indices,
- save_nr_indices,
- i915_render->fallback );
+ OUT_BATCH(_3DPRIMITIVE |
+ PRIM_INDIRECT |
+ i915_render->hwprim |
+ PRIM_INDIRECT_ELTS |
+ nr_indices);
+ draw_generate_indices(render,
+ indices,
+ save_nr_indices,
+ i915_render->fallback);
out:
return;
}
-
static void
-i915_vbuf_render_release_vertices( struct vbuf_render *render )
+i915_vbuf_render_release_vertices(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
struct i915_context *i915 = i915_render->i915;
@@ -499,23 +534,22 @@ i915_vbuf_render_release_vertices( struct vbuf_render *render )
i915->dirty |= I915_NEW_VBO;
}
-
static void
-i915_vbuf_render_destroy( struct vbuf_render *render )
+i915_vbuf_render_destroy(struct vbuf_render *render)
{
struct i915_vbuf_render *i915_render = i915_vbuf_render(render);
FREE(i915_render);
}
-
/**
* Create a new primitive render.
*/
static struct vbuf_render *
-i915_vbuf_render_create( struct i915_context *i915 )
+i915_vbuf_render_create(struct i915_context *i915)
{
struct i915_vbuf_render *i915_render = CALLOC_STRUCT(i915_vbuf_render);
- struct pipe_screen *screen = i915->pipe.screen;
+ struct intel_winsys *iws = i915->iws;
+ int i;
i915_render->i915 = i915;
@@ -536,26 +570,32 @@ i915_vbuf_render_create( struct i915_context *i915 )
i915_render->base.release_vertices = i915_vbuf_render_release_vertices;
i915_render->base.destroy = i915_vbuf_render_destroy;
- i915_render->vbo_alloc_size = 128 * 4096;
- i915_render->vbo_size = i915_render->vbo_alloc_size;
+
+ i915_render->vbo = NULL;
+ i915_render->vbo_size = 0;
i915_render->vbo_offset = 0;
- i915_render->vbo = pipe_buffer_create(screen,
- 64,
- I915_BUFFER_USAGE_LIT_VERTEX,
- i915_render->vbo_size);
- i915_render->vbo_ptr = pipe_buffer_map(screen,
- i915_render->vbo,
- PIPE_BUFFER_USAGE_CPU_WRITE);
- pipe_buffer_unmap(screen, i915_render->vbo);
+
+ i915_render->pool_used = FALSE;
+ i915_render->pool_buffer_size = 128 * 4096;
+ i915_render->pool_fifo = u_fifo_create(6);
+ for (i = 0; i < 6; i++)
+ u_fifo_add(i915_render->pool_fifo,
+ iws->buffer_create(iws, i915_render->pool_buffer_size, 64,
+ INTEL_NEW_VERTEX));
+
+#if 0
+ /* TODO JB: is this realy needed? */
+ i915_render->vbo_ptr = iws->buffer_map(iws, i915_render->vbo, TRUE);
+ iws->buffer_unmap(iws, i915_render->vbo);
+#endif
return &i915_render->base;
}
-
/**
* Create a new primitive vbuf/render stage.
*/
-struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
+struct draw_stage *i915_draw_vbuf_stage(struct i915_context *i915)
{
struct vbuf_render *render;
struct draw_stage *stage;
@@ -564,7 +604,7 @@ struct draw_stage *i915_draw_vbuf_stage( struct i915_context *i915 )
if(!render)
return NULL;
- stage = draw_vbuf_stage( i915->draw, render );
+ stage = draw_vbuf_stage(i915->draw, render);
if(!stage) {
render->destroy(render);
return NULL;
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index f4aa8e60d8..c66558c320 100644
--- a/src/gallium/drivers/i915simple/i915_screen.c
+++ b/src/gallium/drivers/i915simple/i915_screen.c
@@ -26,33 +26,36 @@
**************************************************************************/
-#include "util/u_memory.h"
-#include "util/u_simple_screen.h"
-#include "pipe/internal/p_winsys_screen.h"
#include "pipe/p_inlines.h"
+#include "util/u_memory.h"
#include "util/u_string.h"
#include "i915_reg.h"
#include "i915_context.h"
#include "i915_screen.h"
+#include "i915_buffer.h"
#include "i915_texture.h"
-#include "i915_winsys.h"
+#include "intel_winsys.h"
+
+
+/*
+ * Probe functions
+ */
static const char *
-i915_get_vendor( struct pipe_screen *pscreen )
+i915_get_vendor(struct pipe_screen *screen)
{
- return "Tungsten Graphics, Inc.";
+ return "VMware, Inc.";
}
-
static const char *
-i915_get_name( struct pipe_screen *pscreen )
+i915_get_name(struct pipe_screen *screen)
{
static char buffer[128];
const char *chipset;
- switch (i915_screen(pscreen)->pci_id) {
+ switch (i915_screen(screen)->pci_id) {
case PCI_CHIP_I915_G:
chipset = "915G";
break;
@@ -86,7 +89,6 @@ i915_get_name( struct pipe_screen *pscreen )
return buffer;
}
-
static int
i915_get_param(struct pipe_screen *screen, int param)
{
@@ -99,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:
@@ -122,7 +122,6 @@ i915_get_param(struct pipe_screen *screen, int param)
}
}
-
static float
i915_get_paramf(struct pipe_screen *screen, int param)
{
@@ -148,13 +147,12 @@ i915_get_paramf(struct pipe_screen *screen, int param)
}
}
-
static boolean
-i915_is_format_supported( struct pipe_screen *screen,
- enum pipe_format format,
- enum pipe_texture_target target,
- unsigned tex_usage,
- unsigned geom_flags )
+i915_is_format_supported(struct pipe_screen *screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags)
{
static const enum pipe_format tex_supported[] = {
PIPE_FORMAT_R8G8B8A8_UNORM,
@@ -173,7 +171,6 @@ i915_is_format_supported( struct pipe_screen *screen,
PIPE_FORMAT_A8R8G8B8_UNORM,
PIPE_FORMAT_R5G6B5_UNORM,
PIPE_FORMAT_S8Z24_UNORM,
- /*PIPE_FORMAT_R16G16B16A16_SNORM,*/
PIPE_FORMAT_NONE /* list terminator */
};
const enum pipe_format *list;
@@ -193,120 +190,73 @@ i915_is_format_supported( struct pipe_screen *screen,
}
-static void
-i915_destroy_screen( struct pipe_screen *screen )
-{
- struct pipe_winsys *winsys = screen->winsys;
-
- if(winsys->destroy)
- winsys->destroy(winsys);
-
- FREE(screen);
-}
+/*
+ * Fence functions
+ */
-static struct pipe_transfer*
-i915_get_tex_transfer(struct pipe_screen *screen,
- struct pipe_texture *texture,
- unsigned face, unsigned level, unsigned zslice,
- enum pipe_transfer_usage usage, unsigned x, unsigned y,
- unsigned w, unsigned h)
+static void
+i915_fence_reference(struct pipe_screen *screen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
{
- struct i915_texture *tex = (struct i915_texture *)texture;
- struct i915_transfer *trans;
- unsigned offset; /* in bytes */
+ struct i915_screen *is = i915_screen(screen);
- if (texture->target == PIPE_TEXTURE_CUBE) {
- offset = tex->image_offset[level][face];
- }
- else if (texture->target == PIPE_TEXTURE_3D) {
- offset = tex->image_offset[level][zslice];
- }
- else {
- offset = tex->image_offset[level][0];
- assert(face == 0);
- assert(zslice == 0);
- }
-
- trans = CALLOC_STRUCT(i915_transfer);
- if (trans) {
- pipe_texture_reference(&trans->base.texture, texture);
- trans->base.format = trans->base.format;
- trans->base.width = w;
- trans->base.height = h;
- trans->base.block = texture->block;
- trans->base.nblocksx = texture->nblocksx[level];
- trans->base.nblocksy = texture->nblocksy[level];
- trans->base.stride = tex->stride;
- trans->offset = offset;
- trans->base.usage = usage;
- }
- return &trans->base;
+ is->iws->fence_reference(is->iws, ptr, fence);
}
-static void
-i915_tex_transfer_destroy(struct pipe_transfer *trans)
+static int
+i915_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
{
- pipe_texture_reference(&trans->texture, NULL);
- FREE(trans);
+ struct i915_screen *is = i915_screen(screen);
+
+ return is->iws->fence_signalled(is->iws, fence);
}
-static void *
-i915_transfer_map( struct pipe_screen *screen,
- struct pipe_transfer *transfer )
+static int
+i915_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flags)
{
- struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- char *map;
- unsigned flags = 0;
+ struct i915_screen *is = i915_screen(screen);
- if (transfer->usage != PIPE_TRANSFER_WRITE)
- flags |= PIPE_BUFFER_USAGE_CPU_READ;
+ return is->iws->fence_finish(is->iws, fence);
+}
- if (transfer->usage != PIPE_TRANSFER_READ)
- flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
- map = pipe_buffer_map( screen, tex->buffer, flags );
- if (map == NULL)
- return NULL;
+/*
+ * Generic functions
+ */
- if (transfer->texture &&
- (flags & PIPE_BUFFER_USAGE_CPU_WRITE))
- {
- /* Do something to notify contexts of a texture change.
- */
- /* i915_screen(screen)->timestamp++; */
- }
-
- return map + i915_transfer(transfer)->offset +
- transfer->y / transfer->block.height * transfer->stride +
- transfer->x / transfer->block.width * transfer->block.size;
-}
static void
-i915_transfer_unmap(struct pipe_screen *screen,
- struct pipe_transfer *transfer)
+i915_destroy_screen(struct pipe_screen *screen)
{
- struct i915_texture *tex = (struct i915_texture *)transfer->texture;
- pipe_buffer_unmap( screen, tex->buffer );
-}
+ struct i915_screen *is = i915_screen(screen);
+ if (is->iws)
+ is->iws->destroy(is->iws);
+ FREE(is);
+}
/**
* Create a new i915_screen object
*/
struct pipe_screen *
-i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
+i915_create_screen(struct intel_winsys *iws, uint pci_id)
{
- struct i915_screen *i915screen = CALLOC_STRUCT(i915_screen);
+ struct i915_screen *is = CALLOC_STRUCT(i915_screen);
- if (!i915screen)
+ if (!is)
return NULL;
switch (pci_id) {
case PCI_CHIP_I915_G:
case PCI_CHIP_I915_GM:
- i915screen->is_i945 = FALSE;
+ is->is_i945 = FALSE;
break;
case PCI_CHIP_I945_G:
@@ -315,7 +265,7 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
case PCI_CHIP_G33_G:
case PCI_CHIP_Q33_G:
case PCI_CHIP_Q35_G:
- i915screen->is_i945 = TRUE;
+ is->is_i945 = TRUE;
break;
default:
@@ -324,24 +274,25 @@ i915_create_screen(struct pipe_winsys *winsys, uint pci_id)
return NULL;
}
- i915screen->pci_id = pci_id;
+ is->pci_id = pci_id;
+ is->iws = iws;
+
+ is->base.winsys = NULL;
- i915screen->screen.winsys = winsys;
+ is->base.destroy = i915_destroy_screen;
- i915screen->screen.destroy = i915_destroy_screen;
+ is->base.get_name = i915_get_name;
+ is->base.get_vendor = i915_get_vendor;
+ is->base.get_param = i915_get_param;
+ is->base.get_paramf = i915_get_paramf;
+ is->base.is_format_supported = i915_is_format_supported;
- i915screen->screen.get_name = i915_get_name;
- i915screen->screen.get_vendor = i915_get_vendor;
- i915screen->screen.get_param = i915_get_param;
- i915screen->screen.get_paramf = i915_get_paramf;
- i915screen->screen.is_format_supported = i915_is_format_supported;
- i915screen->screen.get_tex_transfer = i915_get_tex_transfer;
- i915screen->screen.tex_transfer_destroy = i915_tex_transfer_destroy;
- i915screen->screen.transfer_map = i915_transfer_map;
- i915screen->screen.transfer_unmap = i915_transfer_unmap;
+ is->base.fence_reference = i915_fence_reference;
+ is->base.fence_signalled = i915_fence_signalled;
+ is->base.fence_finish = i915_fence_finish;
- i915_init_screen_texture_functions(&i915screen->screen);
- u_simple_screen_init(&i915screen->screen);
+ i915_init_screen_texture_functions(is);
+ i915_init_screen_buffer_functions(is);
- return &i915screen->screen;
+ return &is->base;
}
diff --git a/src/gallium/drivers/i915simple/i915_screen.h b/src/gallium/drivers/i915simple/i915_screen.h
index 5284c32595..5126485caa 100644
--- a/src/gallium/drivers/i915simple/i915_screen.h
+++ b/src/gallium/drivers/i915simple/i915_screen.h
@@ -25,17 +25,14 @@
*
**************************************************************************/
-
#ifndef I915_SCREEN_H
#define I915_SCREEN_H
-
+#include "pipe/p_state.h"
#include "pipe/p_screen.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
+struct intel_winsys;
/**
@@ -43,13 +40,14 @@ extern "C" {
*/
struct i915_screen
{
- struct pipe_screen screen;
+ struct pipe_screen base;
+
+ struct intel_winsys *iws;
boolean is_i945;
uint pci_id;
};
-
/**
* Subclass of pipe_transfer
*/
@@ -61,7 +59,11 @@ struct i915_transfer
};
-/** cast wrappers */
+/*
+ * Cast wrappers
+ */
+
+
static INLINE struct i915_screen *
i915_screen(struct pipe_screen *pscreen)
{
@@ -69,14 +71,10 @@ i915_screen(struct pipe_screen *pscreen)
}
static INLINE struct i915_transfer *
-i915_transfer( struct pipe_transfer *transfer )
+i915_transfer(struct pipe_transfer *transfer)
{
return (struct i915_transfer *)transfer;
}
-#ifdef __cplusplus
-}
-#endif
-
#endif /* I915_SCREEN_H */
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 273e74002a..7d48e6e84d 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -518,7 +518,7 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
const struct pipe_constant_buffer *buf)
{
struct i915_context *i915 = i915_context(pipe);
- struct pipe_winsys *ws = pipe->winsys;
+ struct pipe_screen *screen = pipe->screen;
draw_flush(i915->draw);
assert(shader < PIPE_SHADER_TYPES);
@@ -536,10 +536,10 @@ static void i915_set_constant_buffer(struct pipe_context *pipe,
if (buf) {
void *mapped;
if (buf->buffer && buf->buffer->size &&
- (mapped = ws->buffer_map(ws, buf->buffer,
+ (mapped = pipe_buffer_map(screen, buf->buffer,
PIPE_BUFFER_USAGE_CPU_READ))) {
memcpy(i915->current.constants[shader], mapped, buf->buffer->size);
- ws->buffer_unmap(ws, buf->buffer);
+ pipe_buffer_unmap(screen, buf->buffer);
i915->current.num_user_constants[shader]
= buf->buffer->size / (4 * sizeof(float));
}
@@ -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;
}
@@ -751,38 +759,38 @@ static void i915_set_edgeflags(struct pipe_context *pipe,
void
i915_init_state_functions( struct i915_context *i915 )
{
- i915->pipe.set_edgeflags = i915_set_edgeflags;
- i915->pipe.create_blend_state = i915_create_blend_state;
- i915->pipe.bind_blend_state = i915_bind_blend_state;
- i915->pipe.delete_blend_state = i915_delete_blend_state;
-
- i915->pipe.create_sampler_state = i915_create_sampler_state;
- i915->pipe.bind_sampler_states = i915_bind_sampler_states;
- i915->pipe.delete_sampler_state = i915_delete_sampler_state;
-
- i915->pipe.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
- i915->pipe.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
- i915->pipe.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
-
- i915->pipe.create_rasterizer_state = i915_create_rasterizer_state;
- i915->pipe.bind_rasterizer_state = i915_bind_rasterizer_state;
- i915->pipe.delete_rasterizer_state = i915_delete_rasterizer_state;
- i915->pipe.create_fs_state = i915_create_fs_state;
- i915->pipe.bind_fs_state = i915_bind_fs_state;
- i915->pipe.delete_fs_state = i915_delete_fs_state;
- i915->pipe.create_vs_state = i915_create_vs_state;
- i915->pipe.bind_vs_state = i915_bind_vs_state;
- i915->pipe.delete_vs_state = i915_delete_vs_state;
-
- i915->pipe.set_blend_color = i915_set_blend_color;
- i915->pipe.set_clip_state = i915_set_clip_state;
- i915->pipe.set_constant_buffer = i915_set_constant_buffer;
- i915->pipe.set_framebuffer_state = i915_set_framebuffer_state;
-
- i915->pipe.set_polygon_stipple = i915_set_polygon_stipple;
- i915->pipe.set_scissor_state = i915_set_scissor_state;
- i915->pipe.set_sampler_textures = i915_set_sampler_textures;
- i915->pipe.set_viewport_state = i915_set_viewport_state;
- i915->pipe.set_vertex_buffers = i915_set_vertex_buffers;
- i915->pipe.set_vertex_elements = i915_set_vertex_elements;
+ i915->base.set_edgeflags = i915_set_edgeflags;
+ i915->base.create_blend_state = i915_create_blend_state;
+ i915->base.bind_blend_state = i915_bind_blend_state;
+ i915->base.delete_blend_state = i915_delete_blend_state;
+
+ i915->base.create_sampler_state = i915_create_sampler_state;
+ i915->base.bind_sampler_states = i915_bind_sampler_states;
+ i915->base.delete_sampler_state = i915_delete_sampler_state;
+
+ i915->base.create_depth_stencil_alpha_state = i915_create_depth_stencil_state;
+ i915->base.bind_depth_stencil_alpha_state = i915_bind_depth_stencil_state;
+ i915->base.delete_depth_stencil_alpha_state = i915_delete_depth_stencil_state;
+
+ i915->base.create_rasterizer_state = i915_create_rasterizer_state;
+ i915->base.bind_rasterizer_state = i915_bind_rasterizer_state;
+ i915->base.delete_rasterizer_state = i915_delete_rasterizer_state;
+ i915->base.create_fs_state = i915_create_fs_state;
+ i915->base.bind_fs_state = i915_bind_fs_state;
+ i915->base.delete_fs_state = i915_delete_fs_state;
+ i915->base.create_vs_state = i915_create_vs_state;
+ i915->base.bind_vs_state = i915_bind_vs_state;
+ i915->base.delete_vs_state = i915_delete_vs_state;
+
+ i915->base.set_blend_color = i915_set_blend_color;
+ i915->base.set_clip_state = i915_set_clip_state;
+ i915->base.set_constant_buffer = i915_set_constant_buffer;
+ i915->base.set_framebuffer_state = i915_set_framebuffer_state;
+
+ i915->base.set_polygon_stipple = i915_set_polygon_stipple;
+ i915->base.set_scissor_state = i915_set_scissor_state;
+ i915->base.set_sampler_textures = i915_set_sampler_textures;
+ i915->base.set_viewport_state = i915_set_viewport_state;
+ i915->base.set_vertex_buffers = i915_set_vertex_buffers;
+ i915->base.set_vertex_elements = i915_set_vertex_elements;
}
diff --git a/src/gallium/drivers/i915simple/i915_state_emit.c b/src/gallium/drivers/i915simple/i915_state_emit.c
index 1e1fb968b4..a3d4e3b04e 100644
--- a/src/gallium/drivers/i915simple/i915_state_emit.c
+++ b/src/gallium/drivers/i915simple/i915_state_emit.c
@@ -28,7 +28,6 @@
#include "i915_reg.h"
#include "i915_context.h"
-#include "i915_winsys.h"
#include "i915_batch.h"
#include "i915_reg.h"
@@ -107,7 +106,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
6
) * 3/2; /* plus 50% margin */
const unsigned relocs = ( I915_TEX_UNITS +
- 3
+ 3
) * 3/2; /* plus 50% margin */
#if 0
@@ -123,9 +122,9 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (i915->hardware_dirty & I915_HW_INVARIENT)
{
OUT_BATCH(_3DSTATE_AA_CMD |
- AA_LINE_ECAAR_WIDTH_ENABLE |
- AA_LINE_ECAAR_WIDTH_1_0 |
- AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
+ AA_LINE_ECAAR_WIDTH_ENABLE |
+ AA_LINE_ECAAR_WIDTH_1_0 |
+ AA_LINE_REGION_WIDTH_ENABLE | AA_LINE_REGION_WIDTH_1_0);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
@@ -137,24 +136,24 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(0);
OUT_BATCH(_3DSTATE_COORD_SET_BINDINGS |
- CSB_TCB(0, 0) |
- CSB_TCB(1, 1) |
- CSB_TCB(2, 2) |
- CSB_TCB(3, 3) |
- CSB_TCB(4, 4) |
- CSB_TCB(5, 5) |
- CSB_TCB(6, 6) |
- CSB_TCB(7, 7));
+ CSB_TCB(0, 0) |
+ CSB_TCB(1, 1) |
+ CSB_TCB(2, 2) |
+ CSB_TCB(3, 3) |
+ CSB_TCB(4, 4) |
+ CSB_TCB(5, 5) |
+ CSB_TCB(6, 6) |
+ CSB_TCB(7, 7));
OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) |
- ENABLE_TEXKILL_3D_4D |
- TEXKILL_4D);
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ ENABLE_TEXKILL_3D_4D |
+ TEXKILL_4D);
/* Need to initialize this to zero.
*/
@@ -173,21 +172,21 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (i915->hardware_dirty & I915_HW_IMMEDIATE)
{
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 |
- I1_LOAD_S(0) |
- I1_LOAD_S(1) |
- I1_LOAD_S(2) |
- I1_LOAD_S(4) |
- I1_LOAD_S(5) |
- I1_LOAD_S(6) |
- (5));
+ I1_LOAD_S(0) |
+ I1_LOAD_S(1) |
+ I1_LOAD_S(2) |
+ I1_LOAD_S(4) |
+ I1_LOAD_S(5) |
+ I1_LOAD_S(6) |
+ (5));
if(i915->vbo)
OUT_RELOC(i915->vbo,
- I915_BUFFER_ACCESS_READ,
+ INTEL_USAGE_VERTEX,
i915->current.immediate[I915_IMMEDIATE_S0]);
else
- /* FIXME: we should not do this */
- OUT_BATCH(0);
+ /* FIXME: we should not do this */
+ OUT_BATCH(0);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S1]);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S2]);
OUT_BATCH(i915->current.immediate[I915_IMMEDIATE_S4]);
@@ -200,7 +199,7 @@ i915_emit_hardware_state(struct i915_context *i915 )
{
int i;
for (i = 0; i < I915_MAX_DYNAMIC; i++) {
- OUT_BATCH(i915->current.dynamic[i]);
+ OUT_BATCH(i915->current.dynamic[i]);
}
}
@@ -211,68 +210,68 @@ i915_emit_hardware_state(struct i915_context *i915 )
struct pipe_surface *depth_surface = i915->framebuffer.zsbuf;
if (cbuf_surface) {
- unsigned ctile = BUF_3D_USE_FENCE;
+ unsigned ctile = BUF_3D_USE_FENCE;
struct i915_texture *tex = (struct i915_texture *)
cbuf_surface->texture;
assert(tex);
- if (tex && tex->tiled) {
- ctile = BUF_3D_TILED_SURFACE;
- }
+ if (tex && tex->sw_tiled) {
+ ctile = BUF_3D_TILED_SURFACE;
+ }
- OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
+ OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
- OUT_BATCH(BUF_3D_ID_COLOR_BACK |
- BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
- ctile);
+ OUT_BATCH(BUF_3D_ID_COLOR_BACK |
+ BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
+ ctile);
- OUT_RELOC(tex->buffer,
- I915_BUFFER_ACCESS_WRITE,
- cbuf_surface->offset);
+ OUT_RELOC(tex->buffer,
+ INTEL_USAGE_RENDER,
+ cbuf_surface->offset);
}
/* What happens if no zbuf??
*/
if (depth_surface) {
- unsigned ztile = BUF_3D_USE_FENCE;
+ unsigned ztile = BUF_3D_USE_FENCE;
struct i915_texture *tex = (struct i915_texture *)
depth_surface->texture;
assert(tex);
- if (tex && tex->tiled) {
- ztile = BUF_3D_TILED_SURFACE;
- }
+ if (tex && tex->sw_tiled) {
+ ztile = BUF_3D_TILED_SURFACE;
+ }
- OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
+ OUT_BATCH(_3DSTATE_BUF_INFO_CMD);
- OUT_BATCH(BUF_3D_ID_DEPTH |
- BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
- ztile);
+ OUT_BATCH(BUF_3D_ID_DEPTH |
+ BUF_3D_PITCH(tex->stride) | /* pitch in bytes */
+ ztile);
- OUT_RELOC(tex->buffer,
- I915_BUFFER_ACCESS_WRITE,
- depth_surface->offset);
+ OUT_RELOC(tex->buffer,
+ INTEL_USAGE_RENDER,
+ depth_surface->offset);
}
{
- unsigned cformat, zformat = 0;
+ unsigned cformat, zformat = 0;
- if (cbuf_surface)
+ if (cbuf_surface)
cformat = cbuf_surface->format;
else
cformat = PIPE_FORMAT_A8R8G8B8_UNORM; /* arbitrary */
cformat = translate_format(cformat);
- if (depth_surface)
- zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
+ if (depth_surface)
+ zformat = translate_depth_format( i915->framebuffer.zsbuf->format );
- OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
- OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
- DSTORG_VERT_BIAS(0x8) | /* .5 */
- LOD_PRECLAMP_OGL |
- TEX_DEFAULT_COLOR_OGL |
- cformat |
- zformat );
+ OUT_BATCH(_3DSTATE_DST_BUF_VARS_CMD);
+ OUT_BATCH(DSTORG_HORT_BIAS(0x8) | /* .5 */
+ DSTORG_VERT_BIAS(0x8) | /* .5 */
+ LOD_PRECLAMP_OGL |
+ TEX_DEFAULT_COLOR_OGL |
+ cformat |
+ zformat );
}
}
@@ -290,16 +289,13 @@ i915_emit_hardware_state(struct i915_context *i915 )
OUT_BATCH(enabled);
for (unit = 0; unit < I915_TEX_UNITS; unit++) {
if (enabled & (1 << unit)) {
- struct pipe_buffer *buf =
- i915->texture[unit]->buffer;
+ struct intel_buffer *buf = i915->texture[unit]->buffer;
uint offset = 0;
assert(buf);
count++;
- OUT_RELOC(buf,
- I915_BUFFER_ACCESS_READ,
- offset);
+ OUT_RELOC(buf, INTEL_USAGE_SAMPLER, offset);
OUT_BATCH(i915->current.texbuffer[unit][0]); /* MS3 */
OUT_BATCH(i915->current.texbuffer[unit][1]); /* MS4 */
}
@@ -315,20 +311,20 @@ i915_emit_hardware_state(struct i915_context *i915 )
if (i915->hardware_dirty & I915_HW_SAMPLER)
{
if (i915->current.sampler_enable_nr) {
- int i;
-
- OUT_BATCH( _3DSTATE_SAMPLER_STATE |
- (3 * i915->current.sampler_enable_nr) );
-
- OUT_BATCH( i915->current.sampler_enable_flags );
-
- for (i = 0; i < I915_TEX_UNITS; i++) {
- if (i915->current.sampler_enable_flags & (1<<i)) {
- OUT_BATCH( i915->current.sampler[i][0] );
- OUT_BATCH( i915->current.sampler[i][1] );
- OUT_BATCH( i915->current.sampler[i][2] );
- }
- }
+ int i;
+
+ OUT_BATCH( _3DSTATE_SAMPLER_STATE |
+ (3 * i915->current.sampler_enable_nr) );
+
+ OUT_BATCH( i915->current.sampler_enable_flags );
+
+ for (i = 0; i < I915_TEX_UNITS; i++) {
+ if (i915->current.sampler_enable_flags & (1<<i)) {
+ OUT_BATCH( i915->current.sampler[i][0] );
+ OUT_BATCH( i915->current.sampler[i][1] );
+ OUT_BATCH( i915->current.sampler[i][2] );
+ }
+ }
}
}
#endif
diff --git a/src/gallium/drivers/i915simple/i915_state_sampler.c b/src/gallium/drivers/i915simple/i915_state_sampler.c
index 3667ed1afa..c5e9084d12 100644
--- a/src/gallium/drivers/i915simple/i915_state_sampler.c
+++ b/src/gallium/drivers/i915simple/i915_state_sampler.c
@@ -247,7 +247,7 @@ i915_update_texture(struct i915_context *i915,
assert(format);
assert(pitch);
- if (tex->tiled) {
+ if (tex->sw_tiled) {
assert(!((pitch - 1) & pitch));
tiled = MS3_TILED_SURFACE;
}
diff --git a/src/gallium/drivers/i915simple/i915_surface.c b/src/gallium/drivers/i915simple/i915_surface.c
index 09b2c499b8..ab8331f3e6 100644
--- a/src/gallium/drivers/i915simple/i915_surface.c
+++ b/src/gallium/drivers/i915simple/i915_surface.c
@@ -89,6 +89,6 @@ i915_surface_fill(struct pipe_context *pipe,
void
i915_init_surface_functions(struct i915_context *i915)
{
- i915->pipe.surface_copy = i915_surface_copy;
- i915->pipe.surface_fill = i915_surface_fill;
+ i915->base.surface_copy = i915_surface_copy;
+ i915->base.surface_fill = i915_surface_fill;
}
diff --git a/src/gallium/drivers/i915simple/i915_texture.c b/src/gallium/drivers/i915simple/i915_texture.c
index ca8e87af8d..6a6c654271 100644
--- a/src/gallium/drivers/i915simple/i915_texture.c
+++ b/src/gallium/drivers/i915simple/i915_texture.c
@@ -42,12 +42,14 @@
#include "i915_texture.h"
#include "i915_debug.h"
#include "i915_screen.h"
-#include "i915_winsys.h"
+#include "intel_winsys.h"
+
/*
* Helper function and arrays
*/
+
/**
* Initial offset for Cube map.
*/
@@ -72,11 +74,6 @@ static const int step_offsets[6][2] = {
{-1, 1}
};
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
static unsigned
power_of_two(unsigned x)
{
@@ -138,7 +135,7 @@ i915_miptree_set_level_info(struct i915_texture *tex,
static void
i915_miptree_set_image_offset(struct i915_texture *tex,
- unsigned level, unsigned img, unsigned x, unsigned y)
+ unsigned level, unsigned img, unsigned x, unsigned y)
{
if (img == 0 && level == 0)
assert(x == 0 && y == 0);
@@ -155,49 +152,189 @@ i915_miptree_set_image_offset(struct i915_texture *tex,
/*
- * Layout functions
+ * i915 layout functions, some used by i945
*/
/**
- * Special case to deal with display targets.
+ * Special case to deal with scanout textures.
*/
static boolean
-i915_displaytarget_layout(struct i915_texture *tex)
+i915_scanout_layout(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
if (pt->last_level > 0 || pt->block.size != 4)
return 0;
- i915_miptree_set_level_info( tex, 0, 1,
- tex->base.width[0],
- tex->base.height[0],
- 1 );
- i915_miptree_set_image_offset( tex, 0, 0, 0, 0 );
+ i915_miptree_set_level_info(tex, 0, 1,
+ tex->base.width[0],
+ tex->base.height[0],
+ 1);
+ i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
- if (tex->base.width[0] >= 128) {
+ if (tex->base.width[0] >= 240) {
+ tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
+ tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
+ tex->hw_tiled = INTEL_TILE_X;
+ } else if (tex->base.width[0] == 64 && tex->base.height[0] == 64) {
tex->stride = power_of_two(tex->base.nblocksx[0] * pt->block.size);
tex->total_nblocksy = round_up(tex->base.nblocksy[0], 8);
-#if 0 /* used for tiled display targets */
- tex->tiled = 1;
-#endif
} else {
- tex->stride = round_up(tex->base.nblocksx[0] * pt->block.size, 64);
- tex->total_nblocksy = tex->base.nblocksy[0];
+ return FALSE;
}
- /*
- printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
+ debug_printf("%s size: %d,%d,%d offset %d,%d (0x%x)\n", __FUNCTION__,
tex->base.width[0], tex->base.height[0], pt->block.size,
tex->stride, tex->total_nblocksy, tex->stride * tex->total_nblocksy);
- */
- return 1;
+ return TRUE;
+}
+
+static void
+i915_miptree_layout_2d(struct i915_texture *tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned level;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
+
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+ tex->total_nblocksy = 0;
+
+ for (level = 0; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 1, width, height, 1);
+ i915_miptree_set_image_offset(tex, level, 0, 0, tex->total_nblocksy);
+
+ nblocksy = round_up(MAX2(2, nblocksy), 2);
+
+ tex->total_nblocksy += nblocksy;
+
+ width = minify(width);
+ height = minify(height);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
+ }
+}
+
+static void
+i915_miptree_layout_3d(struct i915_texture *tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned level;
+
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
+ unsigned stack_nblocksy = 0;
+
+ /* Calculate the size of a single slice.
+ */
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+
+ /* XXX: hardware expects/requires 9 levels at minimum.
+ */
+ for (level = 0; level <= MAX2(8, pt->last_level); level++) {
+ i915_miptree_set_level_info(tex, level, depth, width, height, depth);
+
+ stack_nblocksy += MAX2(2, nblocksy);
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
+ }
+
+ /* Fixup depth image_offsets:
+ */
+ depth = pt->depth[0];
+ for (level = 0; level <= pt->last_level; level++) {
+ unsigned i;
+ for (i = 0; i < depth; i++)
+ i915_miptree_set_image_offset(tex, level, i, 0, i * stack_nblocksy);
+
+ depth = minify(depth);
+ }
+
+ /* Multiply slice size by texture depth for total size. It's
+ * remarkable how wasteful of memory the i915 texture layouts
+ * are. They are largely fixed in the i945.
+ */
+ tex->total_nblocksy = stack_nblocksy * pt->depth[0];
+}
+
+static void
+i915_miptree_layout_cube(struct i915_texture *tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned width = pt->width[0], height = pt->height[0];
+ const unsigned nblocks = pt->nblocksx[0];
+ unsigned level;
+ unsigned face;
+
+ assert(width == height); /* cubemap images are square */
+
+ /* double pitch for cube layouts */
+ tex->stride = round_up(nblocks * pt->block.size * 2, 4);
+ tex->total_nblocksy = nblocks * 4;
+
+ for (level = 0; level <= pt->last_level; level++) {
+ i915_miptree_set_level_info(tex, level, 6, width, height, 1);
+ width /= 2;
+ height /= 2;
+ }
+
+ for (face = 0; face < 6; face++) {
+ unsigned x = initial_offsets[face][0] * nblocks;
+ unsigned y = initial_offsets[face][1] * nblocks;
+ unsigned d = nblocks;
+
+ for (level = 0; level <= pt->last_level; level++) {
+ i915_miptree_set_image_offset(tex, level, face, x, y);
+ d >>= 1;
+ x += step_offsets[face][0] * d;
+ y += step_offsets[face][1] * d;
+ }
+ }
+}
+
+static boolean
+i915_miptree_layout(struct i915_texture * tex)
+{
+ struct pipe_texture *pt = &tex->base;
+
+ switch (pt->target) {
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+ i915_miptree_layout_2d(tex);
+ break;
+ case PIPE_TEXTURE_3D:
+ i915_miptree_layout_3d(tex);
+ break;
+ case PIPE_TEXTURE_CUBE:
+ i915_miptree_layout_cube(tex);
+ break;
+ default:
+ assert(0);
+ return FALSE;
+ }
+
+ return TRUE;
}
+
+/*
+ * i945 layout functions
+ */
+
+
static void
-i945_miptree_layout_2d( struct i915_texture *tex )
+i945_miptree_layout_2d(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
const int align_x = 2, align_y = 4;
@@ -209,10 +346,10 @@ i945_miptree_layout_2d( struct i915_texture *tex )
unsigned nblocksx = pt->nblocksx[0];
unsigned nblocksy = pt->nblocksy[0];
- /* used for tiled display targets */
- if (0)
- if (i915_displaytarget_layout(tex))
- return;
+ /* used for scanouts that need special layouts */
+ if (tex->base.tex_usage & PIPE_TEXTURE_USAGE_PRIMARY)
+ if (i915_scanout_layout(tex))
+ return;
tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
@@ -223,11 +360,11 @@ i945_miptree_layout_2d( struct i915_texture *tex )
*/
if (pt->last_level > 0) {
unsigned mip1_nblocksx
- = align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
+ = align(pf_get_nblocksx(&pt->block, minify(width)), align_x)
+ pf_get_nblocksx(&pt->block, minify(minify(width)));
if (mip1_nblocksx > nblocksx)
- tex->stride = mip1_nblocksx * pt->block.size;
+ tex->stride = mip1_nblocksx * pt->block.size;
}
/* Pitch must be a whole number of dwords
@@ -249,10 +386,10 @@ i945_miptree_layout_2d( struct i915_texture *tex )
/* Layout_below: step right after second mipmap level.
*/
if (level == 1) {
- x += align(nblocksx, align_x);
+ x += align(nblocksx, align_x);
}
else {
- y += nblocksy;
+ y += nblocksy;
}
width = minify(width);
@@ -263,6 +400,63 @@ i945_miptree_layout_2d( struct i915_texture *tex )
}
static void
+i945_miptree_layout_3d(struct i915_texture *tex)
+{
+ struct pipe_texture *pt = &tex->base;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
+ unsigned nblocksx = pt->nblocksx[0];
+ unsigned nblocksy = pt->nblocksy[0];
+ unsigned pack_x_pitch, pack_x_nr;
+ unsigned pack_y_pitch;
+ unsigned level;
+
+ tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
+ tex->total_nblocksy = 0;
+
+ pack_y_pitch = MAX2(pt->nblocksy[0], 2);
+ pack_x_pitch = tex->stride / pt->block.size;
+ pack_x_nr = 1;
+
+ for (level = 0; level <= pt->last_level; level++) {
+ int x = 0;
+ int y = 0;
+ unsigned q, j;
+
+ i915_miptree_set_level_info(tex, level, depth, width, height, depth);
+
+ for (q = 0; q < depth;) {
+ for (j = 0; j < pack_x_nr && q < depth; j++, q++) {
+ i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
+ x += pack_x_pitch;
+ }
+
+ x = 0;
+ y += pack_y_pitch;
+ }
+
+ tex->total_nblocksy += y;
+
+ if (pack_x_pitch > 4) {
+ pack_x_pitch >>= 1;
+ pack_x_nr <<= 1;
+ assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
+ }
+
+ if (pack_y_pitch > 2) {
+ pack_y_pitch >>= 1;
+ }
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ nblocksx = pf_get_nblocksx(&pt->block, width);
+ nblocksy = pf_get_nblocksy(&pt->block, height);
+ }
+}
+
+static void
i945_miptree_layout_cube(struct i915_texture *tex)
{
struct pipe_texture *pt = &tex->base;
@@ -364,226 +558,44 @@ i945_miptree_layout_cube(struct i915_texture *tex)
}
static boolean
-i915_miptree_layout(struct i915_texture * tex)
-{
- struct pipe_texture *pt = &tex->base;
- unsigned level;
-
- switch (pt->target) {
- case PIPE_TEXTURE_CUBE: {
- const unsigned nblocks = pt->nblocksx[0];
- unsigned face;
- unsigned width = pt->width[0], height = pt->height[0];
-
- assert(width == height); /* cubemap images are square */
-
- /* double pitch for cube layouts */
- tex->stride = round_up(nblocks * pt->block.size * 2, 4);
- tex->total_nblocksy = nblocks * 4;
-
- for (level = 0; level <= pt->last_level; level++) {
- i915_miptree_set_level_info(tex, level, 6,
- width, height,
- 1);
- width /= 2;
- height /= 2;
- }
-
- for (face = 0; face < 6; face++) {
- unsigned x = initial_offsets[face][0] * nblocks;
- unsigned y = initial_offsets[face][1] * nblocks;
- unsigned d = nblocks;
-
- for (level = 0; level <= pt->last_level; level++) {
- i915_miptree_set_image_offset(tex, level, face, x, y);
- d >>= 1;
- x += step_offsets[face][0] * d;
- y += step_offsets[face][1] * d;
- }
- }
- break;
- }
- case PIPE_TEXTURE_3D:{
- unsigned width = pt->width[0];
- unsigned height = pt->height[0];
- unsigned depth = pt->depth[0];
- unsigned nblocksx = pt->nblocksx[0];
- unsigned nblocksy = pt->nblocksy[0];
- unsigned stack_nblocksy = 0;
-
- /* Calculate the size of a single slice.
- */
- tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
-
- /* XXX: hardware expects/requires 9 levels at minimum.
- */
- for (level = 0; level <= MAX2(8, pt->last_level);
- level++) {
- i915_miptree_set_level_info(tex, level, depth,
- width, height, depth);
-
-
- stack_nblocksy += MAX2(2, nblocksy);
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- nblocksx = pf_get_nblocksx(&pt->block, width);
- nblocksy = pf_get_nblocksy(&pt->block, height);
- }
-
- /* Fixup depth image_offsets:
- */
- depth = pt->depth[0];
- for (level = 0; level <= pt->last_level; level++) {
- unsigned i;
- for (i = 0; i < depth; i++)
- i915_miptree_set_image_offset(tex, level, i,
- 0, i * stack_nblocksy);
-
- depth = minify(depth);
- }
-
-
- /* Multiply slice size by texture depth for total size. It's
- * remarkable how wasteful of memory the i915 texture layouts
- * are. They are largely fixed in the i945.
- */
- tex->total_nblocksy = stack_nblocksy * pt->depth[0];
- break;
- }
-
- default:{
- unsigned width = pt->width[0];
- unsigned height = pt->height[0];
- unsigned nblocksx = pt->nblocksx[0];
- unsigned nblocksy = pt->nblocksy[0];
-
- tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
- tex->total_nblocksy = 0;
-
- for (level = 0; level <= pt->last_level; level++) {
- i915_miptree_set_level_info(tex, level, 1,
- width, height, 1);
- i915_miptree_set_image_offset(tex, level, 0,
- 0, tex->total_nblocksy);
-
- nblocksy = round_up(MAX2(2, nblocksy), 2);
-
- tex->total_nblocksy += nblocksy;
-
- width = minify(width);
- height = minify(height);
- nblocksx = pf_get_nblocksx(&pt->block, width);
- nblocksy = pf_get_nblocksy(&pt->block, height);
- }
- break;
- }
- }
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- tex->pitch,
- tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
- */
-
- return TRUE;
-}
-
-
-static boolean
i945_miptree_layout(struct i915_texture * tex)
{
struct pipe_texture *pt = &tex->base;
- unsigned level;
switch (pt->target) {
+ case PIPE_TEXTURE_1D:
+ case PIPE_TEXTURE_2D:
+ i945_miptree_layout_2d(tex);
+ break;
+ case PIPE_TEXTURE_3D:
+ i945_miptree_layout_3d(tex);
+ break;
case PIPE_TEXTURE_CUBE:
i945_miptree_layout_cube(tex);
break;
- case PIPE_TEXTURE_3D:{
- unsigned width = pt->width[0];
- unsigned height = pt->height[0];
- unsigned depth = pt->depth[0];
- unsigned nblocksx = pt->nblocksx[0];
- unsigned nblocksy = pt->nblocksy[0];
- unsigned pack_x_pitch, pack_x_nr;
- unsigned pack_y_pitch;
-
- tex->stride = round_up(pt->nblocksx[0] * pt->block.size, 4);
- tex->total_nblocksy = 0;
-
- pack_y_pitch = MAX2(pt->nblocksy[0], 2);
- pack_x_pitch = tex->stride / pt->block.size;
- pack_x_nr = 1;
-
- for (level = 0; level <= pt->last_level; level++) {
- unsigned nr_images = pt->target == PIPE_TEXTURE_3D ? depth : 6;
- int x = 0;
- int y = 0;
- unsigned q, j;
-
- i915_miptree_set_level_info(tex, level, nr_images,
- width, height, depth);
-
- for (q = 0; q < nr_images;) {
- for (j = 0; j < pack_x_nr && q < nr_images; j++, q++) {
- i915_miptree_set_image_offset(tex, level, q, x, y + tex->total_nblocksy);
- x += pack_x_pitch;
- }
-
- x = 0;
- y += pack_y_pitch;
- }
-
-
- tex->total_nblocksy += y;
-
- if (pack_x_pitch > 4) {
- pack_x_pitch >>= 1;
- pack_x_nr <<= 1;
- assert(pack_x_pitch * pack_x_nr * pt->block.size <= tex->stride);
- }
-
- if (pack_y_pitch > 2) {
- pack_y_pitch >>= 1;
- }
-
- width = minify(width);
- height = minify(height);
- depth = minify(depth);
- nblocksx = pf_get_nblocksx(&pt->block, width);
- nblocksy = pf_get_nblocksy(&pt->block, height);
- }
- break;
- }
-
- case PIPE_TEXTURE_1D:
- case PIPE_TEXTURE_2D:
-// case PIPE_TEXTURE_RECTANGLE:
- i945_miptree_layout_2d(tex);
- break;
default:
assert(0);
return FALSE;
}
- /*
- DBG("%s: %dx%dx%d - sz 0x%x\n", __FUNCTION__,
- tex->pitch,
- tex->total_nblocksy, pt->block.size, tex->stride * tex->total_nblocksy);
- */
-
return TRUE;
}
+/*
+ * Screen texture functions
+ */
+
+
static struct pipe_texture *
i915_texture_create(struct pipe_screen *screen,
const struct pipe_texture *templat)
{
- struct i915_screen *i915screen = i915_screen(screen);
+ struct i915_screen *is = i915_screen(screen);
+ struct intel_winsys *iws = is->iws;
struct i915_texture *tex = CALLOC_STRUCT(i915_texture);
size_t tex_size;
+ unsigned buf_usage = 0;
if (!tex)
return NULL;
@@ -595,23 +607,35 @@ i915_texture_create(struct pipe_screen *screen,
tex->base.nblocksx[0] = pf_get_nblocksx(&tex->base.block, tex->base.width[0]);
tex->base.nblocksy[0] = pf_get_nblocksy(&tex->base.block, tex->base.height[0]);
- if (i915screen->is_i945) {
+ if (is->is_i945) {
if (!i945_miptree_layout(tex))
- goto fail;
+ goto fail;
} else {
if (!i915_miptree_layout(tex))
- goto fail;
+ goto fail;
}
tex_size = tex->stride * tex->total_nblocksy;
- tex->buffer = screen->buffer_create(screen, 64,
- PIPE_BUFFER_USAGE_PIXEL,
- tex_size);
+
+ /* for scanouts and cursors, cursors arn't scanouts */
+ if (templat->tex_usage & PIPE_TEXTURE_USAGE_PRIMARY && templat->width[0] != 64)
+ buf_usage = INTEL_NEW_SCANOUT;
+ else
+ buf_usage = INTEL_NEW_TEXTURE;
+
+ tex->buffer = iws->buffer_create(iws, tex_size, 64, buf_usage);
if (!tex->buffer)
goto fail;
+ /* setup any hw fences */
+ if (tex->hw_tiled) {
+ assert(tex->sw_tiled == INTEL_TILE_NONE);
+ iws->buffer_set_fence_reg(iws, tex->buffer, tex->stride, tex->hw_tiled);
+ }
+
+
#if 0
void *ptr = ws->buffer_map(ws, tex->buffer,
PIPE_BUFFER_USAGE_CPU_WRITE);
@@ -626,18 +650,56 @@ fail:
return NULL;
}
+static struct pipe_texture *
+i915_texture_blanket(struct pipe_screen * screen,
+ const struct pipe_texture *base,
+ const unsigned *stride,
+ struct pipe_buffer *buffer)
+{
+#if 0
+ struct i915_texture *tex;
+ assert(screen);
+
+ /* Only supports one type */
+ if (base->target != PIPE_TEXTURE_2D ||
+ base->last_level != 0 ||
+ base->depth[0] != 1) {
+ return NULL;
+ }
+
+ tex = CALLOC_STRUCT(i915_texture);
+ if (!tex)
+ return NULL;
+
+ tex->base = *base;
+ pipe_reference_init(&tex->base.reference, 1);
+ tex->base.screen = screen;
+
+ tex->stride = stride[0];
+
+ i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
+ i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
+
+ pipe_buffer_reference(&tex->buffer, buffer);
+
+ return &tex->base;
+#else
+ return NULL;
+#endif
+}
static void
i915_texture_destroy(struct pipe_texture *pt)
{
struct i915_texture *tex = (struct i915_texture *)pt;
+ struct intel_winsys *iws = i915_screen(pt->screen)->iws;
uint i;
/*
DBG("%s deleting %p\n", __FUNCTION__, (void *) tex);
*/
- pipe_buffer_reference(&tex->buffer, NULL);
+ iws->buffer_destroy(iws, tex->buffer);
for (i = 0; i < PIPE_MAX_TEXTURE_LEVELS; i++)
if (tex->image_offset[i])
@@ -646,6 +708,12 @@ i915_texture_destroy(struct pipe_texture *pt)
FREE(tex);
}
+
+/*
+ * Screen surface functions
+ */
+
+
static struct pipe_surface *
i915_get_tex_surface(struct pipe_screen *screen,
struct pipe_texture *pt,
@@ -681,11 +749,122 @@ i915_get_tex_surface(struct pipe_screen *screen,
return ps;
}
-static struct pipe_texture *
-i915_texture_blanket(struct pipe_screen * screen,
- const struct pipe_texture *base,
- const unsigned *stride,
- struct pipe_buffer *buffer)
+static void
+i915_tex_surface_destroy(struct pipe_surface *surf)
+{
+ pipe_texture_reference(&surf->texture, NULL);
+ FREE(surf);
+}
+
+
+/*
+ * Screen transfer functions
+ */
+
+
+static struct pipe_transfer*
+i915_get_tex_transfer(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage, unsigned x, unsigned y,
+ unsigned w, unsigned h)
+{
+ struct i915_texture *tex = (struct i915_texture *)texture;
+ struct i915_transfer *trans;
+ unsigned offset; /* in bytes */
+
+ if (texture->target == PIPE_TEXTURE_CUBE) {
+ offset = tex->image_offset[level][face];
+ }
+ else if (texture->target == PIPE_TEXTURE_3D) {
+ offset = tex->image_offset[level][zslice];
+ }
+ else {
+ offset = tex->image_offset[level][0];
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+
+ trans = CALLOC_STRUCT(i915_transfer);
+ if (trans) {
+ pipe_texture_reference(&trans->base.texture, texture);
+ trans->base.format = trans->base.format;
+ trans->base.x = x;
+ trans->base.y = y;
+ trans->base.width = w;
+ trans->base.height = h;
+ trans->base.block = texture->block;
+ trans->base.nblocksx = texture->nblocksx[level];
+ trans->base.nblocksy = texture->nblocksy[level];
+ trans->base.stride = tex->stride;
+ trans->offset = offset;
+ trans->base.usage = usage;
+ }
+ return &trans->base;
+}
+
+static void *
+i915_transfer_map(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
+{
+ struct i915_texture *tex = (struct i915_texture *)transfer->texture;
+ struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ char *map;
+ boolean write = FALSE;
+
+ if (transfer->usage != PIPE_TRANSFER_READ)
+ write = TRUE;
+
+ map = iws->buffer_map(iws, tex->buffer, write);
+ if (map == NULL)
+ return NULL;
+
+ return map + i915_transfer(transfer)->offset +
+ transfer->y / transfer->block.height * transfer->stride +
+ transfer->x / transfer->block.width * transfer->block.size;
+}
+
+static void
+i915_transfer_unmap(struct pipe_screen *screen,
+ struct pipe_transfer *transfer)
+{
+ struct i915_texture *tex = (struct i915_texture *)transfer->texture;
+ struct intel_winsys *iws = i915_screen(tex->base.screen)->iws;
+ iws->buffer_unmap(iws, tex->buffer);
+}
+
+static void
+i915_tex_transfer_destroy(struct pipe_transfer *trans)
+{
+ pipe_texture_reference(&trans->texture, NULL);
+ FREE(trans);
+}
+
+
+/*
+ * Other texture functions
+ */
+
+
+void
+i915_init_screen_texture_functions(struct i915_screen *is)
+{
+ is->base.texture_create = i915_texture_create;
+ is->base.texture_blanket = i915_texture_blanket;
+ is->base.texture_destroy = i915_texture_destroy;
+ is->base.get_tex_surface = i915_get_tex_surface;
+ is->base.tex_surface_destroy = i915_tex_surface_destroy;
+ is->base.get_tex_transfer = i915_get_tex_transfer;
+ is->base.transfer_map = i915_transfer_map;
+ is->base.transfer_unmap = i915_transfer_unmap;
+ is->base.tex_transfer_destroy = i915_tex_transfer_destroy;
+}
+
+struct pipe_texture *
+i915_texture_blanket_intel(struct pipe_screen *screen,
+ struct pipe_texture *base,
+ unsigned stride,
+ struct intel_buffer *buffer)
{
struct i915_texture *tex;
assert(screen);
@@ -705,52 +884,28 @@ i915_texture_blanket(struct pipe_screen * screen,
pipe_reference_init(&tex->base.reference, 1);
tex->base.screen = screen;
- tex->stride = stride[0];
+ tex->stride = stride;
i915_miptree_set_level_info(tex, 0, 1, base->width[0], base->height[0], 1);
i915_miptree_set_image_offset(tex, 0, 0, 0, 0);
- pipe_buffer_reference(&tex->buffer, buffer);
+ tex->buffer = buffer;
return &tex->base;
}
-void
-i915_init_texture_functions(struct i915_context *i915)
-{
-// i915->pipe.texture_update = i915_texture_update;
-}
-
-static void
-i915_tex_surface_destroy(struct pipe_surface *surf)
-{
- pipe_texture_reference(&surf->texture, NULL);
- FREE(surf);
-}
-
-void
-i915_init_screen_texture_functions(struct pipe_screen *screen)
-{
- screen->texture_create = i915_texture_create;
- screen->texture_destroy = i915_texture_destroy;
- screen->get_tex_surface = i915_get_tex_surface;
- screen->texture_blanket = i915_texture_blanket;
- screen->tex_surface_destroy = i915_tex_surface_destroy;
-}
-
-boolean i915_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride )
+boolean
+i915_get_texture_buffer_intel(struct pipe_texture *texture,
+ struct intel_buffer **buffer,
+ unsigned *stride)
{
struct i915_texture *tex = (struct i915_texture *)texture;
- if (!tex)
+ if (!texture)
return FALSE;
- pipe_buffer_reference(buf, tex->buffer);
-
- if (stride)
- *stride = tex->stride;
+ *stride = tex->stride;
+ *buffer = tex->buffer;
return TRUE;
}
diff --git a/src/gallium/drivers/i915simple/i915_texture.h b/src/gallium/drivers/i915simple/i915_texture.h
index 7225016a9f..51a1dd984c 100644
--- a/src/gallium/drivers/i915simple/i915_texture.h
+++ b/src/gallium/drivers/i915simple/i915_texture.h
@@ -28,16 +28,9 @@
#ifndef I915_TEXTURE_H
#define I915_TEXTURE_H
-struct i915_context;
-struct pipe_screen;
-
+struct i915_screen;
extern void
-i915_init_texture_functions(struct i915_context *i915);
-
-
-extern void
-i915_init_screen_texture_functions(struct pipe_screen *screen);
-
+i915_init_screen_texture_functions(struct i915_screen *is);
#endif /* I915_TEXTURE_H */
diff --git a/src/gallium/drivers/i915simple/i915_winsys.h b/src/gallium/drivers/i915simple/i915_winsys.h
deleted file mode 100644
index ff5b34f193..0000000000
--- a/src/gallium/drivers/i915simple/i915_winsys.h
+++ /dev/null
@@ -1,143 +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.
- *
- **************************************************************************/
-
-/**
- * \file
- * This is the interface that i915simple requires any window system
- * hosting it to implement. This is the only include file in i915simple
- * which is public.
- *
- * This isn't currently true as the winsys needs i915_batchbuffer.h
- */
-
-#ifndef I915_WINSYS_H
-#define I915_WINSYS_H
-
-
-#include "pipe/p_defines.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-/* Pipe drivers are independent of both GL and the window system.
- * The window system provides a buffer manager and a set of additional
- * hooks for things like command buffer submission, etc.
- *
- * There clearly has to be some agreement between the window system
- * driver and the hardware driver about the format of command buffers,
- * etc.
- */
-
-struct i915_batchbuffer;
-struct pipe_texture;
-struct pipe_buffer;
-struct pipe_fence_handle;
-struct pipe_winsys;
-struct pipe_screen;
-
-
-/**
- * Additional winsys interface for i915simple.
- *
- * It is an over-simple batchbuffer mechanism. Will want to improve the
- * performance of this, perhaps based on the cmdstream stuff. It
- * would be pretty impossible to implement swz on top of this
- * interface.
- *
- * Will also need additions/changes to implement static/dynamic
- * indirect state.
- */
-struct i915_winsys {
-
- void (*destroy)( struct i915_winsys *sws );
-
- /**
- * Get the current batch buffer from the winsys.
- */
- struct i915_batchbuffer *(*batch_get)( struct i915_winsys *sws );
-
- /**
- * Emit a relocation to a buffer.
- *
- * Used not only when the buffer addresses are not pinned, but also to
- * ensure refered buffers will not be destroyed until the current batch
- * buffer execution is finished.
- *
- * The access flags is a combination of I915_BUFFER_ACCESS_WRITE and
- * I915_BUFFER_ACCESS_READ macros.
- */
- void (*batch_reloc)( struct i915_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags,
- unsigned delta );
-
- /**
- * Flush the batch.
- */
- void (*batch_flush)( struct i915_winsys *sws,
- struct pipe_fence_handle **fence );
-};
-
-#define I915_BUFFER_ACCESS_WRITE 0x1
-#define I915_BUFFER_ACCESS_READ 0x2
-
-#define I915_BUFFER_USAGE_LIT_VERTEX (PIPE_BUFFER_USAGE_CUSTOM << 0)
-
-
-/**
- * Create i915 pipe_screen.
- */
-struct pipe_screen *i915_create_screen( struct pipe_winsys *winsys,
- uint pci_id );
-
-/**
- * Create a i915 pipe_context.
- */
-struct pipe_context *i915_create_context( struct pipe_screen *screen,
- struct pipe_winsys *winsys,
- struct i915_winsys *i915 );
-
-/**
- * Used for the winsys to get the buffer used for a texture
- * and also the stride used for the texture.
- *
- * Buffer is referenced for you so you need to unref after use.
- *
- * This is needed for example kms.
- */
-boolean i915_get_texture_buffer( struct pipe_texture *texture,
- struct pipe_buffer **buf,
- unsigned *stride );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/src/gallium/drivers/i915simple/intel_batchbuffer.h b/src/gallium/drivers/i915simple/intel_batchbuffer.h
new file mode 100644
index 0000000000..db12dfd2ac
--- /dev/null
+++ b/src/gallium/drivers/i915simple/intel_batchbuffer.h
@@ -0,0 +1,87 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_BATCH_H
+#define INTEL_BATCH_H
+
+#include "intel_winsys.h"
+
+static INLINE boolean
+intel_batchbuffer_check(struct intel_batchbuffer *batch,
+ size_t dwords,
+ size_t relocs)
+{
+ return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
+ relocs <= (batch->max_relocs - batch->relocs);
+}
+
+static INLINE size_t
+intel_batchbuffer_space(struct intel_batchbuffer *batch)
+{
+ return batch->size - (batch->ptr - batch->map);
+}
+
+static INLINE void
+intel_batchbuffer_dword(struct intel_batchbuffer *batch,
+ unsigned dword)
+{
+ if (intel_batchbuffer_space(batch) < 4)
+ return;
+
+ *(unsigned *)batch->ptr = dword;
+ batch->ptr += 4;
+}
+
+static INLINE void
+intel_batchbuffer_write(struct intel_batchbuffer *batch,
+ void *data,
+ size_t size)
+{
+ if (intel_batchbuffer_space(batch) < size)
+ return;
+
+ memcpy(data, batch->ptr, size);
+ batch->ptr += size;
+}
+
+static INLINE int
+intel_batchbuffer_reloc(struct intel_batchbuffer *batch,
+ struct intel_buffer *buffer,
+ enum intel_buffer_usage usage,
+ size_t offset)
+{
+ return batch->iws->batchbuffer_reloc(batch, buffer, usage, offset);
+}
+
+static INLINE void
+intel_batchbuffer_flush(struct intel_batchbuffer *batch,
+ struct pipe_fence_handle **fence)
+{
+ batch->iws->batchbuffer_flush(batch, fence);
+}
+
+#endif
diff --git a/src/gallium/drivers/i915simple/intel_winsys.h b/src/gallium/drivers/i915simple/intel_winsys.h
new file mode 100644
index 0000000000..42c5e7470e
--- /dev/null
+++ b/src/gallium/drivers/i915simple/intel_winsys.h
@@ -0,0 +1,230 @@
+/**************************************************************************
+ *
+ * Copyright © 2009 Jakob Bornecrantz
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef INTEL_WINSYS_H
+#define INTEL_WINSYS_H
+
+#include "pipe/p_compiler.h"
+
+struct intel_winsys;
+struct intel_buffer;
+struct intel_batchbuffer;
+struct pipe_texture;
+struct pipe_fence_handle;
+
+enum intel_buffer_usage
+{
+ /* use on textures */
+ INTEL_USAGE_RENDER = 0x01,
+ INTEL_USAGE_SAMPLER = 0x02,
+ INTEL_USAGE_2D_TARGET = 0x04,
+ INTEL_USAGE_2D_SOURCE = 0x08,
+ /* use on vertex */
+ INTEL_USAGE_VERTEX = 0x10,
+};
+
+enum intel_buffer_type
+{
+ INTEL_NEW_TEXTURE,
+ INTEL_NEW_SCANOUT, /**< a texture used for scanning out from */
+ INTEL_NEW_VERTEX,
+};
+
+enum intel_buffer_tile
+{
+ INTEL_TILE_NONE,
+ INTEL_TILE_X,
+ INTEL_TILE_Y,
+};
+
+struct intel_batchbuffer {
+
+ struct intel_winsys *iws;
+
+ /**
+ * Values exported to speed up the writing the batchbuffer,
+ * instead of having to go trough a accesor function for
+ * each dword written.
+ */
+ /*{@*/
+ uint8_t *map;
+ uint8_t *ptr;
+ size_t size;
+
+ size_t relocs;
+ size_t max_relocs;
+ /*@}*/
+};
+
+struct intel_winsys {
+
+ /**
+ * Batchbuffer functions.
+ */
+ /*@{*/
+ /**
+ * Create a new batchbuffer.
+ */
+ struct intel_batchbuffer *(*batchbuffer_create)(struct intel_winsys *iws);
+
+ /**
+ * Emit a relocation to a buffer.
+ * Target position in batchbuffer is the same as ptr.
+ *
+ * @batch
+ * @reloc buffer address to be inserted into target.
+ * @usage how is the hardware going to use the buffer.
+ * @offset add this to the reloc buffers address
+ * @target buffer where to write the address, null for batchbuffer.
+ */
+ int (*batchbuffer_reloc)(struct intel_batchbuffer *batch,
+ struct intel_buffer *reloc,
+ enum intel_buffer_usage usage,
+ unsigned offset);
+
+ /**
+ * Flush a bufferbatch.
+ */
+ void (*batchbuffer_flush)(struct intel_batchbuffer *batch,
+ struct pipe_fence_handle **fence);
+
+ /**
+ * Destroy a batchbuffer.
+ */
+ void (*batchbuffer_destroy)(struct intel_batchbuffer *batch);
+ /*@}*/
+
+
+ /**
+ * Buffer functions.
+ */
+ /*@{*/
+ /**
+ * Create a buffer.
+ */
+ struct intel_buffer *(*buffer_create)(struct intel_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum intel_buffer_type type);
+
+ /**
+ * Fence a buffer with a fence reg.
+ * Not to be confused with pipe_fence_handle.
+ */
+ int (*buffer_set_fence_reg)(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ unsigned stride,
+ enum intel_buffer_tile tile);
+
+ /**
+ * Map a buffer.
+ */
+ void *(*buffer_map)(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ boolean write);
+
+ /**
+ * Unmap a buffer.
+ */
+ void (*buffer_unmap)(struct intel_winsys *iws,
+ struct intel_buffer *buffer);
+
+ /**
+ * Write to a buffer.
+ *
+ * Arguments follows pwrite(2)
+ */
+ int (*buffer_write)(struct intel_winsys *iws,
+ struct intel_buffer *dst,
+ const void *src,
+ size_t size,
+ size_t offset);
+
+ void (*buffer_destroy)(struct intel_winsys *iws,
+ struct intel_buffer *buffer);
+ /*@}*/
+
+
+ /**
+ * Fence functions.
+ */
+ /*@{*/
+ /**
+ * Reference fence and set ptr to fence.
+ */
+ void (*fence_reference)(struct intel_winsys *iws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence);
+
+ /**
+ * Check if a fence has finished.
+ */
+ int (*fence_signalled)(struct intel_winsys *iws,
+ struct pipe_fence_handle *fence);
+
+ /**
+ * Wait on a fence to finish.
+ */
+ int (*fence_finish)(struct intel_winsys *iws,
+ struct pipe_fence_handle *fence);
+ /*@}*/
+
+
+ /**
+ * Destroy the winsys.
+ */
+ void (*destroy)(struct intel_winsys *iws);
+};
+
+
+/**
+ * Create i915 pipe_screen.
+ */
+struct pipe_screen *i915_create_screen(struct intel_winsys *iws, unsigned pci_id);
+
+/**
+ * Create a i915 pipe_context.
+ */
+struct pipe_context *i915_create_context(struct pipe_screen *screen);
+
+/**
+ * Get the intel_winsys buffer backing the texture.
+ *
+ * TODO UGLY
+ */
+boolean i915_get_texture_buffer_intel(struct pipe_texture *texture,
+ struct intel_buffer **buffer,
+ unsigned *stride);
+
+/**
+ * Wrap a intel_winsys buffer with a texture blanket.
+ *
+ * TODO UGLY
+ */
+struct pipe_texture * i915_texture_blanket_intel(struct pipe_screen *screen,
+ struct pipe_texture *tmplt,
+ unsigned pitch,
+ struct intel_buffer *buffer);
+
+#endif
diff --git a/src/gallium/drivers/i965simple/brw_screen.c b/src/gallium/drivers/i965simple/brw_screen.c
index b22e105f10..4a84c4db23 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/i965simple/brw_surface.c b/src/gallium/drivers/i965simple/brw_surface.c
index 511779dbfa..724a69b2ee 100644
--- a/src/gallium/drivers/i965simple/brw_surface.c
+++ b/src/gallium/drivers/i965simple/brw_surface.c
@@ -60,7 +60,7 @@ brw_surface_copy(struct pipe_context *pipe,
src,
PIPE_BUFFER_USAGE_CPU_READ );
- pipe_copy_rect(dst_map,
+ util_copy_rect(dst_map,
&dst->block,
dst->stride,
dstx, dsty,
@@ -99,7 +99,7 @@ brw_surface_fill(struct pipe_context *pipe,
dst,
PIPE_BUFFER_USAGE_CPU_WRITE );
- pipe_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
+ util_fill_rect(dst_map, &dst->block, dst->stride, dstx, dsty, width, height, value);
pipe->screen->surface_unmap(pipe->screen, dst);
}
diff --git a/src/gallium/drivers/i965simple/brw_tex_layout.c b/src/gallium/drivers/i965simple/brw_tex_layout.c
index 8aea8c0558..998ffaeac4 100644
--- a/src/gallium/drivers/i965simple/brw_tex_layout.c
+++ b/src/gallium/drivers/i965simple/brw_tex_layout.c
@@ -65,11 +65,6 @@ unsigned intel_compressed_alignment(unsigned internalFormat)
}
#endif
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
static void intel_miptree_set_image_offset(struct brw_texture *tex,
unsigned level,
diff --git a/src/gallium/drivers/i965simple/brw_wm_glsl.c b/src/gallium/drivers/i965simple/brw_wm_glsl.c
index ab6410aa60..db75963932 100644
--- a/src/gallium/drivers/i965simple/brw_wm_glsl.c
+++ b/src/gallium/drivers/i965simple/brw_wm_glsl.c
@@ -947,7 +947,7 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c,
#endif
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
c->loop_inst[c->loop_insn++] = brw_DO(p, BRW_EXECUTE_8);
break;
case TGSI_OPCODE_BRK:
@@ -958,11 +958,11 @@ static void brw_wm_emit_instruction( struct brw_wm_compile *c,
brw_CONT(p);
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
c->loop_insn--;
c->inst0 = c->inst1 = brw_WHILE(p, c->loop_inst[c->loop_insn]);
/* patch all the BREAK instructions from
- last BEGINLOOP */
+ last BGNFOR */
while (c->inst0 > c->loop_inst[c->loop_insn]) {
c->inst0--;
if (c->inst0->header.opcode == BRW_OPCODE_BREAK) {
diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c
index a500ec6045..4e700089e3 100644
--- a/src/gallium/drivers/identity/id_context.c
+++ b/src/gallium/drivers/identity/id_context.c
@@ -501,7 +501,7 @@ identity_set_sampler_textures(struct pipe_context *_pipe,
pipe->set_sampler_textures(pipe,
num_textures,
- _textures);
+ textures);
}
static void
diff --git a/src/gallium/drivers/identity/id_drm.c b/src/gallium/drivers/identity/id_drm.c
index 555220f853..14f68ac0d0 100644
--- a/src/gallium/drivers/identity/id_drm.c
+++ b/src/gallium/drivers/identity/id_drm.c
@@ -29,6 +29,7 @@
#include "util/u_memory.h"
#include "identity/id_drm.h"
+#include "identity/id_screen.h"
#include "identity/id_public.h"
#include "identity/id_screen.h"
#include "identity/id_objects.h"
@@ -60,7 +61,7 @@ identity_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
return identity_screen_create(screen);
-};
+}
static struct pipe_context *
identity_drm_create_context(struct drm_api *_api,
@@ -77,83 +78,61 @@ identity_drm_create_context(struct drm_api *_api,
pipe = identity_context_create(_screen, pipe);
return pipe;
-};
-
-static boolean
-identity_drm_buffer_from_texture(struct drm_api *_api,
- struct pipe_texture *_texture,
- struct pipe_buffer **_buffer,
- unsigned *stride)
-{
- struct identity_texture *id_texture = identity_texture(_texture);
- struct identity_drm_api *id_api = identity_drm_api(_api);
- struct pipe_texture *texture = id_texture->texture;
- struct drm_api *api = id_api->api;
- struct pipe_buffer *buffer = NULL;
- boolean result;
-
- result = api->buffer_from_texture(api, texture, &buffer, stride);
-
- if (result && _buffer)
- buffer = identity_buffer_create(identity_screen(texture->screen), buffer);
-
- if (_buffer)
- *_buffer = buffer;
- else
- pipe_buffer_reference(&buffer, NULL);
-
- return result;
}
-static struct pipe_buffer *
-identity_drm_buffer_from_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- const char *name,
- unsigned handle)
+static struct pipe_texture *
+identity_drm_texture_from_shared_handle(struct drm_api *_api,
+ struct pipe_screen *_screen,
+ struct pipe_texture *templ,
+ const char *name,
+ unsigned stride,
+ unsigned handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
struct drm_api *api = id_api->api;
- struct pipe_buffer *result;
+ struct pipe_texture *result;
- result = api->buffer_from_handle(api, screen, name, handle);
+ result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
- result = identity_buffer_create(identity_screen(_screen), result);
+ result = identity_texture_create(identity_screen(_screen), result);
return result;
}
static boolean
-identity_drm_handle_from_buffer(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_buffer *_buffer,
- unsigned *handle)
+identity_drm_shared_handle_from_texture(struct drm_api *_api,
+ struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ unsigned *stride,
+ unsigned *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_buffer *id_buffer = identity_buffer(_buffer);
+ struct identity_texture *id_texture = identity_texture(_texture);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *buffer = id_buffer->buffer;
+ struct pipe_texture *texture = id_texture->texture;
struct drm_api *api = id_api->api;
- return api->handle_from_buffer(api, screen, buffer, handle);
+ return api->shared_handle_from_texture(api, screen, texture, stride, handle);
}
static boolean
-identity_drm_global_handle_from_buffer(struct drm_api *_api,
+identity_drm_local_handle_from_texture(struct drm_api *_api,
struct pipe_screen *_screen,
- struct pipe_buffer *_buffer,
+ struct pipe_texture *_texture,
+ unsigned *stride,
unsigned *handle)
{
struct identity_screen *id_screen = identity_screen(_screen);
- struct identity_buffer *id_buffer = identity_buffer(_buffer);
+ struct identity_texture *id_texture = identity_texture(_texture);
struct identity_drm_api *id_api = identity_drm_api(_api);
struct pipe_screen *screen = id_screen->screen;
- struct pipe_buffer *buffer = id_buffer->buffer;
+ struct pipe_texture *texture = id_texture->texture;
struct drm_api *api = id_api->api;
- return api->global_handle_from_buffer(api, screen, buffer, handle);
+ return api->local_handle_from_texture(api, screen, texture, stride, handle);
}
static void
@@ -169,19 +148,26 @@ identity_drm_destroy(struct drm_api *_api)
struct drm_api *
identity_drm_create(struct drm_api *api)
{
- struct identity_drm_api *id_api = CALLOC_STRUCT(identity_drm_api);
+ struct identity_drm_api *id_api;
+
+ if (!api)
+ goto error;
+
+ id_api = CALLOC_STRUCT(identity_drm_api);
if (!id_api)
- return NULL;
+ goto error;
id_api->base.create_screen = identity_drm_create_screen;
id_api->base.create_context = identity_drm_create_context;
- id_api->base.buffer_from_texture = identity_drm_buffer_from_texture;
- id_api->base.buffer_from_handle = identity_drm_buffer_from_handle;
- id_api->base.handle_from_buffer = identity_drm_handle_from_buffer;
- id_api->base.global_handle_from_buffer = identity_drm_global_handle_from_buffer;
+ id_api->base.texture_from_shared_handle = identity_drm_texture_from_shared_handle;
+ id_api->base.shared_handle_from_texture = identity_drm_shared_handle_from_texture;
+ id_api->base.local_handle_from_texture = identity_drm_local_handle_from_texture;
id_api->base.destroy = identity_drm_destroy;
id_api->api = api;
return &id_api->base;
+
+error:
+ return api;
}
diff --git a/src/gallium/drivers/identity/id_screen.c b/src/gallium/drivers/identity/id_screen.c
index 259f1be36e..26439637d0 100644
--- a/src/gallium/drivers/identity/id_screen.c
+++ b/src/gallium/drivers/identity/id_screen.c
@@ -289,6 +289,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen,
unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct identity_screen *id_screen = identity_screen(_screen);
@@ -300,6 +301,7 @@ identity_screen_surface_buffer_create(struct pipe_screen *_screen,
height,
format,
usage,
+ tex_usage,
stride);
if (result)
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
new file mode 100644
index 0000000000..cd7b6356d2
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -0,0 +1,57 @@
+TOP = ../../../..
+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 \
+ lp_bld_blend_aos.c \
+ lp_bld_blend_logicop.c \
+ lp_bld_blend_soa.c \
+ lp_bld_const.c \
+ lp_bld_conv.c \
+ lp_bld_debug.c \
+ lp_bld_depth.c \
+ lp_bld_flow.c \
+ lp_bld_format_aos.c \
+ lp_bld_format_soa.c \
+ lp_bld_interp.c \
+ lp_bld_intr.c \
+ lp_bld_logic.c \
+ lp_bld_sample_soa.c \
+ lp_bld_swizzle.c \
+ lp_bld_struct.c \
+ lp_bld_tgsi_soa.c \
+ lp_bld_type.c \
+ lp_buffer.c \
+ lp_clear.c \
+ lp_context.c \
+ lp_draw_arrays.c \
+ lp_flush.c \
+ lp_jit.c \
+ lp_prim_setup.c \
+ lp_prim_vbuf.c \
+ lp_setup.c \
+ lp_query.c \
+ lp_screen.c \
+ lp_state_blend.c \
+ lp_state_clip.c \
+ lp_state_derived.c \
+ lp_state_fs.c \
+ lp_state_rasterizer.c \
+ lp_state_sampler.c \
+ lp_state_surface.c \
+ lp_state_vertex.c \
+ lp_state_vs.c \
+ lp_surface.c \
+ lp_tex_cache.c \
+ lp_tex_sample_c.c \
+ lp_tex_sample_llvm.c \
+ lp_texture.c \
+ lp_tile_cache.c \
+ lp_tile_soa.c
+
+include ../../Makefile.template
diff --git a/src/gallium/drivers/llvmpipe/README b/src/gallium/drivers/llvmpipe/README
new file mode 100644
index 0000000000..89d08834a3
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/README
@@ -0,0 +1,149 @@
+LLVMPIPE -- a fork of softpipe that employs LLVM for code generation.
+
+
+Status
+======
+
+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
+ - done in SoA layout
+ - input interpolation also code generated
+
+ - alpha testing
+
+ - blend (including logic ops)
+ - both in SoA and AoS layouts, but only the former used for now
+
+ - code is generic
+ - intermediates can be vectors of floats, ubytes, fixed point, etc, and of
+ any width and length
+ - not all operations are implemented for these types yet though
+
+Most mesa/progs/demos/* work.
+
+To do (probably by this order):
+
+ - code generate stipple and stencil testing
+
+ - 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
+
+
+Requirements
+============
+
+ - Linux
+
+ - udis86, http://udis86.sourceforge.net/ . Use my repository, which decodes
+ opcodes not yet supported by upstream.
+
+ git clone git://people.freedesktop.org/~jrfonseca/udis86
+ cd udis86
+ ./configure --with-pic
+ make
+ sudo make install
+
+ - LLVM 2.5. On Debian based distributions do:
+
+ aptitude install llvm-dev
+
+ There is a typo in one of the llvm-dev 2.5 headers, that causes compilation
+ errors in the debug build:
+
+ --- /usr/include/llvm-c/Core.h.orig 2009-08-10 15:38:54.000000000 +0100
+ +++ /usr/include/llvm-c/Core.h 2009-08-10 15:38:25.000000000 +0100
+ @@ -831,7 +831,7 @@
+ template<typename T>
+ inline T **unwrap(LLVMValueRef *Vals, unsigned Length) {
+ #if DEBUG
+ - for (LLVMValueRef *I = Vals, E = Vals + Length; I != E; ++I)
+ + for (LLVMValueRef *I = Vals, *E = Vals + Length; I != E; ++I)
+ cast<T>(*I);
+ #endif
+ return reinterpret_cast<T**>(Vals);
+
+ - A x86 or amd64 processor with support for sse2, sse3, and sse4.1 SIMD
+ instructions. This is necessary because we emit several SSE intrinsics for
+ convenience. See /proc/cpuinfo to know what your CPU supports.
+
+ - scons
+
+
+Building
+========
+
+To build everything invoke scons as:
+
+ scons debug=yes statetrackers=mesa drivers=llvmpipe winsys=xlib dri=false -k
+
+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 that scons is used.
+
+
+Using
+=====
+
+Building will create a drop-in alternative for libGL.so. To use it set the
+environment variables:
+
+ export LD_LIBRARY_PATH=$PWD/build/linux-x86_64-debug/lib:$LD_LIBRARY_PATH
+
+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
+============
+
+Building will also create several unit tests in
+build/linux-???-debug/gallium/drivers/llvmpipe:
+
+ - lp_test_blend: blending
+ - lp_test_conv: SIMD vector conversion
+ - lp_test_format: pixel unpacking/packing
+
+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
+
+
+Development Notes
+=================
+
+- When looking to this code by the first time start in lp_state_fs.c, and
+ then skim through the lp_bld_* functions called in there, and the comments
+ 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 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 stand-alone example.
diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript
new file mode 100644
index 0000000000..f4a9a3b22e
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/SConscript
@@ -0,0 +1,84 @@
+Import('*')
+
+env = env.Clone()
+
+env.Tool('llvm')
+if not env.has_key('LLVM_VERSION'):
+ print 'warning: LLVM not found: not building llvmpipe'
+ Return()
+
+env.Tool('udis86')
+
+llvmpipe = env.ConvenienceLibrary(
+ target = 'llvmpipe',
+ source = [
+ 'lp_bld_alpha.c',
+ 'lp_bld_arit.c',
+ 'lp_bld_blend_aos.c',
+ 'lp_bld_blend_logicop.c',
+ 'lp_bld_blend_soa.c',
+ 'lp_bld_const.c',
+ 'lp_bld_conv.c',
+ 'lp_bld_debug.c',
+ 'lp_bld_depth.c',
+ 'lp_bld_flow.c',
+ 'lp_bld_format_aos.c',
+ 'lp_bld_format_soa.c',
+ 'lp_bld_interp.c',
+ 'lp_bld_intr.c',
+ 'lp_bld_sample_soa.c',
+ 'lp_bld_struct.c',
+ 'lp_bld_logic.c',
+ 'lp_bld_swizzle.c',
+ 'lp_bld_tgsi_soa.c',
+ 'lp_bld_type.c',
+ 'lp_buffer.c',
+ 'lp_clear.c',
+ 'lp_context.c',
+ 'lp_draw_arrays.c',
+ 'lp_flush.c',
+ 'lp_jit.c',
+ 'lp_prim_setup.c',
+ 'lp_prim_vbuf.c',
+ 'lp_setup.c',
+ 'lp_query.c',
+ 'lp_screen.c',
+ 'lp_state_blend.c',
+ 'lp_state_clip.c',
+ 'lp_state_derived.c',
+ 'lp_state_fs.c',
+ 'lp_state_rasterizer.c',
+ 'lp_state_sampler.c',
+ 'lp_state_surface.c',
+ 'lp_state_vertex.c',
+ 'lp_state_vs.c',
+ 'lp_surface.c',
+ 'lp_tex_cache.c',
+ 'lp_tex_sample_c.c',
+ 'lp_tex_sample_llvm.c',
+ 'lp_texture.c',
+ 'lp_tile_cache.c',
+ 'lp_tile_soa.c',
+ ])
+
+
+env = env.Clone()
+
+env.Prepend(LIBS = [llvmpipe] + auxiliaries)
+
+env.Program(
+ target = 'lp_test_format',
+ source = ['lp_test_format.c'],
+)
+
+env.Program(
+ target = 'lp_test_blend',
+ source = ['lp_test_blend.c', 'lp_test_main.c'],
+)
+
+env.Program(
+ target = 'lp_test_conv',
+ source = ['lp_test_conv.c', 'lp_test_main.c'],
+)
+
+Export('llvmpipe')
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.c b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
new file mode 100644
index 0000000000..2b4bc5c819
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.c
@@ -0,0 +1,64 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * Alpha testing to LLVM IR translation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_state.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_flow.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_alpha.h"
+
+
+void
+lp_build_alpha_test(LLVMBuilderRef builder,
+ const struct pipe_alpha_state *state,
+ struct lp_type type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef alpha,
+ LLVMValueRef ref)
+{
+ struct lp_build_context bld;
+
+ lp_build_context_init(&bld, builder, type);
+
+ if(state->enabled) {
+ LLVMValueRef test = lp_build_cmp(&bld, state->func, alpha, ref);
+
+ lp_build_name(test, "alpha_mask");
+
+ lp_build_mask_update(mask, test);
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_alpha.h b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
new file mode 100644
index 0000000000..634575670d
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_alpha.h
@@ -0,0 +1,54 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * Alpha testing to LLVM IR translation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_ALPHA_H
+#define LP_BLD_ALPHA_H
+
+
+#include <llvm-c/Core.h>
+
+struct pipe_alpha_state;
+struct lp_type;
+struct lp_build_mask_context;
+
+
+void
+lp_build_alpha_test(LLVMBuilderRef builder,
+ const struct pipe_alpha_state *state,
+ struct lp_type type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef alpha,
+ LLVMValueRef ref);
+
+
+#endif /* !LP_BLD_ALPHA_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
new file mode 100644
index 0000000000..0b115fc9b0
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c
@@ -0,0 +1,1177 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Helper
+ *
+ * LLVM IR doesn't support all basic arithmetic operations we care about (most
+ * notably min/max and saturated operations), and it is often necessary to
+ * resort machine-specific intrinsics directly. The functions here hide all
+ * these implementation details from the other modules.
+ *
+ * We also do simple expressions simplification here. Reasons are:
+ * - it is very easy given we have all necessary information readily available
+ * - LLVM optimization passes fail to simplify several vector expressions
+ * - We often know value constraints which the optimization passes have no way
+ * of knowing, such as when source arguments are known to be in [0, 1] range.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_memory.h"
+#include "util/u_debug.h"
+#include "util/u_string.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_arit.h"
+
+
+/**
+ * Generate min(a, b)
+ * No checks for special case values of a or b = 1 or 0 are done.
+ */
+static LLVMValueRef
+lp_build_min_simple(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+ const char *intrinsic = NULL;
+ LLVMValueRef cond;
+
+ /* TODO: optimize the constant case */
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width * type.length == 128) {
+ if(type.floating) {
+ if(type.width == 32)
+ intrinsic = "llvm.x86.sse.min.ps";
+ if(type.width == 64)
+ intrinsic = "llvm.x86.sse2.min.pd";
+ }
+ else {
+ if(type.width == 8 && !type.sign)
+ intrinsic = "llvm.x86.sse2.pminu.b";
+ if(type.width == 8 && type.sign)
+ intrinsic = "llvm.x86.sse41.pminsb";
+ if(type.width == 16 && !type.sign)
+ intrinsic = "llvm.x86.sse41.pminuw";
+ if(type.width == 16 && type.sign)
+ intrinsic = "llvm.x86.sse2.pmins.w";
+ if(type.width == 32 && !type.sign)
+ intrinsic = "llvm.x86.sse41.pminud";
+ if(type.width == 32 && type.sign)
+ intrinsic = "llvm.x86.sse41.pminsd";
+ }
+ }
+#endif
+
+ if(intrinsic)
+ return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+
+ cond = lp_build_cmp(bld, PIPE_FUNC_LESS, a, b);
+ return lp_build_select(bld, cond, a, b);
+}
+
+
+/**
+ * Generate max(a, b)
+ * No checks for special case values of a or b = 1 or 0 are done.
+ */
+static LLVMValueRef
+lp_build_max_simple(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+ const char *intrinsic = NULL;
+ LLVMValueRef cond;
+
+ /* TODO: optimize the constant case */
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width * type.length == 128) {
+ if(type.floating) {
+ if(type.width == 32)
+ intrinsic = "llvm.x86.sse.max.ps";
+ if(type.width == 64)
+ intrinsic = "llvm.x86.sse2.max.pd";
+ }
+ else {
+ if(type.width == 8 && !type.sign)
+ intrinsic = "llvm.x86.sse2.pmaxu.b";
+ if(type.width == 8 && type.sign)
+ intrinsic = "llvm.x86.sse41.pmaxsb";
+ if(type.width == 16 && !type.sign)
+ intrinsic = "llvm.x86.sse41.pmaxuw";
+ if(type.width == 16 && type.sign)
+ intrinsic = "llvm.x86.sse2.pmaxs.w";
+ if(type.width == 32 && !type.sign)
+ intrinsic = "llvm.x86.sse41.pmaxud";
+ if(type.width == 32 && type.sign)
+ intrinsic = "llvm.x86.sse41.pmaxsd";
+ }
+ }
+#endif
+
+ if(intrinsic)
+ return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+
+ cond = lp_build_cmp(bld, PIPE_FUNC_GREATER, a, b);
+ return lp_build_select(bld, cond, a, b);
+}
+
+
+/**
+ * Generate 1 - a, or ~a depending on bld->type.
+ */
+LLVMValueRef
+lp_build_comp(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ if(a == bld->one)
+ return bld->zero;
+ if(a == bld->zero)
+ return bld->one;
+
+ if(type.norm && !type.floating && !type.fixed && !type.sign) {
+ if(LLVMIsConstant(a))
+ return LLVMConstNot(a);
+ else
+ return LLVMBuildNot(bld->builder, a, "");
+ }
+
+ if(LLVMIsConstant(a))
+ return LLVMConstSub(bld->one, a);
+ else
+ return LLVMBuildSub(bld->builder, bld->one, a, "");
+}
+
+
+/**
+ * Generate a + b
+ */
+LLVMValueRef
+lp_build_add(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ if(a == bld->zero)
+ return b;
+ if(b == bld->zero)
+ return a;
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ if(bld->type.norm) {
+ const char *intrinsic = NULL;
+
+ if(a == bld->one || b == bld->one)
+ return bld->one;
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width * type.length == 128 &&
+ !type.floating && !type.fixed) {
+ if(type.width == 8)
+ intrinsic = type.sign ? "llvm.x86.sse2.padds.b" : "llvm.x86.sse2.paddus.b";
+ if(type.width == 16)
+ intrinsic = type.sign ? "llvm.x86.sse2.padds.w" : "llvm.x86.sse2.paddus.w";
+ }
+#endif
+
+ if(intrinsic)
+ return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+ }
+
+ if(LLVMIsConstant(a) && LLVMIsConstant(b))
+ res = LLVMConstAdd(a, b);
+ else
+ res = LLVMBuildAdd(bld->builder, a, b, "");
+
+ /* clamp to ceiling of 1.0 */
+ if(bld->type.norm && (bld->type.floating || bld->type.fixed))
+ res = lp_build_min_simple(bld, res, bld->one);
+
+ /* XXX clamp to floor of -1 or 0??? */
+
+ return res;
+}
+
+
+/**
+ * Generate a - b
+ */
+LLVMValueRef
+lp_build_sub(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ if(b == bld->zero)
+ return a;
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+ if(a == b)
+ return bld->zero;
+
+ if(bld->type.norm) {
+ const char *intrinsic = NULL;
+
+ if(b == bld->one)
+ return bld->zero;
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width * type.length == 128 &&
+ !type.floating && !type.fixed) {
+ if(type.width == 8)
+ intrinsic = type.sign ? "llvm.x86.sse2.psubs.b" : "llvm.x86.sse2.psubus.b";
+ if(type.width == 16)
+ intrinsic = type.sign ? "llvm.x86.sse2.psubs.w" : "llvm.x86.sse2.psubus.w";
+ }
+#endif
+
+ if(intrinsic)
+ return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b);
+ }
+
+ if(LLVMIsConstant(a) && LLVMIsConstant(b))
+ res = LLVMConstSub(a, b);
+ else
+ res = LLVMBuildSub(bld->builder, a, b, "");
+
+ if(bld->type.norm && (bld->type.floating || bld->type.fixed))
+ res = lp_build_max_simple(bld, res, bld->zero);
+
+ return res;
+}
+
+
+/**
+ * Build shuffle vectors that match PUNPCKLxx and PUNPCKHxx instructions.
+ */
+static LLVMValueRef
+lp_build_unpack_shuffle(unsigned n, unsigned lo_hi)
+{
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i, j;
+
+ assert(n <= LP_MAX_VECTOR_LENGTH);
+ assert(lo_hi < 2);
+
+ for(i = 0, j = lo_hi*n/2; i < n; i += 2, ++j) {
+ elems[i + 0] = LLVMConstInt(LLVMInt32Type(), 0 + j, 0);
+ elems[i + 1] = LLVMConstInt(LLVMInt32Type(), n + j, 0);
+ }
+
+ return LLVMConstVector(elems, n);
+}
+
+
+/**
+ * Build constant int vector of width 'n' and value 'c'.
+ */
+static LLVMValueRef
+lp_build_const_vec(LLVMTypeRef type, unsigned n, long long c)
+{
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(n <= LP_MAX_VECTOR_LENGTH);
+
+ for(i = 0; i < n; ++i)
+ elems[i] = LLVMConstInt(type, c, 0);
+
+ return LLVMConstVector(elems, n);
+}
+
+
+/**
+ * Normalized 8bit multiplication.
+ *
+ * - alpha plus one
+ *
+ * makes the following approximation to the division (Sree)
+ *
+ * a*b/255 ~= (a*(b + 1)) >> 256
+ *
+ * which is the fastest method that satisfies the following OpenGL criteria
+ *
+ * 0*0 = 0 and 255*255 = 255
+ *
+ * - geometric series
+ *
+ * takes the geometric series approximation to the division
+ *
+ * t/255 = (t >> 8) + (t >> 16) + (t >> 24) ..
+ *
+ * in this case just the first two terms to fit in 16bit arithmetic
+ *
+ * t/255 ~= (t + (t >> 8)) >> 8
+ *
+ * note that just by itself it doesn't satisfies the OpenGL criteria, as
+ * 255*255 = 254, so the special case b = 255 must be accounted or roundoff
+ * must be used
+ *
+ * - geometric series plus rounding
+ *
+ * when using a geometric series division instead of truncating the result
+ * use roundoff in the approximation (Jim Blinn)
+ *
+ * t/255 ~= (t + (t >> 8) + 0x80) >> 8
+ *
+ * achieving the exact results
+ *
+ * @sa Alvy Ray Smith, Image Compositing Fundamentals, Tech Memo 4, Aug 15, 1995,
+ * ftp://ftp.alvyray.com/Acrobat/4_Comp.pdf
+ * @sa Michael Herf, The "double blend trick", May 2000,
+ * http://www.stereopsis.com/doubleblend.html
+ */
+static LLVMValueRef
+lp_build_mul_u8n(LLVMBuilderRef builder,
+ LLVMValueRef a, LLVMValueRef b)
+{
+ static LLVMValueRef c01 = NULL;
+ static LLVMValueRef c08 = NULL;
+ static LLVMValueRef c80 = NULL;
+ LLVMValueRef ab;
+
+ if(!c01) c01 = lp_build_const_vec(LLVMInt16Type(), 8, 0x01);
+ if(!c08) c08 = lp_build_const_vec(LLVMInt16Type(), 8, 0x08);
+ if(!c80) c80 = lp_build_const_vec(LLVMInt16Type(), 8, 0x80);
+
+#if 0
+
+ /* a*b/255 ~= (a*(b + 1)) >> 256 */
+ b = LLVMBuildAdd(builder, b, c01, "");
+ ab = LLVMBuildMul(builder, a, b, "");
+
+#else
+
+ /* t/255 ~= (t + (t >> 8) + 0x80) >> 8 */
+ ab = LLVMBuildMul(builder, a, b, "");
+ ab = LLVMBuildAdd(builder, ab, LLVMBuildLShr(builder, ab, c08, ""), "");
+ ab = LLVMBuildAdd(builder, ab, c80, "");
+
+#endif
+
+ ab = LLVMBuildLShr(builder, ab, c08, "");
+
+ return ab;
+}
+
+
+/**
+ * Generate a * b
+ */
+LLVMValueRef
+lp_build_mul(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+
+ if(a == bld->zero)
+ return bld->zero;
+ if(a == bld->one)
+ return b;
+ if(b == bld->zero)
+ return bld->zero;
+ if(b == bld->one)
+ return a;
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ if(!type.floating && !type.fixed && type.norm) {
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width == 8 && type.length == 16) {
+ LLVMTypeRef i16x8 = LLVMVectorType(LLVMInt16Type(), 8);
+ LLVMTypeRef i8x16 = LLVMVectorType(LLVMInt8Type(), 16);
+ static LLVMValueRef ml = NULL;
+ static LLVMValueRef mh = NULL;
+ LLVMValueRef al, ah, bl, bh;
+ LLVMValueRef abl, abh;
+ LLVMValueRef ab;
+
+ if(!ml) ml = lp_build_unpack_shuffle(16, 0);
+ if(!mh) mh = lp_build_unpack_shuffle(16, 1);
+
+ /* PUNPCKLBW, PUNPCKHBW */
+ al = LLVMBuildShuffleVector(bld->builder, a, bld->zero, ml, "");
+ bl = LLVMBuildShuffleVector(bld->builder, b, bld->zero, ml, "");
+ ah = LLVMBuildShuffleVector(bld->builder, a, bld->zero, mh, "");
+ bh = LLVMBuildShuffleVector(bld->builder, b, bld->zero, mh, "");
+
+ /* NOP */
+ al = LLVMBuildBitCast(bld->builder, al, i16x8, "");
+ bl = LLVMBuildBitCast(bld->builder, bl, i16x8, "");
+ ah = LLVMBuildBitCast(bld->builder, ah, i16x8, "");
+ bh = LLVMBuildBitCast(bld->builder, bh, i16x8, "");
+
+ /* PMULLW, PSRLW, PADDW */
+ abl = lp_build_mul_u8n(bld->builder, al, bl);
+ abh = lp_build_mul_u8n(bld->builder, ah, bh);
+
+ /* PACKUSWB */
+ ab = lp_build_intrinsic_binary(bld->builder, "llvm.x86.sse2.packuswb.128" , i16x8, abl, abh);
+
+ /* NOP */
+ ab = LLVMBuildBitCast(bld->builder, ab, i8x16, "");
+
+ return ab;
+ }
+#endif
+
+ /* FIXME */
+ assert(0);
+ }
+
+ if(LLVMIsConstant(a) && LLVMIsConstant(b))
+ return LLVMConstMul(a, b);
+
+ return LLVMBuildMul(bld->builder, a, b, "");
+}
+
+
+/**
+ * Generate a / b
+ */
+LLVMValueRef
+lp_build_div(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ const struct lp_type type = bld->type;
+
+ if(a == bld->zero)
+ return bld->zero;
+ if(a == bld->one)
+ return lp_build_rcp(bld, b);
+ if(b == bld->zero)
+ return bld->undef;
+ if(b == bld->one)
+ return a;
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ if(LLVMIsConstant(a) && LLVMIsConstant(b))
+ return LLVMConstFDiv(a, b);
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width == 32 && type.length == 4)
+ return lp_build_mul(bld, a, lp_build_rcp(bld, b));
+#endif
+
+ return LLVMBuildFDiv(bld->builder, a, b, "");
+}
+
+
+LLVMValueRef
+lp_build_lerp(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef v0,
+ LLVMValueRef v1)
+{
+ return lp_build_add(bld, v0, lp_build_mul(bld, x, lp_build_sub(bld, v1, v0)));
+}
+
+
+LLVMValueRef
+lp_build_lerp_2d(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef y,
+ LLVMValueRef v00,
+ LLVMValueRef v01,
+ LLVMValueRef v10,
+ LLVMValueRef v11)
+{
+ LLVMValueRef v0 = lp_build_lerp(bld, x, v00, v01);
+ LLVMValueRef v1 = lp_build_lerp(bld, x, v10, v11);
+ return lp_build_lerp(bld, y, v0, v1);
+}
+
+
+/**
+ * Generate min(a, b)
+ * Do checks for special cases.
+ */
+LLVMValueRef
+lp_build_min(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ if(a == b)
+ return a;
+
+ if(bld->type.norm) {
+ if(a == bld->zero || b == bld->zero)
+ return bld->zero;
+ if(a == bld->one)
+ return b;
+ if(b == bld->one)
+ return a;
+ }
+
+ return lp_build_min_simple(bld, a, b);
+}
+
+
+/**
+ * Generate max(a, b)
+ * Do checks for special cases.
+ */
+LLVMValueRef
+lp_build_max(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ if(a == b)
+ return a;
+
+ if(bld->type.norm) {
+ if(a == bld->one || b == bld->one)
+ return bld->one;
+ if(a == bld->zero)
+ return b;
+ if(b == bld->zero)
+ return a;
+ }
+
+ return lp_build_max_simple(bld, a, b);
+}
+
+
+/**
+ * Generate abs(a)
+ */
+LLVMValueRef
+lp_build_abs(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+
+ if(!type.sign)
+ return a;
+
+ if(type.floating) {
+ /* Mask out the sign bit */
+ 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);
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+ a = LLVMBuildBitCast(bld->builder, a, vec_type, "");
+ return a;
+ }
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width*type.length == 128) {
+ switch(type.width) {
+ case 8:
+ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.b.128", vec_type, a);
+ case 16:
+ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.w.128", vec_type, a);
+ case 32:
+ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.ssse3.pabs.d.128", vec_type, a);
+ }
+ }
+#endif
+
+ return lp_build_max(bld, a, LLVMBuildNeg(bld->builder, a, ""));
+}
+
+
+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,
+ LP_BUILD_ROUND_SSE41_FLOOR = 1,
+ LP_BUILD_ROUND_SSE41_CEIL = 2,
+ LP_BUILD_ROUND_SSE41_TRUNCATE = 3
+};
+
+
+static INLINE LLVMValueRef
+lp_build_round_sse41(struct lp_build_context *bld,
+ LLVMValueRef a,
+ enum lp_build_round_sse41_mode mode)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ const char *intrinsic;
+
+ assert(type.floating);
+ assert(type.width*type.length == 128);
+
+ switch(type.width) {
+ case 32:
+ intrinsic = "llvm.x86.sse41.round.ps";
+ break;
+ case 64:
+ intrinsic = "llvm.x86.sse41.round.pd";
+ break;
+ default:
+ assert(0);
+ return bld->undef;
+ }
+
+ return lp_build_intrinsic_binary(bld->builder, intrinsic, vec_type, a,
+ LLVMConstInt(LLVMInt32Type(), mode, 0));
+}
+
+
+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 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_FLOOR);
+#endif
+
+ /* FIXME */
+ assert(0);
+ return bld->undef;
+}
+
+
+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.
+ */
+LLVMValueRef
+lp_build_int(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+
+ assert(type.floating);
+
+ return LLVMBuildFPToSI(bld->builder, a, int_vec_type, "");
+}
+
+
+LLVMValueRef
+lp_build_ifloor(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ a = lp_build_floor(bld, a);
+ a = lp_build_int(bld, a);
+ return a;
+}
+
+
+LLVMValueRef
+lp_build_sqrt(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ char intrinsic[32];
+
+ /* TODO: optimize the constant case */
+ /* TODO: optimize the constant case */
+
+ assert(type.floating);
+ util_snprintf(intrinsic, sizeof intrinsic, "llvm.sqrt.v%uf%u", type.length, type.width);
+
+ return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
+}
+
+
+LLVMValueRef
+lp_build_rcp(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ if(a == bld->zero)
+ return bld->undef;
+ if(a == bld->one)
+ return bld->one;
+ if(a == bld->undef)
+ return bld->undef;
+
+ assert(type.floating);
+
+ if(LLVMIsConstant(a))
+ return LLVMConstFDiv(bld->one, a);
+
+ /* XXX: is this really necessary? */
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width == 32 && type.length == 4)
+ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rcp.ps", lp_build_vec_type(type), a);
+#endif
+
+ return LLVMBuildFDiv(bld->builder, bld->one, a, "");
+}
+
+
+/**
+ * Generate 1/sqrt(a)
+ */
+LLVMValueRef
+lp_build_rsqrt(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+
+ assert(type.floating);
+
+ /* XXX: is this really necessary? */
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width == 32 && type.length == 4)
+ return lp_build_intrinsic_unary(bld->builder, "llvm.x86.sse.rsqrt.ps", lp_build_vec_type(type), a);
+#endif
+
+ return lp_build_rcp(bld, lp_build_sqrt(bld, a));
+}
+
+
+/**
+ * Generate cos(a)
+ */
+LLVMValueRef
+lp_build_cos(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ char intrinsic[32];
+
+ /* TODO: optimize the constant case */
+
+ assert(type.floating);
+ util_snprintf(intrinsic, sizeof intrinsic, "llvm.cos.v%uf%u", type.length, type.width);
+
+ return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
+}
+
+
+/**
+ * Generate sin(a)
+ */
+LLVMValueRef
+lp_build_sin(struct lp_build_context *bld,
+ LLVMValueRef a)
+{
+ const struct lp_type type = bld->type;
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ char intrinsic[32];
+
+ /* TODO: optimize the constant case */
+
+ assert(type.floating);
+ util_snprintf(intrinsic, sizeof intrinsic, "llvm.sin.v%uf%u", type.length, type.width);
+
+ return lp_build_intrinsic_unary(bld->builder, intrinsic, vec_type, a);
+}
+
+
+/**
+ * Generate pow(x, y)
+ */
+LLVMValueRef
+lp_build_pow(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef y)
+{
+ /* TODO: optimize the constant case */
+ if(LLVMIsConstant(x) && LLVMIsConstant(y))
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+
+ return lp_build_exp2(bld, lp_build_mul(bld, lp_build_log2(bld, x), y));
+}
+
+
+/**
+ * Generate exp(x)
+ */
+LLVMValueRef
+lp_build_exp(struct lp_build_context *bld,
+ LLVMValueRef x)
+{
+ /* log2(e) = 1/log(2) */
+ LLVMValueRef log2e = lp_build_const_scalar(bld->type, 1.4426950408889634);
+
+ return lp_build_mul(bld, log2e, lp_build_exp2(bld, x));
+}
+
+
+/**
+ * Generate log(x)
+ */
+LLVMValueRef
+lp_build_log(struct lp_build_context *bld,
+ LLVMValueRef x)
+{
+ /* log(2) */
+ LLVMValueRef log2 = lp_build_const_scalar(bld->type, 1.4426950408889634);
+
+ return lp_build_mul(bld, log2, lp_build_exp2(bld, x));
+}
+
+
+#define EXP_POLY_DEGREE 3
+#define LOG_POLY_DEGREE 5
+
+
+/**
+ * Generate polynomial.
+ * Ex: x^2 * coeffs[0] + x * coeffs[1] + coeffs[2].
+ */
+static LLVMValueRef
+lp_build_polynomial(struct lp_build_context *bld,
+ LLVMValueRef x,
+ const double *coeffs,
+ unsigned num_coeffs)
+{
+ 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");
+
+ for (i = num_coeffs; i--; ) {
+ LLVMValueRef coeff = lp_build_const_scalar(type, coeffs[i]);
+ if(res)
+ res = lp_build_add(bld, coeff, lp_build_mul(bld, x, res));
+ else
+ res = coeff;
+ }
+
+ if(res)
+ return res;
+ else
+ return bld->undef;
+}
+
+
+/**
+ * Minimax polynomial fit of 2**x, in range [-0.5, 0.5[
+ */
+const double lp_build_exp2_polynomial[] = {
+#if EXP_POLY_DEGREE == 5
+ 9.9999994e-1, 6.9315308e-1, 2.4015361e-1, 5.5826318e-2, 8.9893397e-3, 1.8775767e-3
+#elif EXP_POLY_DEGREE == 4
+ 1.0000026, 6.9300383e-1, 2.4144275e-1, 5.2011464e-2, 1.3534167e-2
+#elif EXP_POLY_DEGREE == 3
+ 9.9992520e-1, 6.9583356e-1, 2.2606716e-1, 7.8024521e-2
+#elif EXP_POLY_DEGREE == 2
+ 1.0017247, 6.5763628e-1, 3.3718944e-1
+#else
+#error
+#endif
+};
+
+
+void
+lp_build_exp2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp2_int_part,
+ LLVMValueRef *p_frac_part,
+ LLVMValueRef *p_exp2)
+{
+ 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;
+ LLVMValueRef fpart = NULL;
+ LLVMValueRef expipart = NULL;
+ LLVMValueRef expfpart = NULL;
+ LLVMValueRef res = NULL;
+
+ 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");
+
+ assert(type.floating && type.width == 32);
+
+ x = lp_build_min(bld, x, lp_build_const_scalar(type, 129.0));
+ x = lp_build_max(bld, x, lp_build_const_scalar(type, -126.99999));
+
+ /* ipart = int(x - 0.5) */
+ ipart = LLVMBuildSub(bld->builder, x, lp_build_const_scalar(type, 0.5f), "");
+ ipart = LLVMBuildFPToSI(bld->builder, ipart, int_vec_type, "");
+
+ /* fpart = x - ipart */
+ fpart = LLVMBuildSIToFP(bld->builder, ipart, vec_type, "");
+ fpart = LLVMBuildSub(bld->builder, x, fpart, "");
+ }
+
+ if(p_exp2_int_part || p_exp2) {
+ /* expipart = (float) (1 << ipart) */
+ expipart = LLVMBuildAdd(bld->builder, ipart, lp_build_int_const_scalar(type, 127), "");
+ expipart = LLVMBuildShl(bld->builder, expipart, lp_build_int_const_scalar(type, 23), "");
+ expipart = LLVMBuildBitCast(bld->builder, expipart, vec_type, "");
+ }
+
+ if(p_exp2) {
+ expfpart = lp_build_polynomial(bld, fpart, lp_build_exp2_polynomial,
+ Elements(lp_build_exp2_polynomial));
+
+ res = LLVMBuildMul(bld->builder, expipart, expfpart, "");
+ }
+
+ if(p_exp2_int_part)
+ *p_exp2_int_part = expipart;
+
+ if(p_frac_part)
+ *p_frac_part = fpart;
+
+ if(p_exp2)
+ *p_exp2 = res;
+}
+
+
+LLVMValueRef
+lp_build_exp2(struct lp_build_context *bld,
+ LLVMValueRef x)
+{
+ LLVMValueRef res;
+ lp_build_exp2_approx(bld, x, NULL, NULL, &res);
+ return res;
+}
+
+
+/**
+ * Minimax polynomial fit of log2(x)/(x - 1), for x in range [1, 2[
+ * These coefficients can be generate with
+ * http://www.boost.org/doc/libs/1_36_0/libs/math/doc/sf_and_dist/html/math_toolkit/toolkit/internals2/minimax.html
+ */
+const double lp_build_log2_polynomial[] = {
+#if LOG_POLY_DEGREE == 6
+ 3.11578814719469302614, -3.32419399085241980044, 2.59883907202499966007, -1.23152682416275988241, 0.318212422185251071475, -0.0344359067839062357313
+#elif LOG_POLY_DEGREE == 5
+ 2.8882704548164776201, -2.52074962577807006663, 1.48116647521213171641, -0.465725644288844778798, 0.0596515482674574969533
+#elif LOG_POLY_DEGREE == 4
+ 2.61761038894603480148, -1.75647175389045657003, 0.688243882994381274313, -0.107254423828329604454
+#elif LOG_POLY_DEGREE == 3
+ 2.28330284476918490682, -1.04913055217340124191, 0.204446009836232697516
+#else
+#error
+#endif
+};
+
+
+/**
+ * See http://www.devmaster.net/forums/showthread.php?p=43580
+ */
+void
+lp_build_log2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp,
+ LLVMValueRef *p_floor_log2,
+ LLVMValueRef *p_log2)
+{
+ 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 expmask = lp_build_int_const_scalar(type, 0x7f800000);
+ LLVMValueRef mantmask = lp_build_int_const_scalar(type, 0x007fffff);
+ LLVMValueRef one = LLVMConstBitCast(bld->one, int_vec_type);
+
+ LLVMValueRef i = NULL;
+ LLVMValueRef exp = NULL;
+ LLVMValueRef mant = NULL;
+ LLVMValueRef logexp = NULL;
+ LLVMValueRef logmant = NULL;
+ LLVMValueRef res = NULL;
+
+ if(p_exp || p_floor_log2 || p_log2) {
+ /* TODO: optimize the constant case */
+ if(LLVMIsConstant(x))
+ debug_printf("%s: inefficient/imprecise constant arithmetic\n");
+
+ assert(type.floating && type.width == 32);
+
+ i = LLVMBuildBitCast(bld->builder, x, int_vec_type, "");
+
+ /* exp = (float) exponent(x) */
+ exp = LLVMBuildAnd(bld->builder, i, expmask, "");
+ }
+
+ if(p_floor_log2 || p_log2) {
+ logexp = LLVMBuildLShr(bld->builder, exp, lp_build_int_const_scalar(type, 23), "");
+ logexp = LLVMBuildSub(bld->builder, logexp, lp_build_int_const_scalar(type, 127), "");
+ logexp = LLVMBuildSIToFP(bld->builder, logexp, vec_type, "");
+ }
+
+ if(p_log2) {
+ /* mant = (float) mantissa(x) */
+ mant = LLVMBuildAnd(bld->builder, i, mantmask, "");
+ mant = LLVMBuildOr(bld->builder, mant, one, "");
+ mant = LLVMBuildSIToFP(bld->builder, mant, vec_type, "");
+
+ logmant = lp_build_polynomial(bld, mant, lp_build_log2_polynomial,
+ Elements(lp_build_log2_polynomial));
+
+ /* This effectively increases the polynomial degree by one, but ensures that log2(1) == 0*/
+ logmant = LLVMBuildMul(bld->builder, logmant, LLVMBuildMul(bld->builder, mant, bld->one, ""), "");
+
+ res = LLVMBuildAdd(bld->builder, logmant, logexp, "");
+ }
+
+ if(p_exp)
+ *p_exp = exp;
+
+ if(p_floor_log2)
+ *p_floor_log2 = logexp;
+
+ if(p_log2)
+ *p_log2 = res;
+}
+
+
+LLVMValueRef
+lp_build_log2(struct lp_build_context *bld,
+ LLVMValueRef x)
+{
+ LLVMValueRef res;
+ lp_build_log2_approx(bld, x, NULL, NULL, &res);
+ return res;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.h b/src/gallium/drivers/llvmpipe/lp_bld_arit.h
new file mode 100644
index 0000000000..d68a97c4b8
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.h
@@ -0,0 +1,191 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper arithmetic functions.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_ARIT_H
+#define LP_BLD_ARIT_H
+
+
+#include <llvm-c/Core.h>
+
+
+struct lp_type type;
+struct lp_build_context;
+
+
+/**
+ * Complement, i.e., 1 - a.
+ */
+LLVMValueRef
+lp_build_comp(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_add(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_sub(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_mul(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_div(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_lerp(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef v0,
+ LLVMValueRef v1);
+
+/**
+ * Bilinear interpolation.
+ *
+ * Values indices are in v_{yx}.
+ */
+LLVMValueRef
+lp_build_lerp_2d(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef y,
+ LLVMValueRef v00,
+ LLVMValueRef v01,
+ LLVMValueRef v10,
+ LLVMValueRef v11);
+
+LLVMValueRef
+lp_build_min(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_max(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+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);
+
+LLVMValueRef
+lp_build_ifloor(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_sqrt(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_rcp(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_rsqrt(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_cos(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_sin(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_pow(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_exp(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_log(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_exp2(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+LLVMValueRef
+lp_build_log2(struct lp_build_context *bld,
+ LLVMValueRef a);
+
+void
+lp_build_exp2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp2_int_part,
+ LLVMValueRef *p_frac_part,
+ LLVMValueRef *p_exp2);
+
+void
+lp_build_log2_approx(struct lp_build_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef *p_exp,
+ LLVMValueRef *p_floor_log2,
+ LLVMValueRef *p_log2);
+
+#endif /* !LP_BLD_ARIT_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend.h b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
new file mode 100644
index 0000000000..da272e549f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend.h
@@ -0,0 +1,107 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_BLD_BLEND_H
+#define LP_BLD_BLEND_H
+
+
+/**
+ * @file
+ * LLVM IR building helpers interfaces.
+ *
+ * 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
+ * genration. See
+ * http://npcontemplation.blogspot.com/2008/06/secret-of-llvm-c-bindings.html
+ * for a standalone example.
+ */
+
+#include <llvm-c/Core.h>
+
+#include "pipe/p_format.h"
+
+
+struct pipe_blend_state;
+struct lp_type;
+struct lp_build_context;
+
+
+/**
+ * Whether the blending function is commutative or not.
+ */
+boolean
+lp_build_blend_func_commutative(unsigned func);
+
+
+/**
+ * Whether the blending functions are the reverse of each other.
+ */
+boolean
+lp_build_blend_func_reverse(unsigned rgb_func, unsigned alpha_func);
+
+
+LLVMValueRef
+lp_build_blend_func(struct lp_build_context *bld,
+ unsigned func,
+ LLVMValueRef term1,
+ LLVMValueRef term2);
+
+
+LLVMValueRef
+lp_build_blend_aos(LLVMBuilderRef builder,
+ const struct pipe_blend_state *blend,
+ struct lp_type type,
+ LLVMValueRef src,
+ LLVMValueRef dst,
+ LLVMValueRef const_,
+ unsigned alpha_swizzle);
+
+
+void
+lp_build_blend_soa(LLVMBuilderRef builder,
+ const struct pipe_blend_state *blend,
+ struct lp_type type,
+ LLVMValueRef src[4],
+ LLVMValueRef dst[4],
+ LLVMValueRef const_[4],
+ LLVMValueRef res[4]);
+
+
+/**
+ * Apply a logic op.
+ *
+ * src/dst parameters are packed values. It should work regardless the inputs
+ * are scalars, or a vector.
+ */
+LLVMValueRef
+lp_build_logicop(LLVMBuilderRef builder,
+ unsigned logicop_func,
+ LLVMValueRef src,
+ LLVMValueRef dst);
+
+
+#endif /* !LP_BLD_BLEND_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
new file mode 100644
index 0000000000..d14f468ba9
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_aos.c
@@ -0,0 +1,356 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Blend LLVM IR generation -- AoS layout.
+ *
+ * AoS blending is in general much slower than SoA, but there are some cases
+ * where it might be faster. In particular, if a pixel is rendered only once
+ * then the overhead of tiling and untiling will dominate over the speedup that
+ * SoA gives. So we might want to detect such cases and fallback to AoS in the
+ * future, but for now this function is here for historical/benchmarking
+ * purposes.
+ *
+ * Run lp_blend_test after any change to this file.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "pipe/p_state.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_blend.h"
+#include "lp_bld_debug.h"
+
+
+/**
+ * We may the same values several times, so we keep them here to avoid
+ * recomputing them. Also reusing the values allows us to do simplifications
+ * that LLVM optimization passes wouldn't normally be able to do.
+ */
+struct lp_build_blend_aos_context
+{
+ struct lp_build_context base;
+
+ LLVMValueRef src;
+ LLVMValueRef dst;
+ LLVMValueRef const_;
+
+ LLVMValueRef inv_src;
+ LLVMValueRef inv_dst;
+ LLVMValueRef inv_const;
+ LLVMValueRef saturate;
+
+ LLVMValueRef rgb_src_factor;
+ LLVMValueRef alpha_src_factor;
+ LLVMValueRef rgb_dst_factor;
+ LLVMValueRef alpha_dst_factor;
+};
+
+
+static LLVMValueRef
+lp_build_blend_factor_unswizzled(struct lp_build_blend_aos_context *bld,
+ unsigned factor,
+ boolean alpha)
+{
+ switch (factor) {
+ case PIPE_BLENDFACTOR_ZERO:
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_ONE:
+ return bld->base.one;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ return bld->src;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ return bld->dst;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ if(alpha)
+ return bld->base.one;
+ else {
+ if(!bld->inv_dst)
+ bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
+ if(!bld->saturate)
+ bld->saturate = lp_build_min(&bld->base, bld->src, bld->inv_dst);
+ return bld->saturate;
+ }
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ return bld->const_;
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ if(!bld->inv_src)
+ bld->inv_src = lp_build_comp(&bld->base, bld->src);
+ return bld->inv_src;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ if(!bld->inv_dst)
+ bld->inv_dst = lp_build_comp(&bld->base, bld->dst);
+ return bld->inv_dst;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ if(!bld->inv_const)
+ bld->inv_const = lp_build_comp(&bld->base, bld->const_);
+ return bld->inv_const;
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ default:
+ assert(0);
+ return bld->base.zero;
+ }
+}
+
+
+enum lp_build_blend_swizzle {
+ LP_BUILD_BLEND_SWIZZLE_RGBA = 0,
+ LP_BUILD_BLEND_SWIZZLE_AAAA = 1,
+};
+
+
+/**
+ * How should we shuffle the base factor.
+ */
+static enum lp_build_blend_swizzle
+lp_build_blend_factor_swizzle(unsigned factor)
+{
+ switch (factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ case PIPE_BLENDFACTOR_ZERO:
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ return LP_BUILD_BLEND_SWIZZLE_RGBA;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ return LP_BUILD_BLEND_SWIZZLE_AAAA;
+ default:
+ assert(0);
+ return LP_BUILD_BLEND_SWIZZLE_RGBA;
+ }
+}
+
+
+static LLVMValueRef
+lp_build_blend_swizzle(struct lp_build_blend_aos_context *bld,
+ LLVMValueRef rgb,
+ LLVMValueRef alpha,
+ enum lp_build_blend_swizzle rgb_swizzle,
+ unsigned alpha_swizzle)
+{
+ if(rgb == alpha) {
+ if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_RGBA)
+ return rgb;
+ if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_AAAA)
+ return lp_build_broadcast_aos(&bld->base, rgb, alpha_swizzle);
+ }
+ else {
+ if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_RGBA) {
+ boolean cond[4] = {0, 0, 0, 0};
+ cond[alpha_swizzle] = 1;
+ return lp_build_select_aos(&bld->base, alpha, rgb, cond);
+ }
+ if(rgb_swizzle == LP_BUILD_BLEND_SWIZZLE_AAAA) {
+ unsigned char swizzle[4];
+ swizzle[0] = alpha_swizzle;
+ swizzle[1] = alpha_swizzle;
+ swizzle[2] = alpha_swizzle;
+ swizzle[3] = alpha_swizzle;
+ swizzle[alpha_swizzle] += 4;
+ return lp_build_swizzle2_aos(&bld->base, rgb, alpha, swizzle);
+ }
+ }
+ assert(0);
+ return bld->base.undef;
+}
+
+
+/**
+ * @sa http://www.opengl.org/sdk/docs/man/xhtml/glBlendFuncSeparate.xml
+ */
+static LLVMValueRef
+lp_build_blend_factor(struct lp_build_blend_aos_context *bld,
+ LLVMValueRef factor1,
+ unsigned rgb_factor,
+ unsigned alpha_factor,
+ unsigned alpha_swizzle)
+{
+ LLVMValueRef rgb_factor_;
+ LLVMValueRef alpha_factor_;
+ LLVMValueRef factor2;
+ enum lp_build_blend_swizzle rgb_swizzle;
+
+ rgb_factor_ = lp_build_blend_factor_unswizzled(bld, rgb_factor, FALSE);
+ alpha_factor_ = lp_build_blend_factor_unswizzled(bld, alpha_factor, TRUE);
+
+ rgb_swizzle = lp_build_blend_factor_swizzle(rgb_factor);
+
+ factor2 = lp_build_blend_swizzle(bld, rgb_factor_, alpha_factor_, rgb_swizzle, alpha_swizzle);
+
+ return lp_build_mul(&bld->base, factor1, factor2);
+}
+
+
+boolean
+lp_build_blend_func_commutative(unsigned func)
+{
+ switch (func) {
+ case PIPE_BLEND_ADD:
+ case PIPE_BLEND_MIN:
+ case PIPE_BLEND_MAX:
+ return TRUE;
+ case PIPE_BLEND_SUBTRACT:
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ return FALSE;
+ default:
+ assert(0);
+ return TRUE;
+ }
+}
+
+
+boolean
+lp_build_blend_func_reverse(unsigned rgb_func, unsigned alpha_func)
+{
+ if(rgb_func == alpha_func)
+ return FALSE;
+ if(rgb_func == PIPE_BLEND_SUBTRACT && alpha_func == PIPE_BLEND_REVERSE_SUBTRACT)
+ return TRUE;
+ if(rgb_func == PIPE_BLEND_REVERSE_SUBTRACT && alpha_func == PIPE_BLEND_SUBTRACT)
+ return TRUE;
+ return FALSE;
+}
+
+
+/**
+ * @sa http://www.opengl.org/sdk/docs/man/xhtml/glBlendEquationSeparate.xml
+ */
+LLVMValueRef
+lp_build_blend_func(struct lp_build_context *bld,
+ unsigned func,
+ LLVMValueRef term1,
+ LLVMValueRef term2)
+{
+ switch (func) {
+ case PIPE_BLEND_ADD:
+ return lp_build_add(bld, term1, term2);
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ return lp_build_sub(bld, term1, term2);
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ return lp_build_sub(bld, term2, term1);
+ case PIPE_BLEND_MIN:
+ return lp_build_min(bld, term1, term2);
+ case PIPE_BLEND_MAX:
+ return lp_build_max(bld, term1, term2);
+ default:
+ assert(0);
+ return bld->zero;
+ }
+}
+
+
+LLVMValueRef
+lp_build_blend_aos(LLVMBuilderRef builder,
+ const struct pipe_blend_state *blend,
+ struct lp_type type,
+ LLVMValueRef src,
+ LLVMValueRef dst,
+ LLVMValueRef const_,
+ unsigned alpha_swizzle)
+{
+ struct lp_build_blend_aos_context bld;
+ LLVMValueRef src_term;
+ LLVMValueRef dst_term;
+
+ /* FIXME */
+ assert(blend->colormask == 0xf);
+
+ if(!blend->blend_enable)
+ return src;
+
+ /* It makes no sense to blend unless values are normalized */
+ assert(type.norm);
+
+ /* Setup build context */
+ memset(&bld, 0, sizeof bld);
+ lp_build_context_init(&bld.base, builder, type);
+ bld.src = src;
+ bld.dst = dst;
+ bld.const_ = const_;
+
+ /* TODO: There are still a few optimization opportunities here. For certain
+ * combinations it is possible to reorder the operations and therefore saving
+ * some instructions. */
+
+ src_term = lp_build_blend_factor(&bld, src, blend->rgb_src_factor, blend->alpha_src_factor, alpha_swizzle);
+ dst_term = lp_build_blend_factor(&bld, dst, blend->rgb_dst_factor, blend->alpha_dst_factor, alpha_swizzle);
+
+ lp_build_name(src_term, "src_term");
+ lp_build_name(dst_term, "dst_term");
+
+ if(blend->rgb_func == blend->alpha_func) {
+ return lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term);
+ }
+ else {
+ /* Seperate RGB / A functions */
+
+ LLVMValueRef rgb;
+ LLVMValueRef alpha;
+
+ rgb = lp_build_blend_func(&bld.base, blend->rgb_func, src_term, dst_term);
+ alpha = lp_build_blend_func(&bld.base, blend->alpha_func, src_term, dst_term);
+
+ return lp_build_blend_swizzle(&bld, rgb, alpha, LP_BUILD_BLEND_SWIZZLE_RGBA, alpha_swizzle);
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c
new file mode 100644
index 0000000000..88321f62a2
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_logicop.c
@@ -0,0 +1,108 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Blend LLVM IR generation -- logic ops.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "pipe/p_state.h"
+
+#include "lp_bld_blend.h"
+
+
+LLVMValueRef
+lp_build_logicop(LLVMBuilderRef builder,
+ unsigned logicop_func,
+ LLVMValueRef src,
+ LLVMValueRef dst)
+{
+ LLVMTypeRef type;
+ LLVMValueRef res;
+
+ type = LLVMTypeOf(src);
+
+ switch (logicop_func) {
+ case PIPE_LOGICOP_CLEAR:
+ res = LLVMConstNull(type);
+ break;
+ case PIPE_LOGICOP_NOR:
+ res = LLVMBuildNot(builder, LLVMBuildOr(builder, src, dst, ""), "");
+ break;
+ case PIPE_LOGICOP_AND_INVERTED:
+ res = LLVMBuildAnd(builder, LLVMBuildNot(builder, src, ""), dst, "");
+ break;
+ case PIPE_LOGICOP_COPY_INVERTED:
+ res = LLVMBuildNot(builder, src, "");
+ break;
+ case PIPE_LOGICOP_AND_REVERSE:
+ res = LLVMBuildAnd(builder, src, LLVMBuildNot(builder, dst, ""), "");
+ break;
+ case PIPE_LOGICOP_INVERT:
+ res = LLVMBuildNot(builder, dst, "");
+ break;
+ case PIPE_LOGICOP_XOR:
+ res = LLVMBuildXor(builder, src, dst, "");
+ break;
+ case PIPE_LOGICOP_NAND:
+ res = LLVMBuildNot(builder, LLVMBuildAnd(builder, src, dst, ""), "");
+ break;
+ case PIPE_LOGICOP_AND:
+ res = LLVMBuildAnd(builder, src, dst, "");
+ break;
+ case PIPE_LOGICOP_EQUIV:
+ res = LLVMBuildNot(builder, LLVMBuildXor(builder, src, dst, ""), "");
+ break;
+ case PIPE_LOGICOP_NOOP:
+ res = dst;
+ break;
+ case PIPE_LOGICOP_OR_INVERTED:
+ res = LLVMBuildOr(builder, LLVMBuildNot(builder, src, ""), dst, "");
+ break;
+ case PIPE_LOGICOP_COPY:
+ res = src;
+ break;
+ case PIPE_LOGICOP_OR_REVERSE:
+ res = LLVMBuildOr(builder, src, LLVMBuildNot(builder, dst, ""), "");
+ break;
+ case PIPE_LOGICOP_OR:
+ res = LLVMBuildOr(builder, src, dst, "");
+ break;
+ case PIPE_LOGICOP_SET:
+ res = LLVMConstAllOnes(type);
+ break;
+ default:
+ assert(0);
+ res = src;
+ }
+
+ return res;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
new file mode 100644
index 0000000000..9511299d55
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_blend_soa.c
@@ -0,0 +1,298 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Blend LLVM IR generation -- SoA layout.
+ *
+ * Blending in SoA is much faster than AoS, especially when separate rgb/alpha
+ * factors/functions are used, since no channel masking/shuffling is necessary
+ * and we can achieve the full throughput of the SIMD operations. Furthermore
+ * the fragment shader output is also in SoA, so it fits nicely with the rest of
+ * the fragment pipeline.
+ *
+ * The drawback is that to be displayed the color buffer needs to be in AoS
+ * layout, so we need to tile/untile the color buffer before/after rendering.
+ * A color buffer like
+ *
+ * R11 G11 B11 A11 R12 G12 B12 A12 R13 G13 B13 A13 R14 G14 B14 A14 ...
+ * R21 G21 B21 A21 R22 G22 B22 A22 R23 G23 B23 A23 R24 G24 B24 A24 ...
+ *
+ * R31 G31 B31 A31 R32 G32 B32 A32 R33 G33 B33 A33 R34 G34 B34 A34 ...
+ * R41 G41 B41 A41 R42 G42 B42 A42 R43 G43 B43 A43 R44 G44 B44 A44 ...
+ *
+ * ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
+ *
+ * will actually be stored in memory as
+ *
+ * R11 R12 R21 R22 R13 R14 R23 R24 ... G11 G12 G21 G22 G13 G14 G23 G24 ... B11 B12 B21 B22 B13 B14 B23 B24 ... A11 A12 A21 A22 A13 A14 A23 A24 ...
+ * R31 R32 R41 R42 R33 R34 R43 R44 ... G31 G32 G41 G42 G33 G34 G43 G44 ... B31 B32 B41 B42 B33 B34 B43 B44 ... A31 A32 A41 A42 A33 A34 A43 A44 ...
+ * ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
+ *
+ * NOTE: Run lp_blend_test after any change to this file.
+ *
+ * You can also run lp_blend_test to obtain AoS vs SoA benchmarks. Invoking it
+ * as:
+ *
+ * lp_blend_test -o blend.tsv
+ *
+ * will generate a tab-seperated-file with the test results and performance
+ * measurements.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "pipe/p_state.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_blend.h"
+
+
+/**
+ * We may the same values several times, so we keep them here to avoid
+ * recomputing them. Also reusing the values allows us to do simplifications
+ * that LLVM optimization passes wouldn't normally be able to do.
+ */
+struct lp_build_blend_soa_context
+{
+ struct lp_build_context base;
+
+ LLVMValueRef src[4];
+ LLVMValueRef dst[4];
+ LLVMValueRef con[4];
+
+ LLVMValueRef inv_src[4];
+ LLVMValueRef inv_dst[4];
+ LLVMValueRef inv_con[4];
+
+ LLVMValueRef src_alpha_saturate;
+
+ /**
+ * We store all factors in a table in order to eliminate redundant
+ * multiplications later.
+ */
+ LLVMValueRef factor[2][2][4];
+
+ /**
+ * Table with all terms.
+ */
+ LLVMValueRef term[2][4];
+};
+
+
+static LLVMValueRef
+lp_build_blend_soa_factor(struct lp_build_blend_soa_context *bld,
+ unsigned factor, unsigned i)
+{
+ /*
+ * Compute src/first term RGB
+ */
+ switch (factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ return bld->base.one;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ return bld->src[i];
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ return bld->src[3];
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ return bld->dst[i];
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ return bld->dst[3];
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ if(i == 3)
+ return bld->base.one;
+ else {
+ if(!bld->inv_dst[3])
+ bld->inv_dst[3] = lp_build_comp(&bld->base, bld->dst[3]);
+ if(!bld->src_alpha_saturate)
+ bld->src_alpha_saturate = lp_build_min(&bld->base, bld->src[3], bld->inv_dst[3]);
+ return bld->src_alpha_saturate;
+ }
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ return bld->con[i];
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ return bld->con[3];
+ case PIPE_BLENDFACTOR_SRC1_COLOR:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_SRC1_ALPHA:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_ZERO:
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ if(!bld->inv_src[i])
+ bld->inv_src[i] = lp_build_comp(&bld->base, bld->src[i]);
+ return bld->inv_src[i];
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ if(!bld->inv_src[3])
+ bld->inv_src[3] = lp_build_comp(&bld->base, bld->src[3]);
+ return bld->inv_src[3];
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ if(!bld->inv_dst[i])
+ bld->inv_dst[i] = lp_build_comp(&bld->base, bld->dst[i]);
+ return bld->inv_dst[i];
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ if(!bld->inv_dst[3])
+ bld->inv_dst[3] = lp_build_comp(&bld->base, bld->dst[3]);
+ return bld->inv_dst[3];
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ if(!bld->inv_con[i])
+ bld->inv_con[i] = lp_build_comp(&bld->base, bld->con[i]);
+ return bld->inv_con[i];
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ if(!bld->inv_con[3])
+ bld->inv_con[3] = lp_build_comp(&bld->base, bld->con[3]);
+ return bld->inv_con[3];
+ case PIPE_BLENDFACTOR_INV_SRC1_COLOR:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ case PIPE_BLENDFACTOR_INV_SRC1_ALPHA:
+ /* TODO */
+ assert(0);
+ return bld->base.zero;
+ default:
+ assert(0);
+ return bld->base.zero;
+ }
+}
+
+
+/**
+ * Generate blend code in SOA mode.
+ * \param src src/fragment color
+ * \param dst dst/framebuffer color
+ * \param con constant blend color
+ * \param res the result/output
+ */
+void
+lp_build_blend_soa(LLVMBuilderRef builder,
+ const struct pipe_blend_state *blend,
+ struct lp_type type,
+ LLVMValueRef src[4],
+ LLVMValueRef dst[4],
+ LLVMValueRef con[4],
+ LLVMValueRef res[4])
+{
+ struct lp_build_blend_soa_context bld;
+ unsigned i, j, k;
+
+ /* Setup build context */
+ memset(&bld, 0, sizeof bld);
+ lp_build_context_init(&bld.base, builder, type);
+ for (i = 0; i < 4; ++i) {
+ bld.src[i] = src[i];
+ bld.dst[i] = dst[i];
+ bld.con[i] = con[i];
+ }
+
+ for (i = 0; i < 4; ++i) {
+ if (blend->colormask & (1 << i)) {
+ if (blend->logicop_enable) {
+ if(!type.floating) {
+ res[i] = lp_build_logicop(builder, blend->logicop_func, src[i], dst[i]);
+ }
+ else
+ res[i] = dst[i];
+ }
+ else if (blend->blend_enable) {
+ unsigned src_factor = i < 3 ? blend->rgb_src_factor : blend->alpha_src_factor;
+ unsigned dst_factor = i < 3 ? blend->rgb_dst_factor : blend->alpha_dst_factor;
+ unsigned func = i < 3 ? blend->rgb_func : blend->alpha_func;
+ boolean func_commutative = lp_build_blend_func_commutative(func);
+
+ /* It makes no sense to blend unless values are normalized */
+ assert(type.norm);
+
+ /*
+ * Compute src/dst factors.
+ */
+
+ bld.factor[0][0][i] = src[i];
+ bld.factor[0][1][i] = lp_build_blend_soa_factor(&bld, src_factor, i);
+ bld.factor[1][0][i] = dst[i];
+ bld.factor[1][1][i] = lp_build_blend_soa_factor(&bld, dst_factor, i);
+
+ /*
+ * Compute src/dst terms
+ */
+
+ for(k = 0; k < 2; ++k) {
+ /* See if this multiplication has been previously computed */
+ for(j = 0; j < i; ++j) {
+ if((bld.factor[k][0][j] == bld.factor[k][0][i] &&
+ bld.factor[k][1][j] == bld.factor[k][1][i]) ||
+ (bld.factor[k][0][j] == bld.factor[k][1][i] &&
+ bld.factor[k][1][j] == bld.factor[k][0][i]))
+ break;
+ }
+
+ if(j < i)
+ bld.term[k][i] = bld.term[k][j];
+ else
+ bld.term[k][i] = lp_build_mul(&bld.base, bld.factor[k][0][i], bld.factor[k][1][i]);
+ }
+
+ /*
+ * Combine terms
+ */
+
+ /* See if this function has been previously applied */
+ for(j = 0; j < i; ++j) {
+ unsigned prev_func = j < 3 ? blend->rgb_func : blend->alpha_func;
+ unsigned func_reverse = lp_build_blend_func_reverse(func, prev_func);
+
+ if((!func_reverse &&
+ bld.term[0][j] == bld.term[0][i] &&
+ bld.term[1][j] == bld.term[1][i]) ||
+ ((func_commutative || func_reverse) &&
+ bld.term[0][j] == bld.term[1][i] &&
+ bld.term[1][j] == bld.term[0][i]))
+ break;
+ }
+
+ if(j < i)
+ res[i] = res[j];
+ else
+ res[i] = lp_build_blend_func(&bld.base, func, bld.term[0][i], bld.term[1][i]);
+ }
+ else {
+ res[i] = src[i];
+ }
+ }
+ else {
+ res[i] = dst[i];
+ }
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.c b/src/gallium/drivers/llvmpipe/lp_bld_const.c
new file mode 100644
index 0000000000..c8eaa8c394
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.c
@@ -0,0 +1,369 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Helper functions for constant building.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include <float.h>
+
+#include "util/u_debug.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+
+
+unsigned
+lp_mantissa(struct lp_type type)
+{
+ assert(type.floating);
+
+ if(type.floating) {
+ switch(type.width) {
+ case 32:
+ return 23;
+ case 64:
+ return 53;
+ default:
+ assert(0);
+ return 0;
+ }
+ }
+ else {
+ if(type.sign)
+ return type.width - 1;
+ else
+ return type.width;
+ }
+}
+
+
+/**
+ * Shift of the unity.
+ *
+ * Same as lp_const_scale(), but in terms of shifts.
+ */
+unsigned
+lp_const_shift(struct lp_type type)
+{
+ if(type.floating)
+ return 0;
+ else if(type.fixed)
+ return type.width/2;
+ else if(type.norm)
+ return type.sign ? type.width - 1 : type.width;
+ else
+ return 0;
+}
+
+
+unsigned
+lp_const_offset(struct lp_type type)
+{
+ if(type.floating || type.fixed)
+ return 0;
+ else if(type.norm)
+ return 1;
+ else
+ return 0;
+}
+
+
+/**
+ * Scaling factor between the LLVM native value and its interpretation.
+ *
+ * This is 1.0 for all floating types and unnormalized integers, and something
+ * else for the fixed points types and normalized integers.
+ */
+double
+lp_const_scale(struct lp_type type)
+{
+ unsigned long long llscale;
+ double dscale;
+
+ llscale = (unsigned long long)1 << lp_const_shift(type);
+ llscale -= lp_const_offset(type);
+ dscale = (double)llscale;
+ assert((unsigned long long)dscale == llscale);
+
+ return dscale;
+}
+
+
+/**
+ * Minimum value representable by the type.
+ */
+double
+lp_const_min(struct lp_type type)
+{
+ unsigned bits;
+
+ if(!type.sign)
+ return 0.0;
+
+ if(type.norm)
+ return -1.0;
+
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return -FLT_MAX;
+ case 64:
+ return -DBL_MAX;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+
+ if(type.fixed)
+ /* FIXME: consider the fractional bits? */
+ bits = type.width / 2 - 1;
+ else
+ bits = type.width - 1;
+
+ return (double)-((long long)1 << bits);
+}
+
+
+/**
+ * Maximum value representable by the type.
+ */
+double
+lp_const_max(struct lp_type type)
+{
+ unsigned bits;
+
+ if(type.norm)
+ return 1.0;
+
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return FLT_MAX;
+ case 64:
+ return DBL_MAX;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+
+ if(type.fixed)
+ bits = type.width / 2;
+ else
+ bits = type.width;
+
+ if(type.sign)
+ bits -= 1;
+
+ return (double)(((unsigned long long)1 << bits) - 1);
+}
+
+
+double
+lp_const_eps(struct lp_type type)
+{
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return FLT_EPSILON;
+ case 64:
+ return DBL_EPSILON;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+ else {
+ double scale = lp_const_scale(type);
+ return 1.0/scale;
+ }
+}
+
+
+LLVMValueRef
+lp_build_undef(struct lp_type type)
+{
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ return LLVMGetUndef(vec_type);
+}
+
+
+LLVMValueRef
+lp_build_zero(struct lp_type type)
+{
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ return LLVMConstNull(vec_type);
+}
+
+
+LLVMValueRef
+lp_build_one(struct lp_type type)
+{
+ LLVMTypeRef elem_type;
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ elem_type = lp_build_elem_type(type);
+
+ if(type.floating)
+ elems[0] = LLVMConstReal(elem_type, 1.0);
+ else if(type.fixed)
+ elems[0] = LLVMConstInt(elem_type, 1LL << (type.width/2), 0);
+ else if(!type.norm)
+ elems[0] = LLVMConstInt(elem_type, 1, 0);
+ else if(type.sign)
+ elems[0] = LLVMConstInt(elem_type, (1LL << (type.width - 1)) - 1, 0);
+ else {
+ /* special case' -- 1.0 for normalized types is more easily attained if
+ * we start with a vector consisting of all bits set */
+ LLVMTypeRef vec_type = LLVMVectorType(elem_type, type.length);
+ LLVMValueRef vec = LLVMConstAllOnes(vec_type);
+
+#if 0
+ if(type.sign)
+ /* TODO: Unfortunately this caused "Tried to create a shift operation
+ * on a non-integer type!" */
+ vec = LLVMConstLShr(vec, lp_build_int_const_scalar(type, 1));
+#endif
+
+ return vec;
+ }
+
+ for(i = 1; i < type.length; ++i)
+ elems[i] = elems[0];
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
+lp_build_const_scalar(struct lp_type type,
+ double val)
+{
+ LLVMTypeRef elem_type = lp_build_elem_type(type);
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ if(type.floating) {
+ elems[0] = LLVMConstReal(elem_type, val);
+ }
+ else {
+ double dscale = lp_const_scale(type);
+
+ elems[0] = LLVMConstInt(elem_type, val*dscale + 0.5, 0);
+ }
+
+ for(i = 1; i < type.length; ++i)
+ elems[i] = elems[0];
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
+lp_build_int_const_scalar(struct lp_type type,
+ long long val)
+{
+ LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ for(i = 0; i < type.length; ++i)
+ elems[i] = LLVMConstInt(elem_type, val, type.sign ? 1 : 0);
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
+lp_build_const_aos(struct lp_type type,
+ double r, double g, double b, double a,
+ const unsigned char *swizzle)
+{
+ const unsigned char default_swizzle[4] = {0, 1, 2, 3};
+ LLVMTypeRef elem_type;
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(type.length % 4 == 0);
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ elem_type = lp_build_elem_type(type);
+
+ if(swizzle == NULL)
+ swizzle = default_swizzle;
+
+ if(type.floating) {
+ elems[swizzle[0]] = LLVMConstReal(elem_type, r);
+ elems[swizzle[1]] = LLVMConstReal(elem_type, g);
+ elems[swizzle[2]] = LLVMConstReal(elem_type, b);
+ elems[swizzle[3]] = LLVMConstReal(elem_type, a);
+ }
+ else {
+ double dscale = lp_const_scale(type);
+
+ elems[swizzle[0]] = LLVMConstInt(elem_type, r*dscale + 0.5, 0);
+ elems[swizzle[1]] = LLVMConstInt(elem_type, g*dscale + 0.5, 0);
+ elems[swizzle[2]] = LLVMConstInt(elem_type, b*dscale + 0.5, 0);
+ elems[swizzle[3]] = LLVMConstInt(elem_type, a*dscale + 0.5, 0);
+ }
+
+ for(i = 4; i < type.length; ++i)
+ elems[i] = elems[i % 4];
+
+ return LLVMConstVector(elems, type.length);
+}
+
+
+LLVMValueRef
+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];
+ unsigned i, j;
+
+ assert(type.length <= LP_MAX_VECTOR_LENGTH);
+
+ for(j = 0; j < type.length; j += 4)
+ for(i = 0; i < 4; ++i)
+ masks[j + i] = LLVMConstInt(elem_type, cond[i] ? ~0 : 0, 0);
+
+ return LLVMConstVector(masks, type.length);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_const.h b/src/gallium/drivers/llvmpipe/lp_bld_const.h
new file mode 100644
index 0000000000..ffb302f736
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_const.h
@@ -0,0 +1,108 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for constant building.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_CONST_H
+#define LP_BLD_CONST_H
+
+
+#include <llvm-c/Core.h>
+
+#include <pipe/p_compiler.h>
+
+
+struct lp_type type;
+
+
+unsigned
+lp_mantissa(struct lp_type type);
+
+
+unsigned
+lp_const_shift(struct lp_type type);
+
+
+unsigned
+lp_const_offset(struct lp_type type);
+
+
+double
+lp_const_scale(struct lp_type type);
+
+double
+lp_const_min(struct lp_type type);
+
+
+double
+lp_const_max(struct lp_type type);
+
+
+double
+lp_const_eps(struct lp_type type);
+
+
+LLVMValueRef
+lp_build_undef(struct lp_type type);
+
+
+LLVMValueRef
+lp_build_zero(struct lp_type type);
+
+
+LLVMValueRef
+lp_build_one(struct lp_type type);
+
+
+LLVMValueRef
+lp_build_const_scalar(struct lp_type type,
+ double val);
+
+
+LLVMValueRef
+lp_build_int_const_scalar(struct lp_type type,
+ long long val);
+
+
+LLVMValueRef
+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(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
new file mode 100644
index 0000000000..186cac70f6
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.c
@@ -0,0 +1,702 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Helper functions for type conversions.
+ *
+ * We want to use the fastest type for a given computation whenever feasible.
+ * The other side of this is that we need to be able convert between several
+ * types accurately and efficiently.
+ *
+ * Conversion between types of different bit width is quite complex since a
+ *
+ * To remember there are a few invariants in type conversions:
+ *
+ * - register width must remain constant:
+ *
+ * src_type.width * src_type.length == dst_type.width * dst_type.length
+ *
+ * - total number of elements must remain constant:
+ *
+ * src_type.length * num_srcs == dst_type.length * num_dsts
+ *
+ * It is not always possible to do the conversion both accurately and
+ * efficiently, usually due to lack of adequate machine instructions. In these
+ * cases it is important not to cut shortcuts here and sacrifice accuracy, as
+ * there this functions can be used anywhere. In the future we might have a
+ * precision parameter which can gauge the accuracy vs efficiency compromise,
+ * but for now if the data conversion between two stages happens to be the
+ * bottleneck, then most likely should just avoid converting at all and run
+ * both stages with the same type.
+ *
+ * Make sure to run lp_test_conv unit test after any change to this file.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_debug.h"
+#include "util/u_math.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_conv.h"
+
+
+/**
+ * Special case for converting clamped IEEE-754 floats to unsigned norms.
+ *
+ * The mathematical voodoo below may seem excessive but it is actually
+ * paramount we do it this way for several reasons. First, there is no single
+ * precision FP to unsigned integer conversion Intel SSE instruction. Second,
+ * secondly, even if there was, since the FP's mantissa takes only a fraction
+ * of register bits the typically scale and cast approach would require double
+ * precision for accurate results, and therefore half the throughput
+ *
+ * Although the result values can be scaled to an arbitrary bit width specified
+ * by dst_width, the actual result type will have the same width.
+ */
+LLVMValueRef
+lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ unsigned dst_width,
+ LLVMValueRef src)
+{
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(src_type);
+ LLVMValueRef res;
+ unsigned mantissa;
+ unsigned n;
+ unsigned long long ubound;
+ unsigned long long mask;
+ double scale;
+ double bias;
+
+ assert(src_type.floating);
+
+ mantissa = lp_mantissa(src_type);
+
+ /* We cannot carry more bits than the mantissa */
+ n = MIN2(mantissa, dst_width);
+
+ /* This magic coefficients will make the desired result to appear in the
+ * lowest significant bits of the mantissa.
+ */
+ ubound = ((unsigned long long)1 << n);
+ mask = ubound - 1;
+ scale = (double)mask/ubound;
+ bias = (double)((unsigned long long)1 << (mantissa - n));
+
+ res = LLVMBuildMul(builder, src, lp_build_const_scalar(src_type, scale), "");
+ res = LLVMBuildAdd(builder, res, lp_build_const_scalar(src_type, bias), "");
+ res = LLVMBuildBitCast(builder, res, int_vec_type, "");
+
+ if(dst_width > n) {
+ int shift = dst_width - n;
+ res = LLVMBuildShl(builder, res, lp_build_int_const_scalar(src_type, shift), "");
+
+ /* TODO: Fill in the empty lower bits for additional precision? */
+#if 0
+ {
+ LLVMValueRef msb;
+ msb = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, dst_width - 1), "");
+ msb = LLVMBuildShl(builder, msb, lp_build_int_const_scalar(src_type, shift), "");
+ msb = LLVMBuildSub(builder, msb, lp_build_int_const_scalar(src_type, 1), "");
+ res = LLVMBuildOr(builder, res, msb, "");
+ }
+#elif 0
+ while(shift > 0) {
+ res = LLVMBuildOr(builder, res, LLVMBuildLShr(builder, res, lp_build_int_const_scalar(src_type, n), ""), "");
+ shift -= n;
+ n *= 2;
+ }
+#endif
+ }
+ else
+ res = LLVMBuildAnd(builder, res, lp_build_int_const_scalar(src_type, mask), "");
+
+ return res;
+}
+
+
+/**
+ * Inverse of lp_build_clamped_float_to_unsigned_norm above.
+ */
+LLVMValueRef
+lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
+ unsigned src_width,
+ struct lp_type dst_type,
+ LLVMValueRef src)
+{
+ LLVMTypeRef vec_type = lp_build_vec_type(dst_type);
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(dst_type);
+ LLVMValueRef bias_;
+ LLVMValueRef res;
+ unsigned mantissa;
+ unsigned n;
+ unsigned long long ubound;
+ unsigned long long mask;
+ double scale;
+ double bias;
+
+ mantissa = lp_mantissa(dst_type);
+
+ n = MIN2(mantissa, src_width);
+
+ ubound = ((unsigned long long)1 << n);
+ mask = ubound - 1;
+ scale = (double)ubound/mask;
+ bias = (double)((unsigned long long)1 << (mantissa - n));
+
+ res = src;
+
+ if(src_width > mantissa) {
+ int shift = src_width - mantissa;
+ res = LLVMBuildLShr(builder, res, lp_build_int_const_scalar(dst_type, shift), "");
+ }
+
+ bias_ = lp_build_const_scalar(dst_type, bias);
+
+ res = LLVMBuildOr(builder,
+ res,
+ LLVMBuildBitCast(builder, bias_, int_vec_type, ""), "");
+
+ res = LLVMBuildBitCast(builder, res, vec_type, "");
+
+ res = LLVMBuildSub(builder, res, bias_, "");
+ res = LLVMBuildMul(builder, res, lp_build_const_scalar(dst_type, scale), "");
+
+ return res;
+}
+
+
+/**
+ * Build shuffle vectors that match PUNPCKLxx and PUNPCKHxx instructions.
+ */
+static LLVMValueRef
+lp_build_const_unpack_shuffle(unsigned n, unsigned lo_hi)
+{
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i, j;
+
+ assert(n <= LP_MAX_VECTOR_LENGTH);
+ assert(lo_hi < 2);
+
+ /* TODO: cache results in a static table */
+
+ for(i = 0, j = lo_hi*n/2; i < n; i += 2, ++j) {
+ elems[i + 0] = LLVMConstInt(LLVMInt32Type(), 0 + j, 0);
+ elems[i + 1] = LLVMConstInt(LLVMInt32Type(), n + j, 0);
+ }
+
+ return LLVMConstVector(elems, n);
+}
+
+
+/**
+ * Build shuffle vectors that match PACKxx instructions.
+ */
+static LLVMValueRef
+lp_build_const_pack_shuffle(unsigned n)
+{
+ LLVMValueRef elems[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ assert(n <= LP_MAX_VECTOR_LENGTH);
+
+ /* TODO: cache results in a static table */
+
+ for(i = 0; i < n; ++i)
+ elems[i] = LLVMConstInt(LLVMInt32Type(), 2*i, 0);
+
+ return LLVMConstVector(elems, n);
+}
+
+
+/**
+ * Expand the bit width.
+ *
+ * This will only change the number of bits the values are represented, not the
+ * values themselves.
+ */
+static void
+lp_build_expand(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ LLVMValueRef src,
+ LLVMValueRef *dst, unsigned num_dsts)
+{
+ unsigned num_tmps;
+ unsigned i;
+
+ /* Register width must remain constant */
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length == dst_type.length * num_dsts);
+
+ num_tmps = 1;
+ dst[0] = src;
+
+ while(src_type.width < dst_type.width) {
+ struct lp_type new_type = src_type;
+ LLVMTypeRef new_vec_type;
+
+ new_type.width *= 2;
+ new_type.length /= 2;
+ new_vec_type = lp_build_vec_type(new_type);
+
+ for(i = num_tmps; i--; ) {
+ LLVMValueRef zero;
+ LLVMValueRef shuffle_lo;
+ LLVMValueRef shuffle_hi;
+ LLVMValueRef lo;
+ LLVMValueRef hi;
+
+ zero = lp_build_zero(src_type);
+ shuffle_lo = lp_build_const_unpack_shuffle(src_type.length, 0);
+ shuffle_hi = lp_build_const_unpack_shuffle(src_type.length, 1);
+
+ /* PUNPCKLBW, PUNPCKHBW */
+ lo = LLVMBuildShuffleVector(builder, dst[i], zero, shuffle_lo, "");
+ hi = LLVMBuildShuffleVector(builder, dst[i], zero, shuffle_hi, "");
+
+ dst[2*i + 0] = LLVMBuildBitCast(builder, lo, new_vec_type, "");
+ dst[2*i + 1] = LLVMBuildBitCast(builder, hi, new_vec_type, "");
+ }
+
+ src_type = new_type;
+
+ num_tmps *= 2;
+ }
+
+ assert(num_tmps == num_dsts);
+}
+
+
+/**
+ * Non-interleaved pack.
+ *
+ * This will move values as
+ *
+ * lo = __ l0 __ l1 __ l2 __.. __ ln
+ * hi = __ h0 __ h1 __ h2 __.. __ hn
+ * res = l0 l1 l2 .. ln h0 h1 h2 .. hn
+ *
+ * TODO: handle saturation consistently.
+ */
+static LLVMValueRef
+lp_build_pack2(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ boolean clamped,
+ LLVMValueRef lo,
+ LLVMValueRef hi)
+{
+ LLVMTypeRef src_vec_type = lp_build_vec_type(src_type);
+ LLVMTypeRef dst_vec_type = lp_build_vec_type(dst_type);
+ LLVMValueRef shuffle;
+ LLVMValueRef res;
+
+ /* Register width must remain constant */
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length * 2 == dst_type.length);
+
+ assert(!src_type.floating);
+ assert(!dst_type.floating);
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(src_type.width * src_type.length == 128) {
+ /* All X86 non-interleaved pack instructions all take signed inputs and
+ * saturate them, so saturate beforehand. */
+ if(!src_type.sign && !clamped) {
+ struct lp_build_context bld;
+ unsigned dst_bits = dst_type.sign ? dst_type.width - 1 : dst_type.width;
+ LLVMValueRef dst_max = lp_build_int_const_scalar(src_type, ((unsigned long long)1 << dst_bits) - 1);
+ lp_build_context_init(&bld, builder, src_type);
+ lo = lp_build_min(&bld, lo, dst_max);
+ hi = lp_build_min(&bld, hi, dst_max);
+ }
+
+ switch(src_type.width) {
+ case 32:
+ if(dst_type.sign)
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packssdw.128", src_vec_type, lo, hi);
+ else
+ /* PACKUSDW is the only instrinsic with a consistent signature */
+ return lp_build_intrinsic_binary(builder, "llvm.x86.sse41.packusdw", dst_vec_type, lo, hi);
+ break;
+
+ case 16:
+ if(dst_type.sign)
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packsswb.128", src_vec_type, lo, hi);
+ else
+ res = lp_build_intrinsic_binary(builder, "llvm.x86.sse2.packuswb.128", src_vec_type, lo, hi);
+ break;
+
+ default:
+ assert(0);
+ return LLVMGetUndef(dst_vec_type);
+ break;
+ }
+
+ res = LLVMBuildBitCast(builder, res, dst_vec_type, "");
+ return res;
+ }
+#endif
+
+ lo = LLVMBuildBitCast(builder, lo, dst_vec_type, "");
+ hi = LLVMBuildBitCast(builder, hi, dst_vec_type, "");
+
+ shuffle = lp_build_const_pack_shuffle(dst_type.length);
+
+ res = LLVMBuildShuffleVector(builder, lo, hi, shuffle, "");
+
+ return res;
+}
+
+
+/**
+ * Truncate the bit width.
+ *
+ * TODO: Handle saturation consistently.
+ */
+static LLVMValueRef
+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;
+
+ /* Register width must remain constant */
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length * num_srcs == dst_type.length);
+
+ for(i = 0; i < num_srcs; ++i)
+ tmp[i] = src[i];
+
+ while(src_type.width > dst_type.width) {
+ struct lp_type new_type = src_type;
+
+ new_type.width /= 2;
+ new_type.length *= 2;
+
+ /* Take in consideration the sign changes only in the last step */
+ if(new_type.width == dst_type.width)
+ new_type.sign = dst_type.sign;
+
+ num_srcs /= 2;
+
+ for(i = 0; i < num_srcs; ++i)
+ tmp[i] = lp_build_pack2(builder, src_type, new_type, clamped,
+ tmp[2*i + 0], tmp[2*i + 1]);
+
+ src_type = new_type;
+ }
+
+ assert(num_srcs == 1);
+
+ return tmp[0];
+}
+
+
+/**
+ * Generic type conversion.
+ *
+ * TODO: Take a precision argument, or even better, add a new precision member
+ * to the lp_type union.
+ */
+void
+lp_build_conv(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ const LLVMValueRef *src, unsigned num_srcs,
+ LLVMValueRef *dst, unsigned num_dsts)
+{
+ struct lp_type tmp_type;
+ LLVMValueRef tmp[LP_MAX_VECTOR_LENGTH];
+ unsigned num_tmps;
+ unsigned i;
+
+ /* Register width must remain constant */
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length * num_srcs == dst_type.length * num_dsts);
+
+ assert(src_type.length <= LP_MAX_VECTOR_LENGTH);
+ assert(dst_type.length <= LP_MAX_VECTOR_LENGTH);
+
+ tmp_type = src_type;
+ for(i = 0; i < num_srcs; ++i)
+ tmp[i] = src[i];
+ num_tmps = num_srcs;
+
+ /*
+ * Clamp if necessary
+ */
+
+ 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);
+ double src_max = lp_const_max(src_type);
+ double dst_max = lp_const_max(dst_type);
+ LLVMValueRef thres;
+
+ lp_build_context_init(&bld, builder, tmp_type);
+
+ if(src_min < dst_min) {
+ if(dst_min == 0.0)
+ thres = bld.zero;
+ else
+ thres = lp_build_const_scalar(src_type, dst_min);
+ for(i = 0; i < num_tmps; ++i)
+ tmp[i] = lp_build_max(&bld, tmp[i], thres);
+ }
+
+ if(src_max > dst_max) {
+ if(dst_max == 1.0)
+ thres = bld.one;
+ else
+ thres = lp_build_const_scalar(src_type, dst_max);
+ for(i = 0; i < num_tmps; ++i)
+ tmp[i] = lp_build_min(&bld, tmp[i], thres);
+ }
+ }
+
+ /*
+ * Scale to the narrowest range
+ */
+
+ if(dst_type.floating) {
+ /* Nothing to do */
+ }
+ else if(tmp_type.floating) {
+ if(!dst_type.fixed && !dst_type.sign && dst_type.norm) {
+ for(i = 0; i < num_tmps; ++i) {
+ tmp[i] = lp_build_clamped_float_to_unsigned_norm(builder,
+ tmp_type,
+ dst_type.width,
+ tmp[i]);
+ }
+ tmp_type.floating = FALSE;
+ }
+ else {
+ double dst_scale = lp_const_scale(dst_type);
+ LLVMTypeRef tmp_vec_type;
+
+ if (dst_scale != 1.0) {
+ LLVMValueRef scale = lp_build_const_scalar(tmp_type, dst_scale);
+ for(i = 0; i < num_tmps; ++i)
+ tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
+ }
+
+ /* Use an equally sized integer for intermediate computations */
+ tmp_type.floating = FALSE;
+ tmp_vec_type = lp_build_vec_type(tmp_type);
+ for(i = 0; i < num_tmps; ++i) {
+#if 0
+ if(dst_type.sign)
+ tmp[i] = LLVMBuildFPToSI(builder, tmp[i], tmp_vec_type, "");
+ else
+ tmp[i] = LLVMBuildFPToUI(builder, tmp[i], tmp_vec_type, "");
+#else
+ /* FIXME: there is no SSE counterpart for LLVMBuildFPToUI */
+ tmp[i] = LLVMBuildFPToSI(builder, tmp[i], tmp_vec_type, "");
+#endif
+ }
+ }
+ }
+ else {
+ unsigned src_shift = lp_const_shift(src_type);
+ unsigned dst_shift = lp_const_shift(dst_type);
+
+ /* FIXME: compensate different offsets too */
+ if(src_shift > dst_shift) {
+ LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, src_shift - dst_shift);
+ for(i = 0; i < num_tmps; ++i)
+ if(src_type.sign)
+ tmp[i] = LLVMBuildAShr(builder, tmp[i], shift, "");
+ else
+ tmp[i] = LLVMBuildLShr(builder, tmp[i], shift, "");
+ }
+ }
+
+ /*
+ * Truncate or expand bit width
+ */
+
+ assert(!tmp_type.floating || tmp_type.width == dst_type.width);
+
+ if(tmp_type.width > dst_type.width) {
+ assert(num_dsts == 1);
+ tmp[0] = lp_build_pack(builder, tmp_type, dst_type, TRUE, tmp, num_tmps);
+ tmp_type.width = dst_type.width;
+ tmp_type.length = dst_type.length;
+ num_tmps = 1;
+ }
+
+ if(tmp_type.width < dst_type.width) {
+ assert(num_tmps == 1);
+ lp_build_expand(builder, tmp_type, dst_type, tmp[0], tmp, num_dsts);
+ tmp_type.width = dst_type.width;
+ tmp_type.length = dst_type.length;
+ num_tmps = num_dsts;
+ }
+
+ assert(tmp_type.width == dst_type.width);
+ assert(tmp_type.length == dst_type.length);
+ assert(num_tmps == num_dsts);
+
+ /*
+ * Scale to the widest range
+ */
+
+ if(src_type.floating) {
+ /* Nothing to do */
+ }
+ else if(!src_type.floating && dst_type.floating) {
+ if(!src_type.fixed && !src_type.sign && src_type.norm) {
+ for(i = 0; i < num_tmps; ++i) {
+ tmp[i] = lp_build_unsigned_norm_to_float(builder,
+ src_type.width,
+ dst_type,
+ tmp[i]);
+ }
+ tmp_type.floating = TRUE;
+ }
+ else {
+ double src_scale = lp_const_scale(src_type);
+ LLVMTypeRef tmp_vec_type;
+
+ /* Use an equally sized integer for intermediate computations */
+ tmp_type.floating = TRUE;
+ tmp_type.sign = TRUE;
+ tmp_vec_type = lp_build_vec_type(tmp_type);
+ for(i = 0; i < num_tmps; ++i) {
+#if 0
+ if(dst_type.sign)
+ tmp[i] = LLVMBuildSIToFP(builder, tmp[i], tmp_vec_type, "");
+ else
+ tmp[i] = LLVMBuildUIToFP(builder, tmp[i], tmp_vec_type, "");
+#else
+ /* FIXME: there is no SSE counterpart for LLVMBuildUIToFP */
+ tmp[i] = LLVMBuildSIToFP(builder, tmp[i], tmp_vec_type, "");
+#endif
+ }
+
+ if (src_scale != 1.0) {
+ LLVMValueRef scale = lp_build_const_scalar(tmp_type, 1.0/src_scale);
+ for(i = 0; i < num_tmps; ++i)
+ tmp[i] = LLVMBuildMul(builder, tmp[i], scale, "");
+ }
+ }
+ }
+ else {
+ unsigned src_shift = lp_const_shift(src_type);
+ unsigned dst_shift = lp_const_shift(dst_type);
+
+ /* FIXME: compensate different offsets too */
+ if(src_shift < dst_shift) {
+ LLVMValueRef shift = lp_build_int_const_scalar(tmp_type, dst_shift - src_shift);
+ for(i = 0; i < num_tmps; ++i)
+ tmp[i] = LLVMBuildShl(builder, tmp[i], shift, "");
+ }
+ }
+
+ for(i = 0; i < num_dsts; ++i)
+ dst[i] = tmp[i];
+}
+
+
+/**
+ * Bit mask conversion.
+ *
+ * This will convert the integer masks that match the given types.
+ *
+ * The mask values should 0 or -1, i.e., all bits either set to zero or one.
+ * Any other value will likely cause in unpredictable results.
+ *
+ * This is basically a very trimmed down version of lp_build_conv.
+ */
+void
+lp_build_conv_mask(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ const LLVMValueRef *src, unsigned num_srcs,
+ LLVMValueRef *dst, unsigned num_dsts)
+{
+ /* Register width must remain constant */
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length * num_srcs == dst_type.length * num_dsts);
+
+ /*
+ * Drop
+ *
+ * We assume all values are 0 or -1
+ */
+
+ src_type.floating = FALSE;
+ src_type.fixed = FALSE;
+ src_type.sign = TRUE;
+ src_type.norm = FALSE;
+
+ dst_type.floating = FALSE;
+ dst_type.fixed = FALSE;
+ dst_type.sign = TRUE;
+ dst_type.norm = FALSE;
+
+ /*
+ * Truncate or expand bit width
+ */
+
+ if(src_type.width > dst_type.width) {
+ assert(num_dsts == 1);
+ 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);
+ lp_build_expand(builder, src_type, dst_type, src[0], dst, num_dsts);
+ }
+ else {
+ assert(num_srcs == num_dsts);
+ memcpy(dst, src, num_dsts * sizeof *dst);
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_conv.h b/src/gallium/drivers/llvmpipe/lp_bld_conv.h
new file mode 100644
index 0000000000..ca378804d2
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_conv.h
@@ -0,0 +1,73 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for type conversions.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_CONV_H
+#define LP_BLD_CONV_H
+
+
+#include <llvm-c/Core.h>
+
+
+struct lp_type type;
+
+
+LLVMValueRef
+lp_build_clamped_float_to_unsigned_norm(LLVMBuilderRef builder,
+ struct lp_type src_type,
+ unsigned dst_width,
+ LLVMValueRef src);
+
+LLVMValueRef
+lp_build_unsigned_norm_to_float(LLVMBuilderRef builder,
+ unsigned src_width,
+ struct lp_type dst_type,
+ LLVMValueRef src);
+
+
+void
+lp_build_conv(LLVMBuilderRef builder,
+ 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,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ const LLVMValueRef *src, unsigned num_srcs,
+ LLVMValueRef *dst, unsigned num_dsts);
+
+#endif /* !LP_BLD_CONV_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.c b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
new file mode 100644
index 0000000000..59d8f492e6
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_debug.c
@@ -0,0 +1,125 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifdef HAVE_UDIS86
+#include <udis86.h>
+#endif
+
+#include "util/u_math.h"
+#include "util/u_debug.h"
+#include "lp_bld_debug.h"
+
+
+/**
+ * Check alignment.
+ *
+ * It is important that this check is not implemented as a macro or inlined
+ * function, as the compiler assumptions in respect to alignment of global
+ * and stack variables would often make the check a no op, defeating the
+ * whole purpose of the exercise.
+ */
+boolean
+lp_check_alignment(const void *ptr, unsigned alignment)
+{
+ assert(util_is_pot(alignment));
+ return ((uintptr_t)ptr & (alignment - 1)) == 0;
+}
+
+
+void
+lp_disassemble(const void* func)
+{
+#ifdef HAVE_UDIS86
+ ud_t ud_obj;
+ uint64_t max_jmp_pc;
+
+ ud_init(&ud_obj);
+
+ ud_set_input_buffer(&ud_obj, (void*)func, 0xffff);
+
+ max_jmp_pc = (uint64_t) (uintptr_t) func;
+ ud_set_pc(&ud_obj, max_jmp_pc);
+
+#ifdef PIPE_ARCH_X86
+ ud_set_mode(&ud_obj, 32);
+#endif
+#ifdef PIPE_ARCH_X86_64
+ ud_set_mode(&ud_obj, 64);
+#endif
+
+ ud_set_syntax(&ud_obj, UD_SYN_ATT);
+
+ while (ud_disassemble(&ud_obj)) {
+
+#ifdef PIPE_ARCH_X86
+ debug_printf("%08lx: ", (unsigned long)ud_insn_off(&ud_obj));
+#endif
+#ifdef PIPE_ARCH_X86_64
+ debug_printf("%016llx: ", (unsigned long long)ud_insn_off(&ud_obj));
+#endif
+
+#if 0
+ debug_printf("%-16s ", ud_insn_hex(&ud_obj));
+#endif
+
+ debug_printf("%s\n", ud_insn_asm(&ud_obj));
+
+ if(ud_obj.mnemonic != UD_Icall) {
+ unsigned i;
+ for(i = 0; i < 3; ++i) {
+ const struct ud_operand *op = &ud_obj.operand[i];
+ if (op->type == UD_OP_JIMM){
+ uint64_t pc = ud_obj.pc;
+
+ switch (op->size) {
+ case 8:
+ pc += op->lval.sbyte;
+ break;
+ case 16:
+ pc += op->lval.sword;
+ break;
+ case 32:
+ pc += op->lval.sdword;
+ break;
+ default:
+ break;
+ }
+ if(pc > max_jmp_pc)
+ max_jmp_pc = pc;
+ }
+ }
+ }
+
+ if (ud_insn_off(&ud_obj) >= max_jmp_pc && ud_obj.mnemonic == UD_Iret)
+ break;
+ }
+ debug_printf("\n");
+#else
+ (void)func;
+#endif
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_debug.h b/src/gallium/drivers/llvmpipe/lp_bld_debug.h
new file mode 100644
index 0000000000..583e6132b4
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_debug.h
@@ -0,0 +1,64 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_BLD_DEBUG_H
+#define LP_BLD_DEBUG_H
+
+
+#include <llvm-c/Core.h>
+
+#include "pipe/p_compiler.h"
+#include "util/u_string.h"
+
+
+static INLINE void
+lp_build_name(LLVMValueRef val, const char *format, ...)
+{
+#ifdef DEBUG
+ char name[32];
+ va_list ap;
+ va_start(ap, format);
+ util_vsnprintf(name, sizeof name, format, ap);
+ va_end(ap);
+ LLVMSetValueName(val, name);
+#else
+ (void)val;
+ (void)format;
+#endif
+}
+
+
+boolean
+lp_check_alignment(const void *ptr, unsigned alignment);
+
+
+void
+lp_disassemble(const void* func);
+
+
+#endif /* !LP_BLD_DEBUG_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_depth.c b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
new file mode 100644
index 0000000000..21c665c4d4
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.c
@@ -0,0 +1,216 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Depth/stencil testing to LLVM IR translation.
+ *
+ * To be done accurately/efficiently the depth/stencil test must be done with
+ * the same type/format of the depth/stencil buffer, which implies massaging
+ * the incoming depths to fit into place. Using a more straightforward
+ * type/format for depth/stencil values internally and only convert when
+ * flushing would avoid this, but it would most likely result in depth fighting
+ * artifacts.
+ *
+ * We are free to use a different pixel layout though. Since our basic
+ * processing unit is a quad (2x2 pixel block) we store the depth/stencil
+ * values tiled, a quad at time. That is, a depth buffer containing
+ *
+ * Z11 Z12 Z13 Z14 ...
+ * Z21 Z22 Z23 Z24 ...
+ * Z31 Z32 Z33 Z34 ...
+ * Z41 Z42 Z43 Z44 ...
+ * ... ... ... ... ...
+ *
+ * will actually be stored in memory as
+ *
+ * Z11 Z12 Z21 Z22 Z13 Z14 Z23 Z24 ...
+ * Z31 Z32 Z41 Z42 Z33 Z34 Z43 Z44 ...
+ * ... ... ... ... ... ... ... ... ...
+ *
+ * FIXME: Code generate stencil test
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_flow.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_depth.h"
+
+
+/**
+ * Return a type appropriate for depth/stencil testing.
+ */
+struct lp_type
+lp_depth_type(const struct util_format_description *format_desc,
+ unsigned length)
+{
+ struct lp_type type;
+ unsigned swizzle;
+
+ assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+
+ swizzle = format_desc->swizzle[0];
+ assert(swizzle < 4);
+
+ memset(&type, 0, sizeof type);
+ type.width = format_desc->block.bits;
+
+ if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_FLOAT) {
+ type.floating = TRUE;
+ assert(swizzle = 0);
+ assert(format_desc->channel[swizzle].size == format_desc->block.bits);
+ }
+ else if(format_desc->channel[swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED) {
+ assert(format_desc->block.bits <= 32);
+ if(format_desc->channel[swizzle].normalized)
+ type.norm = TRUE;
+ }
+ else
+ assert(0);
+
+ assert(type.width <= length);
+ type.length = length / type.width;
+
+ return type;
+}
+
+
+/**
+ * Depth test.
+ */
+void
+lp_build_depth_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *state,
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef src,
+ LLVMValueRef dst_ptr)
+{
+ struct lp_build_context bld;
+ unsigned z_swizzle;
+ LLVMValueRef dst;
+ LLVMValueRef z_bitmask = NULL;
+ LLVMValueRef test;
+
+ if(!state->enabled)
+ return;
+
+ assert(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+
+ z_swizzle = format_desc->swizzle[0];
+ if(z_swizzle == UTIL_FORMAT_SWIZZLE_NONE)
+ return;
+
+ /* Sanity checking */
+ assert(z_swizzle < 4);
+ assert(format_desc->block.bits == type.width);
+ if(type.floating) {
+ assert(z_swizzle == 0);
+ assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_FLOAT);
+ assert(format_desc->channel[z_swizzle].size == format_desc->block.bits);
+ }
+ else {
+ assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(format_desc->channel[z_swizzle].normalized);
+ assert(!type.fixed);
+ assert(!type.sign);
+ assert(type.norm);
+ }
+
+ /* Setup build context */
+ lp_build_context_init(&bld, builder, type);
+
+ dst = LLVMBuildLoad(builder, dst_ptr, "");
+
+ lp_build_name(dst, "zsbuf");
+
+ /* Align the source depth bits with the destination's, and mask out any
+ * stencil or padding bits from both */
+ if(format_desc->channel[z_swizzle].size == format_desc->block.bits) {
+ assert(z_swizzle == 0);
+ /* nothing to do */
+ }
+ else {
+ unsigned padding_left;
+ unsigned padding_right;
+ unsigned chan;
+
+ assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(format_desc->channel[z_swizzle].type == UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(format_desc->channel[z_swizzle].size <= format_desc->block.bits);
+ assert(format_desc->channel[z_swizzle].normalized);
+
+ padding_right = 0;
+ for(chan = 0; chan < z_swizzle; ++chan)
+ padding_right += format_desc->channel[chan].size;
+ padding_left = format_desc->block.bits -
+ (padding_right + format_desc->channel[z_swizzle].size);
+
+ if(padding_left || padding_right) {
+ const unsigned long long mask_left = ((unsigned long long)1 << (format_desc->block.bits - padding_left)) - 1;
+ const unsigned long long mask_right = ((unsigned long long)1 << (padding_right)) - 1;
+ z_bitmask = lp_build_int_const_scalar(type, mask_left ^ mask_right);
+ }
+
+ if(padding_left)
+ src = LLVMBuildLShr(builder, src, lp_build_int_const_scalar(type, padding_left), "");
+ if(padding_right)
+ src = LLVMBuildAnd(builder, src, z_bitmask, "");
+ if(padding_left || padding_right)
+ dst = LLVMBuildAnd(builder, dst, z_bitmask, "");
+ }
+
+ lp_build_name(dst, "zsbuf.z");
+
+ test = lp_build_cmp(&bld, state->func, src, dst);
+ lp_build_mask_update(mask, test);
+
+ if(state->writemask) {
+ if(z_bitmask)
+ z_bitmask = LLVMBuildAnd(builder, mask->value, z_bitmask, "");
+ else
+ z_bitmask = mask->value;
+
+ dst = lp_build_select(&bld, z_bitmask, src, dst);
+ 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
new file mode 100644
index 0000000000..79d6981bb5
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_depth.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * Depth/stencil testing to LLVM IR translation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_DEPTH_H
+#define LP_BLD_DEPTH_H
+
+
+#include <llvm-c/Core.h>
+
+
+struct pipe_depth_state;
+struct util_format_description;
+struct lp_type;
+struct lp_build_mask_context;
+
+
+struct lp_type
+lp_depth_type(const struct util_format_description *format_desc,
+ unsigned length);
+
+
+void
+lp_build_depth_test(LLVMBuilderRef builder,
+ const struct pipe_depth_state *state,
+ struct lp_type type,
+ const struct util_format_description *format_desc,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef src,
+ LLVMValueRef dst_ptr);
+
+
+#endif /* !LP_BLD_DEPTH_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.c b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
new file mode 100644
index 0000000000..dcc25fbff8
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.c
@@ -0,0 +1,493 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * LLVM control flow build helpers.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_flow.h"
+
+
+#define LP_BUILD_FLOW_MAX_VARIABLES 32
+#define LP_BUILD_FLOW_MAX_DEPTH 32
+
+
+/**
+ * Enumeration of all possible flow constructs.
+ */
+enum lp_build_flow_construct_kind {
+ lP_BUILD_FLOW_SCOPE,
+ LP_BUILD_FLOW_SKIP,
+};
+
+
+/**
+ * Variable declaration scope.
+ */
+struct lp_build_flow_scope
+{
+ /** Number of variables declared in this scope */
+ unsigned num_variables;
+};
+
+
+/**
+ * Early exit. Useful to skip to the end of a function or block when
+ * the execution mask becomes zero or when there is an error condition.
+ */
+struct lp_build_flow_skip
+{
+ /** Block to skip to */
+ LLVMBasicBlockRef block;
+
+ /** Number of variables declared at the beginning */
+ unsigned num_variables;
+
+ LLVMValueRef *phi;
+};
+
+
+/**
+ * Union of all possible flow constructs' data
+ */
+union lp_build_flow_construct_data
+{
+ struct lp_build_flow_scope scope;
+ struct lp_build_flow_skip skip;
+};
+
+
+/**
+ * Element of the flow construct stack.
+ */
+struct lp_build_flow_construct
+{
+ enum lp_build_flow_construct_kind kind;
+ union lp_build_flow_construct_data data;
+};
+
+
+/**
+ * All necessary data to generate LLVM control flow constructs.
+ *
+ * Besides keeping track of the control flow construct themselves we also
+ * need to keep track of variables in order to generate SSA Phi values.
+ */
+struct lp_build_flow_context
+{
+ LLVMBuilderRef builder;
+
+ /**
+ * Control flow stack.
+ */
+ struct lp_build_flow_construct constructs[LP_BUILD_FLOW_MAX_DEPTH];
+ unsigned num_constructs;
+
+ /**
+ * Variable stack
+ */
+ LLVMValueRef *variables[LP_BUILD_FLOW_MAX_VARIABLES];
+ unsigned num_variables;
+};
+
+
+struct lp_build_flow_context *
+lp_build_flow_create(LLVMBuilderRef builder)
+{
+ struct lp_build_flow_context *flow;
+
+ flow = CALLOC_STRUCT(lp_build_flow_context);
+ if(!flow)
+ return NULL;
+
+ flow->builder = builder;
+
+ return flow;
+}
+
+
+void
+lp_build_flow_destroy(struct lp_build_flow_context *flow)
+{
+ assert(flow->num_constructs == 0);
+ assert(flow->num_variables == 0);
+ FREE(flow);
+}
+
+
+static union lp_build_flow_construct_data *
+lp_build_flow_push(struct lp_build_flow_context *flow,
+ enum lp_build_flow_construct_kind kind)
+{
+ assert(flow->num_constructs < LP_BUILD_FLOW_MAX_DEPTH);
+ if(flow->num_constructs >= LP_BUILD_FLOW_MAX_DEPTH)
+ return NULL;
+
+ flow->constructs[flow->num_constructs].kind = kind;
+ return &flow->constructs[flow->num_constructs++].data;
+}
+
+
+static union lp_build_flow_construct_data *
+lp_build_flow_peek(struct lp_build_flow_context *flow,
+ enum lp_build_flow_construct_kind kind)
+{
+ assert(flow->num_constructs);
+ if(!flow->num_constructs)
+ return NULL;
+
+ assert(flow->constructs[flow->num_constructs - 1].kind == kind);
+ if(flow->constructs[flow->num_constructs - 1].kind != kind)
+ return NULL;
+
+ return &flow->constructs[flow->num_constructs - 1].data;
+}
+
+
+static union lp_build_flow_construct_data *
+lp_build_flow_pop(struct lp_build_flow_context *flow,
+ enum lp_build_flow_construct_kind kind)
+{
+ assert(flow->num_constructs);
+ if(!flow->num_constructs)
+ return NULL;
+
+ assert(flow->constructs[flow->num_constructs - 1].kind == kind);
+ if(flow->constructs[flow->num_constructs - 1].kind != kind)
+ return NULL;
+
+ return &flow->constructs[--flow->num_constructs].data;
+}
+
+
+/**
+ * Begin a variable scope.
+ *
+ *
+ */
+void
+lp_build_flow_scope_begin(struct lp_build_flow_context *flow)
+{
+ struct lp_build_flow_scope *scope;
+
+ scope = &lp_build_flow_push(flow, lP_BUILD_FLOW_SCOPE)->scope;
+ if(!scope)
+ return;
+
+ scope->num_variables = 0;
+}
+
+
+/**
+ * Declare a variable.
+ *
+ * A variable is a named entity which can have different LLVMValueRef's at
+ * different points of the program. This is relevant for control flow because
+ * when there are mutiple branches to a same location we need to replace
+ * the variable's value with a Phi function as explained in
+ * http://en.wikipedia.org/wiki/Static_single_assignment_form .
+ *
+ * We keep track of variables by keeping around a pointer to where their
+ * current.
+ *
+ * There are a few cautions to observe:
+ *
+ * - Variable's value must not be NULL. If there is no initial value then
+ * LLVMGetUndef() should be used.
+ *
+ * - Variable's value must be kept up-to-date. If the variable is going to be
+ * modified by a function then a pointer should be passed so that its value
+ * is accurate. Failure to do this will cause some of the variables'
+ * transient values to be lost, leading to wrong results.
+ *
+ * - A program should be written from top to bottom, by always appending
+ * instructions to the bottom with a single LLVMBuilderRef. Inserting and/or
+ * modifying existing statements will most likely lead to wrong results.
+ *
+ */
+void
+lp_build_flow_scope_declare(struct lp_build_flow_context *flow,
+ LLVMValueRef *variable)
+{
+ struct lp_build_flow_scope *scope;
+
+ scope = &lp_build_flow_peek(flow, lP_BUILD_FLOW_SCOPE)->scope;
+ if(!scope)
+ return;
+
+ assert(*variable);
+ if(!*variable)
+ return;
+
+ assert(flow->num_variables < LP_BUILD_FLOW_MAX_VARIABLES);
+ if(flow->num_variables >= LP_BUILD_FLOW_MAX_VARIABLES)
+ return;
+
+ flow->variables[flow->num_variables++] = variable;
+ ++scope->num_variables;
+}
+
+
+void
+lp_build_flow_scope_end(struct lp_build_flow_context *flow)
+{
+ struct lp_build_flow_scope *scope;
+
+ scope = &lp_build_flow_pop(flow, lP_BUILD_FLOW_SCOPE)->scope;
+ if(!scope)
+ return;
+
+ assert(flow->num_variables >= scope->num_variables);
+ if(flow->num_variables < scope->num_variables) {
+ flow->num_variables = 0;
+ return;
+ }
+
+ flow->num_variables -= scope->num_variables;
+}
+
+
+static LLVMBasicBlockRef
+lp_build_flow_insert_block(struct lp_build_flow_context *flow)
+{
+ LLVMBasicBlockRef current_block;
+ LLVMBasicBlockRef next_block;
+ LLVMBasicBlockRef new_block;
+
+ current_block = LLVMGetInsertBlock(flow->builder);
+
+ next_block = LLVMGetNextBasicBlock(current_block);
+ if(next_block) {
+ new_block = LLVMInsertBasicBlock(next_block, "");
+ }
+ else {
+ LLVMValueRef function = LLVMGetBasicBlockParent(current_block);
+ new_block = LLVMAppendBasicBlock(function, "");
+ }
+
+ return new_block;
+}
+
+void
+lp_build_flow_skip_begin(struct lp_build_flow_context *flow)
+{
+ struct lp_build_flow_skip *skip;
+ LLVMBuilderRef builder;
+ unsigned i;
+
+ skip = &lp_build_flow_push(flow, LP_BUILD_FLOW_SKIP)->skip;
+ if(!skip)
+ return;
+
+ skip->block = lp_build_flow_insert_block(flow);
+ skip->num_variables = flow->num_variables;
+ if(!skip->num_variables) {
+ skip->phi = NULL;
+ return;
+ }
+
+ skip->phi = MALLOC(skip->num_variables * sizeof *skip->phi);
+ if(!skip->phi) {
+ skip->num_variables = 0;
+ return;
+ }
+
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, skip->block);
+
+ for(i = 0; i < skip->num_variables; ++i)
+ skip->phi[i] = LLVMBuildPhi(builder, LLVMTypeOf(*flow->variables[i]), "");
+
+ LLVMDisposeBuilder(builder);
+}
+
+
+void
+lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
+ LLVMValueRef cond)
+{
+ struct lp_build_flow_skip *skip;
+ LLVMBasicBlockRef current_block;
+ LLVMBasicBlockRef new_block;
+ unsigned i;
+
+ skip = &lp_build_flow_peek(flow, LP_BUILD_FLOW_SKIP)->skip;
+ if(!skip)
+ return;
+
+ current_block = LLVMGetInsertBlock(flow->builder);
+
+ new_block = lp_build_flow_insert_block(flow);
+
+ for(i = 0; i < skip->num_variables; ++i) {
+ assert(*flow->variables[i]);
+ LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
+ }
+
+ LLVMBuildCondBr(flow->builder, cond, skip->block, new_block);
+
+ LLVMPositionBuilderAtEnd(flow->builder, new_block);
+ }
+
+
+void
+lp_build_flow_skip_end(struct lp_build_flow_context *flow)
+{
+ struct lp_build_flow_skip *skip;
+ LLVMBasicBlockRef current_block;
+ unsigned i;
+
+ skip = &lp_build_flow_pop(flow, LP_BUILD_FLOW_SKIP)->skip;
+ if(!skip)
+ return;
+
+ current_block = LLVMGetInsertBlock(flow->builder);
+
+ for(i = 0; i < skip->num_variables; ++i) {
+ assert(*flow->variables[i]);
+ LLVMAddIncoming(skip->phi[i], flow->variables[i], &current_block, 1);
+ *flow->variables[i] = skip->phi[i];
+ }
+
+ LLVMBuildBr(flow->builder, skip->block);
+ LLVMPositionBuilderAtEnd(flow->builder, skip->block);
+
+ FREE(skip->phi);
+}
+
+
+static void
+lp_build_mask_check(struct lp_build_mask_context *mask)
+{
+ LLVMBuilderRef builder = mask->flow->builder;
+ LLVMValueRef cond;
+
+ cond = LLVMBuildICmp(builder,
+ LLVMIntEQ,
+ LLVMBuildBitCast(builder, mask->value, mask->reg_type, ""),
+ LLVMConstNull(mask->reg_type),
+ "");
+
+ lp_build_flow_skip_cond_break(mask->flow, cond);
+}
+
+
+void
+lp_build_mask_begin(struct lp_build_mask_context *mask,
+ struct lp_build_flow_context *flow,
+ struct lp_type type,
+ LLVMValueRef value)
+{
+ memset(mask, 0, sizeof *mask);
+
+ mask->flow = flow;
+ mask->reg_type = LLVMIntType(type.width * type.length);
+ mask->value = value;
+
+ lp_build_flow_scope_begin(flow);
+ lp_build_flow_scope_declare(flow, &mask->value);
+ lp_build_flow_skip_begin(flow);
+
+ lp_build_mask_check(mask);
+}
+
+
+void
+lp_build_mask_update(struct lp_build_mask_context *mask,
+ LLVMValueRef value)
+{
+ mask->value = LLVMBuildAnd( mask->flow->builder, mask->value, value, "");
+
+ lp_build_mask_check(mask);
+}
+
+
+LLVMValueRef
+lp_build_mask_end(struct lp_build_mask_context *mask)
+{
+ lp_build_flow_skip_end(mask->flow);
+ lp_build_flow_scope_end(mask->flow);
+ return mask->value;
+}
+
+
+
+void
+lp_build_loop_begin(LLVMBuilderRef builder,
+ LLVMValueRef start,
+ struct lp_build_loop_state *state)
+{
+ LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+ LLVMValueRef function = LLVMGetBasicBlockParent(block);
+
+ state->block = LLVMAppendBasicBlock(function, "loop");
+
+ LLVMBuildBr(builder, state->block);
+
+ LLVMPositionBuilderAtEnd(builder, state->block);
+
+ state->counter = LLVMBuildPhi(builder, LLVMTypeOf(start), "");
+
+ LLVMAddIncoming(state->counter, &start, &block, 1);
+
+}
+
+
+void
+lp_build_loop_end(LLVMBuilderRef builder,
+ LLVMValueRef end,
+ LLVMValueRef step,
+ struct lp_build_loop_state *state)
+{
+ LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
+ LLVMValueRef function = LLVMGetBasicBlockParent(block);
+ LLVMValueRef next;
+ LLVMValueRef cond;
+ LLVMBasicBlockRef after_block;
+
+ if (!step)
+ step = LLVMConstInt(LLVMTypeOf(end), 1, 0);
+
+ next = LLVMBuildAdd(builder, state->counter, step, "");
+
+ cond = LLVMBuildICmp(builder, LLVMIntNE, next, end, "");
+
+ after_block = LLVMAppendBasicBlock(function, "");
+
+ LLVMBuildCondBr(builder, cond, after_block, state->block);
+
+ LLVMAddIncoming(state->counter, &next, &block, 1);
+
+ LLVMPositionBuilderAtEnd(builder, after_block);
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_flow.h b/src/gallium/drivers/llvmpipe/lp_bld_flow.h
new file mode 100644
index 0000000000..e61999ff06
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_flow.h
@@ -0,0 +1,129 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * LLVM control flow build helpers.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_FLOW_H
+#define LP_BLD_FLOW_H
+
+
+#include <llvm-c/Core.h>
+
+
+struct lp_type;
+
+
+struct lp_build_flow_context;
+
+
+struct lp_build_flow_context *
+lp_build_flow_create(LLVMBuilderRef builder);
+
+void
+lp_build_flow_destroy(struct lp_build_flow_context *flow);
+
+void
+lp_build_flow_scope_begin(struct lp_build_flow_context *flow);
+
+void
+lp_build_flow_scope_declare(struct lp_build_flow_context *flow,
+ LLVMValueRef *variable);
+
+void
+lp_build_flow_scope_end(struct lp_build_flow_context *flow);
+
+void
+lp_build_flow_skip_begin(struct lp_build_flow_context *flow);
+
+void
+lp_build_flow_skip_cond_break(struct lp_build_flow_context *flow,
+ LLVMValueRef cond);
+
+void
+lp_build_flow_skip_end(struct lp_build_flow_context *flow);
+
+
+struct lp_build_mask_context
+{
+ struct lp_build_flow_context *flow;
+
+ LLVMTypeRef reg_type;
+
+ LLVMValueRef value;
+};
+
+
+void
+lp_build_mask_begin(struct lp_build_mask_context *mask,
+ struct lp_build_flow_context *flow,
+ struct lp_type type,
+ LLVMValueRef value);
+
+/**
+ * Bitwise AND the mask with the given value, if a previous mask was set.
+ */
+void
+lp_build_mask_update(struct lp_build_mask_context *mask,
+ LLVMValueRef value);
+
+LLVMValueRef
+lp_build_mask_end(struct lp_build_mask_context *mask);
+
+
+/**
+ * LLVM's IR doesn't represent for-loops directly. Furthermore it
+ * it requires creating code blocks, branches, phi variables, so it
+ * requires a fair amount of code.
+ *
+ * @sa http://www.llvm.org/docs/tutorial/LangImpl5.html#for
+ */
+struct lp_build_loop_state
+{
+ LLVMBasicBlockRef block;
+ LLVMValueRef counter;
+};
+
+
+void
+lp_build_loop_begin(LLVMBuilderRef builder,
+ LLVMValueRef start,
+ struct lp_build_loop_state *state);
+
+
+void
+lp_build_loop_end(LLVMBuilderRef builder,
+ LLVMValueRef end,
+ LLVMValueRef step,
+ struct lp_build_loop_state *state);
+
+
+
+#endif /* !LP_BLD_FLOW_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format.h b/src/gallium/drivers/llvmpipe/lp_bld_format.h
new file mode 100644
index 0000000000..6d3f692619
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format.h
@@ -0,0 +1,119 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_BLD_H
+#define LP_BLD_H
+
+
+/**
+ * @file
+ * Pixel format helpers.
+ */
+
+#include <llvm-c/Core.h>
+
+#include "pipe/p_format.h"
+
+struct util_format_description;
+struct lp_type;
+
+
+/**
+ * Unpack a pixel into its RGBA components.
+ *
+ * @param packed integer.
+ *
+ * @return RGBA in a 4 floats vector.
+ */
+LLVMValueRef
+lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef packed);
+
+
+/**
+ * Pack a pixel.
+ *
+ * @param rgba 4 float vector with the unpacked components.
+ */
+LLVMValueRef
+lp_build_pack_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef rgba);
+
+
+/**
+ * Load a pixel into its RGBA components.
+ *
+ * @param ptr value with the pointer to the packed pixel. Pointer type is
+ * irrelevant.
+ *
+ * @return RGBA in a 4 floats vector.
+ */
+LLVMValueRef
+lp_build_load_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef ptr);
+
+
+/**
+ * Store a pixel.
+ *
+ * @param rgba 4 float vector with the unpacked components.
+ */
+void
+lp_build_store_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef ptr,
+ LLVMValueRef rgba);
+
+LLVMValueRef
+lp_build_gather(LLVMBuilderRef builder,
+ unsigned length,
+ unsigned src_width,
+ unsigned dst_width,
+ LLVMValueRef base_ptr,
+ LLVMValueRef offsets);
+
+
+void
+lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
+ const struct util_format_description *format_desc,
+ struct lp_type type,
+ LLVMValueRef packed,
+ LLVMValueRef *rgba);
+
+
+void
+lp_build_load_rgba_soa(LLVMBuilderRef builder,
+ const struct util_format_description *format_desc,
+ struct lp_type type,
+ LLVMValueRef base_ptr,
+ LLVMValueRef offsets,
+ LLVMValueRef *rgba);
+
+#endif /* !LP_BLD_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
new file mode 100644
index 0000000000..b9b5d84bed
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format_aos.c
@@ -0,0 +1,303 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_format.h"
+
+#include "lp_bld_format.h"
+
+
+LLVMValueRef
+lp_build_unpack_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef packed)
+{
+ const struct util_format_description *desc;
+ LLVMTypeRef type;
+ LLVMValueRef shifted, casted, scaled, masked;
+ LLVMValueRef shifts[4];
+ LLVMValueRef masks[4];
+ LLVMValueRef scales[4];
+ LLVMValueRef swizzles[4];
+ LLVMValueRef aux[4];
+ bool normalized;
+ int empty_channel;
+ unsigned shift;
+ unsigned i;
+
+ desc = util_format_description(format);
+
+ /* FIXME: Support more formats */
+ assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(desc->block.width == 1);
+ assert(desc->block.height == 1);
+ assert(desc->block.bits <= 32);
+
+ type = LLVMIntType(desc->block.bits);
+
+ /* Do the intermediate integer computations with 32bit integers since it
+ * matches floating point size */
+ if (desc->block.bits < 32)
+ packed = LLVMBuildZExt(builder, packed, LLVMInt32Type(), "");
+
+ /* Broadcast the packed value to all four channels */
+ packed = LLVMBuildInsertElement(builder,
+ LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
+ packed,
+ LLVMConstNull(LLVMInt32Type()),
+ "");
+ packed = LLVMBuildShuffleVector(builder,
+ packed,
+ LLVMGetUndef(LLVMVectorType(LLVMInt32Type(), 4)),
+ LLVMConstNull(LLVMVectorType(LLVMInt32Type(), 4)),
+ "");
+
+ /* Initialize vector constants */
+ normalized = FALSE;
+ empty_channel = -1;
+ shift = 0;
+ for (i = 0; i < 4; ++i) {
+ unsigned bits = desc->channel[i].size;
+
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
+ shifts[i] = LLVMGetUndef(LLVMInt32Type());
+ masks[i] = LLVMConstNull(LLVMInt32Type());
+ scales[i] = LLVMConstNull(LLVMFloatType());
+ empty_channel = i;
+ }
+ else {
+ unsigned mask = (1 << bits) - 1;
+
+ assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(bits < 32);
+
+ shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
+ masks[i] = LLVMConstInt(LLVMInt32Type(), mask, 0);
+
+ if (desc->channel[i].normalized) {
+ scales[i] = LLVMConstReal(LLVMFloatType(), 1.0/mask);
+ normalized = TRUE;
+ }
+ else
+ scales[i] = LLVMConstReal(LLVMFloatType(), 1.0);
+ }
+
+ shift += bits;
+ }
+
+ shifted = LLVMBuildLShr(builder, packed, LLVMConstVector(shifts, 4), "");
+ masked = LLVMBuildAnd(builder, shifted, LLVMConstVector(masks, 4), "");
+ // UIToFP can't be expressed in SSE2
+ casted = LLVMBuildSIToFP(builder, masked, LLVMVectorType(LLVMFloatType(), 4), "");
+
+ if (normalized)
+ scaled = LLVMBuildMul(builder, casted, LLVMConstVector(scales, 4), "");
+ else
+ scaled = casted;
+
+ for (i = 0; i < 4; ++i)
+ aux[i] = LLVMGetUndef(LLVMFloatType());
+
+ for (i = 0; i < 4; ++i) {
+ enum util_format_swizzle swizzle = desc->swizzle[i];
+
+ switch (swizzle) {
+ case UTIL_FORMAT_SWIZZLE_X:
+ case UTIL_FORMAT_SWIZZLE_Y:
+ case UTIL_FORMAT_SWIZZLE_Z:
+ case UTIL_FORMAT_SWIZZLE_W:
+ swizzles[i] = LLVMConstInt(LLVMInt32Type(), swizzle, 0);
+ break;
+ case UTIL_FORMAT_SWIZZLE_0:
+ assert(empty_channel >= 0);
+ swizzles[i] = LLVMConstInt(LLVMInt32Type(), empty_channel, 0);
+ break;
+ case UTIL_FORMAT_SWIZZLE_1:
+ swizzles[i] = LLVMConstInt(LLVMInt32Type(), 4, 0);
+ aux[0] = LLVMConstReal(LLVMFloatType(), 1.0);
+ break;
+ case UTIL_FORMAT_SWIZZLE_NONE:
+ swizzles[i] = LLVMGetUndef(LLVMFloatType());
+ assert(0);
+ break;
+ }
+ }
+
+ return LLVMBuildShuffleVector(builder, scaled, LLVMConstVector(aux, 4), LLVMConstVector(swizzles, 4), "");
+}
+
+
+LLVMValueRef
+lp_build_pack_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef rgba)
+{
+ const struct util_format_description *desc;
+ LLVMTypeRef type;
+ LLVMValueRef packed = NULL;
+ LLVMValueRef swizzles[4];
+ LLVMValueRef shifted, casted, scaled, unswizzled;
+ LLVMValueRef shifts[4];
+ LLVMValueRef scales[4];
+ bool normalized;
+ unsigned shift;
+ unsigned i, j;
+
+ desc = util_format_description(format);
+
+ assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(desc->block.width == 1);
+ assert(desc->block.height == 1);
+
+ type = LLVMIntType(desc->block.bits);
+
+ /* Unswizzle the color components into the source vector. */
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 4; ++j) {
+ if (desc->swizzle[j] == i)
+ break;
+ }
+ if (j < 4)
+ swizzles[i] = LLVMConstInt(LLVMInt32Type(), j, 0);
+ else
+ swizzles[i] = LLVMGetUndef(LLVMInt32Type());
+ }
+
+ unswizzled = LLVMBuildShuffleVector(builder, rgba,
+ LLVMGetUndef(LLVMVectorType(LLVMFloatType(), 4)),
+ LLVMConstVector(swizzles, 4), "");
+
+ normalized = FALSE;
+ shift = 0;
+ for (i = 0; i < 4; ++i) {
+ unsigned bits = desc->channel[i].size;
+
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_VOID) {
+ shifts[i] = LLVMGetUndef(LLVMInt32Type());
+ scales[i] = LLVMGetUndef(LLVMFloatType());
+ }
+ else {
+ unsigned mask = (1 << bits) - 1;
+
+ assert(desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED);
+ assert(bits < 32);
+
+ shifts[i] = LLVMConstInt(LLVMInt32Type(), shift, 0);
+
+ if (desc->channel[i].normalized) {
+ scales[i] = LLVMConstReal(LLVMFloatType(), mask);
+ normalized = TRUE;
+ }
+ else
+ scales[i] = LLVMConstReal(LLVMFloatType(), 1.0);
+ }
+
+ shift += bits;
+ }
+
+ if (normalized)
+ scaled = LLVMBuildMul(builder, unswizzled, LLVMConstVector(scales, 4), "");
+ else
+ scaled = unswizzled;
+
+ casted = LLVMBuildFPToSI(builder, scaled, LLVMVectorType(LLVMInt32Type(), 4), "");
+
+ shifted = LLVMBuildShl(builder, casted, LLVMConstVector(shifts, 4), "");
+
+ /* Bitwise or all components */
+ for (i = 0; i < 4; ++i) {
+ if (desc->channel[i].type == UTIL_FORMAT_TYPE_UNSIGNED) {
+ LLVMValueRef component = LLVMBuildExtractElement(builder, shifted, LLVMConstInt(LLVMInt32Type(), i, 0), "");
+ if (packed)
+ packed = LLVMBuildOr(builder, packed, component, "");
+ else
+ packed = component;
+ }
+ }
+
+ if (!packed)
+ packed = LLVMGetUndef(LLVMInt32Type());
+
+ if (desc->block.bits < 32)
+ packed = LLVMBuildTrunc(builder, packed, type, "");
+
+ return packed;
+}
+
+
+LLVMValueRef
+lp_build_load_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef ptr)
+{
+ const struct util_format_description *desc;
+ LLVMTypeRef type;
+ LLVMValueRef packed;
+
+ desc = util_format_description(format);
+
+ /* FIXME: Support more formats */
+ assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(desc->block.width == 1);
+ assert(desc->block.height == 1);
+ assert(desc->block.bits <= 32);
+
+ type = LLVMIntType(desc->block.bits);
+
+ ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
+
+ packed = LLVMBuildLoad(builder, ptr, "");
+
+ return lp_build_unpack_rgba_aos(builder, format, packed);
+}
+
+
+void
+lp_build_store_rgba_aos(LLVMBuilderRef builder,
+ enum pipe_format format,
+ LLVMValueRef ptr,
+ LLVMValueRef rgba)
+{
+ const struct util_format_description *desc;
+ LLVMTypeRef type;
+ LLVMValueRef packed;
+
+ desc = util_format_description(format);
+
+ assert(desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(desc->block.width == 1);
+ assert(desc->block.height == 1);
+
+ type = LLVMIntType(desc->block.bits);
+
+ packed = lp_build_pack_rgba_aos(builder, format, rgba);
+
+ ptr = LLVMBuildBitCast(builder, ptr, LLVMPointerType(type, 0), "");
+
+ LLVMBuildStore(builder, packed, ptr);
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c
new file mode 100644
index 0000000000..b5ff434e1a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_format_soa.c
@@ -0,0 +1,208 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_format.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_conv.h"
+#include "lp_bld_format.h"
+
+
+/**
+ * Gather elements from scatter positions in memory into a single vector.
+ *
+ * @param src_width src element width
+ * @param dst_width result element width (source will be expanded to fit)
+ * @param length length of the offsets,
+ * @param base_ptr base pointer, should be a i8 pointer type.
+ * @param offsets vector with offsets
+ */
+LLVMValueRef
+lp_build_gather(LLVMBuilderRef builder,
+ unsigned length,
+ unsigned src_width,
+ unsigned dst_width,
+ LLVMValueRef base_ptr,
+ LLVMValueRef offsets)
+{
+ LLVMTypeRef src_type = LLVMIntType(src_width);
+ LLVMTypeRef src_ptr_type = LLVMPointerType(src_type, 0);
+ LLVMTypeRef dst_elem_type = LLVMIntType(dst_width);
+ LLVMTypeRef dst_vec_type = LLVMVectorType(dst_elem_type, length);
+ LLVMValueRef res;
+ unsigned i;
+
+ res = LLVMGetUndef(dst_vec_type);
+ for(i = 0; i < length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef elem_offset;
+ LLVMValueRef elem_ptr;
+ LLVMValueRef elem;
+
+ elem_offset = LLVMBuildExtractElement(builder, offsets, index, "");
+ elem_ptr = LLVMBuildGEP(builder, base_ptr, &elem_offset, 1, "");
+ elem_ptr = LLVMBuildBitCast(builder, elem_ptr, src_ptr_type, "");
+ elem = LLVMBuildLoad(builder, elem_ptr, "");
+
+ assert(src_width <= dst_width);
+ if(src_width > dst_width)
+ elem = LLVMBuildTrunc(builder, elem, dst_elem_type, "");
+ if(src_width < dst_width)
+ elem = LLVMBuildZExt(builder, elem, dst_elem_type, "");
+
+ res = LLVMBuildInsertElement(builder, res, elem, index, "");
+ }
+
+ return res;
+}
+
+
+static LLVMValueRef
+lp_build_format_swizzle(struct lp_type type,
+ const LLVMValueRef *inputs,
+ enum util_format_swizzle swizzle)
+{
+ switch (swizzle) {
+ case UTIL_FORMAT_SWIZZLE_X:
+ case UTIL_FORMAT_SWIZZLE_Y:
+ case UTIL_FORMAT_SWIZZLE_Z:
+ case UTIL_FORMAT_SWIZZLE_W:
+ return inputs[swizzle];
+ case UTIL_FORMAT_SWIZZLE_0:
+ return lp_build_zero(type);
+ case UTIL_FORMAT_SWIZZLE_1:
+ return lp_build_one(type);
+ case UTIL_FORMAT_SWIZZLE_NONE:
+ return lp_build_undef(type);
+ default:
+ assert(0);
+ return lp_build_undef(type);
+ }
+}
+
+
+void
+lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
+ const struct util_format_description *format_desc,
+ struct lp_type type,
+ LLVMValueRef packed,
+ LLVMValueRef *rgba)
+{
+ LLVMValueRef inputs[4];
+ unsigned start;
+ unsigned chan;
+
+ /* FIXME: Support more formats */
+ assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+ assert(format_desc->block.bits <= 32);
+
+ /* Decode the input vector components */
+ start = 0;
+ for (chan = 0; chan < 4; ++chan) {
+ unsigned width = format_desc->channel[chan].size;
+ unsigned stop = start + width;
+ LLVMValueRef input;
+
+ input = packed;
+
+ switch(format_desc->channel[chan].type) {
+ case UTIL_FORMAT_TYPE_VOID:
+ input = NULL;
+ break;
+
+ case UTIL_FORMAT_TYPE_UNSIGNED:
+ if(type.floating) {
+ if(start)
+ input = LLVMBuildLShr(builder, input, lp_build_int_const_scalar(type, start), "");
+ if(stop < format_desc->block.bits) {
+ unsigned mask = ((unsigned long long)1 << width) - 1;
+ input = LLVMBuildAnd(builder, input, lp_build_int_const_scalar(type, mask), "");
+ }
+
+ if(format_desc->channel[chan].normalized)
+ input = lp_build_unsigned_norm_to_float(builder, width, type, input);
+ else
+ input = LLVMBuildFPToSI(builder, input, lp_build_vec_type(type), "");
+ }
+ else {
+ /* FIXME */
+ assert(0);
+ input = lp_build_undef(type);
+ }
+ break;
+
+ default:
+ /* fall through */
+ input = lp_build_undef(type);
+ break;
+ }
+
+ inputs[chan] = input;
+
+ start = stop;
+ }
+
+ if(format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
+ enum util_format_swizzle swizzle = format_desc->swizzle[0];
+ LLVMValueRef depth = lp_build_format_swizzle(type, inputs, swizzle);
+ rgba[2] = rgba[1] = rgba[0] = depth;
+ rgba[3] = lp_build_one(type);
+ }
+ else {
+ for (chan = 0; chan < 4; ++chan) {
+ enum util_format_swizzle swizzle = format_desc->swizzle[chan];
+ rgba[chan] = lp_build_format_swizzle(type, inputs, swizzle);
+ }
+ }
+}
+
+
+void
+lp_build_load_rgba_soa(LLVMBuilderRef builder,
+ const struct util_format_description *format_desc,
+ struct lp_type type,
+ LLVMValueRef base_ptr,
+ LLVMValueRef offsets,
+ LLVMValueRef *rgba)
+{
+ LLVMValueRef packed;
+
+ assert(format_desc->layout == UTIL_FORMAT_LAYOUT_ARITH);
+ assert(format_desc->block.width == 1);
+ assert(format_desc->block.height == 1);
+ assert(format_desc->block.bits <= 32);
+
+ packed = lp_build_gather(builder,
+ type.length, format_desc->block.bits, type.width,
+ base_ptr, offsets);
+
+ lp_build_unpack_rgba_soa(builder, format_desc, type, packed, rgba);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.c b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
new file mode 100644
index 0000000000..338dbca6d1
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.c
@@ -0,0 +1,377 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * Copyright 2007-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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Position and shader input interpolation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_shader_tokens.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "tgsi/tgsi_parse.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_const.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_interp.h"
+
+
+static void
+attrib_name(LLVMValueRef val, unsigned attrib, unsigned chan, const char *suffix)
+{
+ if(attrib == 0)
+ lp_build_name(val, "pos.%c%s", "xyzw"[chan], suffix);
+ else
+ lp_build_name(val, "input%u.%c%s", attrib - 1, "xyzw"[chan], suffix);
+}
+
+
+static void
+coeffs_init(struct lp_build_interp_soa_context *bld,
+ LLVMValueRef a0_ptr,
+ LLVMValueRef dadx_ptr,
+ LLVMValueRef dady_ptr)
+{
+ LLVMBuilderRef builder = bld->base.builder;
+ unsigned attrib;
+ unsigned chan;
+
+ for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ unsigned mask = bld->mask[attrib];
+ unsigned mode = bld->mode[attrib];
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(mask & (1 << chan)) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), attrib*NUM_CHANNELS + chan, 0);
+ LLVMValueRef a0 = NULL;
+ LLVMValueRef dadx = NULL;
+ LLVMValueRef dady = NULL;
+
+ switch( mode ) {
+ case TGSI_INTERPOLATE_PERSPECTIVE:
+ /* fall-through */
+
+ case TGSI_INTERPOLATE_LINEAR:
+ dadx = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dadx_ptr, &index, 1, ""), "");
+ dady = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dady_ptr, &index, 1, ""), "");
+ dadx = lp_build_broadcast_scalar(&bld->base, dadx);
+ dady = lp_build_broadcast_scalar(&bld->base, dady);
+ attrib_name(dadx, attrib, chan, ".dadx");
+ attrib_name(dady, attrib, chan, ".dady");
+ /* fall-through */
+
+ case TGSI_INTERPOLATE_CONSTANT:
+ a0 = LLVMBuildLoad(builder, LLVMBuildGEP(builder, a0_ptr, &index, 1, ""), "");
+ a0 = lp_build_broadcast_scalar(&bld->base, a0);
+ attrib_name(a0, attrib, chan, ".dady");
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+
+ bld->a0 [attrib][chan] = a0;
+ bld->dadx[attrib][chan] = dadx;
+ bld->dady[attrib][chan] = dady;
+ }
+ }
+ }
+}
+
+
+/**
+ * Small vector x scale multiplication optimization.
+ *
+ * TODO: Should be elsewhere.
+ */
+static LLVMValueRef
+coeff_multiply(struct lp_build_interp_soa_context *bld,
+ LLVMValueRef coeff,
+ int step)
+{
+ LLVMValueRef factor;
+
+ switch(step) {
+ case 0:
+ return bld->base.zero;
+ case 1:
+ return coeff;
+ case 2:
+ return lp_build_add(&bld->base, coeff, coeff);
+ default:
+ factor = lp_build_const_scalar(bld->base.type, (double)step);
+ return lp_build_mul(&bld->base, coeff, factor);
+ }
+}
+
+
+/**
+ * Multiply the dadx and dady with the xstep and ystep respectively.
+ */
+static void
+coeffs_update(struct lp_build_interp_soa_context *bld)
+{
+ unsigned attrib;
+ unsigned chan;
+
+ for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ unsigned mask = bld->mask[attrib];
+ unsigned mode = bld->mode[attrib];
+ if (mode != TGSI_INTERPOLATE_CONSTANT) {
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(mask & (1 << chan)) {
+ bld->dadx[attrib][chan] = coeff_multiply(bld, bld->dadx[attrib][chan], bld->xstep);
+ bld->dady[attrib][chan] = coeff_multiply(bld, bld->dady[attrib][chan], bld->ystep);
+ }
+ }
+ }
+ }
+}
+
+
+static void
+attribs_init(struct lp_build_interp_soa_context *bld)
+{
+ LLVMValueRef x = bld->pos[0];
+ LLVMValueRef y = bld->pos[1];
+ LLVMValueRef oow = NULL;
+ unsigned attrib;
+ unsigned chan;
+
+ for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ unsigned mask = bld->mask[attrib];
+ unsigned mode = bld->mode[attrib];
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(mask & (1 << chan)) {
+ LLVMValueRef a0 = bld->a0 [attrib][chan];
+ LLVMValueRef dadx = bld->dadx[attrib][chan];
+ LLVMValueRef dady = bld->dady[attrib][chan];
+ LLVMValueRef res;
+
+ res = a0;
+
+ if (mode != TGSI_INTERPOLATE_CONSTANT) {
+ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, x, dadx));
+ res = lp_build_add(&bld->base, res, lp_build_mul(&bld->base, y, dady));
+ }
+
+ /* Keep the value of the attribue before perspective divide for faster updates */
+ bld->attribs_pre[attrib][chan] = res;
+
+ if (mode == TGSI_INTERPOLATE_PERSPECTIVE) {
+ LLVMValueRef w = bld->pos[3];
+ assert(attrib != 0);
+ if(!oow)
+ oow = lp_build_rcp(&bld->base, w);
+ res = lp_build_mul(&bld->base, res, oow);
+ }
+
+ attrib_name(res, attrib, chan, "");
+
+ bld->attribs[attrib][chan] = res;
+ }
+ }
+ }
+}
+
+
+static void
+attribs_update(struct lp_build_interp_soa_context *bld)
+{
+ LLVMValueRef oow = NULL;
+ unsigned attrib;
+ unsigned chan;
+
+ for(attrib = 0; attrib < bld->num_attribs; ++attrib) {
+ unsigned mask = bld->mask[attrib];
+ unsigned mode = bld->mode[attrib];
+
+ if (mode != TGSI_INTERPOLATE_CONSTANT) {
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(mask & (1 << chan)) {
+ LLVMValueRef dadx = bld->dadx[attrib][chan];
+ LLVMValueRef dady = bld->dady[attrib][chan];
+ LLVMValueRef res;
+
+ res = bld->attribs_pre[attrib][chan];
+
+ if(bld->xstep)
+ res = lp_build_add(&bld->base, res, dadx);
+
+ if(bld->ystep)
+ res = lp_build_add(&bld->base, res, dady);
+
+ bld->attribs_pre[attrib][chan] = res;
+
+ if (mode == TGSI_INTERPOLATE_PERSPECTIVE) {
+ LLVMValueRef w = bld->pos[3];
+ assert(attrib != 0);
+ if(!oow)
+ oow = lp_build_rcp(&bld->base, w);
+ res = lp_build_mul(&bld->base, res, oow);
+ }
+
+ attrib_name(res, attrib, chan, "");
+
+ bld->attribs[attrib][chan] = res;
+ }
+ }
+ }
+ }
+}
+
+
+/**
+ * Generate the position vectors.
+ *
+ * Parameter x0, y0 are the integer values with the quad upper left coordinates.
+ */
+static void
+pos_init(struct lp_build_interp_soa_context *bld,
+ LLVMValueRef x0,
+ LLVMValueRef y0)
+{
+ lp_build_name(x0, "pos.x");
+ lp_build_name(y0, "pos.y");
+
+ bld->attribs[0][0] = x0;
+ bld->attribs[0][1] = y0;
+}
+
+
+static void
+pos_update(struct lp_build_interp_soa_context *bld)
+{
+ LLVMValueRef x = bld->attribs[0][0];
+ LLVMValueRef y = bld->attribs[0][1];
+
+ if(bld->xstep)
+ x = lp_build_add(&bld->base, x, lp_build_const_scalar(bld->base.type, bld->xstep));
+
+ if(bld->ystep)
+ y = lp_build_add(&bld->base, y, lp_build_const_scalar(bld->base.type, bld->ystep));
+
+ lp_build_name(x, "pos.x");
+ lp_build_name(y, "pos.y");
+
+ bld->attribs[0][0] = x;
+ bld->attribs[0][1] = y;
+}
+
+
+void
+lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
+ const struct tgsi_token *tokens,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ LLVMValueRef a0_ptr,
+ LLVMValueRef dadx_ptr,
+ LLVMValueRef dady_ptr,
+ LLVMValueRef x0,
+ LLVMValueRef y0,
+ int xstep,
+ int ystep)
+{
+ struct tgsi_parse_context parse;
+ struct tgsi_full_declaration *decl;
+
+ memset(bld, 0, sizeof *bld);
+
+ lp_build_context_init(&bld->base, builder, type);
+
+ /* For convenience */
+ bld->pos = bld->attribs[0];
+ bld->inputs = (const LLVMValueRef (*)[NUM_CHANNELS]) bld->attribs[1];
+
+ /* Position */
+ bld->num_attribs = 1;
+ bld->mask[0] = TGSI_WRITEMASK_ZW;
+ bld->mode[0] = TGSI_INTERPOLATE_LINEAR;
+
+ /* Inputs */
+ tgsi_parse_init( &parse, tokens );
+ while( !tgsi_parse_end_of_tokens( &parse ) ) {
+ tgsi_parse_token( &parse );
+
+ switch( parse.FullToken.Token.Type ) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ decl = &parse.FullToken.FullDeclaration;
+ if( decl->Declaration.File == TGSI_FILE_INPUT ) {
+ unsigned first, last, mask;
+ unsigned attrib;
+
+ first = decl->DeclarationRange.First;
+ last = decl->DeclarationRange.Last;
+ mask = decl->Declaration.UsageMask;
+
+ for( attrib = first; attrib <= last; ++attrib ) {
+ bld->mask[1 + attrib] = mask;
+ bld->mode[1 + attrib] = decl->Declaration.Interpolate;
+ }
+
+ bld->num_attribs = MAX2(bld->num_attribs, 1 + last + 1);
+ }
+ break;
+
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ break;
+
+ default:
+ assert( 0 );
+ }
+ }
+ tgsi_parse_free( &parse );
+
+ coeffs_init(bld, a0_ptr, dadx_ptr, dady_ptr);
+
+ pos_init(bld, x0, y0);
+
+ attribs_init(bld);
+
+ bld->xstep = xstep;
+ bld->ystep = ystep;
+
+ coeffs_update(bld);
+}
+
+
+/**
+ * Advance the position and inputs with the xstep and ystep.
+ */
+void
+lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld)
+{
+ pos_update(bld);
+
+ attribs_update(bld);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_interp.h b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
new file mode 100644
index 0000000000..9c57a10879
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_interp.h
@@ -0,0 +1,99 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Position and shader input interpolation.
+ *
+ * Special attention is given to the interpolation of side by side quads.
+ * Multiplications are made only for the first quad. Interpolation of
+ * inputs for posterior quads are done exclusively with additions, and
+ * perspective divide if necessary.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_INTERP_H
+#define LP_BLD_INTERP_H
+
+
+#include <llvm-c/Core.h>
+
+#include "tgsi/tgsi_exec.h"
+
+#include "lp_bld_type.h"
+
+
+struct tgsi_token;
+
+
+struct lp_build_interp_soa_context
+{
+ struct lp_build_context base;
+
+ unsigned num_attribs;
+ unsigned mask[1 + PIPE_MAX_SHADER_INPUTS];
+ unsigned mode[1 + PIPE_MAX_SHADER_INPUTS];
+
+ LLVMValueRef a0 [1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ LLVMValueRef dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ LLVMValueRef dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+
+ int xstep;
+ int ystep;
+
+ /* Attribute values before perspective divide */
+ LLVMValueRef attribs_pre[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+
+ LLVMValueRef attribs[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+
+ /*
+ * Convenience pointers. Callers may access this one.
+ */
+ const LLVMValueRef *pos;
+ const LLVMValueRef (*inputs)[NUM_CHANNELS];
+};
+
+
+void
+lp_build_interp_soa_init(struct lp_build_interp_soa_context *bld,
+ const struct tgsi_token *tokens,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ LLVMValueRef a0_ptr,
+ LLVMValueRef dadx_ptr,
+ LLVMValueRef dady_ptr,
+ LLVMValueRef x0,
+ LLVMValueRef y0,
+ int xstep,
+ int ystep);
+
+void
+lp_build_interp_soa_update(struct lp_build_interp_soa_context *bld);
+
+
+#endif /* LP_BLD_INTERP_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.c b/src/gallium/drivers/llvmpipe/lp_bld_intr.c
new file mode 100644
index 0000000000..9895749d56
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.c
@@ -0,0 +1,192 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Helpers for emiting intrinsic calls.
+ *
+ * LLVM vanilla IR doesn't represent all basic arithmetic operations we care
+ * about, and it is often necessary to resort target-specific intrinsics for
+ * performance, convenience.
+ *
+ * Ideally we would like to stay away from target specific intrinsics and
+ * move all the instruction selection logic into upstream LLVM where it belongs.
+ *
+ * These functions are also used for calling C functions provided by us from
+ * generated LLVM code.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_debug.h"
+
+#include "lp_bld_intr.h"
+
+
+LLVMValueRef
+lp_declare_intrinsic(LLVMModuleRef module,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMTypeRef *arg_types,
+ unsigned num_args)
+{
+ LLVMTypeRef function_type;
+ LLVMValueRef function;
+
+ assert(!LLVMGetNamedFunction(module, name));
+
+ function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0);
+ function = LLVMAddFunction(module, name, function_type);
+
+ LLVMSetFunctionCallConv(function, LLVMCCallConv);
+ LLVMSetLinkage(function, LLVMExternalLinkage);
+
+ assert(LLVMIsDeclaration(function));
+
+ if(name[0] == 'l' &&
+ name[1] == 'l' &&
+ name[2] == 'v' &&
+ name[3] == 'm' &&
+ name[4] == '.')
+ assert(LLVMGetIntrinsicID(function));
+
+ return function;
+}
+
+
+LLVMValueRef
+lp_build_intrinsic(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef *args,
+ unsigned num_args)
+{
+ LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder)));
+ LLVMValueRef function;
+
+ function = LLVMGetNamedFunction(module, name);
+ if(!function) {
+ LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS];
+ unsigned i;
+
+ assert(num_args <= LP_MAX_FUNC_ARGS);
+
+ for(i = 0; i < num_args; ++i) {
+ assert(args[i]);
+ arg_types[i] = LLVMTypeOf(args[i]);
+ }
+
+ function = lp_declare_intrinsic(module, name, ret_type, arg_types, num_args);
+ }
+
+ return LLVMBuildCall(builder, function, args, num_args, "");
+}
+
+
+LLVMValueRef
+lp_build_intrinsic_unary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a)
+{
+ return lp_build_intrinsic(builder, name, ret_type, &a, 1);
+}
+
+
+LLVMValueRef
+lp_build_intrinsic_binary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ LLVMValueRef args[2];
+
+ args[0] = a;
+ args[1] = b;
+
+ return lp_build_intrinsic(builder, name, ret_type, args, 2);
+}
+
+
+LLVMValueRef
+lp_build_intrinsic_map(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef *args,
+ unsigned num_args)
+{
+ LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type);
+ unsigned n = LLVMGetVectorSize(ret_type);
+ unsigned i, j;
+ LLVMValueRef res;
+
+ assert(num_args <= LP_MAX_FUNC_ARGS);
+
+ res = LLVMGetUndef(ret_type);
+ for(i = 0; i < n; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS];
+ LLVMValueRef res_elem;
+ for(j = 0; j < num_args; ++j)
+ arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, "");
+ res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args);
+ res = LLVMBuildInsertElement(builder, res, res_elem, index, "");
+ }
+
+ return res;
+}
+
+
+LLVMValueRef
+lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a)
+{
+ return lp_build_intrinsic_map(builder, name, ret_type, &a, 1);
+}
+
+
+LLVMValueRef
+lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ LLVMValueRef args[2];
+
+ args[0] = a;
+ args[1] = b;
+
+ return lp_build_intrinsic_map(builder, name, ret_type, args, 2);
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.h b/src/gallium/drivers/llvmpipe/lp_bld_intr.h
new file mode 100644
index 0000000000..f813f27074
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.h
@@ -0,0 +1,102 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for calling intrinsics.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_INTR_H
+#define LP_BLD_INTR_H
+
+
+#include <llvm-c/Core.h>
+
+
+/**
+ * Max number of arguments in an intrinsic.
+ */
+#define LP_MAX_FUNC_ARGS 32
+
+
+LLVMValueRef
+lp_declare_intrinsic(LLVMModuleRef module,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMTypeRef *arg_types,
+ unsigned num_args);
+
+LLVMValueRef
+lp_build_intrinsic(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef *args,
+ unsigned num_args);
+
+
+LLVMValueRef
+lp_build_intrinsic_unary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_intrinsic_binary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+
+LLVMValueRef
+lp_build_intrinsic_map(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef *args,
+ unsigned num_args);
+
+
+LLVMValueRef
+lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a);
+
+
+LLVMValueRef
+lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
+ const char *name,
+ LLVMTypeRef ret_type,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+
+#endif /* !LP_BLD_INTR_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_logic.c b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
new file mode 100644
index 0000000000..6b6f820769
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.c
@@ -0,0 +1,394 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for logical operations.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_logic.h"
+
+
+LLVMValueRef
+lp_build_cmp(struct lp_build_context *bld,
+ unsigned func,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ 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);
+ LLVMValueRef ones = LLVMConstAllOnes(int_vec_type);
+ LLVMValueRef cond;
+ LLVMValueRef res;
+ unsigned i;
+
+ if(func == PIPE_FUNC_NEVER)
+ return zeros;
+ if(func == PIPE_FUNC_ALWAYS)
+ return ones;
+
+ /* TODO: optimize the constant case */
+
+ /* XXX: It is not clear if we should use the ordered or unordered operators */
+
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ if(type.width * type.length == 128) {
+ if(type.floating) {
+ LLVMValueRef args[3];
+ unsigned cc;
+ boolean swap;
+
+ swap = FALSE;
+ switch(func) {
+ case PIPE_FUNC_EQUAL:
+ cc = 0;
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ cc = 4;
+ break;
+ case PIPE_FUNC_LESS:
+ cc = 1;
+ break;
+ case PIPE_FUNC_LEQUAL:
+ cc = 2;
+ break;
+ case PIPE_FUNC_GREATER:
+ cc = 1;
+ swap = TRUE;
+ break;
+ case PIPE_FUNC_GEQUAL:
+ cc = 2;
+ swap = TRUE;
+ break;
+ default:
+ assert(0);
+ return bld->undef;
+ }
+
+ if(swap) {
+ args[0] = b;
+ args[1] = a;
+ }
+ else {
+ args[0] = a;
+ args[1] = b;
+ }
+
+ args[2] = LLVMConstInt(LLVMInt8Type(), cc, 0);
+ res = lp_build_intrinsic(bld->builder,
+ "llvm.x86.sse.cmp.ps",
+ vec_type,
+ args, 3);
+ res = LLVMBuildBitCast(bld->builder, res, int_vec_type, "");
+ return res;
+ }
+ else {
+ static const struct {
+ unsigned swap:1;
+ unsigned eq:1;
+ unsigned gt:1;
+ unsigned not:1;
+ } table[] = {
+ {0, 0, 0, 1}, /* PIPE_FUNC_NEVER */
+ {1, 0, 1, 0}, /* PIPE_FUNC_LESS */
+ {0, 1, 0, 0}, /* PIPE_FUNC_EQUAL */
+ {0, 0, 1, 1}, /* PIPE_FUNC_LEQUAL */
+ {0, 0, 1, 0}, /* PIPE_FUNC_GREATER */
+ {0, 1, 0, 1}, /* PIPE_FUNC_NOTEQUAL */
+ {1, 0, 1, 1}, /* PIPE_FUNC_GEQUAL */
+ {0, 0, 0, 0} /* PIPE_FUNC_ALWAYS */
+ };
+ const char *pcmpeq;
+ const char *pcmpgt;
+ LLVMValueRef args[2];
+ LLVMValueRef res;
+
+ switch (type.width) {
+ case 8:
+ pcmpeq = "llvm.x86.sse2.pcmpeq.b";
+ pcmpgt = "llvm.x86.sse2.pcmpgt.b";
+ break;
+ case 16:
+ pcmpeq = "llvm.x86.sse2.pcmpeq.w";
+ pcmpgt = "llvm.x86.sse2.pcmpgt.w";
+ break;
+ case 32:
+ pcmpeq = "llvm.x86.sse2.pcmpeq.d";
+ pcmpgt = "llvm.x86.sse2.pcmpgt.d";
+ break;
+ default:
+ assert(0);
+ return bld->undef;
+ }
+
+ /* There are no signed byte and unsigned word/dword comparison
+ * instructions. So flip the sign bit so that the results match.
+ */
+ if(table[func].gt &&
+ ((type.width == 8 && type.sign) ||
+ (type.width != 8 && !type.sign))) {
+ LLVMValueRef msb = lp_build_int_const_scalar(type, (unsigned long long)1 << (type.width - 1));
+ a = LLVMBuildXor(bld->builder, a, msb, "");
+ b = LLVMBuildXor(bld->builder, b, msb, "");
+ }
+
+ if(table[func].swap) {
+ args[0] = b;
+ args[1] = a;
+ }
+ else {
+ args[0] = a;
+ args[1] = b;
+ }
+
+ if(table[func].eq)
+ res = lp_build_intrinsic(bld->builder, pcmpeq, vec_type, args, 2);
+ else if (table[func].gt)
+ res = lp_build_intrinsic(bld->builder, pcmpgt, vec_type, args, 2);
+ else
+ res = LLVMConstNull(vec_type);
+
+ if(table[func].not)
+ res = LLVMBuildNot(bld->builder, res, "");
+
+ return res;
+ }
+ }
+#endif
+
+ if(type.floating) {
+ LLVMRealPredicate op;
+ switch(func) {
+ case PIPE_FUNC_NEVER:
+ op = LLVMRealPredicateFalse;
+ break;
+ case PIPE_FUNC_ALWAYS:
+ op = LLVMRealPredicateTrue;
+ break;
+ case PIPE_FUNC_EQUAL:
+ op = LLVMRealUEQ;
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ op = LLVMRealUNE;
+ break;
+ case PIPE_FUNC_LESS:
+ op = LLVMRealULT;
+ break;
+ case PIPE_FUNC_LEQUAL:
+ op = LLVMRealULE;
+ break;
+ case PIPE_FUNC_GREATER:
+ op = LLVMRealUGT;
+ break;
+ case PIPE_FUNC_GEQUAL:
+ op = LLVMRealUGE;
+ break;
+ default:
+ assert(0);
+ return bld->undef;
+ }
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
+ cond = LLVMBuildFCmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildFCmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
+ }
+ else {
+ LLVMIntPredicate op;
+ switch(func) {
+ case PIPE_FUNC_EQUAL:
+ op = LLVMIntEQ;
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ op = LLVMIntNE;
+ break;
+ case PIPE_FUNC_LESS:
+ op = type.sign ? LLVMIntSLT : LLVMIntULT;
+ break;
+ case PIPE_FUNC_LEQUAL:
+ op = type.sign ? LLVMIntSLE : LLVMIntULE;
+ break;
+ case PIPE_FUNC_GREATER:
+ op = type.sign ? LLVMIntSGT : LLVMIntUGT;
+ break;
+ case PIPE_FUNC_GEQUAL:
+ op = type.sign ? LLVMIntSGE : LLVMIntUGE;
+ break;
+ default:
+ assert(0);
+ return bld->undef;
+ }
+
+#if 0
+ /* XXX: Although valid IR, no LLVM target currently support this */
+ cond = LLVMBuildICmp(bld->builder, op, a, b, "");
+ res = LLVMBuildSelect(bld->builder, cond, ones, zeros, "");
+#else
+ debug_printf("%s: warning: using slow element-wise vector comparison\n",
+ __FUNCTION__);
+ res = LLVMGetUndef(int_vec_type);
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ cond = LLVMBuildICmp(bld->builder, op,
+ LLVMBuildExtractElement(bld->builder, a, index, ""),
+ LLVMBuildExtractElement(bld->builder, b, index, ""),
+ "");
+ cond = LLVMBuildSelect(bld->builder, cond,
+ LLVMConstExtractElement(ones, index),
+ LLVMConstExtractElement(zeros, index),
+ "");
+ res = LLVMBuildInsertElement(bld->builder, res, cond, index, "");
+ }
+#endif
+ }
+
+ return res;
+}
+
+
+LLVMValueRef
+lp_build_select(struct lp_build_context *bld,
+ LLVMValueRef mask,
+ LLVMValueRef a,
+ LLVMValueRef b)
+{
+ struct lp_type type = bld->type;
+ LLVMValueRef res;
+
+ if(a == b)
+ return a;
+
+ if(type.floating) {
+ LLVMTypeRef int_vec_type = lp_build_int_vec_type(type);
+ a = LLVMBuildBitCast(bld->builder, a, int_vec_type, "");
+ b = LLVMBuildBitCast(bld->builder, b, int_vec_type, "");
+ }
+
+ a = LLVMBuildAnd(bld->builder, a, mask, "");
+
+ /* This often gets translated to PANDN, but sometimes the NOT is
+ * pre-computed and stored in another constant. The best strategy depends
+ * on available registers, so it is not a big deal -- hopefully LLVM does
+ * the right decision attending the rest of the program.
+ */
+ b = LLVMBuildAnd(bld->builder, b, LLVMBuildNot(bld->builder, mask, ""), "");
+
+ res = LLVMBuildOr(bld->builder, a, b, "");
+
+ if(type.floating) {
+ LLVMTypeRef vec_type = lp_build_vec_type(type);
+ res = LLVMBuildBitCast(bld->builder, res, vec_type, "");
+ }
+
+ return res;
+}
+
+
+LLVMValueRef
+lp_build_select_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b,
+ const boolean cond[4])
+{
+ const struct lp_type type = bld->type;
+ const unsigned n = type.length;
+ unsigned i, j;
+
+ if(a == b)
+ return a;
+ if(cond[0] && cond[1] && cond[2] && cond[3])
+ return a;
+ if(!cond[0] && !cond[1] && !cond[2] && !cond[3])
+ return b;
+ if(a == bld->undef || b == bld->undef)
+ return bld->undef;
+
+ /*
+ * There are three major ways of accomplishing this:
+ * - with a shuffle,
+ * - with a select,
+ * - or with a bit mask.
+ *
+ * Select isn't supported for vector types yet.
+ * The flip between these is empirical and might need to be.
+ */
+ if (n <= 4) {
+ /*
+ * Shuffle.
+ */
+ LLVMTypeRef elem_type = LLVMInt32Type();
+ LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
+
+ for(j = 0; j < n; j += 4)
+ for(i = 0; i < 4; ++i)
+ shuffles[j + i] = LLVMConstInt(elem_type, (cond[i] ? 0 : n) + j + i, 0);
+
+ return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
+ }
+ else {
+#if 0
+ /* XXX: Unfortunately select of vectors do not work */
+ /* Use a select */
+ LLVMTypeRef elem_type = LLVMInt1Type();
+ LLVMValueRef cond[LP_MAX_VECTOR_LENGTH];
+
+ for(j = 0; j < n; j += 4)
+ for(i = 0; i < 4; ++i)
+ cond[j + i] = LLVMConstInt(elem_type, cond[i] ? 1 : 0, 0);
+
+ return LLVMBuildSelect(bld->builder, LLVMConstVector(cond, n), a, b, "");
+#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
new file mode 100644
index 0000000000..a4ee7723b5
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_logic.h
@@ -0,0 +1,72 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for logical operations.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_LOGIC_H
+#define LP_BLD_LOGIC_H
+
+
+#include <llvm-c/Core.h>
+
+#include "pipe/p_defines.h" /* For PIPE_FUNC_xxx */
+
+
+struct lp_type type;
+struct lp_build_context;
+
+
+/**
+ * @param func is one of PIPE_FUNC_xxx
+ */
+LLVMValueRef
+lp_build_cmp(struct lp_build_context *bld,
+ unsigned func,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+
+LLVMValueRef
+lp_build_select(struct lp_build_context *bld,
+ LLVMValueRef mask,
+ LLVMValueRef a,
+ LLVMValueRef b);
+
+LLVMValueRef
+lp_build_select_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b,
+ 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
new file mode 100644
index 0000000000..403d0e4836
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample.h
@@ -0,0 +1,135 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Texture sampling.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_SAMPLE_H
+#define LP_BLD_SAMPLE_H
+
+
+#include <llvm-c/Core.h>
+
+struct pipe_texture;
+struct pipe_sampler_state;
+struct lp_type;
+
+
+/**
+ * Sampler static state.
+ *
+ * These are the bits of state from pipe_texture and pipe_sampler_state that
+ * are embedded in the generated code.
+ */
+struct lp_sampler_static_state
+{
+ /* pipe_texture's state */
+ enum pipe_format format;
+ unsigned target:2;
+ unsigned pot_width:1;
+ unsigned pot_height:1;
+ unsigned pot_depth:1;
+
+ /* pipe_sampler_state's state */
+ unsigned wrap_s:3;
+ unsigned wrap_t:3;
+ unsigned wrap_r:3;
+ unsigned min_img_filter:2;
+ unsigned min_mip_filter:2;
+ unsigned mag_img_filter:2;
+ unsigned compare_mode:1;
+ unsigned compare_func:3;
+ unsigned normalized_coords:1;
+ unsigned prefilter:4;
+};
+
+
+/**
+ * Sampler dynamic state.
+ *
+ * These are the bits of state from pipe_texture and pipe_sampler_state that
+ * are computed in runtime.
+ *
+ * There are obtained through callbacks, as we don't want to tie the texture
+ * sampling code generation logic to any particular texture layout or pipe
+ * driver.
+ */
+struct lp_sampler_dynamic_state
+{
+
+ /** Obtain the base texture width. */
+ LLVMValueRef
+ (*width)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
+
+ /** Obtain the base texture height. */
+ LLVMValueRef
+ (*height)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
+
+ LLVMValueRef
+ (*stride)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
+
+ LLVMValueRef
+ (*data_ptr)( struct lp_sampler_dynamic_state *state,
+ LLVMBuilderRef builder,
+ unsigned unit);
+
+};
+
+
+/**
+ * Derive the sampler static state.
+ */
+void
+lp_sampler_static_state(struct lp_sampler_static_state *state,
+ const struct pipe_texture *texture,
+ const struct pipe_sampler_state *sampler);
+
+
+void
+lp_build_sample_soa(LLVMBuilderRef builder,
+ const struct lp_sampler_static_state *static_state,
+ struct lp_sampler_dynamic_state *dynamic_state,
+ struct lp_type fp_type,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel);
+
+
+
+#endif /* LP_BLD_SAMPLE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
new file mode 100644
index 0000000000..8ca1be6f1b
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_sample_soa.c
@@ -0,0 +1,416 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Texture sampling.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_defines.h"
+#include "pipe/p_state.h"
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_format.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_format.h"
+#include "lp_bld_sample.h"
+
+
+void
+lp_sampler_static_state(struct lp_sampler_static_state *state,
+ const struct pipe_texture *texture,
+ const struct pipe_sampler_state *sampler)
+{
+ memset(state, 0, sizeof *state);
+
+ if(!texture)
+ return;
+
+ if(!sampler)
+ return;
+
+ state->format = texture->format;
+ state->target = texture->target;
+ state->pot_width = util_is_pot(texture->width[0]);
+ state->pot_height = util_is_pot(texture->height[0]);
+ state->pot_depth = util_is_pot(texture->depth[0]);
+
+ state->wrap_s = sampler->wrap_s;
+ state->wrap_t = sampler->wrap_t;
+ state->wrap_r = sampler->wrap_r;
+ state->min_img_filter = sampler->min_img_filter;
+ state->min_mip_filter = sampler->min_mip_filter;
+ state->mag_img_filter = sampler->mag_img_filter;
+ if(sampler->compare_mode) {
+ state->compare_mode = sampler->compare_mode;
+ state->compare_func = sampler->compare_func;
+ }
+ state->normalized_coords = sampler->normalized_coords;
+ state->prefilter = sampler->prefilter;
+}
+
+
+
+/**
+ * Keep all information for sampling code generation in a single place.
+ */
+struct lp_build_sample_context
+{
+ LLVMBuilderRef builder;
+
+ const struct lp_sampler_static_state *static_state;
+
+ struct lp_sampler_dynamic_state *dynamic_state;
+
+ const struct util_format_description *format_desc;
+
+ /** Incoming coordinates type and build context */
+ struct lp_type coord_type;
+ struct lp_build_context coord_bld;
+
+ /** Integer coordinates */
+ struct lp_type int_coord_type;
+ struct lp_build_context int_coord_bld;
+
+ /** Output texels type and build context */
+ struct lp_type texel_type;
+ struct lp_build_context texel_bld;
+};
+
+
+static void
+lp_build_sample_texel(struct lp_build_sample_context *bld,
+ LLVMValueRef x,
+ LLVMValueRef y,
+ LLVMValueRef y_stride,
+ LLVMValueRef data_ptr,
+ LLVMValueRef *texel)
+{
+ struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+ LLVMValueRef x_stride;
+ LLVMValueRef offset;
+
+ x_stride = lp_build_const_scalar(bld->int_coord_type, bld->format_desc->block.bits/8);
+
+ if(bld->format_desc->colorspace == UTIL_FORMAT_COLORSPACE_ZS) {
+ LLVMValueRef x_lo, x_hi;
+ LLVMValueRef y_lo, y_hi;
+ LLVMValueRef x_stride_lo, x_stride_hi;
+ LLVMValueRef y_stride_lo, y_stride_hi;
+ LLVMValueRef x_offset_lo, x_offset_hi;
+ LLVMValueRef y_offset_lo, y_offset_hi;
+ LLVMValueRef offset_lo, offset_hi;
+
+ x_lo = LLVMBuildAnd(bld->builder, x, int_coord_bld->one, "");
+ y_lo = LLVMBuildAnd(bld->builder, y, int_coord_bld->one, "");
+
+ x_hi = LLVMBuildLShr(bld->builder, x, int_coord_bld->one, "");
+ y_hi = LLVMBuildLShr(bld->builder, y, int_coord_bld->one, "");
+
+ x_stride_lo = x_stride;
+ y_stride_lo = lp_build_const_scalar(bld->int_coord_type, 2*bld->format_desc->block.bits/8);
+
+ x_stride_hi = lp_build_const_scalar(bld->int_coord_type, 4*bld->format_desc->block.bits/8);
+ y_stride_hi = LLVMBuildShl(bld->builder, y_stride, int_coord_bld->one, "");
+
+ x_offset_lo = lp_build_mul(int_coord_bld, x_lo, x_stride_lo);
+ y_offset_lo = lp_build_mul(int_coord_bld, y_lo, y_stride_lo);
+ offset_lo = lp_build_add(int_coord_bld, x_offset_lo, y_offset_lo);
+
+ x_offset_hi = lp_build_mul(int_coord_bld, x_hi, x_stride_hi);
+ y_offset_hi = lp_build_mul(int_coord_bld, y_hi, y_stride_hi);
+ offset_hi = lp_build_add(int_coord_bld, x_offset_hi, y_offset_hi);
+
+ offset = lp_build_add(int_coord_bld, offset_hi, offset_lo);
+ }
+ else {
+ LLVMValueRef x_offset;
+ LLVMValueRef y_offset;
+
+ x_offset = lp_build_mul(int_coord_bld, x, x_stride);
+ y_offset = lp_build_mul(int_coord_bld, y, y_stride);
+
+ offset = lp_build_add(int_coord_bld, x_offset, y_offset);
+ }
+
+ lp_build_load_rgba_soa(bld->builder,
+ bld->format_desc,
+ bld->texel_type,
+ data_ptr,
+ offset,
+ texel);
+}
+
+
+static LLVMValueRef
+lp_build_sample_wrap(struct lp_build_sample_context *bld,
+ LLVMValueRef coord,
+ LLVMValueRef length,
+ boolean is_pot,
+ unsigned wrap_mode)
+{
+ struct lp_build_context *int_coord_bld = &bld->int_coord_bld;
+ LLVMValueRef length_minus_one;
+
+ length_minus_one = lp_build_sub(int_coord_bld, length, int_coord_bld->one);
+
+ switch(wrap_mode) {
+ case PIPE_TEX_WRAP_REPEAT:
+ if(is_pot)
+ coord = LLVMBuildAnd(bld->builder, coord, length_minus_one, "");
+ else
+ /* Signed remainder won't give the right results for negative
+ * dividends but unsigned remainder does.*/
+ coord = LLVMBuildURem(bld->builder, coord, length, "");
+ break;
+
+ case PIPE_TEX_WRAP_CLAMP:
+ coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero);
+ coord = lp_build_min(int_coord_bld, coord, length_minus_one);
+ break;
+
+ case PIPE_TEX_WRAP_CLAMP_TO_EDGE:
+ case PIPE_TEX_WRAP_CLAMP_TO_BORDER:
+ case PIPE_TEX_WRAP_MIRROR_REPEAT:
+ 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);
+ }
+
+ return coord;
+}
+
+
+static void
+lp_build_sample_2d_nearest_soa(struct lp_build_sample_context *bld,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef stride,
+ LLVMValueRef data_ptr,
+ LLVMValueRef *texel)
+{
+ LLVMValueRef x;
+ LLVMValueRef y;
+
+ x = lp_build_ifloor(&bld->coord_bld, s);
+ y = lp_build_ifloor(&bld->coord_bld, t);
+
+ x = lp_build_sample_wrap(bld, x, width, bld->static_state->pot_width, bld->static_state->wrap_s);
+ y = lp_build_sample_wrap(bld, y, height, bld->static_state->pot_height, bld->static_state->wrap_t);
+
+ lp_build_sample_texel(bld, x, y, stride, data_ptr, texel);
+}
+
+
+static void
+lp_build_sample_2d_linear_soa(struct lp_build_sample_context *bld,
+ LLVMValueRef s,
+ LLVMValueRef t,
+ LLVMValueRef width,
+ LLVMValueRef height,
+ LLVMValueRef stride,
+ LLVMValueRef data_ptr,
+ LLVMValueRef *texel)
+{
+ LLVMValueRef half;
+ LLVMValueRef s_ipart;
+ LLVMValueRef t_ipart;
+ LLVMValueRef s_fpart;
+ LLVMValueRef t_fpart;
+ LLVMValueRef x0, x1;
+ LLVMValueRef y0, y1;
+ LLVMValueRef neighbors[2][2][4];
+ unsigned chan;
+
+ half = lp_build_const_scalar(bld->coord_type, 0.5);
+ s = lp_build_sub(&bld->coord_bld, s, half);
+ t = lp_build_sub(&bld->coord_bld, t, half);
+
+ s_ipart = lp_build_floor(&bld->coord_bld, s);
+ t_ipart = lp_build_floor(&bld->coord_bld, t);
+
+ s_fpart = lp_build_sub(&bld->coord_bld, s, s_ipart);
+ t_fpart = lp_build_sub(&bld->coord_bld, t, t_ipart);
+
+ x0 = lp_build_int(&bld->coord_bld, s_ipart);
+ y0 = lp_build_int(&bld->coord_bld, t_ipart);
+
+ x0 = lp_build_sample_wrap(bld, x0, width, bld->static_state->pot_width, bld->static_state->wrap_s);
+ y0 = lp_build_sample_wrap(bld, y0, height, bld->static_state->pot_height, bld->static_state->wrap_t);
+
+ x1 = lp_build_add(&bld->int_coord_bld, x0, bld->int_coord_bld.one);
+ y1 = lp_build_add(&bld->int_coord_bld, y0, bld->int_coord_bld.one);
+
+ x1 = lp_build_sample_wrap(bld, x1, width, bld->static_state->pot_width, bld->static_state->wrap_s);
+ y1 = lp_build_sample_wrap(bld, y1, height, bld->static_state->pot_height, bld->static_state->wrap_t);
+
+ lp_build_sample_texel(bld, x0, y0, stride, data_ptr, neighbors[0][0]);
+ lp_build_sample_texel(bld, x1, y0, stride, data_ptr, neighbors[0][1]);
+ lp_build_sample_texel(bld, x0, y1, stride, data_ptr, neighbors[1][0]);
+ lp_build_sample_texel(bld, x1, y1, stride, data_ptr, neighbors[1][1]);
+
+ /* TODO: Don't interpolate missing channels */
+ for(chan = 0; chan < 4; ++chan) {
+ texel[chan] = lp_build_lerp_2d(&bld->texel_bld,
+ s_fpart, t_fpart,
+ neighbors[0][0][chan],
+ neighbors[0][1][chan],
+ neighbors[1][0][chan],
+ neighbors[1][1][chan]);
+ }
+}
+
+
+static void
+lp_build_sample_compare(struct lp_build_sample_context *bld,
+ LLVMValueRef p,
+ LLVMValueRef *texel)
+{
+ struct lp_build_context *texel_bld = &bld->texel_bld;
+ LLVMValueRef res;
+ unsigned chan;
+
+ if(!bld->static_state->compare_mode)
+ return;
+
+ /* TODO: Compare before swizzling, to avoid redundant computations */
+ res = NULL;
+ for(chan = 0; chan < 4; ++chan) {
+ LLVMValueRef cmp;
+ cmp = lp_build_cmp(texel_bld, bld->static_state->compare_func, p, texel[chan]);
+ cmp = lp_build_select(texel_bld, cmp, texel_bld->one, texel_bld->zero);
+
+ if(res)
+ res = lp_build_add(texel_bld, res, cmp);
+ else
+ res = cmp;
+ }
+
+ assert(res);
+ res = lp_build_mul(texel_bld, res, lp_build_const_scalar(texel_bld->type, 0.25));
+
+ /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
+ for(chan = 0; chan < 3; ++chan)
+ texel[chan] = res;
+ texel[3] = texel_bld->one;
+}
+
+
+void
+lp_build_sample_soa(LLVMBuilderRef builder,
+ const struct lp_sampler_static_state *static_state,
+ struct lp_sampler_dynamic_state *dynamic_state,
+ struct lp_type type,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel)
+{
+ struct lp_build_sample_context bld;
+ LLVMValueRef width;
+ LLVMValueRef height;
+ LLVMValueRef stride;
+ LLVMValueRef data_ptr;
+ LLVMValueRef s;
+ LLVMValueRef t;
+ LLVMValueRef p;
+
+ /* Setup our build context */
+ memset(&bld, 0, sizeof bld);
+ bld.builder = builder;
+ bld.static_state = static_state;
+ bld.dynamic_state = dynamic_state;
+ bld.format_desc = util_format_description(static_state->format);
+ bld.coord_type = type;
+ bld.int_coord_type = lp_int_type(type);
+ bld.texel_type = type;
+ lp_build_context_init(&bld.coord_bld, builder, bld.coord_type);
+ lp_build_context_init(&bld.int_coord_bld, builder, bld.int_coord_type);
+ lp_build_context_init(&bld.texel_bld, builder, bld.texel_type);
+
+ /* Get the dynamic state */
+ width = dynamic_state->width(dynamic_state, builder, unit);
+ height = dynamic_state->height(dynamic_state, builder, unit);
+ stride = dynamic_state->stride(dynamic_state, builder, unit);
+ data_ptr = dynamic_state->data_ptr(dynamic_state, builder, unit);
+
+ s = coords[0];
+ t = coords[1];
+ p = coords[2];
+
+ width = lp_build_broadcast_scalar(&bld.int_coord_bld, width);
+ height = lp_build_broadcast_scalar(&bld.int_coord_bld, height);
+ stride = lp_build_broadcast_scalar(&bld.int_coord_bld, stride);
+
+ if(static_state->target == PIPE_TEXTURE_1D)
+ t = bld.coord_bld.zero;
+
+ if(static_state->normalized_coords) {
+ LLVMTypeRef coord_vec_type = lp_build_vec_type(bld.coord_type);
+ LLVMValueRef fp_width = LLVMBuildSIToFP(builder, width, coord_vec_type, "");
+ LLVMValueRef fp_height = LLVMBuildSIToFP(builder, height, coord_vec_type, "");
+ s = lp_build_mul(&bld.coord_bld, s, fp_width);
+ t = lp_build_mul(&bld.coord_bld, t, fp_height);
+ }
+
+ switch (static_state->min_img_filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ lp_build_sample_2d_nearest_soa(&bld, s, t, width, height, stride, data_ptr, texel);
+ break;
+ case PIPE_TEX_FILTER_LINEAR:
+ 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_struct.c b/src/gallium/drivers/llvmpipe/lp_bld_struct.c
new file mode 100644
index 0000000000..3998ac374f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_struct.c
@@ -0,0 +1,72 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Helper functions for manipulation structures.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+#include "lp_bld_debug.h"
+#include "lp_bld_struct.h"
+
+
+LLVMValueRef
+lp_build_struct_get_ptr(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ unsigned member,
+ const char *name)
+{
+ LLVMValueRef indices[2];
+ LLVMValueRef member_ptr;
+ indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ indices[1] = LLVMConstInt(LLVMInt32Type(), member, 0);
+ member_ptr = LLVMBuildGEP(builder, ptr, indices, Elements(indices), "");
+ lp_build_name(member_ptr, "%s.%s_ptr", LLVMGetValueName(ptr), name);
+ return member_ptr;
+}
+
+
+LLVMValueRef
+lp_build_struct_get(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ unsigned member,
+ const char *name)
+{
+ LLVMValueRef member_ptr;
+ LLVMValueRef res;
+ member_ptr = lp_build_struct_get_ptr(builder, ptr, member, name);
+ res = LLVMBuildLoad(builder, member_ptr, "");
+ lp_build_name(res, "%s.%s", LLVMGetValueName(ptr), name);
+ return res;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_struct.h b/src/gallium/drivers/llvmpipe/lp_bld_struct.h
new file mode 100644
index 0000000000..740392f561
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_struct.h
@@ -0,0 +1,75 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for type conversions.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_STRUCT_H
+#define LP_BLD_STRUCT_H
+
+
+#include <llvm-c/Core.h>
+#include <llvm-c/Target.h>
+
+#include "util/u_debug.h"
+#include "util/u_memory.h"
+
+
+#define LP_CHECK_STRUCT_SIZE(_ctype, _ltarget, _ltype) \
+ assert(LLVMABISizeOfType(_ltarget, _ltype) == \
+ sizeof(_ctype))
+
+#define LP_CHECK_MEMBER_OFFSET(_ctype, _cmember, _ltarget, _ltype, _lindex) \
+ assert(LLVMOffsetOfElement(_ltarget, _ltype, _lindex) == \
+ offsetof(_ctype, _cmember))
+
+
+/**
+ * Get value pointer to a structure member.
+ */
+LLVMValueRef
+lp_build_struct_get_ptr(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ unsigned member,
+ const char *name);
+
+/**
+ * Get the value of a structure member.
+ */
+LLVMValueRef
+lp_build_struct_get(LLVMBuilderRef builder,
+ LLVMValueRef ptr,
+ unsigned member,
+ const char *name);
+
+
+#endif /* !LP_BLD_STRUCT_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
new file mode 100644
index 0000000000..64e81f7b1f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.c
@@ -0,0 +1,239 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for swizzling/shuffling.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "util/u_debug.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_swizzle.h"
+
+
+LLVMValueRef
+lp_build_broadcast(LLVMBuilderRef builder,
+ LLVMTypeRef vec_type,
+ LLVMValueRef scalar)
+{
+ const unsigned n = LLVMGetVectorSize(vec_type);
+ LLVMValueRef res;
+ unsigned i;
+
+ res = LLVMGetUndef(vec_type);
+ for(i = 0; i < n; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ res = LLVMBuildInsertElement(builder, res, scalar, index, "");
+ }
+
+ return res;
+}
+
+
+LLVMValueRef
+lp_build_broadcast_scalar(struct lp_build_context *bld,
+ LLVMValueRef scalar)
+{
+ const struct lp_type type = bld->type;
+ LLVMValueRef res;
+ unsigned i;
+
+ res = bld->undef;
+ for(i = 0; i < type.length; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ res = LLVMBuildInsertElement(bld->builder, res, scalar, index, "");
+ }
+
+ return res;
+}
+
+
+LLVMValueRef
+lp_build_broadcast_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ unsigned channel)
+{
+ const struct lp_type type = bld->type;
+ const unsigned n = type.length;
+ unsigned i, j;
+
+ if(a == bld->undef || a == bld->zero || a == bld->one)
+ return a;
+
+ /* XXX: SSE3 has PSHUFB which should be better than bitmasks, but forcing
+ * using shuffles here actually causes worst results. More investigation is
+ * needed. */
+ if (n <= 4) {
+ /*
+ * Shuffle.
+ */
+ LLVMTypeRef elem_type = LLVMInt32Type();
+ LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
+
+ for(j = 0; j < n; j += 4)
+ for(i = 0; i < 4; ++i)
+ shuffles[j + i] = LLVMConstInt(elem_type, j + channel, 0);
+
+ return LLVMBuildShuffleVector(bld->builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
+ }
+ else {
+ /*
+ * Bit mask and recursive shifts
+ *
+ * XYZW XYZW .... XYZW <= input
+ * 0Y00 0Y00 .... 0Y00
+ * YY00 YY00 .... YY00
+ * YYYY YYYY .... YYYY <= output
+ */
+ struct lp_type type4 = type;
+ const char shifts[4][2] = {
+ { 1, 2},
+ {-1, 2},
+ { 1, -2},
+ {-1, -2}
+ };
+ boolean cond[4];
+ unsigned i;
+
+ memset(cond, 0, sizeof cond);
+ cond[channel] = 1;
+
+ a = LLVMBuildAnd(bld->builder, a, lp_build_const_mask_aos(type, cond), "");
+
+ type4.width *= 4;
+ type4.length /= 4;
+
+ a = LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type4), "");
+
+ for(i = 0; i < 2; ++i) {
+ LLVMValueRef tmp = NULL;
+ int shift = shifts[channel][i];
+
+#ifdef PIPE_ARCH_LITTLE_ENDIAN
+ shift = -shift;
+#endif
+
+ if(shift > 0)
+ tmp = LLVMBuildLShr(bld->builder, a, lp_build_int_const_scalar(type4, shift*type.width), "");
+ if(shift < 0)
+ tmp = LLVMBuildShl(bld->builder, a, lp_build_int_const_scalar(type4, -shift*type.width), "");
+
+ assert(tmp);
+ if(tmp)
+ a = LLVMBuildOr(bld->builder, a, tmp, "");
+ }
+
+ return LLVMBuildBitCast(bld->builder, a, lp_build_vec_type(type), "");
+ }
+}
+
+
+LLVMValueRef
+lp_build_swizzle1_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ const unsigned char swizzle[4])
+{
+ const unsigned n = bld->type.length;
+ unsigned i, j;
+
+ if(a == bld->undef || a == bld->zero || a == bld->one)
+ return a;
+
+ if(swizzle[0] == swizzle[1] && swizzle[1] == swizzle[2] && swizzle[2] == swizzle[3])
+ return lp_build_broadcast_aos(bld, a, swizzle[0]);
+
+ {
+ /*
+ * Shuffle.
+ */
+ LLVMTypeRef elem_type = LLVMInt32Type();
+ LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
+
+ for(j = 0; j < n; j += 4)
+ for(i = 0; i < 4; ++i)
+ shuffles[j + i] = LLVMConstInt(elem_type, j + swizzle[i], 0);
+
+ return LLVMBuildShuffleVector(bld->builder, a, bld->undef, LLVMConstVector(shuffles, n), "");
+ }
+}
+
+
+LLVMValueRef
+lp_build_swizzle2_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b,
+ const unsigned char swizzle[4])
+{
+ const unsigned n = bld->type.length;
+ unsigned i, j;
+
+ if(swizzle[0] < 4 && swizzle[1] < 4 && swizzle[2] < 4 && swizzle[3] < 4)
+ return lp_build_swizzle1_aos(bld, a, swizzle);
+
+ if(a == b) {
+ unsigned char swizzle1[4];
+ swizzle1[0] = swizzle[0] % 4;
+ swizzle1[1] = swizzle[1] % 4;
+ swizzle1[2] = swizzle[2] % 4;
+ swizzle1[3] = swizzle[3] % 4;
+ return lp_build_swizzle1_aos(bld, a, swizzle1);
+ }
+
+ if(swizzle[0] % 4 == 0 &&
+ swizzle[1] % 4 == 1 &&
+ swizzle[2] % 4 == 2 &&
+ swizzle[3] % 4 == 3) {
+ boolean cond[4];
+ cond[0] = swizzle[0] / 4;
+ cond[1] = swizzle[1] / 4;
+ cond[2] = swizzle[2] / 4;
+ cond[3] = swizzle[3] / 4;
+ return lp_build_select_aos(bld, a, b, cond);
+ }
+
+ {
+ /*
+ * Shuffle.
+ */
+ LLVMTypeRef elem_type = LLVMInt32Type();
+ LLVMValueRef shuffles[LP_MAX_VECTOR_LENGTH];
+
+ for(j = 0; j < n; j += 4)
+ for(i = 0; i < 4; ++i)
+ shuffles[j + i] = LLVMConstInt(elem_type, j + (swizzle[i] % 4) + (swizzle[i] / 4 * n), 0);
+
+ return LLVMBuildShuffleVector(bld->builder, a, b, LLVMConstVector(shuffles, n), "");
+ }
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h
new file mode 100644
index 0000000000..1f6da80448
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_swizzle.h
@@ -0,0 +1,91 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Helper functions for swizzling/shuffling.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_SWIZZLE_H
+#define LP_BLD_SWIZZLE_H
+
+
+#include <llvm-c/Core.h>
+
+
+struct lp_type type;
+struct lp_build_context;
+
+
+LLVMValueRef
+lp_build_broadcast(LLVMBuilderRef builder,
+ LLVMTypeRef vec_type,
+ LLVMValueRef scalar);
+
+
+LLVMValueRef
+lp_build_broadcast_scalar(struct lp_build_context *bld,
+ LLVMValueRef scalar);
+
+
+/**
+ * Broadcast one channel of a vector composed of arrays of XYZW structures into
+ * all four channel.
+ */
+LLVMValueRef
+lp_build_broadcast_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ unsigned channel);
+
+
+/**
+ * Swizzle a vector consisting of an array of XYZW structs.
+ *
+ * @param swizzle is the in [0,4[ range.
+ */
+LLVMValueRef
+lp_build_swizzle1_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ const unsigned char swizzle[4]);
+
+
+/**
+ * Swizzle two vector consisting of an array of XYZW structs.
+ *
+ * @param swizzle is the in [0,8[ range. Values in [4,8[ range refer to b.
+ */
+LLVMValueRef
+lp_build_swizzle2_aos(struct lp_build_context *bld,
+ LLVMValueRef a,
+ LLVMValueRef b,
+ const unsigned char swizzle[4]);
+
+
+#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
new file mode 100644
index 0000000000..eddb7a83fa
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * TGSI to LLVM IR translation.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_BLD_TGSI_H
+#define LP_BLD_TGSI_H
+
+#include <llvm-c/Core.h>
+
+
+struct tgsi_token;
+struct lp_type;
+struct lp_build_context;
+struct lp_build_mask_context;
+
+
+/**
+ * Sampler code generation interface.
+ *
+ * Although texture sampling is a requirement for TGSI translation, it is
+ * a very different problem with several different approaches to it. This
+ * structure establishes an interface for texture sampling code generation, so
+ * that we can easily use different texture sampling strategies.
+ */
+struct lp_build_sampler_soa
+{
+ void
+ (*destroy)( struct lp_build_sampler_soa *sampler );
+
+ void
+ (*emit_fetch_texel)( struct lp_build_sampler_soa *sampler,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel);
+};
+
+
+void
+lp_build_tgsi_soa(LLVMBuilderRef builder,
+ const struct tgsi_token *tokens,
+ struct lp_type type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef consts_ptr,
+ const LLVMValueRef *pos,
+ const LLVMValueRef (*inputs)[4],
+ LLVMValueRef (*outputs)[4],
+ struct lp_build_sampler_soa *sampler);
+
+
+#endif /* LP_BLD_TGSI_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
new file mode 100644
index 0000000000..adc81569ed
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_tgsi_soa.c
@@ -0,0 +1,1484 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * Copyright 2007-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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * TGSI to LLVM IR translation -- SoA.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ *
+ * Based on tgsi_sse2.c code written by Michal Krol, Keith Whitwell,
+ * Brian Paul, and others.
+ */
+
+#include "pipe/p_config.h"
+#include "pipe/p_shader_tokens.h"
+#include "util/u_debug.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "tgsi/tgsi_info.h"
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_util.h"
+#include "tgsi/tgsi_exec.h"
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_flow.h"
+#include "lp_bld_tgsi.h"
+#include "lp_bld_debug.h"
+
+
+#define LP_MAX_TEMPS 256
+#define LP_MAX_IMMEDIATES 256
+
+
+#define FOR_EACH_CHANNEL( CHAN )\
+ for (CHAN = 0; CHAN < NUM_CHANNELS; CHAN++)
+
+#define IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
+ ((INST)->FullDstRegisters[0].DstRegister.WriteMask & (1 << (CHAN)))
+
+#define IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )\
+ if (IS_DST0_CHANNEL_ENABLED( INST, CHAN ))
+
+#define FOR_EACH_DST0_ENABLED_CHANNEL( INST, CHAN )\
+ FOR_EACH_CHANNEL( CHAN )\
+ IF_IS_DST0_CHANNEL_ENABLED( INST, CHAN )
+
+#define CHAN_X 0
+#define CHAN_Y 1
+#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
+{
+ struct lp_build_context base;
+
+ LLVMValueRef consts_ptr;
+ const LLVMValueRef *pos;
+ const LLVMValueRef (*inputs)[NUM_CHANNELS];
+ LLVMValueRef (*outputs)[NUM_CHANNELS];
+
+ struct lp_build_sampler_soa *sampler;
+
+ LLVMValueRef immediates[LP_MAX_IMMEDIATES][NUM_CHANNELS];
+ LLVMValueRef temps[LP_MAX_TEMPS][NUM_CHANNELS];
+
+ struct lp_build_mask_context *mask;
+};
+
+
+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.
+ */
+static LLVMValueRef
+emit_fetch(
+ struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ unsigned index,
+ const unsigned chan_index )
+{
+ const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[index];
+ unsigned swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index );
+ LLVMValueRef res;
+
+ switch (swizzle) {
+ case TGSI_EXTSWIZZLE_X:
+ case TGSI_EXTSWIZZLE_Y:
+ case TGSI_EXTSWIZZLE_Z:
+ case TGSI_EXTSWIZZLE_W:
+
+ switch (reg->SrcRegister.File) {
+ case TGSI_FILE_CONSTANT: {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), reg->SrcRegister.Index*4 + swizzle, 0);
+ LLVMValueRef scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, &index, 1, "");
+ LLVMValueRef scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
+ res = lp_build_broadcast_scalar(&bld->base, scalar);
+ break;
+ }
+
+ case TGSI_FILE_IMMEDIATE:
+ res = bld->immediates[reg->SrcRegister.Index][swizzle];
+ assert(res);
+ break;
+
+ case TGSI_FILE_INPUT:
+ res = bld->inputs[reg->SrcRegister.Index][swizzle];
+ assert(res);
+ break;
+
+ case TGSI_FILE_TEMPORARY:
+ res = bld->temps[reg->SrcRegister.Index][swizzle];
+ if(!res)
+ return bld->base.undef;
+ break;
+
+ default:
+ assert( 0 );
+ return bld->base.undef;
+ }
+ break;
+
+ case TGSI_EXTSWIZZLE_ZERO:
+ res = bld->base.zero;
+ break;
+
+ case TGSI_EXTSWIZZLE_ONE:
+ res = bld->base.one;
+ break;
+
+ default:
+ assert( 0 );
+ return bld->base.undef;
+ }
+
+ switch( tgsi_util_get_full_src_register_sign_mode( reg, chan_index ) ) {
+ case TGSI_UTIL_SIGN_CLEAR:
+ res = lp_build_abs( &bld->base, res );
+ 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;
+
+ case TGSI_UTIL_SIGN_TOGGLE:
+ res = LLVMBuildNeg( bld->base.builder, res, "" );
+ break;
+
+ case TGSI_UTIL_SIGN_KEEP:
+ break;
+ }
+
+ return res;
+}
+
+
+/**
+ * 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
+emit_store(
+ struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst,
+ unsigned index,
+ unsigned chan_index,
+ LLVMValueRef value)
+{
+ const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[index];
+
+ switch( inst->Instruction.Saturate ) {
+ case TGSI_SAT_NONE:
+ break;
+
+ case TGSI_SAT_ZERO_ONE:
+ value = lp_build_max(&bld->base, value, bld->base.zero);
+ value = lp_build_min(&bld->base, value, bld->base.one);
+ break;
+
+ case TGSI_SAT_MINUS_PLUS_ONE:
+ value = lp_build_max(&bld->base, value, lp_build_const_scalar(bld->base.type, -1.0));
+ value = lp_build_min(&bld->base, value, bld->base.one);
+ break;
+
+ default:
+ assert(0);
+ }
+
+ switch( reg->DstRegister.File ) {
+ case TGSI_FILE_OUTPUT:
+ bld->outputs[reg->DstRegister.Index][chan_index] = value;
+ break;
+
+ case TGSI_FILE_TEMPORARY:
+ bld->temps[reg->DstRegister.Index][chan_index] = value;
+ break;
+
+ case TGSI_FILE_ADDRESS:
+ /* FIXME */
+ assert(0);
+ break;
+
+ default:
+ assert( 0 );
+ }
+}
+
+
+/**
+ * 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,
+ LLVMValueRef *texel)
+{
+ const uint unit = inst->FullSrcRegisters[1].SrcRegister.Index;
+ LLVMValueRef lodbias;
+ LLVMValueRef oow;
+ LLVMValueRef coords[3];
+ unsigned num_coords;
+ unsigned i;
+
+ switch (inst->InstructionExtTexture.Texture) {
+ case TGSI_TEXTURE_1D:
+ num_coords = 1;
+ break;
+ case TGSI_TEXTURE_2D:
+ case TGSI_TEXTURE_RECT:
+ num_coords = 2;
+ break;
+ case TGSI_TEXTURE_SHADOW1D:
+ case TGSI_TEXTURE_SHADOW2D:
+ case TGSI_TEXTURE_SHADOWRECT:
+ case TGSI_TEXTURE_3D:
+ case TGSI_TEXTURE_CUBE:
+ num_coords = 3;
+ break;
+ default:
+ assert(0);
+ return;
+ }
+
+ if(apply_lodbias)
+ lodbias = emit_fetch( bld, inst, 0, 3 );
+ else
+ lodbias = bld->base.zero;
+
+ if (projected) {
+ oow = emit_fetch( bld, inst, 0, 3 );
+ oow = lp_build_rcp(&bld->base, oow);
+ }
+
+ for (i = 0; i < num_coords; i++) {
+ coords[i] = emit_fetch( bld, inst, 0, i );
+ if (projected)
+ coords[i] = lp_build_mul(&bld->base, coords[i], oow);
+ }
+
+ bld->sampler->emit_fetch_texel(bld->sampler,
+ bld->base.builder,
+ bld->base.type,
+ unit, num_coords, coords, lodbias,
+ texel);
+}
+
+
+static void
+emit_kil(
+ struct lp_build_tgsi_soa_context *bld,
+ const struct tgsi_full_instruction *inst )
+{
+ const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[0];
+ LLVMValueRef terms[NUM_CHANNELS];
+ LLVMValueRef mask;
+ unsigned chan_index;
+
+ memset(&terms, 0, sizeof terms);
+
+ FOR_EACH_CHANNEL( chan_index ) {
+ unsigned swizzle;
+
+ /* Unswizzle channel */
+ swizzle = tgsi_util_get_full_src_register_extswizzle( reg, chan_index );
+
+ /* Note that we test if the value is less than zero, so 1.0 and 0.0 need
+ * not to be tested. */
+ if(swizzle == TGSI_EXTSWIZZLE_ZERO || swizzle == TGSI_EXTSWIZZLE_ONE)
+ continue;
+
+ /* Check if the component has not been already tested. */
+ assert(swizzle < NUM_CHANNELS);
+ if( !terms[swizzle] )
+ /* TODO: change the comparison operator instead of setting the sign */
+ terms[swizzle] = emit_fetch(bld, inst, 0, chan_index );
+ }
+
+ mask = NULL;
+ FOR_EACH_CHANNEL( chan_index ) {
+ if(terms[chan_index]) {
+ LLVMValueRef chan_mask;
+
+ chan_mask = lp_build_cmp(&bld->base, PIPE_FUNC_GEQUAL, terms[chan_index], bld->base.zero);
+
+ if(mask)
+ mask = LLVMBuildAnd(bld->base.builder, mask, chan_mask, "");
+ else
+ mask = chan_mask;
+ }
+ }
+
+ if(mask)
+ lp_build_mask_update(bld->mask, mask);
+}
+
+
+/**
+ * Check if inst src/dest regs use indirect addressing into temporary
+ * register file.
+ */
+static boolean
+indirect_temp_reference(const struct tgsi_full_instruction *inst)
+{
+ uint i;
+ for (i = 0; i < inst->Instruction.NumSrcRegs; i++) {
+ const struct tgsi_full_src_register *reg = &inst->FullSrcRegisters[i];
+ if (reg->SrcRegister.File == TGSI_FILE_TEMPORARY &&
+ reg->SrcRegister.Indirect)
+ return TRUE;
+ }
+ for (i = 0; i < inst->Instruction.NumDstRegs; i++) {
+ const struct tgsi_full_dst_register *reg = &inst->FullDstRegisters[i];
+ if (reg->DstRegister.File == TGSI_FILE_TEMPORARY &&
+ reg->DstRegister.Indirect)
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+static int
+emit_instruction(
+ struct lp_build_tgsi_soa_context *bld,
+ 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 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 );
+ dst0[chan_index] = tmp0;
+ }
+ break;
+#endif
+
+ case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_SWZ:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = emit_fetch( bld, inst, 0, chan_index );
+ }
+ break;
+
+ case TGSI_OPCODE_LIT:
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ) {
+ dst0[CHAN_X] = bld->base.one;
+ }
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
+ src0 = emit_fetch( bld, inst, 0, CHAN_X );
+ 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 */
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+ /* XMM[1] = max(XMM[1], 0) */
+ tmp1 = lp_build_max( &bld->base, tmp1, bld->base.zero);
+ /* XMM[2] = SrcReg[0].wwww */
+ tmp2 = emit_fetch( bld, inst, 0, CHAN_W );
+ 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[CHAN_Z] = lp_build_select(&bld->base, tmp2, tmp1, bld->base.zero);
+ }
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) ) {
+ dst0[CHAN_W] = bld->base.one;
+ }
+ break;
+
+ case TGSI_OPCODE_RCP:
+ /* TGSI_OPCODE_RECIP */
+ src0 = emit_fetch( bld, inst, 0, CHAN_X );
+ res = lp_build_rcp(&bld->base, src0);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = res;
+ }
+ break;
+
+ case TGSI_OPCODE_RSQ:
+ /* TGSI_OPCODE_RECIPSQRT */
+ src0 = emit_fetch( bld, inst, 0, CHAN_X );
+ src0 = lp_build_abs(&bld->base, src0);
+ res = lp_build_rsqrt(&bld->base, src0);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = res;
+ }
+ break;
+
+ case TGSI_OPCODE_EXP:
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
+ LLVMValueRef *p_exp2_int_part = NULL;
+ LLVMValueRef *p_frac_part = NULL;
+ LLVMValueRef *p_exp2 = NULL;
+
+ src0 = emit_fetch( bld, inst, 0, CHAN_X );
+
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
+ p_exp2_int_part = &tmp0;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
+ p_frac_part = &tmp1;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
+ p_exp2 = &tmp2;
+
+ lp_build_exp2_approx(&bld->base, src0, p_exp2_int_part, p_frac_part, p_exp2);
+
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
+ dst0[CHAN_X] = tmp0;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
+ dst0[CHAN_Y] = tmp1;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
+ dst0[CHAN_Z] = tmp2;
+ }
+ /* dst.w = 1.0 */
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
+ dst0[CHAN_W] = bld->base.one;
+ }
+ break;
+
+ case TGSI_OPCODE_LOG:
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z )) {
+ LLVMValueRef *p_floor_log2;
+ LLVMValueRef *p_exp;
+ LLVMValueRef *p_log2;
+
+ src0 = emit_fetch( bld, inst, 0, CHAN_X );
+ src0 = lp_build_abs( &bld->base, src0 );
+
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
+ p_floor_log2 = &tmp0;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ))
+ p_exp = &tmp1;
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
+ p_log2 = &tmp2;
+
+ lp_build_log2_approx(&bld->base, src0, p_exp, p_floor_log2, p_log2);
+
+ /* dst.x = floor(lg2(abs(src.x))) */
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ))
+ dst0[CHAN_X] = tmp0;
+ /* dst.y = abs(src)/ex2(floor(lg2(abs(src.x)))) */
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y )) {
+ dst0[CHAN_Y] = lp_build_div( &bld->base, src0, tmp1);
+ }
+ /* dst.z = lg2(abs(src.x)) */
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ))
+ dst0[CHAN_Z] = tmp2;
+ }
+ /* dst.w = 1.0 */
+ if (IS_DST0_CHANNEL_ENABLED( inst, CHAN_W )) {
+ dst0[CHAN_W] = bld->base.one;
+ }
+ break;
+
+ case TGSI_OPCODE_MUL:
+ 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[chan_index] = lp_build_mul(&bld->base, src0, src1);
+ }
+ break;
+
+ case TGSI_OPCODE_ADD:
+ 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[chan_index] = lp_build_add(&bld->base, src0, src1);
+ }
+ break;
+
+ case TGSI_OPCODE_DP3:
+ /* TGSI_OPCODE_DOT3 */
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_DP4:
+ /* TGSI_OPCODE_DOT4 */
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_W );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_W );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_DST:
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
+ 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 );
+ dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp0, tmp1);
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
+ dst0[CHAN_Z] = emit_fetch( bld, inst, 0, CHAN_Z );
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
+ dst0[CHAN_W] = emit_fetch( bld, inst, 1, CHAN_W );
+ }
+ break;
+
+ case TGSI_OPCODE_MIN:
+ 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[chan_index] = lp_build_min( &bld->base, src0, src1 );
+ }
+ break;
+
+ case TGSI_OPCODE_MAX:
+ 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[chan_index] = lp_build_max( &bld->base, src0, src1 );
+ }
+ break;
+
+ case TGSI_OPCODE_SLT:
+ /* TGSI_OPCODE_SETLT */
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_SGE:
+ /* TGSI_OPCODE_SETGE */
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_MAD:
+ /* TGSI_OPCODE_MADD */
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ tmp1 = emit_fetch( bld, inst, 1, chan_index );
+ tmp2 = emit_fetch( bld, inst, 2, chan_index );
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp2);
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_SUB:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ tmp1 = emit_fetch( bld, inst, 1, chan_index );
+ dst0[chan_index] = lp_build_sub( &bld->base, tmp0, tmp1);
+ }
+ break;
+
+ case TGSI_OPCODE_LRP:
+ 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 );
+ tmp0 = lp_build_sub( &bld->base, src1, src2 );
+ tmp0 = lp_build_mul( &bld->base, src0, tmp0 );
+ dst0[chan_index] = lp_build_add( &bld->base, tmp0, src2 );
+ }
+ break;
+
+ case TGSI_OPCODE_CND:
+ 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:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1); /* xmm0 = xmm0 * xmm1 */
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y ); /* xmm1 = src[0].y */
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Y ); /* xmm2 = src[1].y */
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2); /* xmm1 = xmm1 * xmm2 */
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1); /* xmm0 = xmm0 + xmm1 */
+ 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 ) {
+ dst0[chan_index] = tmp0; /* dest[ch] = xmm0 */
+ }
+ break;
+
+ case TGSI_OPCODE_FRC:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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:
+ 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 );
+ 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 );
+ dst0[chan_index] = lp_build_round(&bld->base, tmp0);
+ }
+ break;
+
+ 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 ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+ }
+
+ case TGSI_OPCODE_LG2:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp0 = lp_build_log2( &bld->base, tmp0);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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 );
+ res = lp_build_pow( &bld->base, src0, src1 );
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = res;
+ }
+ break;
+
+ case TGSI_OPCODE_XPD:
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ) {
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_Z );
+ tmp3 = emit_fetch( bld, inst, 0, CHAN_Z );
+ }
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_Y );
+ tmp4 = emit_fetch( bld, inst, 1, CHAN_Y );
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_X ) {
+ tmp2 = tmp0;
+ tmp2 = lp_build_mul( &bld->base, tmp2, tmp1);
+ tmp5 = tmp3;
+ tmp5 = lp_build_mul( &bld->base, tmp5, tmp4);
+ tmp2 = lp_build_sub( &bld->base, tmp2, tmp5);
+ dst0[CHAN_X] = tmp2;
+ }
+ if( IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) ||
+ IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) ) {
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_X );
+ tmp5 = emit_fetch( bld, inst, 0, CHAN_X );
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Y ) {
+ tmp3 = lp_build_mul( &bld->base, tmp3, tmp2);
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp5);
+ tmp3 = lp_build_sub( &bld->base, tmp3, tmp1);
+ 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);
+ dst0[CHAN_Z] = tmp5;
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
+ 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 );
+ dst0[chan_index] = lp_build_abs( &bld->base, tmp0 );
+ }
+ break;
+
+ case TGSI_OPCODE_RCC:
+ /* deprecated? */
+ assert(0);
+ return 0;
+
+ case TGSI_OPCODE_DPH:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_X );
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Y );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Z );
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Z );
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp2);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_W );
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_COS:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp0 = lp_build_cos( &bld->base, tmp0 );
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_DDX:
+ 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:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ emit_fetch_deriv( bld, inst, 0, chan_index, NULL, NULL, &dst0[chan_index]);
+ }
+ break;
+
+ case TGSI_OPCODE_KILP:
+ /* predicated kill */
+ /* FIXME */
+ return 0;
+ break;
+
+ case TGSI_OPCODE_KIL:
+ /* conditional kill */
+ emit_kil( bld, inst );
+ break;
+
+ case TGSI_OPCODE_PK2H:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_PK2US:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_PK4B:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_PK4UB:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_RFL:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_SEQ:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_SFL:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = bld->base.zero;
+ }
+ break;
+
+ case TGSI_OPCODE_SGT:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_SIN:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X );
+ tmp0 = lp_build_sin( &bld->base, tmp0 );
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ dst0[chan_index] = tmp0;
+ }
+ break;
+
+ case TGSI_OPCODE_SLE:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_SNE:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ 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[chan_index] = lp_build_select( &bld->base, tmp0, bld->base.one, bld->base.zero );
+ }
+ break;
+
+ case TGSI_OPCODE_STR:
+ 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, 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 );
+ dst0[chan_index] = tmp0;
+ }
+ break;
+#endif
+
+ case TGSI_OPCODE_BRA:
+ /* deprecated */
+ assert(0);
+ return 0;
+ break;
+
+ case TGSI_OPCODE_CAL:
+ /* FIXME */
+ return 0;
+ break;
+
+ case TGSI_OPCODE_RET:
+ /* FIXME */
+ return 0;
+ break;
+
+ case TGSI_OPCODE_END:
+ break;
+
+ case TGSI_OPCODE_SSG:
+ /* TGSI_OPCODE_SGN */
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ dst0[chan_index] = lp_build_sgn( &bld->base, tmp0 );
+ }
+ break;
+
+ case TGSI_OPCODE_CMP:
+ 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 );
+ tmp0 = lp_build_cmp( &bld->base, PIPE_FUNC_LESS, src0, bld->base.zero );
+ 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 );
+ 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 );
+ dst0[CHAN_Y] = lp_build_sin( &bld->base, tmp0 );
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_Z ) {
+ dst0[CHAN_Z] = bld->base.zero;
+ }
+ IF_IS_DST0_CHANNEL_ENABLED( inst, CHAN_W ) {
+ dst0[CHAN_W] = bld->base.one;
+ }
+ break;
+
+ case TGSI_OPCODE_TXB:
+ emit_tex( bld, inst, TRUE, FALSE, dst0 );
+ break;
+
+ case TGSI_OPCODE_NRM:
+ /* fall-through */
+ case TGSI_OPCODE_NRM4:
+ /* 3 or 4-component normalization */
+ {
+ uint dims = (inst->Instruction.Opcode == TGSI_OPCODE_NRM) ? 3 : 4;
+
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X) ||
+ IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y) ||
+ IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z) ||
+ (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 4)) {
+
+ /* NOTE: Cannot use xmm regs 2/3 here (see emit_rsqrt() above). */
+
+ /* xmm4 = src.x */
+ /* xmm0 = src.x * src.x */
+ tmp0 = emit_fetch(bld, inst, 0, CHAN_X);
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
+ tmp4 = tmp0;
+ }
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp0);
+
+ /* xmm5 = src.y */
+ /* xmm0 = xmm0 + src.y * src.y */
+ tmp1 = emit_fetch(bld, inst, 0, CHAN_Y);
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
+ tmp5 = tmp1;
+ }
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+
+ /* xmm6 = src.z */
+ /* xmm0 = xmm0 + src.z * src.z */
+ tmp1 = emit_fetch(bld, inst, 0, CHAN_Z);
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
+ tmp6 = tmp1;
+ }
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+
+ if (dims == 4) {
+ /* xmm7 = src.w */
+ /* xmm0 = xmm0 + src.w * src.w */
+ tmp1 = emit_fetch(bld, inst, 0, CHAN_W);
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W)) {
+ tmp7 = tmp1;
+ }
+ tmp1 = lp_build_mul( &bld->base, tmp1, tmp1);
+ tmp0 = lp_build_add( &bld->base, tmp0, tmp1);
+ }
+
+ /* xmm1 = 1 / sqrt(xmm0) */
+ tmp1 = lp_build_rsqrt( &bld->base, tmp0);
+
+ /* dst.x = xmm1 * src.x */
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_X)) {
+ dst0[CHAN_X] = lp_build_mul( &bld->base, tmp4, tmp1);
+ }
+
+ /* dst.y = xmm1 * src.y */
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Y)) {
+ dst0[CHAN_Y] = lp_build_mul( &bld->base, tmp5, tmp1);
+ }
+
+ /* dst.z = xmm1 * src.z */
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_Z)) {
+ 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) {
+ dst0[CHAN_W] = lp_build_mul( &bld->base, tmp7, tmp1);
+ }
+ }
+
+ /* dst.w = 1.0 */
+ if (IS_DST0_CHANNEL_ENABLED(inst, CHAN_W) && dims == 3) {
+ dst0[CHAN_W] = bld->base.one;
+ }
+ }
+ break;
+
+ case TGSI_OPCODE_DIV:
+ /* deprecated */
+ assert( 0 );
+ return 0;
+ break;
+
+ case TGSI_OPCODE_DP2:
+ tmp0 = emit_fetch( bld, inst, 0, CHAN_X ); /* xmm0 = src[0].x */
+ tmp1 = emit_fetch( bld, inst, 1, CHAN_X ); /* xmm1 = src[1].x */
+ tmp0 = lp_build_mul( &bld->base, tmp0, tmp1); /* xmm0 = xmm0 * xmm1 */
+ tmp1 = emit_fetch( bld, inst, 0, CHAN_Y ); /* xmm1 = src[0].y */
+ tmp2 = emit_fetch( bld, inst, 1, CHAN_Y ); /* xmm2 = src[1].y */
+ 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 ) {
+ dst0[chan_index] = tmp0; /* dest[ch] = xmm0 */
+ }
+ break;
+
+ case TGSI_OPCODE_TXL:
+ emit_tex( bld, inst, TRUE, FALSE, dst0 );
+ break;
+
+ case TGSI_OPCODE_TXP:
+ 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:
+ 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;
+
+ case TGSI_OPCODE_TRUNC:
+ FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
+ tmp0 = emit_fetch( bld, inst, 0, chan_index );
+ dst0[chan_index] = lp_build_trunc(&bld->base, tmp0);
+ }
+ break;
+
+ 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;
+
+ case TGSI_OPCODE_EMIT:
+ return 0;
+ break;
+
+ case TGSI_OPCODE_ENDPRIM:
+ 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;
+}
+
+
+void
+lp_build_tgsi_soa(LLVMBuilderRef builder,
+ const struct tgsi_token *tokens,
+ struct lp_type type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef consts_ptr,
+ const LLVMValueRef *pos,
+ const LLVMValueRef (*inputs)[NUM_CHANNELS],
+ LLVMValueRef (*outputs)[NUM_CHANNELS],
+ struct lp_build_sampler_soa *sampler)
+{
+ struct lp_build_tgsi_soa_context bld;
+ struct tgsi_parse_context parse;
+ uint num_immediates = 0;
+ unsigned i;
+
+ /* Setup build context */
+ memset(&bld, 0, sizeof bld);
+ lp_build_context_init(&bld.base, builder, type);
+ bld.mask = mask;
+ bld.pos = pos;
+ bld.inputs = inputs;
+ bld.outputs = outputs;
+ bld.consts_ptr = consts_ptr;
+ bld.sampler = sampler;
+
+ tgsi_parse_init( &parse, tokens );
+
+ while( !tgsi_parse_end_of_tokens( &parse ) ) {
+ tgsi_parse_token( &parse );
+
+ switch( parse.FullToken.Token.Type ) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ /* Inputs already interpolated */
+ break;
+
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ {
+ unsigned opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
+ const struct tgsi_opcode_info *info = tgsi_get_opcode_info(opcode);
+ 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:
+ /* simply copy the immediate values into the next immediates[] slot */
+ {
+ const uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
+ assert(size <= 4);
+ assert(num_immediates < LP_MAX_IMMEDIATES);
+ for( i = 0; i < size; ++i )
+ bld.immediates[num_immediates][i] =
+ lp_build_const_scalar(type, parse.FullToken.FullImmediate.u[i].Float);
+ for( i = size; i < 4; ++i )
+ bld.immediates[num_immediates][i] = bld.base.undef;
+ num_immediates++;
+ }
+ break;
+
+ default:
+ assert( 0 );
+ }
+ }
+
+ tgsi_parse_free( &parse );
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.c b/src/gallium/drivers/llvmpipe/lp_bld_type.c
new file mode 100644
index 0000000000..606243d6c5
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.c
@@ -0,0 +1,182 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_debug.h"
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+
+
+LLVMTypeRef
+lp_build_elem_type(struct lp_type type)
+{
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ return LLVMFloatType();
+ break;
+ case 64:
+ return LLVMDoubleType();
+ break;
+ default:
+ assert(0);
+ return LLVMFloatType();
+ }
+ }
+ else {
+ return LLVMIntType(type.width);
+ }
+}
+
+
+LLVMTypeRef
+lp_build_vec_type(struct lp_type type)
+{
+ LLVMTypeRef elem_type = lp_build_elem_type(type);
+ return LLVMVectorType(elem_type, type.length);
+}
+
+
+/**
+ * This function is a mirror of lp_build_elem_type() above.
+ *
+ * XXX: I'm not sure if it wouldn't be easier/efficient to just recreate the
+ * type and check for identity.
+ */
+boolean
+lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type)
+{
+ LLVMTypeKind elem_kind;
+
+ assert(elem_type);
+ if(!elem_type)
+ return FALSE;
+
+ elem_kind = LLVMGetTypeKind(elem_type);
+
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ if(elem_kind != LLVMFloatTypeKind)
+ return FALSE;
+ break;
+ case 64:
+ if(elem_kind != LLVMDoubleTypeKind)
+ return FALSE;
+ break;
+ default:
+ assert(0);
+ return FALSE;
+ }
+ }
+ else {
+ if(elem_kind != LLVMIntegerTypeKind)
+ return FALSE;
+
+ if(LLVMGetIntTypeWidth(elem_type) != type.width)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+boolean
+lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type)
+{
+ LLVMTypeRef elem_type;
+
+ assert(vec_type);
+ if(!vec_type)
+ return FALSE;
+
+ if(LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind)
+ return FALSE;
+
+ if(LLVMGetVectorSize(vec_type) != type.length)
+ return FALSE;
+
+ elem_type = LLVMGetElementType(vec_type);
+
+ return lp_check_elem_type(type, elem_type);
+}
+
+
+boolean
+lp_check_value(struct lp_type type, LLVMValueRef val)
+{
+ LLVMTypeRef vec_type;
+
+ assert(val);
+ if(!val)
+ return FALSE;
+
+ vec_type = LLVMTypeOf(val);
+
+ return lp_check_vec_type(type, vec_type);
+}
+
+
+LLVMTypeRef
+lp_build_int_elem_type(struct lp_type type)
+{
+ return LLVMIntType(type.width);
+}
+
+
+LLVMTypeRef
+lp_build_int_vec_type(struct lp_type type)
+{
+ LLVMTypeRef elem_type = lp_build_int_elem_type(type);
+ return LLVMVectorType(elem_type, type.length);
+}
+
+
+struct lp_type
+lp_int_type(struct lp_type type)
+{
+ 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;
+}
+
+
+void
+lp_build_context_init(struct lp_build_context *bld,
+ LLVMBuilderRef builder,
+ struct lp_type type)
+{
+ bld->builder = builder;
+ bld->type = type;
+ bld->undef = lp_build_undef(type);
+ bld->zero = lp_build_zero(type);
+ bld->one = lp_build_one(type);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_bld_type.h b/src/gallium/drivers/llvmpipe/lp_bld_type.h
new file mode 100644
index 0000000000..ee5ca3483c
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_bld_type.h
@@ -0,0 +1,175 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Convenient representation of SIMD types.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_BLD_TYPE_H
+#define LP_BLD_TYPE_H
+
+
+#include <llvm-c/Core.h>
+
+#include <pipe/p_compiler.h>
+
+
+/**
+ * Several functions can only cope with vectors of length up to this value.
+ * You may need to increase that value if you want to represent bigger vectors.
+ */
+#define LP_MAX_VECTOR_LENGTH 16
+
+#define LP_MAX_TYPE_WIDTH 64
+
+
+/**
+ * The LLVM type system can't conveniently express all the things we care about
+ * on the types used for intermediate computations, such as signed vs unsigned,
+ * normalized values, or fixed point.
+ */
+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;
+};
+
+
+/**
+ * We need most of the information here in order to correctly and efficiently
+ * translate an arithmetic operation into LLVM IR. Putting it here avoids the
+ * trouble of passing it as parameters.
+ */
+struct lp_build_context
+{
+ LLVMBuilderRef builder;
+
+ /**
+ * This not only describes the input/output LLVM types, but also whether
+ * to normalize/clamp the results.
+ */
+ struct lp_type type;
+
+ /** Same as lp_build_undef(type) */
+ LLVMValueRef undef;
+
+ /** Same as lp_build_zero(type) */
+ LLVMValueRef zero;
+
+ /** Same as lp_build_one(type) */
+ LLVMValueRef one;
+};
+
+
+LLVMTypeRef
+lp_build_elem_type(struct lp_type type);
+
+
+LLVMTypeRef
+lp_build_vec_type(struct lp_type type);
+
+
+boolean
+lp_check_elem_type(struct lp_type type, LLVMTypeRef elem_type);
+
+
+boolean
+lp_check_vec_type(struct lp_type type, LLVMTypeRef vec_type);
+
+
+boolean
+lp_check_value(struct lp_type type, LLVMValueRef val);
+
+
+LLVMTypeRef
+lp_build_int_elem_type(struct lp_type type);
+
+
+LLVMTypeRef
+lp_build_int_vec_type(struct 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,
+ struct lp_type type);
+
+
+#endif /* !LP_BLD_TYPE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.c b/src/gallium/drivers/llvmpipe/lp_buffer.c
new file mode 100644
index 0000000000..66f1f8e138
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.c
@@ -0,0 +1,150 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+
+#include "lp_winsys.h"
+#include "lp_screen.h"
+#include "lp_texture.h"
+#include "lp_buffer.h"
+
+
+static void *
+llvmpipe_buffer_map(struct pipe_screen *screen,
+ struct pipe_buffer *buf,
+ unsigned flags)
+{
+ struct llvmpipe_buffer *llvmpipe_buf = llvmpipe_buffer(buf);
+ return llvmpipe_buf->data;
+}
+
+
+static void
+llvmpipe_buffer_unmap(struct pipe_screen *screen,
+ struct pipe_buffer *buf)
+{
+}
+
+
+static void
+llvmpipe_buffer_destroy(struct pipe_buffer *buf)
+{
+ struct llvmpipe_buffer *sbuf = llvmpipe_buffer(buf);
+
+ if (!sbuf->userBuffer)
+ align_free(sbuf->data);
+
+ FREE(sbuf);
+}
+
+
+static struct pipe_buffer *
+llvmpipe_buffer_create(struct pipe_screen *screen,
+ unsigned alignment,
+ unsigned usage,
+ unsigned size)
+{
+ struct llvmpipe_buffer *buffer = CALLOC_STRUCT(llvmpipe_buffer);
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.alignment = MAX2(alignment, 16);
+ buffer->base.usage = usage;
+ buffer->base.size = size;
+
+ buffer->data = align_malloc(size, alignment);
+
+ return &buffer->base;
+}
+
+
+/**
+ * Create buffer which wraps user-space data.
+ */
+static struct pipe_buffer *
+llvmpipe_user_buffer_create(struct pipe_screen *screen,
+ void *ptr,
+ unsigned bytes)
+{
+ struct llvmpipe_buffer *buffer;
+
+ buffer = CALLOC_STRUCT(llvmpipe_buffer);
+ if(!buffer)
+ return NULL;
+
+ pipe_reference_init(&buffer->base.reference, 1);
+ buffer->base.screen = screen;
+ buffer->base.size = bytes;
+ buffer->userBuffer = TRUE;
+ buffer->data = ptr;
+
+ return &buffer->base;
+}
+
+
+static void
+llvmpipe_fence_reference(struct pipe_screen *screen,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+}
+
+
+static int
+llvmpipe_fence_signalled(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+static int
+llvmpipe_fence_finish(struct pipe_screen *screen,
+ struct pipe_fence_handle *fence,
+ unsigned flag)
+{
+ return 0;
+}
+
+
+void
+llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen)
+{
+ screen->buffer_create = llvmpipe_buffer_create;
+ screen->user_buffer_create = llvmpipe_user_buffer_create;
+ screen->buffer_map = llvmpipe_buffer_map;
+ screen->buffer_unmap = llvmpipe_buffer_unmap;
+ screen->buffer_destroy = llvmpipe_buffer_destroy;
+
+ screen->fence_reference = llvmpipe_fence_reference;
+ screen->fence_signalled = llvmpipe_fence_signalled;
+ screen->fence_finish = llvmpipe_fence_finish;
+
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_buffer.h b/src/gallium/drivers/llvmpipe/lp_buffer.h
new file mode 100644
index 0000000000..d6b8184a0b
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_buffer.h
@@ -0,0 +1,55 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_BUFFER_H
+#define LP_BUFFER_H
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_state.h"
+
+
+struct llvmpipe_buffer
+{
+ struct pipe_buffer base;
+ boolean userBuffer; /** Is this a user-space buffer? */
+ void *data;
+};
+
+
+/** Cast wrapper */
+static INLINE struct llvmpipe_buffer *
+llvmpipe_buffer( struct pipe_buffer *buf )
+{
+ return (struct llvmpipe_buffer *)buf;
+}
+
+
+void
+llvmpipe_init_screen_buffer_funcs(struct pipe_screen *screen);
+
+
+#endif /* LP_BUFFER_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.c b/src/gallium/drivers/llvmpipe/lp_clear.c
new file mode 100644
index 0000000000..bdcff94b9b
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_clear.c
@@ -0,0 +1,81 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * 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.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Brian Paul
+ * Michel Dänzer
+ */
+
+
+#include "pipe/p_defines.h"
+#include "util/u_pack_color.h"
+#include "lp_clear.h"
+#include "lp_context.h"
+#include "lp_surface.h"
+#include "lp_state.h"
+#include "lp_tile_cache.h"
+
+
+/**
+ * Clear the given buffers to the specified values.
+ * No masking, no scissor (clear entire buffer).
+ */
+void
+llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ unsigned cv;
+ uint i;
+
+ if (llvmpipe->no_rast)
+ return;
+
+#if 0
+ llvmpipe_update_derived(llvmpipe); /* not needed?? */
+#endif
+
+ if (buffers & PIPE_CLEAR_COLOR) {
+ for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
+ struct pipe_surface *ps = llvmpipe->framebuffer.cbufs[i];
+
+ 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) {
+ struct pipe_surface *ps = llvmpipe->framebuffer.zsbuf;
+
+ cv = util_pack_z_stencil(ps->format, depth, stencil);
+
+ /* non-cached surface */
+ pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_clear.h b/src/gallium/drivers/llvmpipe/lp_clear.h
new file mode 100644
index 0000000000..6d4ffccdf4
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_clear.h
@@ -0,0 +1,43 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Brian Paul
+ */
+
+#ifndef LP_CLEAR_H
+#define LP_CLEAR_H
+
+#include "pipe/p_state.h"
+struct pipe_context;
+
+extern void
+llvmpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
+ double depth, unsigned stencil);
+
+
+#endif /* LP_CLEAR_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c
new file mode 100644
index 0000000000..a4b2bd8c2a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_context.c
@@ -0,0 +1,295 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "draw/draw_context.h"
+#include "pipe/p_defines.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "lp_clear.h"
+#include "lp_context.h"
+#include "lp_flush.h"
+#include "lp_prim_setup.h"
+#include "lp_prim_vbuf.h"
+#include "lp_state.h"
+#include "lp_surface.h"
+#include "lp_tile_cache.h"
+#include "lp_tex_cache.h"
+#include "lp_texture.h"
+#include "lp_winsys.h"
+#include "lp_query.h"
+
+
+
+/**
+ * Map any drawing surfaces which aren't already mapped
+ */
+void
+llvmpipe_map_transfers(struct llvmpipe_context *lp)
+{
+ struct pipe_screen *screen = lp->pipe.screen;
+ struct pipe_surface *zsbuf = lp->framebuffer.zsbuf;
+ unsigned i;
+
+ for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
+ lp_tile_cache_map_transfers(lp->cbuf_cache[i]);
+ }
+
+ if(zsbuf) {
+ if(!lp->zsbuf_transfer)
+ lp->zsbuf_transfer = screen->get_tex_transfer(screen, zsbuf->texture,
+ zsbuf->face, zsbuf->level, zsbuf->zslice,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, zsbuf->width, zsbuf->height);
+ if(lp->zsbuf_transfer && !lp->zsbuf_map)
+ lp->zsbuf_map = screen->transfer_map(screen, lp->zsbuf_transfer);
+
+ }
+}
+
+
+/**
+ * Unmap any mapped drawing surfaces
+ */
+void
+llvmpipe_unmap_transfers(struct llvmpipe_context *lp)
+{
+ uint i;
+
+ for (i = 0; i < lp->framebuffer.nr_cbufs; i++) {
+ lp_tile_cache_unmap_transfers(lp->cbuf_cache[i]);
+ }
+
+ if(lp->zsbuf_transfer) {
+ struct pipe_screen *screen = lp->pipe.screen;
+
+ if(lp->zsbuf_map) {
+ screen->transfer_unmap(screen, lp->zsbuf_transfer);
+ lp->zsbuf_map = NULL;
+ }
+ }
+}
+
+
+static void llvmpipe_destroy( struct pipe_context *pipe )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+ uint i;
+
+ if (llvmpipe->draw)
+ draw_destroy( llvmpipe->draw );
+
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+ lp_destroy_tile_cache(llvmpipe->cbuf_cache[i]);
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+ lp_destroy_tex_tile_cache(llvmpipe->tex_cache[i]);
+
+ for (i = 0; i < Elements(llvmpipe->constants); i++) {
+ if (llvmpipe->constants[i].buffer) {
+ pipe_buffer_reference(&llvmpipe->constants[i].buffer, NULL);
+ }
+ }
+
+ align_free( llvmpipe );
+}
+
+static unsigned int
+llvmpipe_is_texture_referenced( struct pipe_context *pipe,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+ unsigned i;
+
+ if(llvmpipe->dirty_render_cache) {
+ for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++) {
+ if(llvmpipe->framebuffer.cbufs[i] &&
+ llvmpipe->framebuffer.cbufs[i]->texture == texture)
+ return PIPE_REFERENCED_FOR_WRITE;
+ }
+ if(llvmpipe->framebuffer.zsbuf &&
+ llvmpipe->framebuffer.zsbuf->texture == texture)
+ return PIPE_REFERENCED_FOR_WRITE;
+ }
+
+ return PIPE_UNREFERENCED;
+}
+
+static unsigned int
+llvmpipe_is_buffer_referenced( struct pipe_context *pipe,
+ struct pipe_buffer *buf)
+{
+ return PIPE_UNREFERENCED;
+}
+
+struct pipe_context *
+llvmpipe_create( struct pipe_screen *screen )
+{
+ struct llvmpipe_context *llvmpipe;
+ uint i;
+
+ llvmpipe = align_malloc(sizeof(struct llvmpipe_context), 16);
+ if (!llvmpipe)
+ return NULL;
+
+ util_init_math();
+
+ memset(llvmpipe, 0, sizeof *llvmpipe);
+
+ llvmpipe->pipe.winsys = screen->winsys;
+ llvmpipe->pipe.screen = screen;
+ llvmpipe->pipe.destroy = llvmpipe_destroy;
+
+ /* state setters */
+ llvmpipe->pipe.create_blend_state = llvmpipe_create_blend_state;
+ llvmpipe->pipe.bind_blend_state = llvmpipe_bind_blend_state;
+ llvmpipe->pipe.delete_blend_state = llvmpipe_delete_blend_state;
+
+ llvmpipe->pipe.create_sampler_state = llvmpipe_create_sampler_state;
+ llvmpipe->pipe.bind_sampler_states = llvmpipe_bind_sampler_states;
+ llvmpipe->pipe.delete_sampler_state = llvmpipe_delete_sampler_state;
+
+ llvmpipe->pipe.create_depth_stencil_alpha_state = llvmpipe_create_depth_stencil_state;
+ llvmpipe->pipe.bind_depth_stencil_alpha_state = llvmpipe_bind_depth_stencil_state;
+ llvmpipe->pipe.delete_depth_stencil_alpha_state = llvmpipe_delete_depth_stencil_state;
+
+ llvmpipe->pipe.create_rasterizer_state = llvmpipe_create_rasterizer_state;
+ llvmpipe->pipe.bind_rasterizer_state = llvmpipe_bind_rasterizer_state;
+ llvmpipe->pipe.delete_rasterizer_state = llvmpipe_delete_rasterizer_state;
+
+ llvmpipe->pipe.create_fs_state = llvmpipe_create_fs_state;
+ llvmpipe->pipe.bind_fs_state = llvmpipe_bind_fs_state;
+ llvmpipe->pipe.delete_fs_state = llvmpipe_delete_fs_state;
+
+ llvmpipe->pipe.create_vs_state = llvmpipe_create_vs_state;
+ llvmpipe->pipe.bind_vs_state = llvmpipe_bind_vs_state;
+ llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state;
+
+ llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color;
+ llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state;
+ llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer;
+ llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state;
+ llvmpipe->pipe.set_polygon_stipple = llvmpipe_set_polygon_stipple;
+ llvmpipe->pipe.set_scissor_state = llvmpipe_set_scissor_state;
+ llvmpipe->pipe.set_sampler_textures = llvmpipe_set_sampler_textures;
+ llvmpipe->pipe.set_viewport_state = llvmpipe_set_viewport_state;
+
+ llvmpipe->pipe.set_vertex_buffers = llvmpipe_set_vertex_buffers;
+ llvmpipe->pipe.set_vertex_elements = llvmpipe_set_vertex_elements;
+
+ llvmpipe->pipe.draw_arrays = llvmpipe_draw_arrays;
+ llvmpipe->pipe.draw_elements = llvmpipe_draw_elements;
+ llvmpipe->pipe.draw_range_elements = llvmpipe_draw_range_elements;
+ llvmpipe->pipe.set_edgeflags = llvmpipe_set_edgeflags;
+
+
+ llvmpipe->pipe.clear = llvmpipe_clear;
+ llvmpipe->pipe.flush = llvmpipe_flush;
+
+ llvmpipe->pipe.is_texture_referenced = llvmpipe_is_texture_referenced;
+ llvmpipe->pipe.is_buffer_referenced = llvmpipe_is_buffer_referenced;
+
+ llvmpipe_init_query_funcs( llvmpipe );
+ llvmpipe_init_texture_funcs( llvmpipe );
+
+ /*
+ * Alloc caches for accessing drawing surfaces and textures.
+ */
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++)
+ llvmpipe->cbuf_cache[i] = lp_create_tile_cache( screen );
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++)
+ llvmpipe->tex_cache[i] = lp_create_tex_tile_cache( screen );
+
+
+ /* vertex shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ llvmpipe->tgsi.vert_samplers[i].base.get_samples = lp_get_samples;
+ llvmpipe->tgsi.vert_samplers[i].processor = TGSI_PROCESSOR_VERTEX;
+ llvmpipe->tgsi.vert_samplers[i].cache = llvmpipe->tex_cache[i];
+ llvmpipe->tgsi.vert_samplers_list[i] = &llvmpipe->tgsi.vert_samplers[i];
+ }
+
+ /* fragment shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
+ llvmpipe->tgsi.frag_samplers[i].processor = TGSI_PROCESSOR_FRAGMENT;
+ llvmpipe->tgsi.frag_samplers[i].cache = llvmpipe->tex_cache[i];
+ llvmpipe->tgsi.frag_samplers_list[i] = &llvmpipe->tgsi.frag_samplers[i];
+ }
+
+ /*
+ * Create drawing context and plug our rendering stage into it.
+ */
+ llvmpipe->draw = draw_create();
+ if (!llvmpipe->draw)
+ goto fail;
+
+ draw_texture_samplers(llvmpipe->draw,
+ PIPE_MAX_SAMPLERS,
+ (struct tgsi_sampler **)
+ llvmpipe->tgsi.vert_samplers_list);
+
+ llvmpipe->setup = lp_draw_render_stage(llvmpipe);
+ if (!llvmpipe->setup)
+ goto fail;
+
+ if (debug_get_bool_option( "LP_NO_RAST", FALSE ))
+ llvmpipe->no_rast = TRUE;
+
+ if (debug_get_bool_option( "LP_NO_VBUF", FALSE )) {
+ /* Deprecated path -- vbuf is the intended interface to the draw module:
+ */
+ draw_set_rasterize_stage(llvmpipe->draw, llvmpipe->setup);
+ }
+ else {
+ lp_init_vbuf(llvmpipe);
+ }
+
+ /* plug in AA line/point stages */
+ draw_install_aaline_stage(llvmpipe->draw, &llvmpipe->pipe);
+ draw_install_aapoint_stage(llvmpipe->draw, &llvmpipe->pipe);
+
+#if USE_DRAW_STAGE_PSTIPPLE
+ /* Do polygon stipple w/ texture map + frag prog? */
+ draw_install_pstipple_stage(llvmpipe->draw, &llvmpipe->pipe);
+#endif
+
+ lp_init_surface_functions(llvmpipe);
+
+ return &llvmpipe->pipe;
+
+ fail:
+ llvmpipe_destroy(&llvmpipe->pipe);
+ return NULL;
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h
new file mode 100644
index 0000000000..8d5a0d4f1f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_context.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.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef LP_CONTEXT_H
+#define LP_CONTEXT_H
+
+#include "pipe/p_context.h"
+
+#include "draw/draw_vertex.h"
+
+#include "lp_tex_sample.h"
+#include "lp_jit.h"
+
+
+struct llvmpipe_vbuf_render;
+struct draw_context;
+struct draw_stage;
+struct llvmpipe_tile_cache;
+struct llvmpipe_tex_tile_cache;
+struct lp_fragment_shader;
+struct lp_vertex_shader;
+struct lp_blend_state;
+
+
+struct llvmpipe_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;
+ struct lp_fragment_shader *fs;
+ const struct lp_vertex_shader *vs;
+
+ /** Other rendering state */
+ struct pipe_blend_color blend_color[4][16];
+ struct pipe_clip_state clip;
+ struct pipe_constant_buffer constants[PIPE_SHADER_TYPES];
+ struct pipe_framebuffer_state framebuffer;
+ struct pipe_poly_stipple poly_stipple;
+ struct pipe_scissor_state scissor;
+ struct pipe_texture *texture[PIPE_MAX_SAMPLERS];
+ struct pipe_viewport_state viewport;
+ struct pipe_vertex_buffer vertex_buffer[PIPE_MAX_ATTRIBS];
+ struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS];
+
+ unsigned num_samplers;
+ unsigned num_textures;
+ unsigned num_vertex_elements;
+ unsigned num_vertex_buffers;
+
+ unsigned dirty; /**< Mask of LP_NEW_x flags */
+
+ /* Counter for occlusion queries. Note this supports overlapping
+ * queries.
+ */
+ uint64_t occlusion_count;
+ unsigned active_query_count;
+
+ /** Mapped vertex buffers */
+ ubyte *mapped_vbuffer[PIPE_MAX_ATTRIBS];
+
+ /** Mapped constant buffers */
+ void *mapped_constants[PIPE_SHADER_TYPES];
+
+ /** Vertex format */
+ struct vertex_info vertex_info;
+ struct vertex_info vertex_info_vbuf;
+
+ /** Which vertex shader output slot contains point size */
+ int psize_slot;
+
+ /* 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;
+
+ unsigned line_stipple_counter;
+
+ /** TGSI exec things */
+ struct {
+ struct lp_shader_sampler vert_samplers[PIPE_MAX_SAMPLERS];
+ struct lp_shader_sampler *vert_samplers_list[PIPE_MAX_SAMPLERS];
+ struct lp_shader_sampler frag_samplers[PIPE_MAX_SAMPLERS];
+ struct lp_shader_sampler *frag_samplers_list[PIPE_MAX_SAMPLERS];
+ } tgsi;
+
+ /** The primitive drawing context */
+ struct draw_context *draw;
+ struct draw_stage *setup;
+ struct draw_stage *vbuf;
+ struct llvmpipe_vbuf_render *vbuf_render;
+
+ boolean dirty_render_cache;
+
+ struct llvmpipe_tile_cache *cbuf_cache[PIPE_MAX_COLOR_BUFS];
+
+ /* TODO: we shouldn't be using external interfaces internally like this */
+ struct pipe_transfer *zsbuf_transfer;
+ uint8_t *zsbuf_map;
+
+ unsigned tex_timestamp;
+ struct llvmpipe_tex_tile_cache *tex_cache[PIPE_MAX_SAMPLERS];
+
+ unsigned no_rast : 1;
+
+ struct lp_jit_context jit_context;
+};
+
+
+static INLINE struct llvmpipe_context *
+llvmpipe_context( struct pipe_context *pipe )
+{
+ return (struct llvmpipe_context *)pipe;
+}
+
+#endif /* LP_CONTEXT_H */
+
diff --git a/src/gallium/drivers/llvmpipe/lp_draw_arrays.c b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
new file mode 100644
index 0000000000..89772e62d3
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_draw_arrays.c
@@ -0,0 +1,192 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Brian Paul
+ * Keith Whitwell
+ */
+
+
+#include "pipe/p_defines.h"
+#include "pipe/p_context.h"
+#include "pipe/internal/p_winsys_screen.h"
+#include "pipe/p_inlines.h"
+#include "util/u_prim.h"
+
+#include "lp_buffer.h"
+#include "lp_context.h"
+#include "lp_state.h"
+
+#include "draw/draw_context.h"
+
+
+
+static void
+llvmpipe_map_constant_buffers(struct llvmpipe_context *lp)
+{
+ struct pipe_screen *screen = lp->pipe.screen;
+ uint i, size;
+
+ for (i = 0; i < PIPE_SHADER_TYPES; i++) {
+ if (lp->constants[i].buffer && lp->constants[i].buffer->size)
+ lp->mapped_constants[i] = screen->buffer_map(screen, lp->constants[i].buffer,
+ PIPE_BUFFER_USAGE_CPU_READ);
+ }
+
+ if (lp->constants[PIPE_SHADER_VERTEX].buffer)
+ size = lp->constants[PIPE_SHADER_VERTEX].buffer->size;
+ else
+ size = 0;
+
+ lp->jit_context.constants = lp->mapped_constants[PIPE_SHADER_FRAGMENT];
+
+ draw_set_mapped_constant_buffer(lp->draw,
+ lp->mapped_constants[PIPE_SHADER_VERTEX],
+ size);
+}
+
+
+static void
+llvmpipe_unmap_constant_buffers(struct llvmpipe_context *lp)
+{
+ struct pipe_screen *screen = lp->pipe.screen;
+ uint i;
+
+ /* really need to flush all prims since the vert/frag shaders const buffers
+ * are going away now.
+ */
+ draw_flush(lp->draw);
+
+ draw_set_mapped_constant_buffer(lp->draw, NULL, 0);
+
+ lp->jit_context.constants = NULL;
+
+ for (i = 0; i < 2; i++) {
+ if (lp->constants[i].buffer && lp->constants[i].buffer->size)
+ screen->buffer_unmap(screen, lp->constants[i].buffer);
+ lp->mapped_constants[i] = NULL;
+ }
+}
+
+
+boolean
+llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count)
+{
+ return llvmpipe_draw_elements(pipe, NULL, 0, mode, start, count);
+}
+
+
+/**
+ * Draw vertex arrays, with optional indexing.
+ * Basically, map the vertex buffers (and drawing surfaces), then hand off
+ * the drawing to the 'draw' module.
+ */
+boolean
+llvmpipe_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count)
+{
+ struct llvmpipe_context *lp = llvmpipe_context(pipe);
+ struct draw_context *draw = lp->draw;
+ unsigned i;
+
+ lp->reduced_api_prim = u_reduced_prim(mode);
+
+ if (lp->dirty)
+ llvmpipe_update_derived( lp );
+
+ llvmpipe_map_transfers(lp);
+ llvmpipe_map_constant_buffers(lp);
+
+ /*
+ * Map vertex buffers
+ */
+ for (i = 0; i < lp->num_vertex_buffers; i++) {
+ void *buf = llvmpipe_buffer(lp->vertex_buffer[i].buffer)->data;
+ draw_set_mapped_vertex_buffer(draw, i, buf);
+ }
+
+ /* Map index buffer, if present */
+ if (indexBuffer) {
+ void *mapped_indexes = llvmpipe_buffer(indexBuffer)->data;
+ draw_set_mapped_element_buffer_range(draw, indexSize,
+ min_index,
+ max_index,
+ mapped_indexes);
+ }
+ else {
+ /* no index/element buffer */
+ draw_set_mapped_element_buffer_range(draw, 0, start,
+ start + count - 1, NULL);
+ }
+
+ /* draw! */
+ draw_arrays(draw, mode, start, count);
+
+ /*
+ * unmap vertex/index buffers - will cause draw module to flush
+ */
+ for (i = 0; i < lp->num_vertex_buffers; i++) {
+ draw_set_mapped_vertex_buffer(draw, i, NULL);
+ }
+ if (indexBuffer) {
+ draw_set_mapped_element_buffer(draw, 0, NULL);
+ }
+
+
+ /* Note: leave drawing surfaces mapped */
+ llvmpipe_unmap_constant_buffers(lp);
+
+ lp->dirty_render_cache = TRUE;
+
+ return TRUE;
+}
+
+
+boolean
+llvmpipe_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count)
+{
+ return llvmpipe_draw_range_elements( pipe, indexBuffer,
+ indexSize,
+ 0, 0xffffffff,
+ mode, start, count );
+}
+
+
+void
+llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags)
+{
+ struct llvmpipe_context *lp = llvmpipe_context(pipe);
+ draw_set_edgeflags(lp->draw, edgeflags);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.c b/src/gallium/drivers/llvmpipe/lp_flush.c
new file mode 100644
index 0000000000..b5c1c95bb7
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_flush.c
@@ -0,0 +1,98 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "pipe/p_defines.h"
+#include "draw/draw_context.h"
+#include "lp_flush.h"
+#include "lp_context.h"
+#include "lp_surface.h"
+#include "lp_state.h"
+#include "lp_tile_cache.h"
+#include "lp_tex_cache.h"
+#include "lp_winsys.h"
+
+
+void
+llvmpipe_flush( struct pipe_context *pipe,
+ unsigned flags,
+ struct pipe_fence_handle **fence )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ uint i;
+
+ draw_flush(llvmpipe->draw);
+
+ 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 < llvmpipe->framebuffer.nr_cbufs; i++)
+ if (llvmpipe->cbuf_cache[i])
+ lp_flush_tile_cache(llvmpipe->cbuf_cache[i]);
+
+ /* Need this call for hardware buffers before swapbuffers.
+ *
+ * there should probably be another/different flush-type function
+ * that's called before swapbuffers because we don't always want
+ * to unmap surfaces when flushing.
+ */
+ llvmpipe_unmap_transfers(llvmpipe);
+ }
+ else if (flags & PIPE_FLUSH_RENDER_CACHE) {
+ for (i = 0; i < llvmpipe->framebuffer.nr_cbufs; i++)
+ if (llvmpipe->cbuf_cache[i])
+ lp_flush_tile_cache(llvmpipe->cbuf_cache[i]);
+
+ /* FIXME: untile zsbuf! */
+
+ llvmpipe->dirty_render_cache = FALSE;
+ }
+
+ /* Enable to dump BMPs of the color/depth buffers each frame */
+#if 0
+ if(flags & PIPE_FLUSH_FRAME) {
+ static unsigned frame_no = 1;
+ static char filename[256];
+ util_snprintf(filename, sizeof(filename), "cbuf_%u.bmp", frame_no);
+ debug_dump_surface_bmp(filename, llvmpipe->framebuffer.cbufs[0]);
+ util_snprintf(filename, sizeof(filename), "zsbuf_%u.bmp", frame_no);
+ debug_dump_surface_bmp(filename, llvmpipe->framebuffer.zsbuf);
+ ++frame_no;
+ }
+#endif
+
+ if (fence)
+ *fence = NULL;
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_flush.h b/src/gallium/drivers/llvmpipe/lp_flush.h
new file mode 100644
index 0000000000..10b2b52583
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_flush.h
@@ -0,0 +1,37 @@
+/**************************************************************************
+ *
+ * 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 LP_FLUSH_H
+#define LP_FLUSH_H
+
+struct pipe_context;
+struct pipe_fence_handle;
+
+void llvmpipe_flush(struct pipe_context *pipe, unsigned flags,
+ struct pipe_fence_handle **fence);
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
new file mode 100644
index 0000000000..b4a22ff4a9
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -0,0 +1,173 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * C - JIT interfaces
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include <llvm-c/Transforms/Scalar.h>
+
+#include "util/u_memory.h"
+#include "lp_screen.h"
+#include "lp_bld_intr.h"
+#include "lp_jit.h"
+
+
+static void
+lp_jit_init_globals(struct llvmpipe_screen *screen)
+{
+ LLVMTypeRef texture_type;
+
+ /* struct lp_jit_texture */
+ {
+ LLVMTypeRef elem_types[4];
+
+ elem_types[LP_JIT_TEXTURE_WIDTH] = LLVMInt32Type();
+ elem_types[LP_JIT_TEXTURE_HEIGHT] = LLVMInt32Type();
+ elem_types[LP_JIT_TEXTURE_STRIDE] = LLVMInt32Type();
+ elem_types[LP_JIT_TEXTURE_DATA] = LLVMPointerType(LLVMInt8Type(), 0);
+
+ texture_type = LLVMStructType(elem_types, Elements(elem_types), 0);
+
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, width,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_WIDTH);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, height,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_HEIGHT);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, stride,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_STRIDE);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_texture, data,
+ screen->target, texture_type,
+ LP_JIT_TEXTURE_DATA);
+ LP_CHECK_STRUCT_SIZE(struct lp_jit_texture,
+ screen->target, texture_type);
+
+ LLVMAddTypeName(screen->module, "texture", texture_type);
+ }
+
+ /* struct lp_jit_context */
+ {
+ LLVMTypeRef elem_types[5];
+ LLVMTypeRef context_type;
+
+ elem_types[0] = LLVMPointerType(LLVMFloatType(), 0); /* constants */
+ elem_types[1] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
+ elem_types[2] = LLVMFloatType(); /* alpha_ref_value */
+ elem_types[3] = LLVMPointerType(LLVMInt8Type(), 0); /* blend_color */
+ elem_types[4] = LLVMArrayType(texture_type, PIPE_MAX_SAMPLERS); /* textures */
+
+ context_type = LLVMStructType(elem_types, Elements(elem_types), 0);
+
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, constants,
+ screen->target, context_type, 0);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, samplers,
+ screen->target, context_type, 1);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, alpha_ref_value,
+ screen->target, context_type, 2);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, blend_color,
+ screen->target, context_type, 3);
+ LP_CHECK_MEMBER_OFFSET(struct lp_jit_context, textures,
+ screen->target, context_type,
+ LP_JIT_CONTEXT_TEXTURES_INDEX);
+ LP_CHECK_STRUCT_SIZE(struct lp_jit_context,
+ screen->target, context_type);
+
+ LLVMAddTypeName(screen->module, "context", context_type);
+
+ screen->context_ptr_type = LLVMPointerType(context_type, 0);
+ }
+
+ /* fetch_texel
+ */
+ {
+ LLVMTypeRef ret_type;
+ LLVMTypeRef arg_types[3];
+ LLVMValueRef fetch_texel;
+
+ ret_type = LLVMVoidType();
+ arg_types[0] = LLVMPointerType(LLVMInt8Type(), 0); /* samplers */
+ arg_types[1] = LLVMInt32Type(); /* unit */
+ arg_types[2] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0); /* store */
+
+ fetch_texel = lp_declare_intrinsic(screen->module, "fetch_texel",
+ ret_type, arg_types, Elements(arg_types));
+
+ LLVMAddGlobalMapping(screen->engine, fetch_texel, lp_fetch_texel_soa);
+ }
+
+#ifdef DEBUG
+ LLVMDumpModule(screen->module);
+#endif
+}
+
+
+void
+lp_jit_screen_cleanup(struct llvmpipe_screen *screen)
+{
+ if(screen->engine)
+ LLVMDisposeExecutionEngine(screen->engine);
+
+ if(screen->pass)
+ LLVMDisposePassManager(screen->pass);
+}
+
+
+void
+lp_jit_screen_init(struct llvmpipe_screen *screen)
+{
+ char *error = NULL;
+
+ screen->module = LLVMModuleCreateWithName("llvmpipe");
+
+ screen->provider = LLVMCreateModuleProviderForExistingModule(screen->module);
+
+ if (LLVMCreateJITCompiler(&screen->engine, screen->provider, 1, &error)) {
+ _debug_printf("%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+ screen->target = LLVMGetExecutionEngineTargetData(screen->engine);
+
+ screen->pass = LLVMCreateFunctionPassManager(screen->provider);
+ LLVMAddTargetData(screen->target, screen->pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(screen->pass);
+ LLVMAddInstructionCombiningPass(screen->pass);
+ LLVMAddPromoteMemoryToRegisterPass(screen->pass);
+ LLVMAddGVNPass(screen->pass);
+ LLVMAddCFGSimplificationPass(screen->pass);
+
+ lp_jit_init_globals(screen);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.h b/src/gallium/drivers/llvmpipe/lp_jit.h
new file mode 100644
index 0000000000..58f716ede2
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_jit.h
@@ -0,0 +1,135 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * C - JIT interfaces
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#ifndef LP_JIT_H
+#define LP_JIT_H
+
+
+#include "lp_bld_struct.h"
+
+#include "pipe/p_state.h"
+
+
+struct tgsi_sampler;
+struct llvmpipe_screen;
+
+
+struct lp_jit_texture
+{
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
+ const void *data;
+};
+
+
+enum {
+ LP_JIT_TEXTURE_WIDTH = 0,
+ LP_JIT_TEXTURE_HEIGHT,
+ LP_JIT_TEXTURE_STRIDE,
+ LP_JIT_TEXTURE_DATA
+};
+
+
+
+/**
+ * This structure is passed directly to the generated fragment shader.
+ *
+ * It contains the derived state.
+ *
+ * Changes here must be reflected in the lp_jit_context_* macros and
+ * lp_jit_init_types function. Changes to the ordering should be avoided.
+ *
+ * Only use types with a clear size and padding here, in particular prefer the
+ * stdint.h types to the basic integer types.
+ */
+struct lp_jit_context
+{
+ const float *constants;
+
+ struct tgsi_sampler **samplers;
+
+ float alpha_ref_value;
+
+ /* FIXME: store (also?) in floats */
+ uint8_t *blend_color;
+
+ struct lp_jit_texture textures[PIPE_MAX_SAMPLERS];
+};
+
+
+#define lp_jit_context_constants(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 0, "constants")
+
+#define lp_jit_context_samplers(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 1, "samplers")
+
+#define lp_jit_context_alpha_ref_value(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 2, "alpha_ref_value")
+
+#define lp_jit_context_blend_color(_builder, _ptr) \
+ lp_build_struct_get(_builder, _ptr, 3, "blend_color")
+
+#define LP_JIT_CONTEXT_TEXTURES_INDEX 4
+
+#define lp_jit_context_textures(_builder, _ptr) \
+ lp_build_struct_get_ptr(_builder, _ptr, LP_JIT_CONTEXT_TEXTURES_INDEX, "textures")
+
+
+typedef void
+(*lp_jit_frag_func)(struct lp_jit_context *context,
+ uint32_t x,
+ uint32_t y,
+ const void *a0,
+ const void *dadx,
+ const void *dady,
+ uint32_t *mask,
+ void *color,
+ void *depth);
+
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+ uint32_t unit,
+ float *store );
+
+
+void
+lp_jit_screen_cleanup(struct llvmpipe_screen *screen);
+
+
+void
+lp_jit_screen_init(struct llvmpipe_screen *screen);
+
+
+#endif /* LP_JIT_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_setup.c b/src/gallium/drivers/llvmpipe/lp_prim_setup.c
new file mode 100644
index 0000000000..b14f8fb99d
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_prim_setup.c
@@ -0,0 +1,190 @@
+/**************************************************************************
+ *
+ * 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 lp_prim_vbuf.c.
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ * \author Brian Paul
+ */
+
+
+#include "lp_context.h"
+#include "lp_setup.h"
+#include "lp_state.h"
+#include "lp_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 );
+
+ llvmpipe_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 );
+
+ llvmpipe_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 );
+
+ llvmpipe_setup_point( setup->setup,
+ (cptrf4)prim->v[0]->data );
+}
+
+
+
+
+static void setup_begin( struct draw_stage *stage )
+{
+ struct setup_stage *setup = setup_stage(stage);
+
+ llvmpipe_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);
+ llvmpipe_setup_destroy_context(ssetup->setup);
+ FREE( stage );
+}
+
+
+/**
+ * Create a new primitive setup/render stage.
+ */
+struct draw_stage *lp_draw_render_stage( struct llvmpipe_context *llvmpipe )
+{
+ struct setup_stage *sstage = CALLOC_STRUCT(setup_stage);
+
+ sstage->setup = llvmpipe_setup_create_context(llvmpipe);
+ sstage->stage.draw = llvmpipe->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 *
+lp_draw_setup_context( struct draw_stage *stage )
+{
+ struct setup_stage *ssetup = setup_stage(stage);
+ return ssetup->setup;
+}
+
+void
+lp_draw_flush( struct draw_stage *stage )
+{
+ stage->flush( stage, 0 );
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_setup.h b/src/gallium/drivers/llvmpipe/lp_prim_setup.h
new file mode 100644
index 0000000000..da6cae6375
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_prim_setup.h
@@ -0,0 +1,85 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#ifndef LP_PRIM_SETUP_H
+#define LP_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 llvmpipe_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 *
+lp_draw_render_stage( struct llvmpipe_context *llvmpipe );
+
+extern struct setup_context *
+lp_draw_setup_context( struct draw_stage * );
+
+extern void
+lp_draw_flush( struct draw_stage * );
+
+
+extern struct draw_stage *
+lp_draw_vbuf_stage( struct draw_context *draw_context,
+ struct pipe_context *pipe,
+ vbuf_draw_func draw );
+
+
+#endif /* LP_PRIM_SETUP_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
new file mode 100644
index 0000000000..c394dcb61d
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.c
@@ -0,0 +1,607 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * Interface between 'draw' module's output and the llvmpipe rasterizer/setup
+ * code. When the 'draw' module has finished filling a vertex buffer, the
+ * draw_arrays() functions below will be called. Loop over the vertices and
+ * call the point/line/tri setup functions.
+ *
+ * Authors
+ * Brian Paul
+ */
+
+
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_prim_vbuf.h"
+#include "lp_prim_setup.h"
+#include "lp_setup.h"
+#include "draw/draw_context.h"
+#include "draw/draw_vbuf.h"
+#include "util/u_memory.h"
+#include "util/u_prim.h"
+
+
+#define LP_MAX_VBUF_INDEXES 1024
+#define LP_MAX_VBUF_SIZE 4096
+
+typedef const float (*cptrf4)[4];
+
+/**
+ * Subclass of vbuf_render.
+ */
+struct llvmpipe_vbuf_render
+{
+ struct vbuf_render base;
+ struct llvmpipe_context *llvmpipe;
+ uint prim;
+ uint vertex_size;
+ uint nr_vertices;
+ uint vertex_buffer_size;
+ void *vertex_buffer;
+};
+
+
+/** cast wrapper */
+static struct llvmpipe_vbuf_render *
+llvmpipe_vbuf_render(struct vbuf_render *vbr)
+{
+ return (struct llvmpipe_vbuf_render *) vbr;
+}
+
+
+static const struct vertex_info *
+lp_vbuf_get_vertex_info(struct vbuf_render *vbr)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ return llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe);
+}
+
+
+static boolean
+lp_vbuf_allocate_vertices(struct vbuf_render *vbr,
+ ushort vertex_size, ushort nr_vertices)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ unsigned size = vertex_size * nr_vertices;
+
+ if (cvbr->vertex_buffer_size < size) {
+ align_free(cvbr->vertex_buffer);
+ cvbr->vertex_buffer = align_malloc(size, 16);
+ cvbr->vertex_buffer_size = size;
+ }
+
+ cvbr->vertex_size = vertex_size;
+ cvbr->nr_vertices = nr_vertices;
+
+ return cvbr->vertex_buffer != NULL;
+}
+
+static void
+lp_vbuf_release_vertices(struct vbuf_render *vbr)
+{
+#if 0
+ {
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ const struct vertex_info *info =
+ llvmpipe_get_vbuf_vertex_info(cvbr->llvmpipe);
+ 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 */
+}
+
+static void *
+lp_vbuf_map_vertices(struct vbuf_render *vbr)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ return cvbr->vertex_buffer;
+}
+
+static void
+lp_vbuf_unmap_vertices(struct vbuf_render *vbr,
+ ushort min_index,
+ ushort max_index )
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ assert( cvbr->vertex_buffer_size >= (max_index+1) * cvbr->vertex_size );
+ /* do nothing */
+}
+
+
+static boolean
+lp_vbuf_set_primitive(struct vbuf_render *vbr, unsigned prim)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+
+ /* XXX: break this dependency - make setup_context live under
+ * llvmpipe, rename the old "setup" draw stage to something else.
+ */
+ struct setup_context *setup_ctx = lp_draw_setup_context(cvbr->llvmpipe->setup);
+
+ llvmpipe_setup_prepare( setup_ctx );
+
+ cvbr->llvmpipe->reduced_prim = u_reduced_prim(prim);
+ cvbr->prim = prim;
+ return TRUE;
+
+}
+
+
+static INLINE cptrf4 get_vert( const void *vertex_buffer,
+ int index,
+ int stride )
+{
+ return (cptrf4)((char *)vertex_buffer + index * stride);
+}
+
+
+/**
+ * draw elements / indexed primitives
+ */
+static void
+lp_vbuf_draw(struct vbuf_render *vbr, const ushort *indices, uint nr)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
+ const unsigned stride = llvmpipe->vertex_info_vbuf.size * sizeof(float);
+ const void *vertex_buffer = cvbr->vertex_buffer;
+ unsigned i;
+
+ /* XXX: break this dependency - make setup_context live under
+ * llvmpipe, rename the old "setup" draw stage to something else.
+ */
+ struct draw_stage *setup = llvmpipe->setup;
+ struct setup_context *setup_ctx = lp_draw_setup_context(setup);
+
+ switch (cvbr->prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < nr; i++) {
+ llvmpipe_setup_point( setup_ctx,
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 1; i < nr; i += 2) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP:
+ for (i = 1; i < nr; i ++) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINE_LOOP:
+ for (i = 1; i < nr; i ++) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ if (nr) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, indices[nr-1], stride),
+ get_vert(vertex_buffer, indices[0], stride) );
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 3) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i += 3) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i+(i&1)-2], stride),
+ get_vert(vertex_buffer, indices[i-(i&1)-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[0], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUADS:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 4) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride) );
+ llvmpipe_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-3], stride) );
+ }
+ }
+ else {
+ for (i = 3; i < nr; i += 4) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUAD_STRIP:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 2) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride));
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-3], stride) );
+ }
+ }
+ else {
+ for (i = 3; i < nr; i += 2) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-2], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[i-3], stride),
+ get_vert(vertex_buffer, indices[i-0], stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_POLYGON:
+ /* Almost same as tri fan but the _first_ vertex specifies the flat
+ * shading color. Note that the first polygon vertex is passed as
+ * the last triangle vertex here.
+ * flatshade_first state makes no difference.
+ */
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, indices[i-0], stride),
+ get_vert(vertex_buffer, indices[i-1], stride),
+ get_vert(vertex_buffer, indices[0], stride) );
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+
+ /* XXX: why are we calling this??? If we had to call something, it
+ * would be a function in lp_setup.c:
+ */
+ lp_draw_flush( setup );
+}
+
+
+/**
+ * This function is hit when the draw module is working in pass-through mode.
+ * It's up to us to convert the vertex array into point/line/tri prims.
+ */
+static void
+lp_vbuf_draw_arrays(struct vbuf_render *vbr, uint start, uint nr)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ struct llvmpipe_context *llvmpipe = cvbr->llvmpipe;
+ const unsigned stride = llvmpipe->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
+ * llvmpipe, rename the old "setup" draw stage to something else.
+ */
+ struct draw_stage *setup = llvmpipe->setup;
+ struct setup_context *setup_ctx = lp_draw_setup_context(setup);
+
+ switch (cvbr->prim) {
+ case PIPE_PRIM_POINTS:
+ for (i = 0; i < nr; i++) {
+ llvmpipe_setup_point( setup_ctx,
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINES:
+ for (i = 1; i < nr; i += 2) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINE_STRIP:
+ for (i = 1; i < nr; i ++) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ break;
+
+ case PIPE_PRIM_LINE_LOOP:
+ for (i = 1; i < nr; i ++) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ if (nr) {
+ llvmpipe_setup_line( setup_ctx,
+ get_vert(vertex_buffer, nr-1, stride),
+ get_vert(vertex_buffer, 0, stride) );
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLES:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 3) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i += 3) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_STRIP:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i++) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i++) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i+(i&1)-2, stride),
+ get_vert(vertex_buffer, i-(i&1)-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_TRIANGLE_FAN:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_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 {
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, 0, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUADS:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 4) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride) );
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-3, stride) );
+ }
+ }
+ else {
+ for (i = 3; i < nr; i += 4) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_QUAD_STRIP:
+ if (llvmpipe->rasterizer->flatshade_first) {
+ for (i = 3; i < nr; i += 2) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride) );
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, i-3, stride) );
+ }
+ }
+ else {
+ for (i = 3; i < nr; i += 2) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-2, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-3, stride),
+ get_vert(vertex_buffer, i-0, stride) );
+ }
+ }
+ break;
+
+ case PIPE_PRIM_POLYGON:
+ /* Almost same as tri fan but the _first_ vertex specifies the flat
+ * shading color. Note that the first polygon vertex is passed as
+ * the last triangle vertex here.
+ * flatshade_first state makes no difference.
+ */
+ for (i = 2; i < nr; i += 1) {
+ llvmpipe_setup_tri( setup_ctx,
+ get_vert(vertex_buffer, i-1, stride),
+ get_vert(vertex_buffer, i-0, stride),
+ get_vert(vertex_buffer, 0, stride) );
+ }
+ break;
+
+ default:
+ assert(0);
+ }
+}
+
+
+
+static void
+lp_vbuf_destroy(struct vbuf_render *vbr)
+{
+ struct llvmpipe_vbuf_render *cvbr = llvmpipe_vbuf_render(vbr);
+ cvbr->llvmpipe->vbuf_render = NULL;
+ FREE(cvbr);
+}
+
+
+/**
+ * Initialize the post-transform vertex buffer information for the given
+ * context.
+ */
+void
+lp_init_vbuf(struct llvmpipe_context *lp)
+{
+ assert(lp->draw);
+
+ lp->vbuf_render = CALLOC_STRUCT(llvmpipe_vbuf_render);
+
+ lp->vbuf_render->base.max_indices = LP_MAX_VBUF_INDEXES;
+ lp->vbuf_render->base.max_vertex_buffer_bytes = LP_MAX_VBUF_SIZE;
+
+ lp->vbuf_render->base.get_vertex_info = lp_vbuf_get_vertex_info;
+ lp->vbuf_render->base.allocate_vertices = lp_vbuf_allocate_vertices;
+ lp->vbuf_render->base.map_vertices = lp_vbuf_map_vertices;
+ lp->vbuf_render->base.unmap_vertices = lp_vbuf_unmap_vertices;
+ lp->vbuf_render->base.set_primitive = lp_vbuf_set_primitive;
+ lp->vbuf_render->base.draw = lp_vbuf_draw;
+ lp->vbuf_render->base.draw_arrays = lp_vbuf_draw_arrays;
+ lp->vbuf_render->base.release_vertices = lp_vbuf_release_vertices;
+ lp->vbuf_render->base.destroy = lp_vbuf_destroy;
+
+ lp->vbuf_render->llvmpipe = lp;
+
+ lp->vbuf = draw_vbuf_stage(lp->draw, &lp->vbuf_render->base);
+
+ draw_set_rasterize_stage(lp->draw, lp->vbuf);
+
+ draw_set_render(lp->draw, &lp->vbuf_render->base);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h
new file mode 100644
index 0000000000..6c4e6063e6
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_prim_vbuf.h
@@ -0,0 +1,38 @@
+/**************************************************************************
+ *
+ * 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 LP_VBUF_H
+#define LP_VBUF_H
+
+
+struct llvmpipe_context;
+
+extern void
+lp_init_vbuf(struct llvmpipe_context *llvmpipe);
+
+
+#endif /* LP_VBUF_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_quad.h b/src/gallium/drivers/llvmpipe/lp_quad.h
new file mode 100644
index 0000000000..7eb05de77a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_quad.h
@@ -0,0 +1,114 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef LP_QUAD_H
+#define LP_QUAD_H
+
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_exec.h"
+
+
+#define QUAD_PRIM_POINT 1
+#define QUAD_PRIM_LINE 2
+#define QUAD_PRIM_TRI 3
+
+
+/* The rasterizer generates 2x2 quads of fragment and feeds them to
+ * the current fp_machine (see below).
+ * Remember that Y=0=top with Y increasing down the window.
+ */
+#define QUAD_TOP_LEFT 0
+#define QUAD_TOP_RIGHT 1
+#define QUAD_BOTTOM_LEFT 2
+#define QUAD_BOTTOM_RIGHT 3
+
+#define MASK_TOP_LEFT (1 << QUAD_TOP_LEFT)
+#define MASK_TOP_RIGHT (1 << QUAD_TOP_RIGHT)
+#define MASK_BOTTOM_LEFT (1 << QUAD_BOTTOM_LEFT)
+#define MASK_BOTTOM_RIGHT (1 << QUAD_BOTTOM_RIGHT)
+#define MASK_ALL 0xf
+
+
+/**
+ * Quad stage inputs (pos, coverage, front/back face, etc)
+ */
+struct quad_header_input
+{
+ int x0, y0; /**< quad window pos, always even */
+ float coverage[QUAD_SIZE]; /**< fragment coverage for antialiasing */
+ unsigned facing:1; /**< Front (0) or back (1) facing? */
+ unsigned prim:2; /**< QUAD_PRIM_POINT, LINE, TRI */
+};
+
+
+/**
+ * Quad stage inputs/outputs.
+ */
+struct quad_header_inout
+{
+ unsigned mask:4;
+};
+
+
+/**
+ * Quad stage outputs (color & depth).
+ */
+struct quad_header_output
+{
+ /** colors in SOA format (rrrr, gggg, bbbb, aaaa) */
+ float ALIGN16_ATTRIB color[PIPE_MAX_COLOR_BUFS][NUM_CHANNELS][QUAD_SIZE];
+};
+
+
+/**
+ * Input interpolation coefficients
+ */
+struct quad_interp_coef
+{
+ float ALIGN16_ATTRIB a0[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ float ALIGN16_ATTRIB dadx[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+ float ALIGN16_ATTRIB dady[1 + PIPE_MAX_SHADER_INPUTS][NUM_CHANNELS];
+};
+
+
+/**
+ * Encodes everything we need to know about a 2x2 pixel block. Uses
+ * "Channel-Serial" or "SoA" layout.
+ */
+struct quad_header {
+ struct quad_header_input input;
+ struct quad_header_inout inout;
+
+ /* Redundant/duplicated:
+ */
+ const struct quad_interp_coef *coef;
+};
+
+#endif /* LP_QUAD_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_query.c b/src/gallium/drivers/llvmpipe/lp_query.c
new file mode 100644
index 0000000000..5554285425
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_query.c
@@ -0,0 +1,111 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "draw/draw_context.h"
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "lp_context.h"
+#include "lp_query.h"
+#include "lp_state.h"
+
+struct llvmpipe_query {
+ uint64_t start;
+ uint64_t end;
+};
+
+
+static struct llvmpipe_query *llvmpipe_query( struct pipe_query *p )
+{
+ return (struct llvmpipe_query *)p;
+}
+
+static struct pipe_query *
+llvmpipe_create_query(struct pipe_context *pipe,
+ unsigned type)
+{
+ assert(type == PIPE_QUERY_OCCLUSION_COUNTER);
+ return (struct pipe_query *)CALLOC_STRUCT( llvmpipe_query );
+}
+
+
+static void
+llvmpipe_destroy_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ FREE(q);
+}
+
+
+static void
+llvmpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+ struct llvmpipe_query *sq = llvmpipe_query(q);
+
+ sq->start = llvmpipe->occlusion_count;
+ llvmpipe->active_query_count++;
+ llvmpipe->dirty |= LP_NEW_QUERY;
+}
+
+
+static void
+llvmpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context( pipe );
+ struct llvmpipe_query *sq = llvmpipe_query(q);
+
+ llvmpipe->active_query_count--;
+ sq->end = llvmpipe->occlusion_count;
+ llvmpipe->dirty |= LP_NEW_QUERY;
+}
+
+
+static boolean
+llvmpipe_get_query_result(struct pipe_context *pipe,
+ struct pipe_query *q,
+ boolean wait,
+ uint64_t *result )
+{
+ struct llvmpipe_query *sq = llvmpipe_query(q);
+ *result = sq->end - sq->start;
+ return TRUE;
+}
+
+
+void llvmpipe_init_query_funcs(struct llvmpipe_context *llvmpipe )
+{
+ llvmpipe->pipe.create_query = llvmpipe_create_query;
+ llvmpipe->pipe.destroy_query = llvmpipe_destroy_query;
+ llvmpipe->pipe.begin_query = llvmpipe_begin_query;
+ llvmpipe->pipe.end_query = llvmpipe_end_query;
+ llvmpipe->pipe.get_query_result = llvmpipe_get_query_result;
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_query.h b/src/gallium/drivers/llvmpipe/lp_query.h
new file mode 100644
index 0000000000..fa9fcd8713
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_query.h
@@ -0,0 +1,39 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Author:
+ * Keith Whitwell
+ */
+
+#ifndef LP_QUERY_H
+#define LP_QUERY_H
+
+struct llvmpipe_context;
+extern void llvmpipe_init_query_funcs(struct llvmpipe_context * );
+
+
+#endif /* LP_QUERY_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
new file mode 100644
index 0000000000..ff7ef8658a
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -0,0 +1,238 @@
+/**************************************************************************
+ *
+ * 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 "util/u_memory.h"
+#include "pipe/p_defines.h"
+#include "pipe/p_screen.h"
+
+#include "lp_texture.h"
+#include "lp_buffer.h"
+#include "lp_winsys.h"
+#include "lp_jit.h"
+#include "lp_screen.h"
+
+
+static const char *
+llvmpipe_get_vendor(struct pipe_screen *screen)
+{
+ return "VMware, Inc.";
+}
+
+
+static const char *
+llvmpipe_get_name(struct pipe_screen *screen)
+{
+ return "llvmpipe";
+}
+
+
+static int
+llvmpipe_get_param(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS:
+ return PIPE_MAX_SAMPLERS;
+ case PIPE_CAP_MAX_VERTEX_TEXTURE_UNITS:
+ return PIPE_MAX_SAMPLERS;
+ case PIPE_CAP_NPOT_TEXTURES:
+ return 1;
+ case PIPE_CAP_TWO_SIDED_STENCIL:
+ return 1;
+ case PIPE_CAP_GLSL:
+ return 1;
+ case PIPE_CAP_ANISOTROPIC_FILTER:
+ return 0;
+ case PIPE_CAP_POINT_SPRITE:
+ return 1;
+ case PIPE_CAP_MAX_RENDER_TARGETS:
+ return PIPE_MAX_COLOR_BUFS;
+ case PIPE_CAP_OCCLUSION_QUERY:
+ return 1;
+ case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
+ return 1;
+ case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
+ return 1;
+ case PIPE_CAP_TEXTURE_SHADOW_MAP:
+ return 1;
+ case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
+ return 13; /* max 4Kx4K */
+ case PIPE_CAP_MAX_TEXTURE_3D_LEVELS:
+ return 8; /* max 128x128x128 */
+ case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS:
+ return 13; /* max 4Kx4K */
+ case PIPE_CAP_TGSI_CONT_SUPPORTED:
+ return 1;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+static float
+llvmpipe_get_paramf(struct pipe_screen *screen, int param)
+{
+ switch (param) {
+ case PIPE_CAP_MAX_LINE_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_LINE_WIDTH_AA:
+ return 255.0; /* arbitrary */
+ case PIPE_CAP_MAX_POINT_WIDTH:
+ /* fall-through */
+ case PIPE_CAP_MAX_POINT_WIDTH_AA:
+ return 255.0; /* arbitrary */
+ case PIPE_CAP_MAX_TEXTURE_ANISOTROPY:
+ return 16.0; /* not actually signficant at this time */
+ case PIPE_CAP_MAX_TEXTURE_LOD_BIAS:
+ return 16.0; /* arbitrary */
+ default:
+ return 0;
+ }
+}
+
+
+/**
+ * Query format support for creating a texture, drawing surface, etc.
+ * \param format the format to test
+ * \param type one of PIPE_TEXTURE, PIPE_SURFACE
+ */
+static boolean
+llvmpipe_is_format_supported( struct pipe_screen *_screen,
+ enum pipe_format format,
+ enum pipe_texture_target target,
+ unsigned tex_usage,
+ unsigned geom_flags )
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_winsys *winsys = screen->winsys;
+
+ assert(target == PIPE_TEXTURE_1D ||
+ target == PIPE_TEXTURE_2D ||
+ target == PIPE_TEXTURE_3D ||
+ target == PIPE_TEXTURE_CUBE);
+
+ if(format == PIPE_FORMAT_Z16_UNORM)
+ return FALSE;
+ if(format == PIPE_FORMAT_S8_UNORM)
+ return FALSE;
+
+ switch(format) {
+ case PIPE_FORMAT_DXT1_RGB:
+ case PIPE_FORMAT_DXT1_RGBA:
+ case PIPE_FORMAT_DXT3_RGBA:
+ case PIPE_FORMAT_DXT5_RGBA:
+ return FALSE;
+ default:
+ break;
+ }
+
+ if(tex_usage & PIPE_TEXTURE_USAGE_DISPLAY_TARGET)
+ return winsys->is_displaytarget_format_supported(winsys, format);
+
+ return TRUE;
+}
+
+
+static struct pipe_buffer *
+llvmpipe_surface_buffer_create(struct pipe_screen *screen,
+ unsigned width, unsigned height,
+ enum pipe_format format,
+ unsigned tex_usage,
+ unsigned usage,
+ unsigned *stride)
+{
+ /* This function should never be used */
+ assert(0);
+ return NULL;
+}
+
+
+static void
+llvmpipe_flush_frontbuffer(struct pipe_screen *_screen,
+ struct pipe_surface *surface,
+ void *context_private)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_winsys *winsys = screen->winsys;
+ struct llvmpipe_texture *texture = llvmpipe_texture(surface->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ winsys->displaytarget_display(winsys, texture->dt, context_private);
+}
+
+
+static void
+llvmpipe_destroy_screen( struct pipe_screen *_screen )
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_winsys *winsys = screen->winsys;
+
+ lp_jit_screen_cleanup(screen);
+
+ if(winsys->destroy)
+ winsys->destroy(winsys);
+
+ FREE(screen);
+}
+
+
+
+/**
+ * Create a new pipe_screen object
+ * Note: we're not presently subclassing pipe_screen (no llvmpipe_screen).
+ */
+struct pipe_screen *
+llvmpipe_create_screen(struct llvmpipe_winsys *winsys)
+{
+ struct llvmpipe_screen *screen = CALLOC_STRUCT(llvmpipe_screen);
+
+ if (!screen)
+ return NULL;
+
+ screen->winsys = winsys;
+
+ screen->base.destroy = llvmpipe_destroy_screen;
+
+ screen->base.get_name = llvmpipe_get_name;
+ screen->base.get_vendor = llvmpipe_get_vendor;
+ screen->base.get_param = llvmpipe_get_param;
+ screen->base.get_paramf = llvmpipe_get_paramf;
+ screen->base.is_format_supported = llvmpipe_is_format_supported;
+
+ screen->base.surface_buffer_create = llvmpipe_surface_buffer_create;
+ screen->base.flush_frontbuffer = llvmpipe_flush_frontbuffer;
+
+ llvmpipe_init_screen_texture_funcs(&screen->base);
+ llvmpipe_init_screen_buffer_funcs(&screen->base);
+
+ lp_jit_screen_init(screen);
+
+ return &screen->base;
+}
diff --git a/src/gallium/state_trackers/wgl/shared/stw_public.h b/src/gallium/drivers/llvmpipe/lp_screen.h
index 7fe9cfb356..4a1b4d6f3e 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_public.h
+++ b/src/gallium/drivers/llvmpipe/lp_screen.h
@@ -1,6 +1,7 @@
/**************************************************************************
- *
+ *
* Copyright 2009 VMware, Inc.
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
@@ -10,11 +11,11 @@
* distribute, sub license, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
- *
+ *
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
- *
+ *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
@@ -22,52 +23,57 @@
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 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
+/**
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ * @author Keith Whitwell <keith@tungstengraphics.com>
+ */
-#include <windows.h>
+#ifndef LP_SCREEN_H
+#define LP_SCREEN_H
-BOOL stw_copy_context( UINT_PTR hglrcSrc,
- UINT_PTR hglrcDst,
- UINT mask );
+#include <llvm-c/Core.h>
+#include <llvm-c/Analysis.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/ExecutionEngine.h>
-UINT_PTR stw_create_layer_context( HDC hdc,
- int iLayerPlane );
+#include "pipe/p_screen.h"
+#include "pipe/p_defines.h"
-BOOL stw_share_lists( UINT_PTR hglrc1, UINT_PTR hglrc2 );
-BOOL stw_delete_context( UINT_PTR hglrc );
+struct llvmpipe_winsys;
-BOOL
-stw_release_context( UINT_PTR dhglrc );
-UINT_PTR stw_get_current_context( void );
+struct llvmpipe_screen
+{
+ struct pipe_screen base;
-HDC stw_get_current_dc( void );
+ struct llvmpipe_winsys *winsys;
-BOOL stw_make_current( HDC hdc, UINT_PTR hglrc );
+ LLVMModuleRef module;
+ LLVMExecutionEngineRef engine;
+ LLVMModuleProviderRef provider;
+ LLVMTargetDataRef target;
+ LLVMPassManagerRef pass;
-BOOL stw_swap_buffers( HDC hdc );
+ LLVMTypeRef context_ptr_type;
-BOOL
-stw_swap_layer_buffers( HDC hdc, UINT fuPlanes );
+ /* Increments whenever textures are modified. Contexts can track
+ * this.
+ */
+ unsigned timestamp;
+};
-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 );
+static INLINE struct llvmpipe_screen *
+llvmpipe_screen( struct pipe_screen *pipe )
+{
+ return (struct llvmpipe_screen *)pipe;
+}
-int stw_pixelformat_choose( HDC hdc,
- CONST PIXELFORMATDESCRIPTOR *ppfd );
-#endif
+#endif /* LP_SCREEN_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c
new file mode 100644
index 0000000000..2d2fc19a65
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_setup.c
@@ -0,0 +1,1483 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * \brief Primitive rasterization/rendering (points, lines, triangles)
+ *
+ * \author Keith Whitwell <keith@tungstengraphics.com>
+ * \author Brian Paul
+ */
+
+#include "lp_context.h"
+#include "lp_prim_setup.h"
+#include "lp_quad.h"
+#include "lp_setup.h"
+#include "lp_state.h"
+#include "draw/draw_context.h"
+#include "draw/draw_private.h"
+#include "draw/draw_vertex.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_thread.h"
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "lp_bld_debug.h"
+#include "lp_tile_cache.h"
+#include "lp_tile_soa.h"
+
+
+#define DEBUG_VERTS 0
+#define DEBUG_FRAGS 0
+
+/**
+ * Triangle edge info
+ */
+struct edge {
+ float dx; /**< X(v1) - X(v0), used only during setup */
+ float dy; /**< Y(v1) - Y(v0), used only during setup */
+ float dxdy; /**< dx/dy */
+ float sx, sy; /**< first sample point coord */
+ int lines; /**< number of lines on this edge */
+};
+
+
+#define MAX_QUADS 16
+
+
+/**
+ * Triangle setup info (derived from draw_stage).
+ * Also used for line drawing (taking some liberties).
+ */
+struct setup_context {
+ struct llvmpipe_context *llvmpipe;
+
+ /* Vertices are just an array of floats making up each attribute in
+ * turn. Currently fixed at 4 floats, but should change in time.
+ * Codegen will help cope with this.
+ */
+ const float (*vmax)[4];
+ const float (*vmid)[4];
+ const float (*vmin)[4];
+ const float (*vprovoke)[4];
+
+ struct edge ebot;
+ struct edge etop;
+ struct edge emaj;
+
+ float oneoverarea;
+ int facing;
+
+ struct quad_header quad[MAX_QUADS];
+ struct quad_header *quad_ptrs[MAX_QUADS];
+ unsigned count;
+
+ struct quad_interp_coef coef;
+
+ struct {
+ int left[2]; /**< [0] = row0, [1] = row1 */
+ int right[2];
+ int y;
+ } span;
+
+#if DEBUG_FRAGS
+ uint numFragsEmitted; /**< per primitive */
+ uint numFragsWritten; /**< per primitive */
+#endif
+
+ unsigned winding; /* which winding to cull */
+};
+
+
+
+/**
+ * Execute fragment shader for the four fragments in the quad.
+ */
+static void
+shade_quads(struct llvmpipe_context *llvmpipe,
+ struct quad_header *quads[],
+ unsigned nr)
+{
+ struct lp_fragment_shader *fs = llvmpipe->fs;
+ struct quad_header *quad = quads[0];
+ const unsigned x = quad->input.x0;
+ const unsigned y = quad->input.y0;
+ uint8_t *tile = lp_get_cached_tile(llvmpipe->cbuf_cache[0], x, y);
+ uint8_t *color;
+ void *depth;
+ uint32_t ALIGN16_ATTRIB mask[4][NUM_CHANNELS];
+ unsigned chan_index;
+ unsigned q;
+
+ assert(fs->current);
+ if(!fs->current)
+ return;
+
+ /* Sanity checks */
+ assert(nr * QUAD_SIZE == TILE_VECTOR_HEIGHT * TILE_VECTOR_WIDTH);
+ assert(x % TILE_VECTOR_WIDTH == 0);
+ assert(y % TILE_VECTOR_HEIGHT == 0);
+ for (q = 0; q < nr; ++q) {
+ assert(quads[q]->input.x0 == x + q*2);
+ assert(quads[q]->input.y0 == y);
+ }
+
+ /* mask */
+ for (q = 0; q < 4; ++q)
+ for (chan_index = 0; chan_index < NUM_CHANNELS; ++chan_index)
+ mask[q][chan_index] = quads[q]->inout.mask & (1 << chan_index) ? ~0 : 0;
+
+ /* color buffer */
+ color = &TILE_PIXEL(tile, x & (TILE_SIZE-1), y & (TILE_SIZE-1), 0);
+
+ /* depth buffer */
+ if(llvmpipe->zsbuf_map) {
+ assert((x % 2) == 0);
+ assert((y % 2) == 0);
+ depth = llvmpipe->zsbuf_map +
+ y*llvmpipe->zsbuf_transfer->stride +
+ 2*x*llvmpipe->zsbuf_transfer->block.size;
+ }
+ else
+ depth = NULL;
+
+ /* XXX: This will most likely fail on 32bit x86 without -mstackrealign */
+ assert(lp_check_alignment(mask, 16));
+
+ assert(lp_check_alignment(depth, 16));
+ assert(lp_check_alignment(color, 16));
+ assert(lp_check_alignment(llvmpipe->jit_context.blend_color, 16));
+
+ /* run shader */
+ fs->current->jit_function( &llvmpipe->jit_context,
+ x, y,
+ quad->coef->a0,
+ quad->coef->dadx,
+ quad->coef->dady,
+ &mask[0][0],
+ color,
+ depth);
+}
+
+
+
+
+/**
+ * Do triangle cull test using tri determinant (sign indicates orientation)
+ * \return true if triangle is to be culled.
+ */
+static INLINE boolean
+cull_tri(const struct setup_context *setup, float det)
+{
+ if (det != 0) {
+ /* if (det < 0 then Z points toward camera and triangle is
+ * counter-clockwise winding.
+ */
+ unsigned winding = (det < 0) ? PIPE_WINDING_CCW : PIPE_WINDING_CW;
+
+ if ((winding & setup->winding) == 0)
+ return FALSE;
+ }
+
+ /* Culled:
+ */
+ return TRUE;
+}
+
+
+
+/**
+ * Clip setup->quad against the scissor/surface bounds.
+ */
+static INLINE void
+quad_clip( struct setup_context *setup, struct quad_header *quad )
+{
+ const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect;
+ const int minx = (int) cliprect->minx;
+ const int maxx = (int) cliprect->maxx;
+ const int miny = (int) cliprect->miny;
+ const int maxy = (int) cliprect->maxy;
+
+ if (quad->input.x0 >= maxx ||
+ quad->input.y0 >= maxy ||
+ quad->input.x0 + 1 < minx ||
+ quad->input.y0 + 1 < miny) {
+ /* totally clipped */
+ quad->inout.mask = 0x0;
+ return;
+ }
+ if (quad->input.x0 < minx)
+ quad->inout.mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
+ if (quad->input.y0 < miny)
+ quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
+ if (quad->input.x0 == maxx - 1)
+ quad->inout.mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
+ if (quad->input.y0 == maxy - 1)
+ quad->inout.mask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
+}
+
+
+
+/**
+ * Given an X or Y coordinate, return the block/quad coordinate that it
+ * belongs to.
+ */
+static INLINE int block( int x )
+{
+ return x & ~(2-1);
+}
+
+static INLINE int block_x( int x )
+{
+ return x & ~(TILE_VECTOR_WIDTH - 1);
+}
+
+
+/**
+ * Emit a quad (pass to next stage) with clipping.
+ */
+static INLINE void
+clip_emit_quad( struct setup_context *setup, struct quad_header *quad )
+{
+ quad_clip( setup, quad );
+
+ if (quad->inout.mask) {
+ struct llvmpipe_context *lp = setup->llvmpipe;
+
+#if 1
+ /* XXX: The blender expects 4 quads. This is far from efficient, but
+ * until we codegenerate single-quad variants of the fragment pipeline
+ * we need this hack. */
+ const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE;
+ struct quad_header quads[nr_quads];
+ struct quad_header *quad_ptrs[nr_quads];
+ int x0 = block_x(quad->input.x0);
+ unsigned i;
+
+ for(i = 0; i < nr_quads; ++i) {
+ int x = x0 + 2*i;
+ if(x == quad->input.x0)
+ memcpy(&quads[i], quad, sizeof quads[i]);
+ else {
+ memset(&quads[i], 0, sizeof quads[i]);
+ quads[i].input.x0 = x;
+ quads[i].input.y0 = quad->input.y0;
+ quads[i].coef = quad->coef;
+ }
+ quad_ptrs[i] = &quads[i];
+ }
+
+ shade_quads( lp, quad_ptrs, nr_quads );
+#else
+ shade_quads( lp, &quad, 1 );
+#endif
+ }
+}
+
+
+/**
+ * Render a horizontal span of quads
+ */
+static void flush_spans( struct setup_context *setup )
+{
+ const int step = TILE_VECTOR_WIDTH;
+ 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 = block_x(MIN2(xleft0, xleft1));
+ int maxright = MAX2(xright0, xright1);
+ int x;
+
+ 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;
+ const unsigned nr_quads = TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH/QUAD_SIZE;
+ unsigned q = 0;
+
+ 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) {
+ for(q = 0; q < nr_quads; ++q) {
+ unsigned quadmask = (mask0 & 3) | ((mask1 & 3) << 2);
+ setup->quad[q].input.x0 = lx;
+ setup->quad[q].input.y0 = setup->span.y;
+ setup->quad[q].inout.mask = quadmask;
+ setup->quad_ptrs[q] = &setup->quad[q];
+ mask0 >>= 2;
+ mask1 >>= 2;
+ lx += 2;
+ }
+ assert(!(mask0 | mask1));
+
+ shade_quads(setup->llvmpipe, setup->quad_ptrs, nr_quads );
+ }
+ }
+
+
+ setup->span.y = 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] */
+}
+
+
+#if DEBUG_VERTS
+static void print_vertex(const struct setup_context *setup,
+ const float (*v)[4])
+{
+ int i;
+ debug_printf(" Vertex: (%p)\n", v);
+ 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])) {
+ debug_printf(" NaN!\n");
+ }
+ }
+}
+#endif
+
+/**
+ * Sort the vertices from top to bottom order, setting up the triangle
+ * edge fields (ebot, emaj, etop).
+ * \return FALSE if coords are inf/nan (cull the tri), TRUE otherwise
+ */
+static boolean setup_sort_vertices( struct setup_context *setup,
+ float det,
+ const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4] )
+{
+ setup->vprovoke = v2;
+
+ /* determine bottom to top order of vertices */
+ {
+ float y0 = v0[0][1];
+ float y1 = v1[0][1];
+ float y2 = v2[0][1];
+ if (y0 <= y1) {
+ if (y1 <= y2) {
+ /* y0<=y1<=y2 */
+ setup->vmin = v0;
+ setup->vmid = v1;
+ setup->vmax = v2;
+ }
+ else if (y2 <= y0) {
+ /* y2<=y0<=y1 */
+ setup->vmin = v2;
+ setup->vmid = v0;
+ setup->vmax = v1;
+ }
+ else {
+ /* y0<=y2<=y1 */
+ setup->vmin = v0;
+ setup->vmid = v2;
+ setup->vmax = v1;
+ }
+ }
+ else {
+ if (y0 <= y2) {
+ /* y1<=y0<=y2 */
+ setup->vmin = v1;
+ setup->vmid = v0;
+ setup->vmax = v2;
+ }
+ else if (y2 <= y1) {
+ /* y2<=y1<=y0 */
+ setup->vmin = v2;
+ setup->vmid = v1;
+ setup->vmax = v0;
+ }
+ else {
+ /* y1<=y2<=y0 */
+ setup->vmin = v1;
+ setup->vmid = v2;
+ setup->vmax = v0;
+ }
+ }
+ }
+
+ setup->ebot.dx = setup->vmid[0][0] - setup->vmin[0][0];
+ setup->ebot.dy = setup->vmid[0][1] - setup->vmin[0][1];
+ setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0];
+ setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1];
+ setup->etop.dx = setup->vmax[0][0] - setup->vmid[0][0];
+ setup->etop.dy = setup->vmax[0][1] - setup->vmid[0][1];
+
+ /*
+ * Compute triangle's area. Use 1/area to compute partial
+ * derivatives of attributes later.
+ *
+ * The area will be the same as prim->det, but the sign may be
+ * different depending on how the vertices get sorted above.
+ *
+ * To determine whether the primitive is front or back facing we
+ * use the prim->det value because its sign is correct.
+ */
+ {
+ const float area = (setup->emaj.dx * setup->ebot.dy -
+ setup->ebot.dx * setup->emaj.dy);
+
+ setup->oneoverarea = 1.0f / area;
+
+ /*
+ debug_printf("%s one-over-area %f area %f det %f\n",
+ __FUNCTION__, setup->oneoverarea, area, det );
+ */
+ if (util_is_inf_or_nan(setup->oneoverarea))
+ return FALSE;
+ }
+
+ /* We need to know if this is a front or back-facing triangle for:
+ * - the GLSL gl_FrontFacing fragment attribute (bool)
+ * - two-sided stencil test
+ */
+ setup->facing =
+ ((det > 0.0) ^
+ (setup->llvmpipe->rasterizer->front_winding == PIPE_WINDING_CW));
+
+ return TRUE;
+}
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a triangle.
+ */
+static void tri_pos_coeff( struct setup_context *setup,
+ uint vertSlot, unsigned i)
+{
+ float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i];
+ float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i];
+ float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
+ float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
+ float dadx = a * setup->oneoverarea;
+ float dady = b * setup->oneoverarea;
+
+ assert(i <= 3);
+
+ setup->coef.dadx[0][i] = dadx;
+ setup->coef.dady[0][i] = dady;
+
+ /* calculate a0 as the value which would be sampled for the
+ * fragment at (0,0), taking into account that we want to sample at
+ * pixel centers, in other words (0.5, 0.5).
+ *
+ * this is neat but unfortunately not a good way to do things for
+ * triangles with very large values of dadx or dady as it will
+ * result in the subtraction and re-addition from a0 of a very
+ * large number, which means we'll end up loosing a lot of the
+ * fractional bits and precision from a0. the way to fix this is
+ * to define a0 as the sample at a pixel center somewhere near vmin
+ * instead - i'll switch to this later.
+ */
+ setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+
+ /*
+ debug_printf("attr[%d].%c: %f dx:%f dy:%f\n",
+ slot, "xyzw"[i],
+ setup->coef[slot].a0[i],
+ setup->coef[slot].dadx[i],
+ setup->coef[slot].dady[i]);
+ */
+}
+
+
+/**
+ * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
+ * The value value comes from vertex[slot][i].
+ * The result will be put into setup->coef[slot].a0[i].
+ * \param slot which attribute slot
+ * \param i which component of the slot (0..3)
+ */
+static void const_pos_coeff( struct setup_context *setup,
+ uint vertSlot, unsigned i)
+{
+ setup->coef.dadx[0][i] = 0;
+ setup->coef.dady[0][i] = 0;
+
+ /* need provoking vertex info!
+ */
+ setup->coef.a0[0][i] = setup->vprovoke[vertSlot][i];
+}
+
+
+/**
+ * Compute a0 for a constant-valued coefficient (GL_FLAT shading).
+ * The value value comes from vertex[slot][i].
+ * The result will be put into setup->coef[slot].a0[i].
+ * \param slot which attribute slot
+ * \param i which component of the slot (0..3)
+ */
+static void const_coeff( struct setup_context *setup,
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ setup->coef.dadx[1 + attrib][i] = 0;
+ setup->coef.dady[1 + attrib][i] = 0;
+
+ /* need provoking vertex info!
+ */
+ setup->coef.a0[1 + attrib][i] = setup->vprovoke[vertSlot][i];
+ }
+}
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a triangle.
+ */
+static void tri_linear_coeff( struct setup_context *setup,
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ float botda = setup->vmid[vertSlot][i] - setup->vmin[vertSlot][i];
+ float majda = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i];
+ float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
+ float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
+ float dadx = a * setup->oneoverarea;
+ float dady = b * setup->oneoverarea;
+
+ assert(i <= 3);
+
+ setup->coef.dadx[1 + attrib][i] = dadx;
+ setup->coef.dady[1 + attrib][i] = dady;
+
+ /* calculate a0 as the value which would be sampled for the
+ * fragment at (0,0), taking into account that we want to sample at
+ * pixel centers, in other words (0.5, 0.5).
+ *
+ * this is neat but unfortunately not a good way to do things for
+ * triangles with very large values of dadx or dady as it will
+ * result in the subtraction and re-addition from a0 of a very
+ * large number, which means we'll end up loosing a lot of the
+ * fractional bits and precision from a0. the way to fix this is
+ * to define a0 as the sample at a pixel center somewhere near vmin
+ * instead - i'll switch to this later.
+ */
+ setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+
+ /*
+ debug_printf("attr[%d].%c: %f dx:%f dy:%f\n",
+ slot, "xyzw"[i],
+ setup->coef[slot].a0[i],
+ setup->coef[slot].dadx[i],
+ setup->coef[slot].dady[i]);
+ */
+ }
+}
+
+
+/**
+ * Compute a0, dadx and dady for a perspective-corrected interpolant,
+ * for a triangle.
+ * We basically multiply the vertex value by 1/w before computing
+ * the plane coefficients (a0, dadx, dady).
+ * Later, when we compute the value at a particular fragment position we'll
+ * divide the interpolated value by the interpolated W at that fragment.
+ */
+static void tri_persp_coeff( struct setup_context *setup,
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ /* premultiply by 1/w (v[0][3] is always W):
+ */
+ float mina = setup->vmin[vertSlot][i] * setup->vmin[0][3];
+ float mida = setup->vmid[vertSlot][i] * setup->vmid[0][3];
+ float maxa = setup->vmax[vertSlot][i] * setup->vmax[0][3];
+ float botda = mida - mina;
+ float majda = maxa - mina;
+ float a = setup->ebot.dy * majda - botda * setup->emaj.dy;
+ float b = setup->emaj.dx * botda - majda * setup->ebot.dx;
+ float dadx = a * setup->oneoverarea;
+ float dady = b * setup->oneoverarea;
+
+ /*
+ debug_printf("tri persp %d,%d: %f %f %f\n", vertSlot, i,
+ setup->vmin[vertSlot][i],
+ setup->vmid[vertSlot][i],
+ setup->vmax[vertSlot][i]
+ );
+ */
+ assert(i <= 3);
+
+ setup->coef.dadx[1 + attrib][i] = dadx;
+ setup->coef.dady[1 + attrib][i] = dady;
+ setup->coef.a0[1 + attrib][i] = (mina -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+ }
+}
+
+
+/**
+ * Special coefficient setup for gl_FragCoord.
+ * X and Y are trivial, though Y has to be inverted for OpenGL.
+ * Z and W are copied from posCoef which should have already been computed.
+ * We could do a bit less work if we'd examine gl_FragCoord's swizzle mask.
+ */
+static void
+setup_fragcoord_coeff(struct setup_context *setup, uint slot)
+{
+ /*X*/
+ setup->coef.a0[1 + slot][0] = 0;
+ setup->coef.dadx[1 + slot][0] = 1.0;
+ setup->coef.dady[1 + slot][0] = 0.0;
+ /*Y*/
+ setup->coef.a0[1 + slot][1] = 0.0;
+ setup->coef.dadx[1 + slot][1] = 0.0;
+ setup->coef.dady[1 + slot][1] = 1.0;
+ /*Z*/
+ setup->coef.a0[1 + slot][2] = setup->coef.a0[0][2];
+ setup->coef.dadx[1 + slot][2] = setup->coef.dadx[0][2];
+ setup->coef.dady[1 + slot][2] = setup->coef.dady[0][2];
+ /*W*/
+ setup->coef.a0[1 + slot][3] = setup->coef.a0[0][3];
+ setup->coef.dadx[1 + slot][3] = setup->coef.dadx[0][3];
+ setup->coef.dady[1 + slot][3] = setup->coef.dady[0][3];
+}
+
+
+
+/**
+ * Compute the setup->coef[] array dadx, dady, a0 values.
+ * Must be called after setup->vmin,vmid,vmax,vprovoke are initialized.
+ */
+static void setup_tri_coefficients( struct setup_context *setup )
+{
+ struct llvmpipe_context *llvmpipe = setup->llvmpipe;
+ const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+ const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe);
+ uint fragSlot;
+
+ /* z and w are done by linear interpolation:
+ */
+ tri_pos_coeff(setup, 0, 2);
+ tri_pos_coeff(setup, 0, 3);
+
+ /* setup interpolation for all the remaining attributes:
+ */
+ for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) {
+ const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+
+ switch (vinfo->attrib[fragSlot].interp_mode) {
+ case INTERP_CONSTANT:
+ const_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_LINEAR:
+ tri_linear_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_PERSPECTIVE:
+ tri_persp_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_POS:
+ setup_fragcoord_coeff(setup, fragSlot);
+ break;
+ default:
+ assert(0);
+ }
+
+ if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
+ setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing;
+ setup->coef.dadx[1 + fragSlot][0] = 0.0;
+ setup->coef.dady[1 + fragSlot][0] = 0.0;
+ }
+ }
+}
+
+
+
+static void setup_tri_edges( struct setup_context *setup )
+{
+ float vmin_x = setup->vmin[0][0] + 0.5f;
+ float vmid_x = setup->vmid[0][0] + 0.5f;
+
+ float vmin_y = setup->vmin[0][1] - 0.5f;
+ float vmid_y = setup->vmid[0][1] - 0.5f;
+ float vmax_y = setup->vmax[0][1] - 0.5f;
+
+ setup->emaj.sy = ceilf(vmin_y);
+ setup->emaj.lines = (int) ceilf(vmax_y - setup->emaj.sy);
+ setup->emaj.dxdy = setup->emaj.dx / setup->emaj.dy;
+ setup->emaj.sx = vmin_x + (setup->emaj.sy - vmin_y) * setup->emaj.dxdy;
+
+ setup->etop.sy = ceilf(vmid_y);
+ setup->etop.lines = (int) ceilf(vmax_y - setup->etop.sy);
+ setup->etop.dxdy = setup->etop.dx / setup->etop.dy;
+ setup->etop.sx = vmid_x + (setup->etop.sy - vmid_y) * setup->etop.dxdy;
+
+ setup->ebot.sy = ceilf(vmin_y);
+ setup->ebot.lines = (int) ceilf(vmid_y - setup->ebot.sy);
+ setup->ebot.dxdy = setup->ebot.dx / setup->ebot.dy;
+ setup->ebot.sx = vmin_x + (setup->ebot.sy - vmin_y) * setup->ebot.dxdy;
+}
+
+
+/**
+ * Render the upper or lower half of a triangle.
+ * Scissoring/cliprect is applied here too.
+ */
+static void subtriangle( struct setup_context *setup,
+ struct edge *eleft,
+ struct edge *eright,
+ unsigned lines )
+{
+ const struct pipe_scissor_state *cliprect = &setup->llvmpipe->cliprect;
+ const int minx = (int) cliprect->minx;
+ const int maxx = (int) cliprect->maxx;
+ const int miny = (int) cliprect->miny;
+ const int maxy = (int) cliprect->maxy;
+ int y, start_y, finish_y;
+ int sy = (int)eleft->sy;
+
+ assert((int)eleft->sy == (int) eright->sy);
+
+ /* clip top/bottom */
+ start_y = sy;
+ if (start_y < miny)
+ start_y = miny;
+
+ finish_y = sy + lines;
+ if (finish_y > maxy)
+ finish_y = maxy;
+
+ start_y -= sy;
+ finish_y -= sy;
+
+ /*
+ debug_printf("%s %d %d\n", __FUNCTION__, start_y, finish_y);
+ */
+
+ for (y = start_y; y < finish_y; y++) {
+
+ /* avoid accumulating adds as floats don't have the precision to
+ * accurately iterate large triangle edges that way. luckily we
+ * can just multiply these days.
+ *
+ * this is all drowned out by the attribute interpolation anyway.
+ */
+ int left = (int)(eleft->sx + y * eleft->dxdy);
+ int right = (int)(eright->sx + y * eright->dxdy);
+
+ /* clip left/right */
+ if (left < minx)
+ left = minx;
+ if (right > maxx)
+ right = maxx;
+
+ if (left < right) {
+ int _y = sy + y;
+ if (block(_y) != setup->span.y) {
+ flush_spans(setup);
+ setup->span.y = block(_y);
+ }
+
+ setup->span.left[_y&1] = left;
+ setup->span.right[_y&1] = right;
+ }
+ }
+
+
+ /* save the values so that emaj can be restarted:
+ */
+ eleft->sx += lines * eleft->dxdy;
+ eright->sx += lines * eright->dxdy;
+ eleft->sy += lines;
+ eright->sy += lines;
+}
+
+
+/**
+ * Recalculate prim's determinant. This is needed as we don't have
+ * get this information through the vbuf_render interface & we must
+ * calculate it here.
+ */
+static float
+calc_det( const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4] )
+{
+ /* edge vectors e = v0 - v2, f = v1 - v2 */
+ const float ex = v0[0][0] - v2[0][0];
+ const float ey = v0[0][1] - v2[0][1];
+ const float fx = v1[0][0] - v2[0][0];
+ const float fy = v1[0][1] - v2[0][1];
+
+ /* det = cross(e,f).z */
+ return ex * fy - ey * fx;
+}
+
+
+/**
+ * Do setup for triangle rasterization, then render the triangle.
+ */
+void llvmpipe_setup_tri( struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4] )
+{
+ float det;
+
+#if DEBUG_VERTS
+ debug_printf("Setup triangle:\n");
+ print_vertex(setup, v0);
+ print_vertex(setup, v1);
+ print_vertex(setup, v2);
+#endif
+
+ if (setup->llvmpipe->no_rast)
+ return;
+
+ det = calc_det(v0, v1, v2);
+ /*
+ debug_printf("%s\n", __FUNCTION__ );
+ */
+
+#if DEBUG_FRAGS
+ setup->numFragsEmitted = 0;
+ setup->numFragsWritten = 0;
+#endif
+
+ if (cull_tri( setup, det ))
+ return;
+
+ if (!setup_sort_vertices( setup, det, v0, v1, v2 ))
+ return;
+ setup_tri_coefficients( setup );
+ setup_tri_edges( setup );
+
+ assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_TRIANGLES);
+
+ setup->span.y = 0;
+ setup->span.right[0] = 0;
+ setup->span.right[1] = 0;
+ /* setup->span.z_mode = tri_z_mode( setup->ctx ); */
+
+ /* init_constant_attribs( setup ); */
+
+ if (setup->oneoverarea < 0.0) {
+ /* emaj on left:
+ */
+ subtriangle( setup, &setup->emaj, &setup->ebot, setup->ebot.lines );
+ subtriangle( setup, &setup->emaj, &setup->etop, setup->etop.lines );
+ }
+ else {
+ /* emaj on right:
+ */
+ subtriangle( setup, &setup->ebot, &setup->emaj, setup->ebot.lines );
+ subtriangle( setup, &setup->etop, &setup->emaj, setup->etop.lines );
+ }
+
+ flush_spans( setup );
+
+#if DEBUG_FRAGS
+ printf("Tri: %u frags emitted, %u written\n",
+ setup->numFragsEmitted,
+ setup->numFragsWritten);
+#endif
+}
+
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a line.
+ */
+static void
+linear_pos_coeff(struct setup_context *setup,
+ uint vertSlot, uint i)
+{
+ const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i];
+ const float dadx = da * setup->emaj.dx * setup->oneoverarea;
+ const float dady = da * setup->emaj.dy * setup->oneoverarea;
+ setup->coef.dadx[0][i] = dadx;
+ setup->coef.dady[0][i] = dady;
+ setup->coef.a0[0][i] = (setup->vmin[vertSlot][i] -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+}
+
+
+/**
+ * Compute a0, dadx and dady for a linearly interpolated coefficient,
+ * for a line.
+ */
+static void
+line_linear_coeff(struct setup_context *setup,
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ const float da = setup->vmax[vertSlot][i] - setup->vmin[vertSlot][i];
+ const float dadx = da * setup->emaj.dx * setup->oneoverarea;
+ const float dady = da * setup->emaj.dy * setup->oneoverarea;
+ setup->coef.dadx[1 + attrib][i] = dadx;
+ setup->coef.dady[1 + attrib][i] = dady;
+ setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+ }
+}
+
+
+/**
+ * Compute a0, dadx and dady for a perspective-corrected interpolant,
+ * for a line.
+ */
+static void
+line_persp_coeff(struct setup_context *setup,
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ /* XXX double-check/verify this arithmetic */
+ const float a0 = setup->vmin[vertSlot][i] * setup->vmin[0][3];
+ const float a1 = setup->vmax[vertSlot][i] * setup->vmax[0][3];
+ const float da = a1 - a0;
+ const float dadx = da * setup->emaj.dx * setup->oneoverarea;
+ const float dady = da * setup->emaj.dy * setup->oneoverarea;
+ setup->coef.dadx[1 + attrib][i] = dadx;
+ setup->coef.dady[1 + attrib][i] = dady;
+ setup->coef.a0[1 + attrib][i] = (setup->vmin[vertSlot][i] -
+ (dadx * (setup->vmin[0][0] - 0.5f) +
+ dady * (setup->vmin[0][1] - 0.5f)));
+ }
+}
+
+
+/**
+ * Compute the setup->coef[] array dadx, dady, a0 values.
+ * Must be called after setup->vmin,vmax are initialized.
+ */
+static INLINE boolean
+setup_line_coefficients(struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4])
+{
+ struct llvmpipe_context *llvmpipe = setup->llvmpipe;
+ const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+ const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe);
+ uint fragSlot;
+ float area;
+
+ /* use setup->vmin, vmax to point to vertices */
+ if (llvmpipe->rasterizer->flatshade_first)
+ setup->vprovoke = v0;
+ else
+ setup->vprovoke = v1;
+ setup->vmin = v0;
+ setup->vmax = v1;
+
+ setup->emaj.dx = setup->vmax[0][0] - setup->vmin[0][0];
+ setup->emaj.dy = setup->vmax[0][1] - setup->vmin[0][1];
+
+ /* NOTE: this is not really area but something proportional to it */
+ area = setup->emaj.dx * setup->emaj.dx + setup->emaj.dy * setup->emaj.dy;
+ if (area == 0.0f || util_is_inf_or_nan(area))
+ return FALSE;
+ setup->oneoverarea = 1.0f / area;
+
+ /* z and w are done by linear interpolation:
+ */
+ linear_pos_coeff(setup, 0, 2);
+ linear_pos_coeff(setup, 0, 3);
+
+ /* setup interpolation for all the remaining attributes:
+ */
+ for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) {
+ const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+
+ switch (vinfo->attrib[fragSlot].interp_mode) {
+ case INTERP_CONSTANT:
+ const_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_LINEAR:
+ line_linear_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_PERSPECTIVE:
+ line_persp_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_POS:
+ setup_fragcoord_coeff(setup, fragSlot);
+ break;
+ default:
+ assert(0);
+ }
+
+ if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
+ setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing;
+ setup->coef.dadx[1 + fragSlot][0] = 0.0;
+ setup->coef.dady[1 + fragSlot][0] = 0.0;
+ }
+ }
+ return TRUE;
+}
+
+
+/**
+ * Plot a pixel in a line segment.
+ */
+static INLINE void
+plot(struct setup_context *setup, int x, int y)
+{
+ const int iy = y & 1;
+ const int ix = x & 1;
+ const int quadX = x - ix;
+ const int quadY = y - iy;
+ const int mask = (1 << ix) << (2 * iy);
+
+ if (quadX != setup->quad[0].input.x0 ||
+ quadY != setup->quad[0].input.y0)
+ {
+ /* flush prev quad, start new quad */
+
+ if (setup->quad[0].input.x0 != -1)
+ clip_emit_quad( setup, &setup->quad[0] );
+
+ setup->quad[0].input.x0 = quadX;
+ setup->quad[0].input.y0 = quadY;
+ setup->quad[0].inout.mask = 0x0;
+ }
+
+ setup->quad[0].inout.mask |= mask;
+}
+
+
+/**
+ * Do setup for line rasterization, then render the line.
+ * Single-pixel width, no stipple, etc. We rely on the 'draw' module
+ * to handle stippling and wide lines.
+ */
+void
+llvmpipe_setup_line(struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4])
+{
+ int x0 = (int) v0[0][0];
+ int x1 = (int) v1[0][0];
+ int y0 = (int) v0[0][1];
+ int y1 = (int) v1[0][1];
+ int dx = x1 - x0;
+ int dy = y1 - y0;
+ int xstep, ystep;
+
+#if DEBUG_VERTS
+ debug_printf("Setup line:\n");
+ print_vertex(setup, v0);
+ print_vertex(setup, v1);
+#endif
+
+ if (setup->llvmpipe->no_rast)
+ return;
+
+ if (dx == 0 && dy == 0)
+ return;
+
+ if (!setup_line_coefficients(setup, v0, v1))
+ return;
+
+ assert(v0[0][0] < 1.0e9);
+ assert(v0[0][1] < 1.0e9);
+ assert(v1[0][0] < 1.0e9);
+ assert(v1[0][1] < 1.0e9);
+
+ if (dx < 0) {
+ dx = -dx; /* make positive */
+ xstep = -1;
+ }
+ else {
+ xstep = 1;
+ }
+
+ if (dy < 0) {
+ dy = -dy; /* make positive */
+ ystep = -1;
+ }
+ else {
+ ystep = 1;
+ }
+
+ assert(dx >= 0);
+ assert(dy >= 0);
+ assert(setup->llvmpipe->reduced_prim == PIPE_PRIM_LINES);
+
+ setup->quad[0].input.x0 = setup->quad[0].input.y0 = -1;
+ setup->quad[0].inout.mask = 0x0;
+
+ /* XXX temporary: set coverage to 1.0 so the line appears
+ * if AA mode happens to be enabled.
+ */
+ 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 ***/
+ int i;
+ const int errorInc = dy + dy;
+ int error = errorInc - dx;
+ const int errorDec = error - dx;
+
+ for (i = 0; i < dx; i++) {
+ plot(setup, x0, y0);
+
+ x0 += xstep;
+ if (error < 0) {
+ error += errorInc;
+ }
+ else {
+ error += errorDec;
+ y0 += ystep;
+ }
+ }
+ }
+ else {
+ /*** Y-major line ***/
+ int i;
+ const int errorInc = dx + dx;
+ int error = errorInc - dy;
+ const int errorDec = error - dy;
+
+ for (i = 0; i < dy; i++) {
+ plot(setup, x0, y0);
+
+ y0 += ystep;
+ if (error < 0) {
+ error += errorInc;
+ }
+ else {
+ error += errorDec;
+ x0 += xstep;
+ }
+ }
+ }
+
+ /* draw final quad */
+ if (setup->quad[0].inout.mask) {
+ clip_emit_quad( setup, &setup->quad[0] );
+ }
+}
+
+
+static void
+point_persp_coeff(struct setup_context *setup,
+ const float (*vert)[4],
+ unsigned attrib,
+ uint vertSlot)
+{
+ unsigned i;
+ for(i = 0; i < NUM_CHANNELS; ++i) {
+ setup->coef.dadx[1 + attrib][i] = 0.0F;
+ setup->coef.dady[1 + attrib][i] = 0.0F;
+ setup->coef.a0[1 + attrib][i] = vert[vertSlot][i] * vert[0][3];
+ }
+}
+
+
+/**
+ * Do setup for point rasterization, then render the point.
+ * Round or square points...
+ * XXX could optimize a lot for 1-pixel points.
+ */
+void
+llvmpipe_setup_point( struct setup_context *setup,
+ const float (*v0)[4] )
+{
+ struct llvmpipe_context *llvmpipe = setup->llvmpipe;
+ const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+ const int sizeAttr = setup->llvmpipe->psize_slot;
+ const float size
+ = sizeAttr > 0 ? v0[sizeAttr][0]
+ : setup->llvmpipe->rasterizer->point_size;
+ const float halfSize = 0.5F * size;
+ const boolean round = (boolean) setup->llvmpipe->rasterizer->point_smooth;
+ const float x = v0[0][0]; /* Note: data[0] is always position */
+ const float y = v0[0][1];
+ const struct vertex_info *vinfo = llvmpipe_get_vertex_info(llvmpipe);
+ uint fragSlot;
+
+#if DEBUG_VERTS
+ debug_printf("Setup point:\n");
+ print_vertex(setup, v0);
+#endif
+
+ if (llvmpipe->no_rast)
+ return;
+
+ assert(setup->llvmpipe->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???
+ * We may do point sprites as textured quads...
+ *
+ * KW: We don't know which coefficients are texcoords - ultimately
+ * the choice of what interpolation mode to use for each attribute
+ * should be determined by the fragment program, using
+ * per-attribute declaration statements that include interpolation
+ * mode as a parameter. So either the fragment program will have
+ * to be adjusted for pointsprite vs normal point behaviour, or
+ * otherwise a special interpolation mode will have to be defined
+ * which matches the required behaviour for point sprites. But -
+ * the latter is not a feature of normal hardware, and as such
+ * probably should be ruled out on that basis.
+ */
+ setup->vprovoke = v0;
+
+ /* setup Z, W */
+ const_pos_coeff(setup, 0, 2);
+ const_pos_coeff(setup, 0, 3);
+
+ for (fragSlot = 0; fragSlot < lpfs->info.num_inputs; fragSlot++) {
+ const uint vertSlot = vinfo->attrib[fragSlot].src_index;
+
+ switch (vinfo->attrib[fragSlot].interp_mode) {
+ case INTERP_CONSTANT:
+ /* fall-through */
+ case INTERP_LINEAR:
+ const_coeff(setup, fragSlot, vertSlot);
+ break;
+ case INTERP_PERSPECTIVE:
+ point_persp_coeff(setup, setup->vprovoke, fragSlot, vertSlot);
+ break;
+ case INTERP_POS:
+ setup_fragcoord_coeff(setup, fragSlot);
+ break;
+ default:
+ assert(0);
+ }
+
+ if (lpfs->info.input_semantic_name[fragSlot] == TGSI_SEMANTIC_FACE) {
+ setup->coef.a0[1 + fragSlot][0] = 1.0f - setup->facing;
+ setup->coef.dadx[1 + fragSlot][0] = 0.0;
+ setup->coef.dady[1 + fragSlot][0] = 0.0;
+ }
+ }
+
+
+ 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[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) {
+ /* rounded points */
+ const int ixmin = block((int) (x - halfSize));
+ const int ixmax = block((int) (x + halfSize));
+ const int iymin = block((int) (y - halfSize));
+ const int iymax = block((int) (y + halfSize));
+ const float rmin = halfSize - 0.7071F; /* 0.7071 = sqrt(2)/2 */
+ const float rmax = halfSize + 0.7071F;
+ const float rmin2 = MAX2(0.0F, rmin * rmin);
+ const float rmax2 = rmax * rmax;
+ const float cscale = 1.0F / (rmax2 - rmin2);
+ int ix, iy;
+
+ for (iy = iymin; iy <= iymax; iy += 2) {
+ for (ix = ixmin; ix <= ixmax; ix += 2) {
+ float dx, dy, dist2, cover;
+
+ 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[0].input.coverage[QUAD_TOP_LEFT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_TOP_LEFT;
+ }
+
+ dx = (ix + 1.5f) - x;
+ dy = (iy + 0.5f) - y;
+ dist2 = dx * dx + dy * dy;
+ if (dist2 <= rmax2) {
+ cover = 1.0F - (dist2 - rmin2) * cscale;
+ 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;
+ dy = (iy + 1.5f) - y;
+ dist2 = dx * dx + dy * dy;
+ if (dist2 <= rmax2) {
+ cover = 1.0F - (dist2 - rmin2) * cscale;
+ 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;
+ dy = (iy + 1.5f) - y;
+ dist2 = dx * dx + dy * dy;
+ if (dist2 <= rmax2) {
+ cover = 1.0F - (dist2 - rmin2) * cscale;
+ setup->quad[0].input.coverage[QUAD_BOTTOM_RIGHT] = MIN2(cover, 1.0f);
+ setup->quad[0].inout.mask |= MASK_BOTTOM_RIGHT;
+ }
+
+ 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] );
+ }
+ }
+ }
+ }
+ else {
+ /* square points */
+ const int xmin = (int) (x + 0.75 - halfSize);
+ const int ymin = (int) (y + 0.25 - halfSize);
+ const int xmax = xmin + (int) size;
+ const int ymax = ymin + (int) size;
+ /* XXX could apply scissor to xmin,ymin,xmax,ymax now */
+ const int ixmin = block(xmin);
+ const int ixmax = block(xmax - 1);
+ const int iymin = block(ymin);
+ const int iymax = block(ymax - 1);
+ int ix, iy;
+
+ /*
+ debug_printf("(%f, %f) -> X:%d..%d Y:%d..%d\n", x, y, xmin, xmax,ymin,ymax);
+ */
+ for (iy = iymin; iy <= iymax; iy += 2) {
+ uint rowMask = 0xf;
+ if (iy < ymin) {
+ /* above the top edge */
+ rowMask &= (MASK_BOTTOM_LEFT | MASK_BOTTOM_RIGHT);
+ }
+ if (iy + 1 >= ymax) {
+ /* below the bottom edge */
+ rowMask &= (MASK_TOP_LEFT | MASK_TOP_RIGHT);
+ }
+
+ for (ix = ixmin; ix <= ixmax; ix += 2) {
+ uint mask = rowMask;
+
+ if (ix < xmin) {
+ /* fragment is past left edge of point, turn off left bits */
+ mask &= (MASK_BOTTOM_RIGHT | MASK_TOP_RIGHT);
+ }
+ if (ix + 1 >= xmax) {
+ /* past the right edge */
+ mask &= (MASK_BOTTOM_LEFT | MASK_TOP_LEFT);
+ }
+
+ 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] );
+ }
+ }
+ }
+ }
+}
+
+void llvmpipe_setup_prepare( struct setup_context *setup )
+{
+ struct llvmpipe_context *lp = setup->llvmpipe;
+
+ if (lp->dirty) {
+ llvmpipe_update_derived(lp);
+ }
+
+ if (lp->reduced_api_prim == PIPE_PRIM_TRIANGLES &&
+ lp->rasterizer->fill_cw == PIPE_POLYGON_MODE_FILL &&
+ lp->rasterizer->fill_ccw == PIPE_POLYGON_MODE_FILL) {
+ /* we'll do culling */
+ setup->winding = lp->rasterizer->cull_mode;
+ }
+ else {
+ /* 'draw' will do culling */
+ setup->winding = PIPE_WINDING_NONE;
+ }
+}
+
+
+
+void llvmpipe_setup_destroy_context( struct setup_context *setup )
+{
+ align_free( setup );
+}
+
+
+/**
+ * Create a new primitive setup/render stage.
+ */
+struct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe )
+{
+ struct setup_context *setup;
+ unsigned i;
+
+ setup = align_malloc(sizeof(struct setup_context), 16);
+ if (!setup)
+ return NULL;
+
+ memset(setup, 0, sizeof *setup);
+ setup->llvmpipe = llvmpipe;
+
+ for (i = 0; i < MAX_QUADS; i++) {
+ setup->quad[i].coef = &setup->coef;
+ }
+
+ 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/llvmpipe/lp_setup.h b/src/gallium/drivers/llvmpipe/lp_setup.h
new file mode 100644
index 0000000000..89c43da046
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_setup.h
@@ -0,0 +1,53 @@
+/**************************************************************************
+ *
+ * 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 LP_SETUP_H
+#define LP_SETUP_H
+
+struct setup_context;
+struct llvmpipe_context;
+
+void
+llvmpipe_setup_tri( struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4],
+ const float (*v2)[4] );
+
+void
+llvmpipe_setup_line(struct setup_context *setup,
+ const float (*v0)[4],
+ const float (*v1)[4]);
+
+void
+llvmpipe_setup_point( struct setup_context *setup,
+ const float (*v0)[4] );
+
+
+struct setup_context *llvmpipe_setup_create_context( struct llvmpipe_context *llvmpipe );
+void llvmpipe_setup_prepare( struct setup_context *setup );
+void llvmpipe_setup_destroy_context( struct setup_context *setup );
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h
new file mode 100644
index 0000000000..7b26ce61a3
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state.h
@@ -0,0 +1,230 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef LP_STATE_H
+#define LP_STATE_H
+
+#include <llvm-c/Core.h>
+
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h"
+#include "lp_jit.h"
+#include "lp_bld_sample.h" /* for struct lp_sampler_static_state */
+
+
+#define LP_NEW_VIEWPORT 0x1
+#define LP_NEW_RASTERIZER 0x2
+#define LP_NEW_FS 0x4
+#define LP_NEW_BLEND 0x8
+#define LP_NEW_CLIP 0x10
+#define LP_NEW_SCISSOR 0x20
+#define LP_NEW_STIPPLE 0x40
+#define LP_NEW_FRAMEBUFFER 0x80
+#define LP_NEW_DEPTH_STENCIL_ALPHA 0x100
+#define LP_NEW_CONSTANTS 0x200
+#define LP_NEW_SAMPLER 0x400
+#define LP_NEW_TEXTURE 0x800
+#define LP_NEW_VERTEX 0x1000
+#define LP_NEW_VS 0x2000
+#define LP_NEW_QUERY 0x4000
+
+
+struct tgsi_sampler;
+struct vertex_info;
+struct pipe_context;
+struct llvmpipe_context;
+
+struct lp_fragment_shader;
+
+
+struct lp_fragment_shader_variant_key
+{
+ enum pipe_format zsbuf_format;
+ struct pipe_depth_state depth;
+ struct pipe_alpha_state alpha;
+ struct pipe_blend_state blend;
+
+ struct lp_sampler_static_state sampler[PIPE_MAX_SAMPLERS];
+};
+
+
+struct lp_fragment_shader_variant
+{
+ struct lp_fragment_shader *shader;
+
+ struct lp_fragment_shader_variant_key key;
+
+ LLVMValueRef function;
+
+ lp_jit_frag_func jit_function;
+
+ struct lp_fragment_shader_variant *next;
+};
+
+
+/**
+ * Subclass of pipe_shader_state (though it doesn't really need to be).
+ *
+ * This is starting to look an awful lot like a quad pipeline stage...
+ */
+struct lp_fragment_shader
+{
+ struct pipe_shader_state base;
+
+ struct tgsi_shader_info info;
+
+ struct lp_fragment_shader_variant *variants;
+
+ struct lp_fragment_shader_variant *current;
+};
+
+
+/** Subclass of pipe_shader_state */
+struct lp_vertex_shader {
+ struct pipe_shader_state shader;
+ struct draw_vertex_shader *draw_data;
+};
+
+
+
+void *
+llvmpipe_create_blend_state(struct pipe_context *,
+ const struct pipe_blend_state *);
+void llvmpipe_bind_blend_state(struct pipe_context *,
+ void *);
+void llvmpipe_delete_blend_state(struct pipe_context *,
+ void *);
+
+void *
+llvmpipe_create_sampler_state(struct pipe_context *,
+ const struct pipe_sampler_state *);
+void llvmpipe_bind_sampler_states(struct pipe_context *, unsigned, void **);
+void llvmpipe_delete_sampler_state(struct pipe_context *, void *);
+
+void *
+llvmpipe_create_depth_stencil_state(struct pipe_context *,
+ const struct pipe_depth_stencil_alpha_state *);
+void llvmpipe_bind_depth_stencil_state(struct pipe_context *, void *);
+void llvmpipe_delete_depth_stencil_state(struct pipe_context *, void *);
+
+void *
+llvmpipe_create_rasterizer_state(struct pipe_context *,
+ const struct pipe_rasterizer_state *);
+void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *);
+void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *);
+
+void llvmpipe_set_framebuffer_state( struct pipe_context *,
+ const struct pipe_framebuffer_state * );
+
+void llvmpipe_set_blend_color( struct pipe_context *pipe,
+ const struct pipe_blend_color *blend_color );
+
+void llvmpipe_set_clip_state( struct pipe_context *,
+ const struct pipe_clip_state * );
+
+void llvmpipe_set_constant_buffer(struct pipe_context *,
+ uint shader, uint index,
+ const struct pipe_constant_buffer *buf);
+
+void *llvmpipe_create_fs_state(struct pipe_context *,
+ const struct pipe_shader_state *);
+void llvmpipe_bind_fs_state(struct pipe_context *, void *);
+void llvmpipe_delete_fs_state(struct pipe_context *, void *);
+void *llvmpipe_create_vs_state(struct pipe_context *,
+ const struct pipe_shader_state *);
+void llvmpipe_bind_vs_state(struct pipe_context *, void *);
+void llvmpipe_delete_vs_state(struct pipe_context *, void *);
+
+void llvmpipe_set_polygon_stipple( struct pipe_context *,
+ const struct pipe_poly_stipple * );
+
+void llvmpipe_set_scissor_state( struct pipe_context *,
+ const struct pipe_scissor_state * );
+
+void llvmpipe_set_sampler_textures( struct pipe_context *,
+ unsigned num,
+ struct pipe_texture ** );
+
+void llvmpipe_set_viewport_state( struct pipe_context *,
+ const struct pipe_viewport_state * );
+
+void llvmpipe_set_vertex_elements(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_element *);
+
+void llvmpipe_set_vertex_buffers(struct pipe_context *,
+ unsigned count,
+ const struct pipe_vertex_buffer *);
+
+void llvmpipe_update_fs(struct llvmpipe_context *lp);
+
+void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe );
+
+
+boolean llvmpipe_draw_arrays(struct pipe_context *pipe, unsigned mode,
+ unsigned start, unsigned count);
+
+boolean llvmpipe_draw_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned mode, unsigned start, unsigned count);
+boolean
+llvmpipe_draw_range_elements(struct pipe_context *pipe,
+ struct pipe_buffer *indexBuffer,
+ unsigned indexSize,
+ unsigned min_index,
+ unsigned max_index,
+ unsigned mode, unsigned start, unsigned count);
+
+void
+llvmpipe_set_edgeflags(struct pipe_context *pipe, const unsigned *edgeflags);
+
+
+void
+llvmpipe_map_transfers(struct llvmpipe_context *lp);
+
+void
+llvmpipe_unmap_transfers(struct llvmpipe_context *lp);
+
+void
+llvmpipe_map_texture_surfaces(struct llvmpipe_context *lp);
+
+void
+llvmpipe_unmap_texture_surfaces(struct llvmpipe_context *lp);
+
+
+struct vertex_info *
+llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe);
+
+struct vertex_info *
+llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe);
+
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c
new file mode 100644
index 0000000000..3f03bd0057
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c
@@ -0,0 +1,114 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ * @author Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "util/u_memory.h"
+#include "util/u_math.h"
+#include "util/u_debug_dump.h"
+#include "lp_screen.h"
+#include "lp_context.h"
+#include "lp_state.h"
+
+
+void *
+llvmpipe_create_blend_state(struct pipe_context *pipe,
+ const struct pipe_blend_state *blend)
+{
+ return mem_dup(blend, sizeof(*blend));
+}
+
+void llvmpipe_bind_blend_state( struct pipe_context *pipe,
+ void *blend )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ llvmpipe->blend = blend;
+
+ llvmpipe->dirty |= LP_NEW_BLEND;
+}
+
+void llvmpipe_delete_blend_state(struct pipe_context *pipe,
+ void *blend)
+{
+ FREE( blend );
+}
+
+
+void llvmpipe_set_blend_color( struct pipe_context *pipe,
+ const struct pipe_blend_color *blend_color )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ unsigned i, j;
+
+ memcpy(&llvmpipe->blend_color, blend_color, sizeof *blend_color);
+
+ if(!llvmpipe->jit_context.blend_color)
+ llvmpipe->jit_context.blend_color = align_malloc(4 * 16, 16);
+ for (i = 0; i < 4; ++i) {
+ uint8_t c = float_to_ubyte(blend_color->color[i]);
+ for (j = 0; j < 16; ++j)
+ llvmpipe->jit_context.blend_color[i*4 + j] = c;
+ }
+}
+
+
+/** XXX move someday? Or consolidate all these simple state setters
+ * into one file.
+ */
+
+
+void *
+llvmpipe_create_depth_stencil_state(struct pipe_context *pipe,
+ const struct pipe_depth_stencil_alpha_state *depth_stencil)
+{
+ return mem_dup(depth_stencil, sizeof(*depth_stencil));
+}
+
+void
+llvmpipe_bind_depth_stencil_state(struct pipe_context *pipe,
+ void *depth_stencil)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ llvmpipe->depth_stencil = (const struct pipe_depth_stencil_alpha_state *)depth_stencil;
+
+ if(llvmpipe->depth_stencil)
+ llvmpipe->jit_context.alpha_ref_value = llvmpipe->depth_stencil->alpha.ref_value;
+
+ llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA;
+}
+
+void
+llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth)
+{
+ FREE( depth );
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_clip.c b/src/gallium/drivers/llvmpipe/lp_state_clip.c
new file mode 100644
index 0000000000..df68f27acc
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_clip.c
@@ -0,0 +1,79 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+#include "lp_context.h"
+#include "lp_state.h"
+#include "draw/draw_context.h"
+
+
+void llvmpipe_set_clip_state( struct pipe_context *pipe,
+ const struct pipe_clip_state *clip )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ /* pass the clip state to the draw module */
+ draw_set_clip_state(llvmpipe->draw, clip);
+}
+
+
+void llvmpipe_set_viewport_state( struct pipe_context *pipe,
+ const struct pipe_viewport_state *viewport )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ /* pass the viewport info to the draw module */
+ draw_set_viewport_state(llvmpipe->draw, viewport);
+
+ llvmpipe->viewport = *viewport; /* struct copy */
+ llvmpipe->dirty |= LP_NEW_VIEWPORT;
+}
+
+
+void llvmpipe_set_scissor_state( struct pipe_context *pipe,
+ const struct pipe_scissor_state *scissor )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ draw_flush(llvmpipe->draw);
+
+ llvmpipe->scissor = *scissor; /* struct copy */
+ llvmpipe->dirty |= LP_NEW_SCISSOR;
+}
+
+
+void llvmpipe_set_polygon_stipple( struct pipe_context *pipe,
+ const struct pipe_poly_stipple *stipple )
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ draw_flush(llvmpipe->draw);
+
+ llvmpipe->poly_stipple = *stipple; /* struct copy */
+ llvmpipe->dirty |= LP_NEW_STIPPLE;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_derived.c b/src/gallium/drivers/llvmpipe/lp_state_derived.c
new file mode 100644
index 0000000000..30fb41ea65
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_derived.c
@@ -0,0 +1,277 @@
+/**************************************************************************
+ *
+ * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw/draw_context.h"
+#include "draw/draw_vertex.h"
+#include "draw/draw_private.h"
+#include "lp_context.h"
+#include "lp_screen.h"
+#include "lp_tex_cache.h"
+#include "lp_state.h"
+
+
+/**
+ * Mark the current vertex layout as "invalid".
+ * We'll validate the vertex layout later, when we start to actually
+ * render a point or line or tri.
+ */
+static void
+invalidate_vertex_layout(struct llvmpipe_context *llvmpipe)
+{
+ llvmpipe->vertex_info.num_attribs = 0;
+}
+
+
+/**
+ * The vertex info describes how to convert the post-transformed vertices
+ * (simple float[][4]) used by the 'draw' module into vertices for
+ * rasterization.
+ *
+ * This function validates the vertex layout and returns a pointer to a
+ * vertex_info object.
+ */
+struct vertex_info *
+llvmpipe_get_vertex_info(struct llvmpipe_context *llvmpipe)
+{
+ struct vertex_info *vinfo = &llvmpipe->vertex_info;
+
+ if (vinfo->num_attribs == 0) {
+ /* compute vertex layout now */
+ const struct lp_fragment_shader *lpfs = llvmpipe->fs;
+ const enum interp_mode colorInterp
+ = llvmpipe->rasterizer->flatshade ? INTERP_CONSTANT : INTERP_LINEAR;
+ uint i;
+
+ if (llvmpipe->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 = &llvmpipe->vertex_info_vbuf;
+ const uint num = draw_num_vs_outputs(llvmpipe->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);
+ }
+
+ /*
+ * Loop over fragment shader inputs, searching for the matching output
+ * from the vertex shader.
+ */
+ 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,
+ TGSI_SEMANTIC_POSITION, 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_POS, src);
+ break;
+
+ case TGSI_SEMANTIC_COLOR:
+ src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_COLOR,
+ lpfs->info.input_semantic_index[i]);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, colorInterp, src);
+ break;
+
+ case TGSI_SEMANTIC_FOG:
+ src = draw_find_vs_output(llvmpipe->draw, TGSI_SEMANTIC_FOG, 0);
+ draw_emit_vertex_attr(vinfo, EMIT_4F, interp, src);
+ break;
+
+ case TGSI_SEMANTIC_GENERIC:
+ case TGSI_SEMANTIC_FACE:
+ /* 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, src);
+ break;
+
+ default:
+ assert(0);
+ }
+ }
+
+ llvmpipe->psize_slot = draw_find_vs_output(llvmpipe->draw,
+ TGSI_SEMANTIC_PSIZE, 0);
+ if (llvmpipe->psize_slot > 0) {
+ draw_emit_vertex_attr(vinfo, EMIT_4F, INTERP_CONSTANT,
+ llvmpipe->psize_slot);
+ }
+
+ draw_compute_vertex_size(vinfo);
+ }
+
+ return vinfo;
+}
+
+
+/**
+ * Called from vbuf module.
+ *
+ * Note that there's actually two different vertex layouts in llvmpipe.
+ *
+ * The normal one is computed in llvmpipe_get_vertex_info() above and is
+ * used by the point/line/tri "setup" code.
+ *
+ * The other one (this one) is only used by the vbuf module (which is
+ * not normally used by default but used in testing). For the vbuf module,
+ * we basically want to pass-through the draw module's vertex layout as-is.
+ * When the llvmpipe vbuf code begins drawing, the normal vertex layout
+ * will come into play again.
+ */
+struct vertex_info *
+llvmpipe_get_vbuf_vertex_info(struct llvmpipe_context *llvmpipe)
+{
+ (void) llvmpipe_get_vertex_info(llvmpipe);
+ return &llvmpipe->vertex_info_vbuf;
+}
+
+
+/**
+ * Recompute cliprect from scissor bounds, scissor enable and surface size.
+ */
+static void
+compute_cliprect(struct llvmpipe_context *lp)
+{
+ /* LP_NEW_FRAMEBUFFER
+ */
+ uint surfWidth = lp->framebuffer.width;
+ uint surfHeight = lp->framebuffer.height;
+
+ /* LP_NEW_RASTERIZER
+ */
+ if (lp->rasterizer->scissor) {
+
+ /* LP_NEW_SCISSOR
+ *
+ * clip to scissor rect:
+ */
+ lp->cliprect.minx = MAX2(lp->scissor.minx, 0);
+ lp->cliprect.miny = MAX2(lp->scissor.miny, 0);
+ lp->cliprect.maxx = MIN2(lp->scissor.maxx, surfWidth);
+ lp->cliprect.maxy = MIN2(lp->scissor.maxy, surfHeight);
+ }
+ else {
+ /* clip to surface bounds */
+ lp->cliprect.minx = 0;
+ lp->cliprect.miny = 0;
+ lp->cliprect.maxx = surfWidth;
+ lp->cliprect.maxy = surfHeight;
+ }
+}
+
+
+static void
+update_tgsi_samplers( struct llvmpipe_context *llvmpipe )
+{
+ unsigned i;
+
+ /* vertex shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ llvmpipe->tgsi.vert_samplers[i].sampler = llvmpipe->sampler[i];
+ llvmpipe->tgsi.vert_samplers[i].texture = llvmpipe->texture[i];
+ llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
+ }
+
+ /* fragment shader samplers */
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ llvmpipe->tgsi.frag_samplers[i].sampler = llvmpipe->sampler[i];
+ llvmpipe->tgsi.frag_samplers[i].texture = llvmpipe->texture[i];
+ llvmpipe->tgsi.frag_samplers[i].base.get_samples = lp_get_samples;
+ }
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ lp_tex_tile_cache_validate_texture( llvmpipe->tex_cache[i] );
+ }
+
+ llvmpipe->jit_context.samplers = (struct tgsi_sampler **)llvmpipe->tgsi.frag_samplers_list;
+}
+
+/* Hopefully this will remain quite simple, otherwise need to pull in
+ * something like the state tracker mechanism.
+ */
+void llvmpipe_update_derived( struct llvmpipe_context *llvmpipe )
+{
+ struct llvmpipe_screen *lp_screen = llvmpipe_screen(llvmpipe->pipe.screen);
+
+ /* Check for updated textures.
+ */
+ if (llvmpipe->tex_timestamp != lp_screen->timestamp) {
+ llvmpipe->tex_timestamp = lp_screen->timestamp;
+ llvmpipe->dirty |= LP_NEW_TEXTURE;
+ }
+
+ if (llvmpipe->dirty & (LP_NEW_SAMPLER |
+ LP_NEW_TEXTURE))
+ update_tgsi_samplers( llvmpipe );
+
+ if (llvmpipe->dirty & (LP_NEW_RASTERIZER |
+ LP_NEW_FS |
+ LP_NEW_VS))
+ invalidate_vertex_layout( llvmpipe );
+
+ if (llvmpipe->dirty & (LP_NEW_SCISSOR |
+ LP_NEW_RASTERIZER |
+ LP_NEW_FRAMEBUFFER))
+ compute_cliprect(llvmpipe);
+
+ if (llvmpipe->dirty & (LP_NEW_FS |
+ LP_NEW_BLEND |
+ LP_NEW_DEPTH_STENCIL_ALPHA |
+ LP_NEW_SAMPLER |
+ LP_NEW_TEXTURE))
+ llvmpipe_update_fs( llvmpipe );
+
+
+ llvmpipe->dirty = 0;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
new file mode 100644
index 0000000000..9faed5a0b1
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -0,0 +1,762 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Code generate the whole fragment pipeline.
+ *
+ * The fragment pipeline consists of the following stages:
+ * - stipple (TBI)
+ * - early depth test
+ * - fragment shader
+ * - alpha test
+ * - depth/stencil test (stencil TBI)
+ * - blending
+ *
+ * This file has only the glue to assembly the fragment pipeline. The actual
+ * plumbing of converting Gallium state into LLVM IR is done elsewhere, in the
+ * lp_bld_*.[ch] files, and in a complete generic and reusable way. Here we
+ * muster the LLVM JIT execution engine to create a function that follows an
+ * established binary interface and that can be called from C directly.
+ *
+ * A big source of complexity here is that we often want to run different
+ * stages with different precisions and data types and precisions. For example,
+ * the fragment shader needs typically to be done in floats, but the
+ * depth/stencil test and blending is better done in the type that most closely
+ * matches the depth/stencil and color buffer respectively.
+ *
+ * Since the width of a SIMD vector register stays the same regardless of the
+ * element type, different types imply different number of elements, so we must
+ * code generate more instances of the stages with larger types to be able to
+ * feed/consume the stages with smaller types.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "util/u_format.h"
+#include "util/u_debug_dump.h"
+#include "pipe/internal/p_winsys_screen.h"
+#include "pipe/p_shader_tokens.h"
+#include "draw/draw_context.h"
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_parse.h"
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_conv.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_logic.h"
+#include "lp_bld_depth.h"
+#include "lp_bld_interp.h"
+#include "lp_bld_tgsi.h"
+#include "lp_bld_alpha.h"
+#include "lp_bld_blend.h"
+#include "lp_bld_swizzle.h"
+#include "lp_bld_flow.h"
+#include "lp_bld_debug.h"
+#include "lp_screen.h"
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_quad.h"
+#include "lp_tex_sample.h"
+
+
+static const unsigned char quad_offset_x[4] = {0, 1, 0, 1};
+static const unsigned char quad_offset_y[4] = {0, 0, 1, 1};
+
+
+/*
+ * Derive from the quad's upper left scalar coordinates the coordinates for
+ * all other quad pixels
+ */
+static void
+generate_pos0(LLVMBuilderRef builder,
+ LLVMValueRef x,
+ LLVMValueRef y,
+ LLVMValueRef *x0,
+ LLVMValueRef *y0)
+{
+ LLVMTypeRef int_elem_type = LLVMInt32Type();
+ LLVMTypeRef int_vec_type = LLVMVectorType(int_elem_type, QUAD_SIZE);
+ LLVMTypeRef elem_type = LLVMFloatType();
+ LLVMTypeRef vec_type = LLVMVectorType(elem_type, QUAD_SIZE);
+ LLVMValueRef x_offsets[QUAD_SIZE];
+ LLVMValueRef y_offsets[QUAD_SIZE];
+ unsigned i;
+
+ x = lp_build_broadcast(builder, int_vec_type, x);
+ y = lp_build_broadcast(builder, int_vec_type, y);
+
+ for(i = 0; i < QUAD_SIZE; ++i) {
+ x_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_x[i], 0);
+ y_offsets[i] = LLVMConstInt(int_elem_type, quad_offset_y[i], 0);
+ }
+
+ x = LLVMBuildAdd(builder, x, LLVMConstVector(x_offsets, QUAD_SIZE), "");
+ y = LLVMBuildAdd(builder, y, LLVMConstVector(y_offsets, QUAD_SIZE), "");
+
+ *x0 = LLVMBuildSIToFP(builder, x, vec_type, "");
+ *y0 = LLVMBuildSIToFP(builder, y, vec_type, "");
+}
+
+
+/**
+ * Generate the depth test.
+ */
+static void
+generate_depth(LLVMBuilderRef builder,
+ const struct lp_fragment_shader_variant_key *key,
+ struct lp_type src_type,
+ struct lp_build_mask_context *mask,
+ LLVMValueRef src,
+ LLVMValueRef dst_ptr)
+{
+ const struct util_format_description *format_desc;
+ struct lp_type dst_type;
+
+ if(!key->depth.enabled)
+ return;
+
+ format_desc = util_format_description(key->zsbuf_format);
+ assert(format_desc);
+
+ /* Pick the depth type. */
+ dst_type = lp_depth_type(format_desc, src_type.width*src_type.length);
+
+ /* FIXME: Cope with a depth test type with a different bit width. */
+ assert(dst_type.width == src_type.width);
+ assert(dst_type.length == src_type.length);
+
+#if 1
+ src = lp_build_clamped_float_to_unsigned_norm(builder,
+ src_type,
+ dst_type.width,
+ src);
+#else
+ lp_build_conv(builder, src_type, dst_type, &src, 1, &src, 1);
+#endif
+
+ lp_build_depth_test(builder,
+ &key->depth,
+ dst_type,
+ format_desc,
+ mask,
+ src,
+ dst_ptr);
+}
+
+
+/**
+ * Generate the fragment shader, depth/stencil test, and alpha tests.
+ */
+static void
+generate_fs(struct llvmpipe_context *lp,
+ struct lp_fragment_shader *shader,
+ const struct lp_fragment_shader_variant_key *key,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ LLVMValueRef context_ptr,
+ unsigned i,
+ const struct lp_build_interp_soa_context *interp,
+ struct lp_build_sampler_soa *sampler,
+ LLVMValueRef *pmask,
+ LLVMValueRef *color,
+ LLVMValueRef depth_ptr)
+{
+ const struct tgsi_token *tokens = shader->base.tokens;
+ LLVMTypeRef elem_type;
+ LLVMTypeRef vec_type;
+ LLVMTypeRef int_vec_type;
+ LLVMValueRef consts_ptr;
+ LLVMValueRef outputs[PIPE_MAX_SHADER_OUTPUTS][NUM_CHANNELS];
+ LLVMValueRef z = interp->pos[2];
+ struct lp_build_flow_context *flow;
+ struct lp_build_mask_context mask;
+ boolean early_depth_test;
+ unsigned attrib;
+ unsigned chan;
+
+ elem_type = lp_build_elem_type(type);
+ vec_type = lp_build_vec_type(type);
+ int_vec_type = lp_build_int_vec_type(type);
+
+ consts_ptr = lp_jit_context_constants(builder, context_ptr);
+
+ flow = lp_build_flow_create(builder);
+
+ memset(outputs, 0, sizeof outputs);
+
+ lp_build_flow_scope_begin(flow);
+
+ /* Declare the color and z variables */
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ color[chan] = LLVMGetUndef(vec_type);
+ lp_build_flow_scope_declare(flow, &color[chan]);
+ }
+ lp_build_flow_scope_declare(flow, &z);
+
+ lp_build_mask_begin(&mask, flow, type, *pmask);
+
+ early_depth_test =
+ key->depth.enabled &&
+ !key->alpha.enabled &&
+ !shader->info.uses_kill &&
+ !shader->info.writes_z;
+
+ if(early_depth_test)
+ generate_depth(builder, key,
+ type, &mask,
+ z, depth_ptr);
+
+ lp_build_tgsi_soa(builder, tokens, type, &mask,
+ consts_ptr, interp->pos, interp->inputs,
+ outputs, sampler);
+
+ for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ if(outputs[attrib][chan]) {
+ lp_build_name(outputs[attrib][chan], "output%u.%u.%c", i, attrib, "xyzw"[chan]);
+
+ switch (shader->info.output_semantic_name[attrib]) {
+ case TGSI_SEMANTIC_COLOR:
+ {
+ unsigned cbuf = shader->info.output_semantic_index[attrib];
+
+ lp_build_name(outputs[attrib][chan], "color%u.%u.%c", i, attrib, "rgba"[chan]);
+
+ /* Alpha test */
+ /* XXX: should the alpha reference value be passed separately? */
+ if(cbuf == 0 && chan == 3) {
+ LLVMValueRef alpha = outputs[attrib][chan];
+ LLVMValueRef alpha_ref_value;
+ alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
+ alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
+ lp_build_alpha_test(builder, &key->alpha, type,
+ &mask, alpha, alpha_ref_value);
+ }
+
+ if(cbuf == 0)
+ color[chan] = outputs[attrib][chan];
+
+ break;
+ }
+
+ case TGSI_SEMANTIC_POSITION:
+ if(chan == 2)
+ z = outputs[attrib][chan];
+ break;
+ }
+ }
+ }
+ }
+
+ if(!early_depth_test)
+ generate_depth(builder, key,
+ type, &mask,
+ z, depth_ptr);
+
+ lp_build_mask_end(&mask);
+
+ lp_build_flow_scope_end(flow);
+
+ lp_build_flow_destroy(flow);
+
+ *pmask = mask.value;
+
+}
+
+
+/**
+ * Generate color blending and color output.
+ */
+static void
+generate_blend(const struct pipe_blend_state *blend,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ LLVMValueRef context_ptr,
+ LLVMValueRef mask,
+ LLVMValueRef *src,
+ LLVMValueRef dst_ptr)
+{
+ struct lp_build_context bld;
+ struct lp_build_flow_context *flow;
+ struct lp_build_mask_context mask_ctx;
+ LLVMTypeRef vec_type;
+ LLVMTypeRef int_vec_type;
+ LLVMValueRef const_ptr;
+ LLVMValueRef con[4];
+ LLVMValueRef dst[4];
+ LLVMValueRef res[4];
+ unsigned chan;
+
+ lp_build_context_init(&bld, builder, type);
+
+ flow = lp_build_flow_create(builder);
+ lp_build_mask_begin(&mask_ctx, flow, type, mask);
+
+ vec_type = lp_build_vec_type(type);
+ int_vec_type = lp_build_int_vec_type(type);
+
+ const_ptr = lp_jit_context_blend_color(builder, context_ptr);
+ const_ptr = LLVMBuildBitCast(builder, const_ptr,
+ LLVMPointerType(vec_type, 0), "");
+
+ for(chan = 0; chan < 4; ++chan) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
+ con[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
+
+ dst[chan] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
+
+ lp_build_name(con[chan], "con.%c", "rgba"[chan]);
+ lp_build_name(dst[chan], "dst.%c", "rgba"[chan]);
+ }
+
+ lp_build_blend_soa(builder, blend, type, src, dst, con, res);
+
+ for(chan = 0; chan < 4; ++chan) {
+ if(blend->colormask & (1 << chan)) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), chan, 0);
+ lp_build_name(res[chan], "res.%c", "rgba"[chan]);
+ res[chan] = lp_build_select(&bld, mask, res[chan], dst[chan]);
+ LLVMBuildStore(builder, res[chan], LLVMBuildGEP(builder, dst_ptr, &index, 1, ""));
+ }
+ }
+
+ lp_build_mask_end(&mask_ctx);
+ lp_build_flow_destroy(flow);
+}
+
+
+/**
+ * Generate the runtime callable function for the whole fragment pipeline.
+ */
+static struct lp_fragment_shader_variant *
+generate_fragment(struct llvmpipe_context *lp,
+ struct lp_fragment_shader *shader,
+ const struct lp_fragment_shader_variant_key *key)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(lp->pipe.screen);
+ struct lp_fragment_shader_variant *variant;
+ struct lp_type fs_type;
+ struct lp_type blend_type;
+ LLVMTypeRef fs_elem_type;
+ LLVMTypeRef fs_vec_type;
+ LLVMTypeRef fs_int_vec_type;
+ LLVMTypeRef blend_vec_type;
+ LLVMTypeRef blend_int_vec_type;
+ LLVMTypeRef arg_types[9];
+ LLVMTypeRef func_type;
+ LLVMValueRef context_ptr;
+ LLVMValueRef x;
+ LLVMValueRef y;
+ LLVMValueRef a0_ptr;
+ LLVMValueRef dadx_ptr;
+ LLVMValueRef dady_ptr;
+ LLVMValueRef mask_ptr;
+ LLVMValueRef color_ptr;
+ LLVMValueRef depth_ptr;
+ LLVMBasicBlockRef block;
+ LLVMBuilderRef builder;
+ LLVMValueRef x0;
+ LLVMValueRef y0;
+ struct lp_build_sampler_soa *sampler;
+ struct lp_build_interp_soa_context interp;
+ LLVMValueRef fs_mask[LP_MAX_VECTOR_LENGTH];
+ LLVMValueRef fs_out_color[NUM_CHANNELS][LP_MAX_VECTOR_LENGTH];
+ LLVMValueRef blend_mask;
+ LLVMValueRef blend_in_color[NUM_CHANNELS];
+ unsigned num_fs;
+ unsigned i;
+ unsigned chan;
+
+#ifdef DEBUG
+ tgsi_dump(shader->base.tokens, 0);
+ if(key->depth.enabled) {
+ debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE));
+ debug_printf("depth.writemask = %u\n", key->depth.writemask);
+ debug_printf("depth.occlusion_count = %u\n", key->depth.occlusion_count);
+ }
+ if(key->alpha.enabled) {
+ debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE));
+ debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value);
+ }
+ if(key->blend.logicop_enable) {
+ debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func);
+ }
+ else if(key->blend.blend_enable) {
+ debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rgb_func, TRUE));
+ debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_src_factor, TRUE));
+ debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rgb_dst_factor, TRUE));
+ debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.alpha_func, TRUE));
+ debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_src_factor, TRUE));
+ debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.alpha_dst_factor, TRUE));
+ }
+ debug_printf("blend.colormask = 0x%x\n", key->blend.colormask);
+#endif
+
+ variant = CALLOC_STRUCT(lp_fragment_shader_variant);
+ if(!variant)
+ return NULL;
+
+ variant->shader = shader;
+ memcpy(&variant->key, key, sizeof *key);
+
+ /* TODO: actually pick these based on the fs and color buffer
+ * characteristics. */
+
+ 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] */
+ fs_type.width = 32; /* 32-bit float */
+ fs_type.length = 4; /* 4 element per vector */
+ num_fs = 4;
+
+ 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] */
+ blend_type.width = 8; /* 8-bit ubyte values */
+ blend_type.length = 16; /* 16 elements per vector */
+
+ /*
+ * Generate the function prototype. Any change here must be reflected in
+ * lp_jit.h's lp_jit_frag_func function pointer type, and vice-versa.
+ */
+
+ fs_elem_type = lp_build_elem_type(fs_type);
+ fs_vec_type = lp_build_vec_type(fs_type);
+ fs_int_vec_type = lp_build_int_vec_type(fs_type);
+
+ blend_vec_type = lp_build_vec_type(blend_type);
+ blend_int_vec_type = lp_build_int_vec_type(blend_type);
+
+ arg_types[0] = screen->context_ptr_type; /* context */
+ arg_types[1] = LLVMInt32Type(); /* x */
+ arg_types[2] = LLVMInt32Type(); /* y */
+ arg_types[3] = LLVMPointerType(fs_elem_type, 0); /* a0 */
+ arg_types[4] = LLVMPointerType(fs_elem_type, 0); /* dadx */
+ arg_types[5] = LLVMPointerType(fs_elem_type, 0); /* dady */
+ arg_types[6] = LLVMPointerType(fs_int_vec_type, 0); /* mask */
+ arg_types[7] = LLVMPointerType(blend_vec_type, 0); /* color */
+ arg_types[8] = LLVMPointerType(fs_int_vec_type, 0); /* depth */
+
+ func_type = LLVMFunctionType(LLVMVoidType(), arg_types, Elements(arg_types), 0);
+
+ variant->function = LLVMAddFunction(screen->module, "shader", func_type);
+ LLVMSetFunctionCallConv(variant->function, LLVMCCallConv);
+ for(i = 0; i < Elements(arg_types); ++i)
+ if(LLVMGetTypeKind(arg_types[i]) == LLVMPointerTypeKind)
+ LLVMAddAttribute(LLVMGetParam(variant->function, i), LLVMNoAliasAttribute);
+
+ context_ptr = LLVMGetParam(variant->function, 0);
+ x = LLVMGetParam(variant->function, 1);
+ y = LLVMGetParam(variant->function, 2);
+ a0_ptr = LLVMGetParam(variant->function, 3);
+ dadx_ptr = LLVMGetParam(variant->function, 4);
+ dady_ptr = LLVMGetParam(variant->function, 5);
+ mask_ptr = LLVMGetParam(variant->function, 6);
+ color_ptr = LLVMGetParam(variant->function, 7);
+ depth_ptr = LLVMGetParam(variant->function, 8);
+
+ lp_build_name(context_ptr, "context");
+ lp_build_name(x, "x");
+ lp_build_name(y, "y");
+ lp_build_name(a0_ptr, "a0");
+ lp_build_name(dadx_ptr, "dadx");
+ lp_build_name(dady_ptr, "dady");
+ lp_build_name(mask_ptr, "mask");
+ lp_build_name(color_ptr, "color");
+ lp_build_name(depth_ptr, "depth");
+
+ /*
+ * Function body
+ */
+
+ block = LLVMAppendBasicBlock(variant->function, "entry");
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, block);
+
+ generate_pos0(builder, x, y, &x0, &y0);
+
+ lp_build_interp_soa_init(&interp, shader->base.tokens, builder, fs_type,
+ a0_ptr, dadx_ptr, dady_ptr,
+ x0, y0, 2, 0);
+
+#if 0
+ /* C texture sampling */
+ sampler = lp_c_sampler_soa_create(context_ptr);
+#else
+ /* code generated texture sampling */
+ sampler = lp_llvm_sampler_soa_create(key->sampler, context_ptr);
+#endif
+
+ for(i = 0; i < num_fs; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef out_color[NUM_CHANNELS];
+ LLVMValueRef depth_ptr_i;
+
+ if(i != 0)
+ lp_build_interp_soa_update(&interp);
+
+ fs_mask[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, mask_ptr, &index, 1, ""), "");
+ depth_ptr_i = LLVMBuildGEP(builder, depth_ptr, &index, 1, "");
+
+ generate_fs(lp, shader, key,
+ builder,
+ fs_type,
+ context_ptr,
+ i,
+ &interp,
+ sampler,
+ &fs_mask[i],
+ out_color,
+ depth_ptr_i);
+
+ for(chan = 0; chan < NUM_CHANNELS; ++chan)
+ fs_out_color[chan][i] = out_color[chan];
+ }
+
+ sampler->destroy(sampler);
+
+ /*
+ * Convert the fs's output color and mask to fit to the blending type.
+ */
+
+ for(chan = 0; chan < NUM_CHANNELS; ++chan) {
+ lp_build_conv(builder, fs_type, blend_type,
+ fs_out_color[chan], num_fs,
+ &blend_in_color[chan], 1);
+ lp_build_name(blend_in_color[chan], "color.%c", "rgba"[chan]);
+
+ }
+
+ lp_build_conv_mask(builder, fs_type, blend_type,
+ fs_mask, num_fs,
+ &blend_mask, 1);
+
+ /*
+ * Blending.
+ */
+
+ generate_blend(&key->blend,
+ builder,
+ blend_type,
+ context_ptr,
+ blend_mask,
+ blend_in_color,
+ color_ptr);
+
+ LLVMBuildRetVoid(builder);
+
+ LLVMDisposeBuilder(builder);
+
+ /*
+ * Translate the LLVM IR into machine code.
+ */
+
+ LLVMRunFunctionPassManager(screen->pass, variant->function);
+
+#ifdef DEBUG
+ LLVMDumpValue(variant->function);
+ debug_printf("\n");
+#endif
+
+ if(LLVMVerifyFunction(variant->function, LLVMPrintMessageAction)) {
+ LLVMDumpValue(variant->function);
+ abort();
+ }
+
+ variant->jit_function = (lp_jit_frag_func)LLVMGetPointerToGlobal(screen->engine, variant->function);
+
+#ifdef DEBUG
+ lp_disassemble(variant->jit_function);
+#endif
+
+ variant->next = shader->variants;
+ shader->variants = variant;
+
+ return variant;
+}
+
+
+void *
+llvmpipe_create_fs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *templ)
+{
+ struct lp_fragment_shader *shader;
+
+ shader = CALLOC_STRUCT(lp_fragment_shader);
+ if (!shader)
+ return NULL;
+
+ /* get/save the summary info for this shader */
+ tgsi_scan_shader(templ->tokens, &shader->info);
+
+ /* we need to keep a local copy of the tokens */
+ shader->base.tokens = tgsi_dup_tokens(templ->tokens);
+
+ return shader;
+}
+
+
+void
+llvmpipe_bind_fs_state(struct pipe_context *pipe, void *fs)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ llvmpipe->fs = (struct lp_fragment_shader *) fs;
+
+ llvmpipe->dirty |= LP_NEW_FS;
+}
+
+
+void
+llvmpipe_delete_fs_state(struct pipe_context *pipe, void *fs)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ struct llvmpipe_screen *screen = llvmpipe_screen(pipe->screen);
+ struct lp_fragment_shader *shader = fs;
+ struct lp_fragment_shader_variant *variant;
+
+ assert(fs != llvmpipe->fs);
+
+ variant = shader->variants;
+ while(variant) {
+ struct lp_fragment_shader_variant *next = variant->next;
+
+ if(variant->function) {
+ if(variant->jit_function)
+ LLVMFreeMachineCodeForFunction(screen->engine, variant->function);
+ LLVMDeleteFunction(variant->function);
+ }
+
+ FREE(variant);
+
+ variant = next;
+ }
+
+ FREE((void *) shader->base.tokens);
+ FREE(shader);
+}
+
+
+
+void
+llvmpipe_set_constant_buffer(struct pipe_context *pipe,
+ uint shader, uint index,
+ const struct pipe_constant_buffer *buf)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ assert(shader < PIPE_SHADER_TYPES);
+ assert(index == 0);
+
+ /* note: reference counting */
+ pipe_buffer_reference(&llvmpipe->constants[shader].buffer,
+ buf ? buf->buffer : NULL);
+
+ llvmpipe->dirty |= LP_NEW_CONSTANTS;
+}
+
+
+/**
+ * We need to generate several variants of the fragment pipeline to match
+ * all the combinations of the contributing state atoms.
+ *
+ * TODO: there is actually no reason to tie this to context state -- the
+ * generated code could be cached globally in the screen.
+ */
+static void
+make_variant_key(struct llvmpipe_context *lp,
+ struct lp_fragment_shader *shader,
+ struct lp_fragment_shader_variant_key *key)
+{
+ unsigned i;
+
+ memset(key, 0, sizeof *key);
+
+ if(lp->framebuffer.zsbuf &&
+ lp->depth_stencil->depth.enabled) {
+ key->zsbuf_format = lp->framebuffer.zsbuf->format;
+ memcpy(&key->depth, &lp->depth_stencil->depth, sizeof key->depth);
+ }
+
+ key->alpha.enabled = lp->depth_stencil->alpha.enabled;
+ if(key->alpha.enabled)
+ key->alpha.func = lp->depth_stencil->alpha.func;
+ /* alpha.ref_value is passed in jit_context */
+
+ if(lp->framebuffer.cbufs[0]) {
+ const struct util_format_description *format_desc;
+ unsigned chan;
+
+ memcpy(&key->blend, lp->blend, sizeof key->blend);
+
+ format_desc = util_format_description(lp->framebuffer.cbufs[0]->format);
+ assert(format_desc->layout == UTIL_FORMAT_COLORSPACE_RGB ||
+ format_desc->layout == UTIL_FORMAT_COLORSPACE_SRGB);
+
+ /* mask out color channels not present in the color buffer */
+ for(chan = 0; chan < 4; ++chan) {
+ enum util_format_swizzle swizzle = format_desc->swizzle[chan];
+ if(swizzle > 4)
+ key->blend.colormask &= ~(1 << chan);
+ }
+ }
+
+ for(i = 0; i < PIPE_MAX_SAMPLERS; ++i)
+ if(shader->info.file_mask[TGSI_FILE_SAMPLER] & (1 << i))
+ lp_sampler_static_state(&key->sampler[i], lp->texture[i], lp->sampler[i]);
+}
+
+
+void
+llvmpipe_update_fs(struct llvmpipe_context *lp)
+{
+ struct lp_fragment_shader *shader = lp->fs;
+ struct lp_fragment_shader_variant_key key;
+ struct lp_fragment_shader_variant *variant;
+
+ make_variant_key(lp, shader, &key);
+
+ variant = shader->variants;
+ while(variant) {
+ if(memcmp(&variant->key, &key, sizeof key) == 0)
+ break;
+
+ variant = variant->next;
+ }
+
+ if(!variant)
+ variant = generate_fragment(lp, shader, &key);
+
+ shader->current = variant;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
new file mode 100644
index 0000000000..4561c6b845
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_rasterizer.c
@@ -0,0 +1,62 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#include "pipe/p_defines.h"
+#include "util/u_memory.h"
+#include "lp_context.h"
+#include "lp_state.h"
+#include "draw/draw_context.h"
+
+
+
+void *
+llvmpipe_create_rasterizer_state(struct pipe_context *pipe,
+ const struct pipe_rasterizer_state *rast)
+{
+ return mem_dup(rast, sizeof(*rast));
+}
+
+void llvmpipe_bind_rasterizer_state(struct pipe_context *pipe,
+ void *setup)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ /* pass-through to draw module */
+ draw_set_rasterizer_state(llvmpipe->draw, setup);
+
+ llvmpipe->rasterizer = (struct pipe_rasterizer_state *)setup;
+
+ llvmpipe->dirty |= LP_NEW_RASTERIZER;
+}
+
+void llvmpipe_delete_rasterizer_state(struct pipe_context *pipe,
+ void *rasterizer)
+{
+ FREE( rasterizer );
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
new file mode 100644
index 0000000000..c69d90c723
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -0,0 +1,127 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors:
+ * Brian Paul
+ */
+
+#include "util/u_memory.h"
+
+#include "draw/draw_context.h"
+
+#include "lp_context.h"
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_texture.h"
+#include "lp_tex_cache.h"
+#include "draw/draw_context.h"
+
+
+
+void *
+llvmpipe_create_sampler_state(struct pipe_context *pipe,
+ const struct pipe_sampler_state *sampler)
+{
+ return mem_dup(sampler, sizeof(*sampler));
+}
+
+
+void
+llvmpipe_bind_sampler_states(struct pipe_context *pipe,
+ unsigned num, void **sampler)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ unsigned i;
+
+ assert(num <= PIPE_MAX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num == llvmpipe->num_samplers &&
+ !memcmp(llvmpipe->sampler, sampler, num * sizeof(void *)))
+ return;
+
+ draw_flush(llvmpipe->draw);
+
+ for (i = 0; i < num; ++i)
+ llvmpipe->sampler[i] = sampler[i];
+ for (i = num; i < PIPE_MAX_SAMPLERS; ++i)
+ llvmpipe->sampler[i] = NULL;
+
+ llvmpipe->num_samplers = num;
+
+ llvmpipe->dirty |= LP_NEW_SAMPLER;
+}
+
+
+void
+llvmpipe_set_sampler_textures(struct pipe_context *pipe,
+ unsigned num, struct pipe_texture **texture)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ uint i;
+
+ assert(num <= PIPE_MAX_SAMPLERS);
+
+ /* Check for no-op */
+ if (num == llvmpipe->num_textures &&
+ !memcmp(llvmpipe->texture, texture, num * sizeof(struct pipe_texture *)))
+ return;
+
+ draw_flush(llvmpipe->draw);
+
+ for (i = 0; i < PIPE_MAX_SAMPLERS; i++) {
+ struct pipe_texture *tex = i < num ? texture[i] : NULL;
+
+ pipe_texture_reference(&llvmpipe->texture[i], tex);
+ lp_tex_tile_cache_set_texture(llvmpipe->tex_cache[i], tex);
+
+ if(tex) {
+ struct llvmpipe_texture *lp_tex = llvmpipe_texture(tex);
+ struct lp_jit_texture *jit_tex = &llvmpipe->jit_context.textures[i];
+ jit_tex->width = tex->width[0];
+ jit_tex->height = tex->height[0];
+ jit_tex->stride = lp_tex->stride[0];
+ if(!lp_tex->dt)
+ jit_tex->data = lp_tex->data;
+ }
+ }
+
+ llvmpipe->num_textures = num;
+
+ llvmpipe->dirty |= LP_NEW_TEXTURE;
+}
+
+
+void
+llvmpipe_delete_sampler_state(struct pipe_context *pipe,
+ void *sampler)
+{
+ FREE( sampler );
+}
+
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_state_surface.c b/src/gallium/drivers/llvmpipe/lp_state_surface.c
new file mode 100644
index 0000000000..177a26b7b1
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_surface.c
@@ -0,0 +1,106 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_surface.h"
+#include "lp_tile_cache.h"
+
+#include "draw/draw_context.h"
+
+
+/**
+ * XXX this might get moved someday
+ * Set the framebuffer surface info: color buffers, zbuffer, stencil buffer.
+ * Here, we flush the old surfaces and update the tile cache to point to the new
+ * surfaces.
+ */
+void
+llvmpipe_set_framebuffer_state(struct pipe_context *pipe,
+ const struct pipe_framebuffer_state *fb)
+{
+ struct llvmpipe_context *lp = llvmpipe_context(pipe);
+ uint i;
+
+ for (i = 0; i < PIPE_MAX_COLOR_BUFS; i++) {
+ /* check if changing cbuf */
+ if (lp->framebuffer.cbufs[i] != fb->cbufs[i]) {
+ /* flush old */
+ lp_flush_tile_cache(lp->cbuf_cache[i]);
+
+ /* assign new */
+ lp->framebuffer.cbufs[i] = fb->cbufs[i];
+
+ /* update cache */
+ lp_tile_cache_set_surface(lp->cbuf_cache[i], fb->cbufs[i]);
+ }
+ }
+
+ lp->framebuffer.nr_cbufs = fb->nr_cbufs;
+
+ /* zbuf changing? */
+ if (lp->framebuffer.zsbuf != fb->zsbuf) {
+
+ if(lp->zsbuf_transfer) {
+ struct pipe_screen *screen = pipe->screen;
+
+ if(lp->zsbuf_map) {
+ screen->transfer_unmap(screen, lp->zsbuf_transfer);
+ lp->zsbuf_map = NULL;
+ }
+
+ screen->tex_transfer_destroy(lp->zsbuf_transfer);
+ lp->zsbuf_transfer = NULL;
+ }
+
+ /* assign new */
+ lp->framebuffer.zsbuf = fb->zsbuf;
+
+ /* Tell draw module how deep the Z/depth buffer is */
+ if (lp->framebuffer.zsbuf) {
+ int depth_bits;
+ double mrd;
+ depth_bits = pf_get_component_bits(lp->framebuffer.zsbuf->format,
+ PIPE_FORMAT_COMP_Z);
+ if (depth_bits > 16) {
+ mrd = 0.0000001;
+ }
+ else {
+ mrd = 0.00002;
+ }
+ draw_set_mrd(lp->draw, mrd);
+ }
+ }
+
+ lp->framebuffer.width = fb->width;
+ lp->framebuffer.height = fb->height;
+
+ lp->dirty |= LP_NEW_FRAMEBUFFER;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vertex.c b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
new file mode 100644
index 0000000000..1a17631a4c
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_vertex.c
@@ -0,0 +1,73 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+
+#include "lp_context.h"
+#include "lp_state.h"
+#include "lp_surface.h"
+
+#include "draw/draw_context.h"
+
+
+void
+llvmpipe_set_vertex_elements(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_element *attribs)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(llvmpipe->vertex_element, attribs,
+ count * sizeof(struct pipe_vertex_element));
+ llvmpipe->num_vertex_elements = count;
+
+ llvmpipe->dirty |= LP_NEW_VERTEX;
+
+ draw_set_vertex_elements(llvmpipe->draw, count, attribs);
+}
+
+
+void
+llvmpipe_set_vertex_buffers(struct pipe_context *pipe,
+ unsigned count,
+ const struct pipe_vertex_buffer *buffers)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ assert(count <= PIPE_MAX_ATTRIBS);
+
+ memcpy(llvmpipe->vertex_buffer, buffers, count * sizeof(buffers[0]));
+ llvmpipe->num_vertex_buffers = count;
+
+ llvmpipe->dirty |= LP_NEW_VERTEX;
+
+ draw_set_vertex_buffers(llvmpipe->draw, count, buffers);
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_vs.c b/src/gallium/drivers/llvmpipe/lp_state_vs.c
new file mode 100644
index 0000000000..15c3029614
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_state_vs.c
@@ -0,0 +1,96 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * 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 "pipe/p_defines.h"
+#include "tgsi/tgsi_parse.h"
+#include "util/u_memory.h"
+#include "draw/draw_context.h"
+
+#include "lp_context.h"
+#include "lp_state.h"
+
+
+void *
+llvmpipe_create_vs_state(struct pipe_context *pipe,
+ const struct pipe_shader_state *templ)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+ struct lp_vertex_shader *state;
+
+ state = CALLOC_STRUCT(lp_vertex_shader);
+ if (state == NULL )
+ goto fail;
+
+ /* copy shader tokens, the ones passed in will go away.
+ */
+ state->shader.tokens = tgsi_dup_tokens(templ->tokens);
+ if (state->shader.tokens == NULL)
+ goto fail;
+
+ state->draw_data = draw_create_vertex_shader(llvmpipe->draw, templ);
+ if (state->draw_data == NULL)
+ goto fail;
+
+ return state;
+
+fail:
+ if (state) {
+ FREE( (void *)state->shader.tokens );
+ FREE( state->draw_data );
+ FREE( state );
+ }
+ return NULL;
+}
+
+
+void
+llvmpipe_bind_vs_state(struct pipe_context *pipe, void *vs)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ llvmpipe->vs = (const struct lp_vertex_shader *)vs;
+
+ draw_bind_vertex_shader(llvmpipe->draw,
+ (llvmpipe->vs ? llvmpipe->vs->draw_data : NULL));
+
+ llvmpipe->dirty |= LP_NEW_VS;
+}
+
+
+void
+llvmpipe_delete_vs_state(struct pipe_context *pipe, void *vs)
+{
+ struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe);
+
+ struct lp_vertex_shader *state =
+ (struct lp_vertex_shader *)vs;
+
+ draw_delete_vertex_shader(llvmpipe->draw, state->draw_data);
+ FREE( state );
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
new file mode 100644
index 0000000000..6110b0a193
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -0,0 +1,50 @@
+/**************************************************************************
+ *
+ * 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_rect.h"
+#include "lp_context.h"
+#include "lp_surface.h"
+
+
+static void
+lp_surface_copy(struct pipe_context *pipe,
+ struct pipe_surface *dest, unsigned destx, unsigned desty,
+ struct pipe_surface *src, unsigned srcx, unsigned srcy,
+ unsigned width, unsigned height)
+{
+ util_surface_copy(pipe, FALSE,
+ dest, destx, desty,
+ src, srcx, srcy,
+ width, height);
+}
+
+void
+lp_init_surface_functions(struct llvmpipe_context *lp)
+{
+ lp->pipe.surface_copy = lp_surface_copy;
+ lp->pipe.surface_fill = util_surface_fill;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.h b/src/gallium/drivers/llvmpipe/lp_surface.h
new file mode 100644
index 0000000000..4d78a53c4f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_surface.h
@@ -0,0 +1,42 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/* Authors: Keith Whitwell <keith@tungstengraphics.com>
+ */
+
+#ifndef LP_SURFACE_H
+#define LP_SURFACE_H
+
+
+struct llvmpipe_context;
+
+
+extern void
+lp_init_surface_functions(struct llvmpipe_context *lp);
+
+
+#endif /* LP_SURFACE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h
new file mode 100644
index 0000000000..a88e110c66
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test.h
@@ -0,0 +1,128 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * Shared testing code.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#ifndef LP_TEST_H
+#define LP_TEST_H
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <float.h>
+
+#include <llvm-c/Core.h>
+#include <llvm-c/Analysis.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/BitWriter.h>
+#include <llvm-c/Transforms/Scalar.h>
+
+#include "pipe/p_state.h"
+#include "util/u_format.h"
+#include "util/u_math.h"
+#include "util/u_debug_dump.h"
+
+#include "lp_bld_type.h"
+
+
+void
+write_tsv_header(FILE *fp);
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n);
+
+
+boolean
+test_all(unsigned verbose, FILE *fp);
+
+
+static INLINE uint64_t
+rdtsc(void)
+{
+#if defined(PIPE_ARCH_X86) || defined(PIPE_ARCH_X86_64)
+ uint32_t hi, lo;
+ __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
+ return ((uint64_t)lo) | (((uint64_t)hi) << 32);
+#else
+ return 0;
+#endif
+}
+
+
+float
+random_float(void);
+
+
+void
+dump_type(FILE *fp, struct lp_type type);
+
+
+double
+read_elem(struct lp_type type, const void *src, unsigned index);
+
+
+void
+write_elem(struct lp_type type, void *dst, unsigned index, double src);
+
+
+void
+random_elem(struct lp_type type, void *dst, unsigned index);
+
+
+void
+read_vec(struct lp_type type, const void *src, double *dst);
+
+
+void
+write_vec(struct lp_type type, void *dst, const double *src);
+
+
+void
+random_vec(struct lp_type type, void *dst);
+
+
+boolean
+compare_vec_with_eps(struct lp_type type, const void *res, const void *ref, double eps);
+
+
+boolean
+compare_vec(struct lp_type type, const void *res, const void *ref);
+
+
+void
+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
new file mode 100644
index 0000000000..94b661dcba
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c
@@ -0,0 +1,881 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Unit tests for blend LLVM IR generation
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ *
+ * Blend computation code derived from code written by
+ * @author Brian Paul <brian@vmware.com>
+ */
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_arit.h"
+#include "lp_bld_blend.h"
+#include "lp_bld_debug.h"
+#include "lp_test.h"
+
+
+enum vector_mode
+{
+ AoS = 0,
+ SoA = 1
+};
+
+
+typedef void (*blend_test_ptr_t)(const void *src, const void *dst, const void *con, void *res);
+
+
+void
+write_tsv_header(FILE *fp)
+{
+ fprintf(fp,
+ "result\t"
+ "cycles_per_channel\t"
+ "mode\t"
+ "type\t"
+ "sep_func\t"
+ "sep_src_factor\t"
+ "sep_dst_factor\t"
+ "rgb_func\t"
+ "rgb_src_factor\t"
+ "rgb_dst_factor\t"
+ "alpha_func\t"
+ "alpha_src_factor\t"
+ "alpha_dst_factor\n");
+
+ fflush(fp);
+}
+
+
+static void
+write_tsv_row(FILE *fp,
+ const struct pipe_blend_state *blend,
+ enum vector_mode mode,
+ struct lp_type type,
+ double cycles,
+ boolean success)
+{
+ fprintf(fp, "%s\t", success ? "pass" : "fail");
+
+ if (mode == AoS) {
+ fprintf(fp, "%.1f\t", cycles / type.length);
+ fprintf(fp, "aos\t");
+ }
+
+ if (mode == SoA) {
+ fprintf(fp, "%.1f\t", cycles / (4 * type.length));
+ fprintf(fp, "soa\t");
+ }
+
+ fprintf(fp, "%s%u%sx%u\t",
+ type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
+ type.width,
+ type.norm ? "n" : "",
+ type.length);
+
+ fprintf(fp,
+ "%s\t%s\t%s\t",
+ blend->rgb_func != blend->alpha_func ? "true" : "false",
+ blend->rgb_src_factor != blend->alpha_src_factor ? "true" : "false",
+ blend->rgb_dst_factor != blend->alpha_dst_factor ? "true" : "false");
+
+ fprintf(fp,
+ "%s\t%s\t%s\t%s\t%s\t%s\n",
+ debug_dump_blend_func(blend->rgb_func, TRUE),
+ debug_dump_blend_factor(blend->rgb_src_factor, TRUE),
+ debug_dump_blend_factor(blend->rgb_dst_factor, TRUE),
+ debug_dump_blend_func(blend->alpha_func, TRUE),
+ debug_dump_blend_factor(blend->alpha_src_factor, TRUE),
+ debug_dump_blend_factor(blend->alpha_dst_factor, TRUE));
+
+ fflush(fp);
+}
+
+
+static void
+dump_blend_type(FILE *fp,
+ const struct pipe_blend_state *blend,
+ enum vector_mode mode,
+ struct lp_type type)
+{
+ fprintf(fp, "%s", mode ? "soa" : "aos");
+
+ fprintf(fp, " type=%s%u%sx%u",
+ type.floating ? "f" : (type.fixed ? "h" : (type.sign ? "s" : "u")),
+ type.width,
+ type.norm ? "n" : "",
+ type.length);
+
+ fprintf(fp,
+ " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s",
+ "rgb_func", debug_dump_blend_func(blend->rgb_func, TRUE),
+ "rgb_src_factor", debug_dump_blend_factor(blend->rgb_src_factor, TRUE),
+ "rgb_dst_factor", debug_dump_blend_factor(blend->rgb_dst_factor, TRUE),
+ "alpha_func", debug_dump_blend_func(blend->alpha_func, TRUE),
+ "alpha_src_factor", debug_dump_blend_factor(blend->alpha_src_factor, TRUE),
+ "alpha_dst_factor", debug_dump_blend_factor(blend->alpha_dst_factor, TRUE));
+
+ fprintf(fp, " ...\n");
+ fflush(fp);
+}
+
+
+static LLVMValueRef
+add_blend_test(LLVMModuleRef module,
+ const struct pipe_blend_state *blend,
+ enum vector_mode mode,
+ struct lp_type type)
+{
+ LLVMTypeRef ret_type;
+ LLVMTypeRef vec_type;
+ LLVMTypeRef args[4];
+ LLVMValueRef func;
+ LLVMValueRef src_ptr;
+ LLVMValueRef dst_ptr;
+ LLVMValueRef const_ptr;
+ LLVMValueRef res_ptr;
+ LLVMBasicBlockRef block;
+ LLVMBuilderRef builder;
+
+ ret_type = LLVMInt64Type();
+ vec_type = lp_build_vec_type(type);
+
+ args[3] = args[2] = args[1] = args[0] = LLVMPointerType(vec_type, 0);
+ func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 4, 0));
+ LLVMSetFunctionCallConv(func, LLVMCCallConv);
+ src_ptr = LLVMGetParam(func, 0);
+ dst_ptr = LLVMGetParam(func, 1);
+ const_ptr = LLVMGetParam(func, 2);
+ res_ptr = LLVMGetParam(func, 3);
+
+ block = LLVMAppendBasicBlock(func, "entry");
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, block);
+
+ if (mode == AoS) {
+ LLVMValueRef src;
+ LLVMValueRef dst;
+ LLVMValueRef con;
+ LLVMValueRef res;
+
+ src = LLVMBuildLoad(builder, src_ptr, "src");
+ dst = LLVMBuildLoad(builder, dst_ptr, "dst");
+ con = LLVMBuildLoad(builder, const_ptr, "const");
+
+ res = lp_build_blend_aos(builder, blend, type, src, dst, con, 3);
+
+ lp_build_name(res, "res");
+
+ LLVMBuildStore(builder, res, res_ptr);
+ }
+
+ if (mode == SoA) {
+ LLVMValueRef src[4];
+ LLVMValueRef dst[4];
+ LLVMValueRef con[4];
+ LLVMValueRef res[4];
+ unsigned i;
+
+ for(i = 0; i < 4; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ src[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, src_ptr, &index, 1, ""), "");
+ dst[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, dst_ptr, &index, 1, ""), "");
+ con[i] = LLVMBuildLoad(builder, LLVMBuildGEP(builder, const_ptr, &index, 1, ""), "");
+ lp_build_name(src[i], "src.%c", "rgba"[i]);
+ lp_build_name(con[i], "con.%c", "rgba"[i]);
+ lp_build_name(dst[i], "dst.%c", "rgba"[i]);
+ }
+
+ lp_build_blend_soa(builder, blend, type, src, dst, con, res);
+
+ for(i = 0; i < 4; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ lp_build_name(res[i], "res.%c", "rgba"[i]);
+ LLVMBuildStore(builder, res[i], LLVMBuildGEP(builder, res_ptr, &index, 1, ""));
+ }
+ }
+
+ LLVMBuildRetVoid(builder);;
+
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+/** Add and limit result to ceiling of 1.0 */
+#define ADD_SAT(R, A, B) \
+do { \
+ R = (A) + (B); if (R > 1.0f) R = 1.0f; \
+} while (0)
+
+/** Subtract and limit result to floor of 0.0 */
+#define SUB_SAT(R, A, B) \
+do { \
+ R = (A) - (B); if (R < 0.0f) R = 0.0f; \
+} while (0)
+
+
+static void
+compute_blend_ref_term(unsigned rgb_factor,
+ unsigned alpha_factor,
+ const double *factor,
+ const double *src,
+ const double *dst,
+ const double *con,
+ double *term)
+{
+ double temp;
+
+ switch (rgb_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ term[0] = factor[0]; /* R */
+ term[1] = factor[1]; /* G */
+ term[2] = factor[2]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ term[0] = factor[0] * src[0]; /* R */
+ term[1] = factor[1] * src[1]; /* G */
+ term[2] = factor[2] * src[2]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ term[0] = factor[0] * src[3]; /* R */
+ term[1] = factor[1] * src[3]; /* G */
+ term[2] = factor[2] * src[3]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ term[0] = factor[0] * dst[0]; /* R */
+ term[1] = factor[1] * dst[1]; /* G */
+ term[2] = factor[2] * dst[2]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ term[0] = factor[0] * dst[3]; /* R */
+ term[1] = factor[1] * dst[3]; /* G */
+ term[2] = factor[2] * dst[3]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ temp = MIN2(src[3], 1.0f - dst[3]);
+ term[0] = factor[0] * temp; /* R */
+ term[1] = factor[1] * temp; /* G */
+ term[2] = factor[2] * temp; /* B */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ term[0] = factor[0] * con[0]; /* R */
+ term[1] = factor[1] * con[1]; /* G */
+ term[2] = factor[2] * con[2]; /* B */
+ break;
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ term[0] = factor[0] * con[3]; /* R */
+ term[1] = factor[1] * con[3]; /* G */
+ term[2] = factor[2] * con[3]; /* 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:
+ term[0] = 0.0f; /* R */
+ term[1] = 0.0f; /* G */
+ term[2] = 0.0f; /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ term[0] = factor[0] * (1.0f - src[0]); /* R */
+ term[1] = factor[1] * (1.0f - src[1]); /* G */
+ term[2] = factor[2] * (1.0f - src[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ term[0] = factor[0] * (1.0f - src[3]); /* R */
+ term[1] = factor[1] * (1.0f - src[3]); /* G */
+ term[2] = factor[2] * (1.0f - src[3]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ term[0] = factor[0] * (1.0f - dst[3]); /* R */
+ term[1] = factor[1] * (1.0f - dst[3]); /* G */
+ term[2] = factor[2] * (1.0f - dst[3]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ term[0] = factor[0] * (1.0f - dst[0]); /* R */
+ term[1] = factor[1] * (1.0f - dst[1]); /* G */
+ term[2] = factor[2] * (1.0f - dst[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ term[0] = factor[0] * (1.0f - con[0]); /* R */
+ term[1] = factor[1] * (1.0f - con[1]); /* G */
+ term[2] = factor[2] * (1.0f - con[2]); /* B */
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ term[0] = factor[0] * (1.0f - con[3]); /* R */
+ term[1] = factor[1] * (1.0f - con[3]); /* G */
+ term[2] = factor[2] * (1.0f - con[3]); /* 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 (alpha_factor) {
+ case PIPE_BLENDFACTOR_ONE:
+ term[3] = factor[3]; /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_COLOR:
+ case PIPE_BLENDFACTOR_SRC_ALPHA:
+ term[3] = factor[3] * src[3]; /* A */
+ break;
+ case PIPE_BLENDFACTOR_DST_COLOR:
+ case PIPE_BLENDFACTOR_DST_ALPHA:
+ term[3] = factor[3] * dst[3]; /* A */
+ break;
+ case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE:
+ term[3] = src[3]; /* A */
+ break;
+ case PIPE_BLENDFACTOR_CONST_COLOR:
+ case PIPE_BLENDFACTOR_CONST_ALPHA:
+ term[3] = factor[3] * con[3]; /* A */
+ break;
+ case PIPE_BLENDFACTOR_ZERO:
+ term[3] = 0.0f; /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_SRC_COLOR:
+ case PIPE_BLENDFACTOR_INV_SRC_ALPHA:
+ term[3] = factor[3] * (1.0f - src[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_DST_COLOR:
+ case PIPE_BLENDFACTOR_INV_DST_ALPHA:
+ term[3] = factor[3] * (1.0f - dst[3]); /* A */
+ break;
+ case PIPE_BLENDFACTOR_INV_CONST_COLOR:
+ case PIPE_BLENDFACTOR_INV_CONST_ALPHA:
+ term[3] = factor[3] * (1.0f - con[3]);
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+static void
+compute_blend_ref(const struct pipe_blend_state *blend,
+ const double *src,
+ const double *dst,
+ const double *con,
+ double *res)
+{
+ double src_term[4];
+ double dst_term[4];
+
+ compute_blend_ref_term(blend->rgb_src_factor, blend->alpha_src_factor, src, src, dst, con, src_term);
+ compute_blend_ref_term(blend->rgb_dst_factor, blend->alpha_dst_factor, dst, src, dst, con, dst_term);
+
+ /*
+ * Combine RGB terms
+ */
+ switch (blend->rgb_func) {
+ case PIPE_BLEND_ADD:
+ ADD_SAT(res[0], src_term[0], dst_term[0]); /* R */
+ ADD_SAT(res[1], src_term[1], dst_term[1]); /* G */
+ ADD_SAT(res[2], src_term[2], dst_term[2]); /* B */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ SUB_SAT(res[0], src_term[0], dst_term[0]); /* R */
+ SUB_SAT(res[1], src_term[1], dst_term[1]); /* G */
+ SUB_SAT(res[2], src_term[2], dst_term[2]); /* B */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ SUB_SAT(res[0], dst_term[0], src_term[0]); /* R */
+ SUB_SAT(res[1], dst_term[1], src_term[1]); /* G */
+ SUB_SAT(res[2], dst_term[2], src_term[2]); /* B */
+ break;
+ case PIPE_BLEND_MIN:
+ res[0] = MIN2(src_term[0], dst_term[0]); /* R */
+ res[1] = MIN2(src_term[1], dst_term[1]); /* G */
+ res[2] = MIN2(src_term[2], dst_term[2]); /* B */
+ break;
+ case PIPE_BLEND_MAX:
+ res[0] = MAX2(src_term[0], dst_term[0]); /* R */
+ res[1] = MAX2(src_term[1], dst_term[1]); /* G */
+ res[2] = MAX2(src_term[2], dst_term[2]); /* B */
+ break;
+ default:
+ assert(0);
+ }
+
+ /*
+ * Combine A terms
+ */
+ switch (blend->alpha_func) {
+ case PIPE_BLEND_ADD:
+ ADD_SAT(res[3], src_term[3], dst_term[3]); /* A */
+ break;
+ case PIPE_BLEND_SUBTRACT:
+ SUB_SAT(res[3], src_term[3], dst_term[3]); /* A */
+ break;
+ case PIPE_BLEND_REVERSE_SUBTRACT:
+ SUB_SAT(res[3], dst_term[3], src_term[3]); /* A */
+ break;
+ case PIPE_BLEND_MIN:
+ res[3] = MIN2(src_term[3], dst_term[3]); /* A */
+ break;
+ case PIPE_BLEND_MAX:
+ res[3] = MAX2(src_term[3], dst_term[3]); /* A */
+ break;
+ default:
+ assert(0);
+ }
+}
+
+
+static boolean
+test_one(unsigned verbose,
+ FILE *fp,
+ const struct pipe_blend_state *blend,
+ enum vector_mode mode,
+ struct lp_type type)
+{
+ LLVMModuleRef module = NULL;
+ LLVMValueRef func = NULL;
+ LLVMExecutionEngineRef engine = NULL;
+ LLVMModuleProviderRef provider = NULL;
+ LLVMPassManagerRef pass = NULL;
+ char *error = NULL;
+ blend_test_ptr_t blend_test_ptr;
+ boolean success;
+ const unsigned n = 32;
+ int64_t cycles[n];
+ double cycles_avg = 0.0;
+ unsigned i, j;
+
+ if(verbose >= 1)
+ dump_blend_type(stdout, blend, mode, type);
+
+ module = LLVMModuleCreateWithName("test");
+
+ func = add_blend_test(module, blend, mode, type);
+
+ if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+ LLVMDumpModule(module);
+ abort();
+ }
+ LLVMDisposeMessage(error);
+
+ provider = LLVMCreateModuleProviderForExistingModule(module);
+ if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+ if(verbose < 1)
+ dump_blend_type(stderr, blend, mode, type);
+ fprintf(stderr, "%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+#if 0
+ pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMAddPromoteMemoryToRegisterPass(pass);
+ LLVMAddGVNPass(pass);
+ LLVMAddCFGSimplificationPass(pass);
+ LLVMRunPassManager(pass, module);
+#else
+ (void)pass;
+#endif
+
+ if(verbose >= 2)
+ LLVMDumpModule(module);
+
+ blend_test_ptr = (blend_test_ptr_t)LLVMGetPointerToGlobal(engine, func);
+
+ if(verbose >= 2)
+ lp_disassemble(blend_test_ptr);
+
+ success = TRUE;
+ for(i = 0; i < n && success; ++i) {
+ if(mode == AoS) {
+ uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t con[LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t res[LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ int64_t start_counter = 0;
+ int64_t end_counter = 0;
+
+ random_vec(type, src);
+ random_vec(type, dst);
+ random_vec(type, con);
+
+ {
+ double fsrc[LP_MAX_VECTOR_LENGTH];
+ double fdst[LP_MAX_VECTOR_LENGTH];
+ double fcon[LP_MAX_VECTOR_LENGTH];
+ double fref[LP_MAX_VECTOR_LENGTH];
+
+ read_vec(type, src, fsrc);
+ read_vec(type, dst, fdst);
+ read_vec(type, con, fcon);
+
+ for(j = 0; j < type.length; j += 4)
+ compute_blend_ref(blend, fsrc + j, fdst + j, fcon + j, fref + j);
+
+ write_vec(type, ref, fref);
+ }
+
+ start_counter = rdtsc();
+ blend_test_ptr(src, dst, con, res);
+ end_counter = rdtsc();
+
+ cycles[i] = end_counter - start_counter;
+
+ if(!compare_vec(type, res, ref)) {
+ success = FALSE;
+
+ if(verbose < 1)
+ dump_blend_type(stderr, blend, mode, type);
+ fprintf(stderr, "MISMATCH\n");
+
+ fprintf(stderr, " Src: ");
+ dump_vec(stderr, type, src);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Dst: ");
+ dump_vec(stderr, type, dst);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Con: ");
+ dump_vec(stderr, type, con);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Res: ");
+ dump_vec(stderr, type, res);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Ref: ");
+ dump_vec(stderr, type, ref);
+ fprintf(stderr, "\n");
+ }
+ }
+
+ if(mode == SoA) {
+ const unsigned stride = type.length*type.width/8;
+ uint8_t src[4*LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t dst[4*LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t con[4*LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t res[4*LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ uint8_t ref[4*LP_MAX_VECTOR_LENGTH*LP_MAX_TYPE_WIDTH/8];
+ int64_t start_counter = 0;
+ int64_t end_counter = 0;
+ boolean mismatch;
+
+ for(j = 0; j < 4; ++j) {
+ random_vec(type, src + j*stride);
+ random_vec(type, dst + j*stride);
+ random_vec(type, con + j*stride);
+ }
+
+ {
+ double fsrc[4];
+ double fdst[4];
+ double fcon[4];
+ double fref[4];
+ unsigned k;
+
+ for(k = 0; k < type.length; ++k) {
+ for(j = 0; j < 4; ++j) {
+ fsrc[j] = read_elem(type, src + j*stride, k);
+ fdst[j] = read_elem(type, dst + j*stride, k);
+ fcon[j] = read_elem(type, con + j*stride, k);
+ }
+
+ compute_blend_ref(blend, fsrc, fdst, fcon, fref);
+
+ for(j = 0; j < 4; ++j)
+ write_elem(type, ref + j*stride, k, fref[j]);
+ }
+ }
+
+ start_counter = rdtsc();
+ blend_test_ptr(src, dst, con, res);
+ end_counter = rdtsc();
+
+ cycles[i] = end_counter - start_counter;
+
+ mismatch = FALSE;
+ for (j = 0; j < 4; ++j)
+ if(!compare_vec(type, res + j*stride, ref + j*stride))
+ mismatch = TRUE;
+
+ if (mismatch) {
+ success = FALSE;
+
+ if(verbose < 1)
+ dump_blend_type(stderr, blend, mode, type);
+ fprintf(stderr, "MISMATCH\n");
+ for(j = 0; j < 4; ++j) {
+ char channel = "RGBA"[j];
+ fprintf(stderr, " Src%c: ", channel);
+ dump_vec(stderr, type, src + j*stride);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Dst%c: ", channel);
+ dump_vec(stderr, type, dst + j*stride);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Con%c: ", channel);
+ dump_vec(stderr, type, con + j*stride);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Res%c: ", channel);
+ dump_vec(stderr, type, res + j*stride);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Ref%c: ", channel);
+ dump_vec(stderr, type, ref + j*stride);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+ }
+
+ /*
+ * Unfortunately the output of cycle counter is not very reliable as it comes
+ * -- sometimes we get outliers (due IRQs perhaps?) which are
+ * better removed to avoid random or biased data.
+ */
+ {
+ double sum = 0.0, sum2 = 0.0;
+ double avg, std;
+ unsigned m;
+
+ for(i = 0; i < n; ++i) {
+ sum += cycles[i];
+ sum2 += cycles[i]*cycles[i];
+ }
+
+ avg = sum/n;
+ std = sqrtf((sum2 - n*avg*avg)/n);
+
+ m = 0;
+ sum = 0.0;
+ for(i = 0; i < n; ++i) {
+ if(fabs(cycles[i] - avg) <= 4.0*std) {
+ sum += cycles[i];
+ ++m;
+ }
+ }
+
+ cycles_avg = sum/m;
+
+ }
+
+ if(fp)
+ write_tsv_row(fp, blend, mode, type, cycles_avg, success);
+
+ if (!success) {
+ if(verbose < 2)
+ LLVMDumpModule(module);
+ LLVMWriteBitcodeToFile(module, "blend.bc");
+ fprintf(stderr, "blend.bc written\n");
+ fprintf(stderr, "Invoke as \"llc -o - blend.bc\"\n");
+ abort();
+ }
+
+ LLVMFreeMachineCodeForFunction(engine, func);
+
+ LLVMDisposeExecutionEngine(engine);
+ if(pass)
+ LLVMDisposePassManager(pass);
+
+ return success;
+}
+
+
+const unsigned
+blend_factors[] = {
+ PIPE_BLENDFACTOR_ZERO,
+ PIPE_BLENDFACTOR_ONE,
+ PIPE_BLENDFACTOR_SRC_COLOR,
+ PIPE_BLENDFACTOR_SRC_ALPHA,
+ PIPE_BLENDFACTOR_DST_COLOR,
+ PIPE_BLENDFACTOR_DST_ALPHA,
+ PIPE_BLENDFACTOR_CONST_COLOR,
+ PIPE_BLENDFACTOR_CONST_ALPHA,
+#if 0
+ PIPE_BLENDFACTOR_SRC1_COLOR,
+ PIPE_BLENDFACTOR_SRC1_ALPHA,
+#endif
+ PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE,
+ PIPE_BLENDFACTOR_INV_SRC_COLOR,
+ PIPE_BLENDFACTOR_INV_SRC_ALPHA,
+ PIPE_BLENDFACTOR_INV_DST_COLOR,
+ PIPE_BLENDFACTOR_INV_DST_ALPHA,
+ PIPE_BLENDFACTOR_INV_CONST_COLOR,
+ PIPE_BLENDFACTOR_INV_CONST_ALPHA,
+#if 0
+ PIPE_BLENDFACTOR_INV_SRC1_COLOR,
+ PIPE_BLENDFACTOR_INV_SRC1_ALPHA,
+#endif
+};
+
+
+const unsigned
+blend_funcs[] = {
+ PIPE_BLEND_ADD,
+ PIPE_BLEND_SUBTRACT,
+ PIPE_BLEND_REVERSE_SUBTRACT,
+ PIPE_BLEND_MIN,
+ PIPE_BLEND_MAX
+};
+
+
+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 */
+};
+
+
+const unsigned num_funcs = sizeof(blend_funcs)/sizeof(blend_funcs[0]);
+const unsigned num_factors = sizeof(blend_factors)/sizeof(blend_factors[0]);
+const unsigned num_types = sizeof(blend_types)/sizeof(blend_types[0]);
+
+
+boolean
+test_all(unsigned verbose, FILE *fp)
+{
+ const unsigned *rgb_func;
+ const unsigned *rgb_src_factor;
+ const unsigned *rgb_dst_factor;
+ const unsigned *alpha_func;
+ const unsigned *alpha_src_factor;
+ const unsigned *alpha_dst_factor;
+ struct pipe_blend_state blend;
+ enum vector_mode mode;
+ const struct lp_type *type;
+ bool success = TRUE;
+
+ for(rgb_func = blend_funcs; rgb_func < &blend_funcs[num_funcs]; ++rgb_func) {
+ for(alpha_func = blend_funcs; alpha_func < &blend_funcs[num_funcs]; ++alpha_func) {
+ for(rgb_src_factor = blend_factors; rgb_src_factor < &blend_factors[num_factors]; ++rgb_src_factor) {
+ for(rgb_dst_factor = blend_factors; rgb_dst_factor <= rgb_src_factor; ++rgb_dst_factor) {
+ for(alpha_src_factor = blend_factors; alpha_src_factor < &blend_factors[num_factors]; ++alpha_src_factor) {
+ for(alpha_dst_factor = blend_factors; alpha_dst_factor <= alpha_src_factor; ++alpha_dst_factor) {
+ for(mode = 0; mode < 2; ++mode) {
+ for(type = blend_types; type < &blend_types[num_types]; ++type) {
+
+ if(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE ||
+ *alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE)
+ continue;
+
+ memset(&blend, 0, sizeof blend);
+ blend.blend_enable = 1;
+ blend.rgb_func = *rgb_func;
+ blend.rgb_src_factor = *rgb_src_factor;
+ blend.rgb_dst_factor = *rgb_dst_factor;
+ blend.alpha_func = *alpha_func;
+ blend.alpha_src_factor = *alpha_src_factor;
+ blend.alpha_dst_factor = *alpha_dst_factor;
+ blend.colormask = PIPE_MASK_RGBA;
+
+ if(!test_one(verbose, fp, &blend, mode, *type))
+ success = FALSE;
+
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return success;
+}
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n)
+{
+ const unsigned *rgb_func;
+ const unsigned *rgb_src_factor;
+ const unsigned *rgb_dst_factor;
+ const unsigned *alpha_func;
+ const unsigned *alpha_src_factor;
+ const unsigned *alpha_dst_factor;
+ struct pipe_blend_state blend;
+ enum vector_mode mode;
+ const struct lp_type *type;
+ unsigned long i;
+ bool success = TRUE;
+
+ for(i = 0; i < n; ++i) {
+ 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[rand() % num_factors];
+ } while(*rgb_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
+
+ do {
+ alpha_dst_factor = &blend_factors[rand() % num_factors];
+ } while(*alpha_dst_factor == PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE);
+
+ mode = rand() & 1;
+
+ type = &blend_types[rand() % num_types];
+
+ memset(&blend, 0, sizeof blend);
+ blend.blend_enable = 1;
+ blend.rgb_func = *rgb_func;
+ blend.rgb_src_factor = *rgb_src_factor;
+ blend.rgb_dst_factor = *rgb_dst_factor;
+ blend.alpha_func = *alpha_func;
+ blend.alpha_src_factor = *alpha_src_factor;
+ blend.alpha_dst_factor = *alpha_dst_factor;
+ blend.colormask = PIPE_MASK_RGBA;
+
+ if(!test_one(verbose, fp, &blend, mode, *type))
+ success = FALSE;
+ }
+
+ return success;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_test_conv.c b/src/gallium/drivers/llvmpipe/lp_test_conv.c
new file mode 100644
index 0000000000..9dcf58e5dc
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_conv.c
@@ -0,0 +1,427 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Unit tests for type conversion.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_const.h"
+#include "lp_bld_conv.h"
+#include "lp_bld_debug.h"
+#include "lp_test.h"
+
+
+typedef void (*conv_test_ptr_t)(const void *src, const void *dst);
+
+
+void
+write_tsv_header(FILE *fp)
+{
+ fprintf(fp,
+ "result\t"
+ "cycles_per_channel\t"
+ "src_type\t"
+ "dst_type\n");
+
+ fflush(fp);
+}
+
+
+static void
+write_tsv_row(FILE *fp,
+ struct lp_type src_type,
+ struct lp_type dst_type,
+ double cycles,
+ boolean success)
+{
+ fprintf(fp, "%s\t", success ? "pass" : "fail");
+
+ fprintf(fp, "%.1f\t", cycles / MAX2(src_type.length, dst_type.length));
+
+ dump_type(fp, src_type);
+ fprintf(fp, "\t");
+
+ dump_type(fp, dst_type);
+ fprintf(fp, "\n");
+
+ fflush(fp);
+}
+
+
+static void
+dump_conv_types(FILE *fp,
+ struct lp_type src_type,
+ struct lp_type dst_type)
+{
+ fprintf(fp, "src_type=");
+ dump_type(fp, src_type);
+
+ fprintf(fp, " dst_type=");
+ dump_type(fp, dst_type);
+
+ fprintf(fp, " ...\n");
+ fflush(fp);
+}
+
+
+static LLVMValueRef
+add_conv_test(LLVMModuleRef module,
+ struct lp_type src_type, unsigned num_srcs,
+ struct lp_type dst_type, unsigned num_dsts)
+{
+ LLVMTypeRef args[2];
+ LLVMValueRef func;
+ LLVMValueRef src_ptr;
+ LLVMValueRef dst_ptr;
+ LLVMBasicBlockRef block;
+ LLVMBuilderRef builder;
+ LLVMValueRef src[LP_MAX_VECTOR_LENGTH];
+ LLVMValueRef dst[LP_MAX_VECTOR_LENGTH];
+ unsigned i;
+
+ args[0] = LLVMPointerType(lp_build_vec_type(src_type), 0);
+ args[1] = LLVMPointerType(lp_build_vec_type(dst_type), 0);
+
+ func = LLVMAddFunction(module, "test", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+ LLVMSetFunctionCallConv(func, LLVMCCallConv);
+ src_ptr = LLVMGetParam(func, 0);
+ dst_ptr = LLVMGetParam(func, 1);
+
+ block = LLVMAppendBasicBlock(func, "entry");
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, block);
+
+ for(i = 0; i < num_srcs; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef ptr = LLVMBuildGEP(builder, src_ptr, &index, 1, "");
+ src[i] = LLVMBuildLoad(builder, ptr, "");
+ }
+
+ lp_build_conv(builder, src_type, dst_type, src, num_srcs, dst, num_dsts);
+
+ for(i = 0; i < num_dsts; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef ptr = LLVMBuildGEP(builder, dst_ptr, &index, 1, "");
+ LLVMBuildStore(builder, dst[i], ptr);
+ }
+
+ LLVMBuildRetVoid(builder);;
+
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+static boolean
+test_one(unsigned verbose,
+ FILE *fp,
+ struct lp_type src_type,
+ struct lp_type dst_type)
+{
+ LLVMModuleRef module = NULL;
+ LLVMValueRef func = NULL;
+ LLVMExecutionEngineRef engine = NULL;
+ LLVMModuleProviderRef provider = NULL;
+ LLVMPassManagerRef pass = NULL;
+ char *error = NULL;
+ conv_test_ptr_t conv_test_ptr;
+ boolean success;
+ const unsigned n = 32;
+ int64_t cycles[n];
+ double cycles_avg = 0.0;
+ unsigned num_srcs;
+ unsigned num_dsts;
+ double eps;
+ unsigned i, j;
+
+ if(verbose >= 1)
+ dump_conv_types(stdout, src_type, dst_type);
+
+ if(src_type.length > dst_type.length) {
+ num_srcs = 1;
+ num_dsts = src_type.length/dst_type.length;
+ }
+ else {
+ num_dsts = 1;
+ num_srcs = dst_type.length/src_type.length;
+ }
+
+ assert(src_type.width * src_type.length == dst_type.width * dst_type.length);
+
+ /* We must not loose or gain channels. Only precision */
+ assert(src_type.length * num_srcs == dst_type.length * num_dsts);
+
+ eps = MAX2(lp_const_eps(src_type), lp_const_eps(dst_type));
+
+ module = LLVMModuleCreateWithName("test");
+
+ func = add_conv_test(module, src_type, num_srcs, dst_type, num_dsts);
+
+ if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+ LLVMDumpModule(module);
+ abort();
+ }
+ LLVMDisposeMessage(error);
+
+ provider = LLVMCreateModuleProviderForExistingModule(module);
+ if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+ if(verbose < 1)
+ dump_conv_types(stderr, src_type, dst_type);
+ fprintf(stderr, "%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+#if 0
+ pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMAddPromoteMemoryToRegisterPass(pass);
+ LLVMAddGVNPass(pass);
+ LLVMAddCFGSimplificationPass(pass);
+ LLVMRunPassManager(pass, module);
+#else
+ (void)pass;
+#endif
+
+ if(verbose >= 2)
+ LLVMDumpModule(module);
+
+ conv_test_ptr = (conv_test_ptr_t)LLVMGetPointerToGlobal(engine, func);
+
+ if(verbose >= 2)
+ lp_disassemble(conv_test_ptr);
+
+ success = TRUE;
+ for(i = 0; i < n && success; ++i) {
+ unsigned src_stride = src_type.length*src_type.width/8;
+ unsigned dst_stride = dst_type.length*dst_type.width/8;
+ uint8_t src[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ uint8_t dst[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ double fref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ uint8_t ref[LP_MAX_VECTOR_LENGTH*LP_MAX_VECTOR_LENGTH];
+ int64_t start_counter = 0;
+ int64_t end_counter = 0;
+
+ for(j = 0; j < num_srcs; ++j) {
+ random_vec(src_type, src + j*src_stride);
+ read_vec(src_type, src + j*src_stride, fref + j*src_type.length);
+ }
+
+ for(j = 0; j < num_dsts; ++j) {
+ write_vec(dst_type, ref + j*dst_stride, fref + j*dst_type.length);
+ }
+
+ start_counter = rdtsc();
+ conv_test_ptr(src, dst);
+ end_counter = rdtsc();
+
+ cycles[i] = end_counter - start_counter;
+
+ for(j = 0; j < num_dsts; ++j) {
+ if(!compare_vec_with_eps(dst_type, dst + j*dst_stride, ref + j*dst_stride, eps))
+ success = FALSE;
+ }
+
+ if (!success) {
+ if(verbose < 1)
+ dump_conv_types(stderr, src_type, dst_type);
+ fprintf(stderr, "MISMATCH\n");
+
+ for(j = 0; j < num_srcs; ++j) {
+ fprintf(stderr, " Src%u: ", j);
+ dump_vec(stderr, src_type, src + j*src_stride);
+ fprintf(stderr, "\n");
+ }
+
+#if 1
+ fprintf(stderr, " Ref: ");
+ for(j = 0; j < src_type.length*num_srcs; ++j)
+ fprintf(stderr, " %f", fref[j]);
+ fprintf(stderr, "\n");
+#endif
+
+ for(j = 0; j < num_dsts; ++j) {
+ fprintf(stderr, " Dst%u: ", j);
+ dump_vec(stderr, dst_type, dst + j*dst_stride);
+ fprintf(stderr, "\n");
+
+ fprintf(stderr, " Ref%u: ", j);
+ dump_vec(stderr, dst_type, ref + j*dst_stride);
+ fprintf(stderr, "\n");
+ }
+ }
+ }
+
+ /*
+ * Unfortunately the output of cycle counter is not very reliable as it comes
+ * -- sometimes we get outliers (due IRQs perhaps?) which are
+ * better removed to avoid random or biased data.
+ */
+ {
+ double sum = 0.0, sum2 = 0.0;
+ double avg, std;
+ unsigned m;
+
+ for(i = 0; i < n; ++i) {
+ sum += cycles[i];
+ sum2 += cycles[i]*cycles[i];
+ }
+
+ avg = sum/n;
+ std = sqrtf((sum2 - n*avg*avg)/n);
+
+ m = 0;
+ sum = 0.0;
+ for(i = 0; i < n; ++i) {
+ if(fabs(cycles[i] - avg) <= 4.0*std) {
+ sum += cycles[i];
+ ++m;
+ }
+ }
+
+ cycles_avg = sum/m;
+
+ }
+
+ if(fp)
+ write_tsv_row(fp, src_type, dst_type, cycles_avg, success);
+
+ if (!success) {
+ static boolean firsttime = TRUE;
+ if(firsttime) {
+ if(verbose < 2)
+ LLVMDumpModule(module);
+ LLVMWriteBitcodeToFile(module, "conv.bc");
+ fprintf(stderr, "conv.bc written\n");
+ fprintf(stderr, "Invoke as \"llc -o - conv.bc\"\n");
+ firsttime = FALSE;
+ //abort();
+ }
+ }
+
+ LLVMFreeMachineCodeForFunction(engine, func);
+
+ LLVMDisposeExecutionEngine(engine);
+ if(pass)
+ LLVMDisposePassManager(pass);
+
+ return success;
+}
+
+
+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 },
+
+ /* 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 },
+};
+
+
+const unsigned num_types = sizeof(conv_types)/sizeof(conv_types[0]);
+
+
+boolean
+test_all(unsigned verbose, FILE *fp)
+{
+ 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) {
+ for(dst_type = conv_types; dst_type < &conv_types[num_types]; ++dst_type) {
+
+ if(src_type == dst_type)
+ continue;
+
+ if(src_type->norm != dst_type->norm)
+ continue;
+
+ if(!test_one(verbose, fp, *src_type, *dst_type))
+ success = FALSE;
+
+ }
+ }
+
+ return success;
+}
+
+
+boolean
+test_some(unsigned verbose, FILE *fp, unsigned long n)
+{
+ 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[rand() % num_types];
+
+ do {
+ 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))
+ success = FALSE;
+ }
+
+ return success;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_test_format.c b/src/gallium/drivers/llvmpipe/lp_test_format.c
new file mode 100644
index 0000000000..d8455e5649
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_format.c
@@ -0,0 +1,272 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <llvm-c/Core.h>
+#include <llvm-c/Analysis.h>
+#include <llvm-c/ExecutionEngine.h>
+#include <llvm-c/Target.h>
+#include <llvm-c/Transforms/Scalar.h>
+
+#include "util/u_format.h"
+
+#include "lp_bld_flow.h"
+#include "lp_bld_format.h"
+
+
+struct pixel_test_case
+{
+ enum pipe_format format;
+ uint32_t packed;
+ double unpacked[4];
+};
+
+
+struct pixel_test_case test_cases[] =
+{
+ {PIPE_FORMAT_R5G6B5_UNORM, 0x0000, {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5G6B5_UNORM, 0x001f, {0.0, 0.0, 1.0, 1.0}},
+ {PIPE_FORMAT_R5G6B5_UNORM, 0x07e0, {0.0, 1.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5G6B5_UNORM, 0xf800, {1.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R5G6B5_UNORM, 0xffff, {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0x0000, {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0x001f, {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0x03e0, {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0x7c00, {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0x8000, {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A1R5G5B5_UNORM, 0xffff, {1.0, 1.0, 1.0, 1.0}},
+
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0x000000ff, {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0x0000ff00, {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0x00ff0000, {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0xff000000, {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_A8R8G8B8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}},
+
+#if 0
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0x000000ff, {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0x0000ff00, {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0x00ff0000, {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0xff000000, {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_R8G8B8A8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}},
+#endif
+
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0x00000000, {0.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0x000000ff, {0.0, 0.0, 0.0, 1.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0x0000ff00, {1.0, 0.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0x00ff0000, {0.0, 1.0, 0.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0xff000000, {0.0, 0.0, 1.0, 0.0}},
+ {PIPE_FORMAT_B8G8R8A8_UNORM, 0xffffffff, {1.0, 1.0, 1.0, 1.0}},
+};
+
+
+typedef void (*load_ptr_t)(const void *, float *);
+
+
+static LLVMValueRef
+add_load_rgba_test(LLVMModuleRef module,
+ enum pipe_format format)
+{
+ LLVMTypeRef args[2];
+ LLVMValueRef func;
+ LLVMValueRef ptr;
+ LLVMValueRef rgba_ptr;
+ LLVMBasicBlockRef block;
+ LLVMBuilderRef builder;
+ LLVMValueRef rgba;
+ struct lp_build_loop_state loop;
+
+ args[0] = LLVMPointerType(LLVMInt8Type(), 0);
+ args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
+
+ func = LLVMAddFunction(module, "load", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+ LLVMSetFunctionCallConv(func, LLVMCCallConv);
+ ptr = LLVMGetParam(func, 0);
+ rgba_ptr = LLVMGetParam(func, 1);
+
+ block = LLVMAppendBasicBlock(func, "entry");
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, block);
+
+ lp_build_loop_begin(builder, LLVMConstInt(LLVMInt32Type(), 1, 0), &loop);
+
+ rgba = lp_build_load_rgba_aos(builder, format, ptr);
+ LLVMBuildStore(builder, rgba, rgba_ptr);
+
+ lp_build_loop_end(builder, LLVMConstInt(LLVMInt32Type(), 4, 0), NULL, &loop);
+
+ LLVMBuildRetVoid(builder);
+
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+typedef void (*store_ptr_t)(void *, const float *);
+
+
+static LLVMValueRef
+add_store_rgba_test(LLVMModuleRef module,
+ enum pipe_format format)
+{
+ LLVMTypeRef args[2];
+ LLVMValueRef func;
+ LLVMValueRef ptr;
+ LLVMValueRef rgba_ptr;
+ LLVMBasicBlockRef block;
+ LLVMBuilderRef builder;
+ LLVMValueRef rgba;
+
+ args[0] = LLVMPointerType(LLVMInt8Type(), 0);
+ args[1] = LLVMPointerType(LLVMVectorType(LLVMFloatType(), 4), 0);
+
+ func = LLVMAddFunction(module, "store", LLVMFunctionType(LLVMVoidType(), args, 2, 0));
+ LLVMSetFunctionCallConv(func, LLVMCCallConv);
+ ptr = LLVMGetParam(func, 0);
+ rgba_ptr = LLVMGetParam(func, 1);
+
+ block = LLVMAppendBasicBlock(func, "entry");
+ builder = LLVMCreateBuilder();
+ LLVMPositionBuilderAtEnd(builder, block);
+
+ rgba = LLVMBuildLoad(builder, rgba_ptr, "");
+
+ lp_build_store_rgba_aos(builder, format, ptr, rgba);
+
+ LLVMBuildRetVoid(builder);
+
+ LLVMDisposeBuilder(builder);
+ return func;
+}
+
+
+static boolean
+test_format(const struct pixel_test_case *test)
+{
+ LLVMModuleRef module = NULL;
+ LLVMValueRef load = NULL;
+ LLVMValueRef store = NULL;
+ LLVMExecutionEngineRef engine = NULL;
+ LLVMModuleProviderRef provider = NULL;
+ LLVMPassManagerRef pass = NULL;
+ char *error = NULL;
+ const struct util_format_description *desc;
+ load_ptr_t load_ptr;
+ store_ptr_t store_ptr;
+ float unpacked[4];
+ unsigned packed;
+ boolean success;
+ unsigned i;
+
+ desc = util_format_description(test->format);
+ fprintf(stderr, "%s\n", desc->name);
+
+ module = LLVMModuleCreateWithName("test");
+
+ load = add_load_rgba_test(module, test->format);
+ store = add_store_rgba_test(module, test->format);
+
+ if(LLVMVerifyModule(module, LLVMPrintMessageAction, &error)) {
+ LLVMDumpModule(module);
+ abort();
+ }
+ LLVMDisposeMessage(error);
+
+ provider = LLVMCreateModuleProviderForExistingModule(module);
+ if (LLVMCreateJITCompiler(&engine, provider, 1, &error)) {
+ fprintf(stderr, "%s\n", error);
+ LLVMDisposeMessage(error);
+ abort();
+ }
+
+#if 0
+ pass = LLVMCreatePassManager();
+ LLVMAddTargetData(LLVMGetExecutionEngineTargetData(engine), pass);
+ /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+ * but there are more on SVN. */
+ LLVMAddConstantPropagationPass(pass);
+ LLVMAddInstructionCombiningPass(pass);
+ LLVMAddPromoteMemoryToRegisterPass(pass);
+ LLVMAddGVNPass(pass);
+ LLVMAddCFGSimplificationPass(pass);
+ LLVMRunPassManager(pass, module);
+#else
+ (void)pass;
+#endif
+
+ load_ptr = (load_ptr_t) LLVMGetPointerToGlobal(engine, load);
+ store_ptr = (store_ptr_t)LLVMGetPointerToGlobal(engine, store);
+
+ memset(unpacked, 0, sizeof unpacked);
+ packed = 0;
+
+ load_ptr(&test->packed, unpacked);
+ store_ptr(&packed, unpacked);
+
+ success = TRUE;
+ if(test->packed != packed)
+ success = FALSE;
+ for(i = 0; i < 4; ++i)
+ if(test->unpacked[i] != unpacked[i])
+ success = FALSE;
+
+ if (!success) {
+ printf("FAILED\n");
+ printf(" Packed: %08x\n", test->packed);
+ printf(" %08x\n", packed);
+ printf(" Unpacked: %f %f %f %f\n", unpacked[0], unpacked[1], unpacked[2], unpacked[3]);
+ printf(" %f %f %f %f\n", test->unpacked[0], test->unpacked[1], test->unpacked[2], test->unpacked[3]);
+ LLVMDumpModule(module);
+ }
+
+ LLVMFreeMachineCodeForFunction(engine, store);
+ LLVMFreeMachineCodeForFunction(engine, load);
+
+ LLVMDisposeExecutionEngine(engine);
+ if(pass)
+ LLVMDisposePassManager(pass);
+
+ return success;
+}
+
+
+int main(int argc, char **argv)
+{
+ unsigned i;
+ int ret;
+
+ for (i = 0; i < sizeof(test_cases)/sizeof(test_cases[0]); ++i)
+ if(!test_format(&test_cases[i]))
+ ret = 1;
+
+ return ret;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_test_main.c b/src/gallium/drivers/llvmpipe/lp_test_main.c
new file mode 100644
index 0000000000..4592dc0b2d
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_test_main.c
@@ -0,0 +1,384 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+
+/**
+ * @file
+ * Shared testing code.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+
+#include "lp_bld_const.h"
+#include "lp_test.h"
+
+
+void
+dump_type(FILE *fp,
+ struct lp_type type)
+{
+ fprintf(fp, "%s%s%u%sx%u",
+ type.sign ? (type.floating || type.fixed ? "" : "s") : "u",
+ type.floating ? "f" : (type.fixed ? "h" : "i"),
+ type.width,
+ type.norm ? "n" : "",
+ type.length);
+}
+
+
+double
+read_elem(struct lp_type type, const void *src, unsigned index)
+{
+ double scale = lp_const_scale(type);
+ double value;
+ assert(index < type.length);
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ value = *((const float *)src + index);
+ break;
+ case 64:
+ value = *((const double *)src + index);
+ break;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+ else {
+ if(type.sign) {
+ switch(type.width) {
+ case 8:
+ value = *((const int8_t *)src + index);
+ break;
+ case 16:
+ value = *((const int16_t *)src + index);
+ break;
+ case 32:
+ value = *((const int32_t *)src + index);
+ break;
+ case 64:
+ value = *((const int64_t *)src + index);
+ break;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+ else {
+ switch(type.width) {
+ case 8:
+ value = *((const uint8_t *)src + index);
+ break;
+ case 16:
+ value = *((const uint16_t *)src + index);
+ break;
+ case 32:
+ value = *((const uint32_t *)src + index);
+ break;
+ case 64:
+ value = *((const uint64_t *)src + index);
+ break;
+ default:
+ assert(0);
+ return 0.0;
+ }
+ }
+ }
+ return value/scale;
+}
+
+
+void
+write_elem(struct lp_type type, void *dst, unsigned index, double value)
+{
+ assert(index < type.length);
+ if(!type.sign && value < 0.0)
+ value = 0.0;
+ if(type.norm && value < -1.0)
+ value = -1.0;
+ if(type.norm && value > 1.0)
+ value = 1.0;
+ if (type.floating) {
+ switch(type.width) {
+ case 32:
+ *((float *)dst + index) = (float)(value);
+ break;
+ case 64:
+ *((double *)dst + index) = value;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ else {
+ double scale = lp_const_scale(type);
+ value = round(value*scale);
+ if(type.sign) {
+ long long lvalue = (long long)value;
+ lvalue = MIN2(lvalue, ((long long)1 << (type.width - 1)) - 1);
+ switch(type.width) {
+ case 8:
+ *((int8_t *)dst + index) = (int8_t)lvalue;
+ break;
+ case 16:
+ *((int16_t *)dst + index) = (int16_t)lvalue;
+ break;
+ case 32:
+ *((int32_t *)dst + index) = (int32_t)lvalue;
+ break;
+ case 64:
+ *((int64_t *)dst + index) = (int64_t)lvalue;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ else {
+ unsigned long long lvalue = (long long)value;
+ lvalue = MIN2(lvalue, ((unsigned long long)1 << type.width) - 1);
+ switch(type.width) {
+ case 8:
+ *((uint8_t *)dst + index) = (uint8_t)lvalue;
+ break;
+ case 16:
+ *((uint16_t *)dst + index) = (uint16_t)lvalue;
+ break;
+ case 32:
+ *((uint32_t *)dst + index) = (uint32_t)lvalue;
+ break;
+ case 64:
+ *((uint64_t *)dst + index) = (uint64_t)lvalue;
+ break;
+ default:
+ assert(0);
+ }
+ }
+ }
+}
+
+
+void
+random_elem(struct lp_type type, void *dst, unsigned index)
+{
+ double value;
+ assert(index < type.length);
+ value = (double)rand()/(double)RAND_MAX;
+ if(!type.norm) {
+ unsigned long long mask;
+ if (type.floating)
+ mask = ~(unsigned long long)0;
+ else if (type.fixed)
+ mask = ((unsigned long long)1 << (type.width / 2)) - 1;
+ else if (type.sign)
+ mask = ((unsigned long long)1 << (type.width - 1)) - 1;
+ else
+ mask = ((unsigned long long)1 << type.width) - 1;
+ value += (double)(mask & rand());
+ }
+ if(!type.sign)
+ if(rand() & 1)
+ value = -value;
+ write_elem(type, dst, index, value);
+}
+
+
+void
+read_vec(struct lp_type type, const void *src, double *dst)
+{
+ unsigned i;
+ for (i = 0; i < type.length; ++i)
+ dst[i] = read_elem(type, src, i);
+}
+
+
+void
+write_vec(struct lp_type type, void *dst, const double *src)
+{
+ unsigned i;
+ for (i = 0; i < type.length; ++i)
+ write_elem(type, dst, i, src[i]);
+}
+
+
+float
+random_float(void)
+{
+ return (float)((double)rand()/(double)RAND_MAX);
+}
+
+
+void
+random_vec(struct lp_type type, void *dst)
+{
+ unsigned i;
+ for (i = 0; i < type.length; ++i)
+ random_elem(type, dst, i);
+}
+
+
+boolean
+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) {
+ double res_elem = read_elem(type, res, i);
+ double ref_elem = read_elem(type, ref, i);
+ double delta = fabs(res_elem - ref_elem);
+ if(delta >= 2.0*eps)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+boolean
+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);
+}
+
+
+void
+dump_vec(FILE *fp, struct lp_type type, const void *src)
+{
+ unsigned i;
+ for (i = 0; i < type.length; ++i) {
+ if(i)
+ fprintf(fp, " ");
+ if (type.floating) {
+ double value;
+ switch(type.width) {
+ case 32:
+ value = *((const float *)src + i);
+ break;
+ case 64:
+ value = *((const double *)src + i);
+ break;
+ default:
+ assert(0);
+ value = 0.0;
+ }
+ fprintf(fp, "%f", value);
+ }
+ else {
+ if(type.sign && !type.norm) {
+ long long value;
+ const char *format;
+ switch(type.width) {
+ case 8:
+ value = *((const int8_t *)src + i);
+ format = "%3lli";
+ break;
+ case 16:
+ value = *((const int16_t *)src + i);
+ format = "%5lli";
+ break;
+ case 32:
+ value = *((const int32_t *)src + i);
+ format = "%10lli";
+ break;
+ case 64:
+ value = *((const int64_t *)src + i);
+ format = "%20lli";
+ break;
+ default:
+ assert(0);
+ value = 0.0;
+ format = "?";
+ }
+ fprintf(fp, format, value);
+ }
+ else {
+ unsigned long long value;
+ const char *format;
+ switch(type.width) {
+ case 8:
+ value = *((const uint8_t *)src + i);
+ format = type.norm ? "%2x" : "%4llu";
+ break;
+ case 16:
+ value = *((const uint16_t *)src + i);
+ format = type.norm ? "%4x" : "%6llx";
+ break;
+ case 32:
+ value = *((const uint32_t *)src + i);
+ format = type.norm ? "%8x" : "%11llx";
+ break;
+ case 64:
+ value = *((const uint64_t *)src + i);
+ format = type.norm ? "%16x" : "%21llx";
+ break;
+ default:
+ assert(0);
+ value = 0.0;
+ format = "?";
+ }
+ fprintf(fp, format, value);
+ }
+ }
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ unsigned verbose = 0;
+ FILE *fp = NULL;
+ unsigned long n = 1000;
+ unsigned i;
+ boolean success;
+
+ for(i = 1; i < argc; ++i) {
+ if(strcmp(argv[i], "-v") == 0)
+ ++verbose;
+ else if(strcmp(argv[i], "-o") == 0)
+ fp = fopen(argv[++i], "wt");
+ else
+ n = atoi(argv[i]);
+ }
+
+ if(fp) {
+ /* Warm up the caches */
+ test_some(0, NULL, 100);
+
+ write_tsv_header(fp);
+ }
+
+ if(n)
+ success = test_some(verbose, fp, n);
+ else
+ success = test_all(verbose, fp);
+
+ if(fp)
+ fclose(fp);
+
+ return success ? 0 : 1;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.c b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
new file mode 100644
index 0000000000..773e848242
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.c
@@ -0,0 +1,304 @@
+/**************************************************************************
+ *
+ * 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 "util/u_format.h"
+#include "lp_context.h"
+#include "lp_surface.h"
+#include "lp_texture.h"
+#include "lp_tex_cache.h"
+
+
+
+/**
+ * Return the position in the cache for the tile that contains win pos (x,y).
+ * We currently use a direct mapped cache so this is like a hack key.
+ * At some point we should investige something more sophisticated, like
+ * a LRU replacement policy.
+ */
+#define CACHE_POS(x, y) \
+ (((x) + (y) * 5) % NUM_ENTRIES)
+
+
+
+/**
+ * Is the tile at (x,y) in cleared state?
+ */
+static INLINE uint
+is_clear_flag_set(const uint *bitvec, union tex_tile_address addr)
+{
+ int pos, bit;
+ pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x;
+ assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32);
+ bit = bitvec[pos / 32] & (1 << (pos & 31));
+ return bit;
+}
+
+
+/**
+ * Mark the tile at (x,y) as not cleared.
+ */
+static INLINE void
+clear_clear_flag(uint *bitvec, union tex_tile_address addr)
+{
+ int pos;
+ pos = addr.bits.y * (MAX_TEX_WIDTH / TEX_TILE_SIZE) + addr.bits.x;
+ assert(pos / 32 < (MAX_TEX_WIDTH / TEX_TILE_SIZE) * (MAX_TEX_HEIGHT / TEX_TILE_SIZE) / 32);
+ bitvec[pos / 32] &= ~(1 << (pos & 31));
+}
+
+
+struct llvmpipe_tex_tile_cache *
+lp_create_tex_tile_cache( struct pipe_screen *screen )
+{
+ struct llvmpipe_tex_tile_cache *tc;
+ uint pos;
+
+ tc = CALLOC_STRUCT( llvmpipe_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
+lp_destroy_tex_tile_cache(struct llvmpipe_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
+lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_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);
+}
+
+
+void
+lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc)
+{
+ if (tc->transfer_map) {
+ 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;
+ }
+}
+
+void
+lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc)
+{
+ if (tc->texture) {
+ struct llvmpipe_texture *lpt = llvmpipe_texture(tc->texture);
+ if (lpt->timestamp != tc->timestamp) {
+ /* texture was modified, invalidate all cached tiles */
+ uint i;
+ debug_printf("INV %d %d\n", tc->timestamp, lpt->timestamp);
+ for (i = 0; i < NUM_ENTRIES; i++) {
+ tc->entries[i].addr.bits.invalid = 1;
+ }
+
+ tc->timestamp = lpt->timestamp;
+ }
+ }
+}
+
+/**
+ * Specify the texture to cache.
+ */
+void
+lp_tex_tile_cache_set_texture(struct llvmpipe_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 */
+ }
+}
+
+
+/**
+ * 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 lp_get_cached_tile() but for textures.
+ * Tiles are read-only and indexed with more params.
+ */
+const struct llvmpipe_cached_tex_tile *
+lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
+ union tex_tile_address addr )
+{
+ struct pipe_screen *screen = tc->screen;
+ struct llvmpipe_cached_tex_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/TEX_TILE_SIZE, y/TEX_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;
+ }
+
+ {
+ unsigned x = addr.bits.x * TEX_TILE_SIZE;
+ unsigned y = addr.bits.y * TEX_TILE_SIZE;
+ unsigned w = TEX_TILE_SIZE;
+ unsigned h = TEX_TILE_SIZE;
+
+ if (pipe_clip_tile(x, y, &w, &h, tc->tex_trans)) {
+ assert(0);
+ }
+
+ util_format_read_4ub(tc->tex_trans->format,
+ (uint8_t *)tile->color, sizeof tile->color[0],
+ tc->tex_trans_map, tc->tex_trans->stride,
+ x, y, w, h);
+ }
+
+ tile->addr = addr;
+ }
+
+ tc->last_tile = tile;
+ return tile;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_cache.h b/src/gallium/drivers/llvmpipe/lp_tex_cache.h
new file mode 100644
index 0000000000..9fa6c36812
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tex_cache.h
@@ -0,0 +1,151 @@
+/**************************************************************************
+ *
+ * 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 LP_TEX_CACHE_H
+#define LP_TEX_CACHE_H
+
+
+#include "pipe/p_compiler.h"
+
+
+struct llvmpipe_context;
+struct llvmpipe_tex_tile_cache;
+
+
+/**
+ * Cache tile size (width and height). This needs to be a power of two.
+ */
+#define TEX_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 / TEX_TILE_SIZE */
+ unsigned y:6; /* 4096 / TEX_TILE_SIZE */
+ unsigned z:12; /* 4096 -- z not tiled */
+ unsigned face:3;
+ unsigned level:4;
+ unsigned invalid:1;
+ } bits;
+ unsigned value;
+};
+
+
+struct llvmpipe_cached_tex_tile
+{
+ union tex_tile_address addr;
+ uint8_t color[TEX_TILE_SIZE][TEX_TILE_SIZE][4];
+};
+
+#define NUM_ENTRIES 50
+
+
+/** XXX move these */
+#define MAX_TEX_WIDTH 2048
+#define MAX_TEX_HEIGHT 2048
+
+
+struct llvmpipe_tex_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 */
+ unsigned timestamp;
+
+ struct llvmpipe_cached_tex_tile entries[NUM_ENTRIES];
+
+ struct pipe_transfer *tex_trans;
+ void *tex_trans_map;
+ int tex_face, tex_level, tex_z;
+
+ struct llvmpipe_cached_tex_tile *last_tile; /**< most recently retrieved tile */
+};
+
+
+extern struct llvmpipe_tex_tile_cache *
+lp_create_tex_tile_cache( struct pipe_screen *screen );
+
+extern void
+lp_destroy_tex_tile_cache(struct llvmpipe_tex_tile_cache *tc);
+
+extern void
+lp_tex_tile_cache_map_transfers(struct llvmpipe_tex_tile_cache *tc);
+
+extern void
+lp_tex_tile_cache_unmap_transfers(struct llvmpipe_tex_tile_cache *tc);
+
+extern void
+lp_tex_tile_cache_set_texture(struct llvmpipe_tex_tile_cache *tc,
+ struct pipe_texture *texture);
+
+void
+lp_tex_tile_cache_validate_texture(struct llvmpipe_tex_tile_cache *tc);
+
+extern const struct llvmpipe_cached_tex_tile *
+lp_find_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
+ union tex_tile_address addr );
+
+static INLINE const 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 / TEX_TILE_SIZE;
+ addr.bits.y = y / TEX_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 llvmpipe_cached_tex_tile *
+lp_get_cached_tex_tile(struct llvmpipe_tex_tile_cache *tc,
+ union tex_tile_address addr )
+{
+ if (tc->last_tile->addr.value == addr.value)
+ return tc->last_tile;
+
+ return lp_find_cached_tex_tile( tc, addr );
+}
+
+
+#endif /* LP_TEX_CACHE_H */
+
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample.h b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
new file mode 100644
index 0000000000..9ad1bde956
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample.h
@@ -0,0 +1,101 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef LP_TEX_SAMPLE_H
+#define LP_TEX_SAMPLE_H
+
+
+#include <llvm-c/Core.h>
+
+#include "tgsi/tgsi_exec.h"
+
+
+struct llvmpipe_tex_tile_cache;
+struct lp_sampler_static_state;
+
+
+/**
+ * Subclass of tgsi_sampler
+ */
+struct lp_shader_sampler
+{
+ struct tgsi_sampler base; /**< base class */
+
+ unsigned processor;
+
+ /* For lp_get_samples_2d_linear_POT:
+ */
+ unsigned xpot;
+ unsigned ypot;
+ unsigned level;
+
+ const struct pipe_texture *texture;
+ const struct pipe_sampler_state *sampler;
+
+ struct llvmpipe_tex_tile_cache *cache;
+};
+
+
+
+static INLINE struct lp_shader_sampler *
+lp_shader_sampler(const struct tgsi_sampler *sampler)
+{
+ return (struct lp_shader_sampler *) sampler;
+}
+
+
+
+extern void
+lp_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]);
+
+
+/**
+ * Texture sampling code generator that just calls lp_get_samples C function
+ * for the actual sampling computation.
+ *
+ * @param context_ptr LLVM value with the pointer to the struct lp_jit_context.
+ */
+struct lp_build_sampler_soa *
+lp_c_sampler_soa_create(LLVMValueRef context_ptr);
+
+
+/**
+ * Pure-LLVM texture sampling code generator.
+ *
+ * @param context_ptr LLVM value with the pointer to the struct lp_jit_context.
+ */
+struct lp_build_sampler_soa *
+lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *key,
+ LLVMValueRef context_ptr);
+
+
+#endif /* LP_TEX_SAMPLE_H */
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
new file mode 100644
index 0000000000..a1365a045f
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_c.c
@@ -0,0 +1,1713 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ * Copyright 2008 VMware, Inc. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, 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 sampling
+ *
+ * Authors:
+ * Brian Paul
+ */
+
+#include "lp_context.h"
+#include "lp_quad.h"
+#include "lp_surface.h"
+#include "lp_texture.h"
+#include "lp_tex_sample.h"
+#include "lp_tex_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"
+
+
+
+/*
+ * Note, the FRAC macro has to work perfectly. Otherwise 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))
+
+
+/**
+ * Linear interpolation macro
+ */
+static INLINE float
+lerp(float a, float v0, float v1)
+{
+ return v0 + a * (v1 - v0);
+}
+
+
+/**
+ * Do 2D/biliner interpolation of float values.
+ * v00, v10, v01 and v11 are typically four texture samples in a square/box.
+ * a and b are the horizontal and vertical interpolants.
+ * It's important that this function is inlined when compiled with
+ * optimization! If we find that's not true on some systems, convert
+ * to a macro.
+ */
+static INLINE float
+lerp_2d(float a, float b,
+ float v00, float v10, float v01, float v11)
+{
+ const float temp0 = lerp(a, v00, v10);
+ const float temp1 = lerp(a, v01, v11);
+ return lerp(b, temp0, temp1);
+}
+
+
+/**
+ * As above, but 3D interpolation of 8 values.
+ */
+static INLINE float
+lerp_3d(float a, float b, float c,
+ float v000, float v100, float v010, float v110,
+ float v001, float v101, float v011, float v111)
+{
+ const float temp0 = lerp_2d(a, b, v000, v100, v010, v110);
+ const float temp1 = lerp_2d(a, b, v001, v101, v011, v111);
+ return lerp(c, temp0, temp1);
+}
+
+
+
+/**
+ * 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.
+ */
+#define REMAINDER(A, B) ((unsigned) (A) % (unsigned) (B))
+
+
+/**
+ * Apply texture coord wrapping mode and return integer texture indexes
+ * for a vector of four texcoords (S or T or P).
+ * \param wrapMode PIPE_TEX_WRAP_x
+ * \param s the incoming texcoords
+ * \param size the texture image size
+ * \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])
+{
+ 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++) {
+ 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);
+ }
+}
+
+
+/**
+ * Used to compute texel locations for linear sampling for four texcoords.
+ * \param wrapMode PIPE_TEX_WRAP_x
+ * \param s the texcoords
+ * \param size the texture image size
+ * \param icoord0 returns first texture indexes
+ * \param icoord1 returns second texture indexes (usually icoord0 + 1)
+ * \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,
+ int icoord0[4], int icoord1[4], float w[4])
+{
+ uint ch;
+
+ 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);
+ }
+}
+
+
+/**
+ * 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])
+{
+ 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 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])
+{
+ 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);
+ }
+}
+
+
+static unsigned
+choose_cube_face(float rx, float ry, float rz, float *newS, float *newT)
+{
+ /*
+ 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;
+ }
+ else {
+ face = PIPE_TEX_FACE_NEG_X;
+ sc = rz;
+ tc = -ry;
+ ma = arx;
+ }
+ }
+ 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;
+ }
+ }
+
+ *newS = ( sc / ma + 1.0F ) * 0.5F;
+ *newT = ( tc / ma + 1.0F ) * 0.5F;
+
+ return face;
+}
+
+
+/**
+ * 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(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias)
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ float rho, lambda;
+
+ if (samp->processor == TGSI_PROCESSOR_VERTEX)
+ return lodbias;
+
+ assert(sampler->normalized_coords);
+
+ 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) * texture->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) * texture->height[0];
+ rho = MAX2(rho, max);
+ }
+ 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) * texture->depth[0];
+ rho = MAX2(rho, max);
+ }
+
+ lambda = util_fast_log2(rho);
+ lambda += lodbias + sampler->lod_bias;
+ lambda = CLAMP(lambda, sampler->min_lod, sampler->max_lod);
+
+ return lambda;
+}
+
+
+/**
+ * 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(struct tgsi_sampler *tgsi_sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ unsigned *level0, unsigned *level1, float *levelBlend,
+ unsigned *imgFilter)
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+
+ 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(tgsi_sampler, s, t, p, lodbias);
+ if (lambda <= 0.0) {
+ *imgFilter = sampler->mag_img_filter;
+ }
+ else {
+ *imgFilter = sampler->min_img_filter;
+ }
+ }
+ else {
+ *imgFilter = sampler->mag_img_filter;
+ }
+ }
+ else {
+ float lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
+
+ if (lambda <= 0.0) { /* XXX threshold depends on the filter */
+ /* magnifying */
+ *imgFilter = sampler->mag_img_filter;
+ *level0 = *level1 = 0;
+ }
+ 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 */
+ }
+ }
+ }
+}
+
+
+/**
+ * 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 lp_tile_cache.c and merge with the
+ * lp_get_cached_tile_tex() function. Also, get 4 texels instead of 1...
+ */
+static void
+get_texel_quad_2d(const struct tgsi_sampler *tgsi_sampler,
+ unsigned face, unsigned level, int x, int y,
+ const uint8_t *out[4])
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+
+ const struct llvmpipe_cached_tex_tile *tile
+ = lp_get_cached_tex_tile(samp->cache,
+ tex_tile_address(x, y, 0, face, level));
+
+ y %= TEX_TILE_SIZE;
+ x %= TEX_TILE_SIZE;
+
+ out[0] = &tile->color[y ][x ][0];
+ out[1] = &tile->color[y ][x+1][0];
+ out[2] = &tile->color[y+1][x ][0];
+ out[3] = &tile->color[y+1][x+1][0];
+}
+
+static INLINE const uint8_t *
+get_texel_2d_ptr(const struct tgsi_sampler *tgsi_sampler,
+ unsigned face, unsigned level, int x, int y)
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+
+ const struct llvmpipe_cached_tex_tile *tile
+ = lp_get_cached_tex_tile(samp->cache,
+ tex_tile_address(x, y, 0, face, level));
+
+ y %= TEX_TILE_SIZE;
+ x %= TEX_TILE_SIZE;
+
+ return &tile->color[y][x][0];
+}
+
+
+static void
+get_texel_quad_2d_mt(const struct tgsi_sampler *tgsi_sampler,
+ unsigned face, unsigned level,
+ int x0, int y0,
+ int x1, int y1,
+ const uint8_t *out[4])
+{
+ unsigned i;
+
+ for (i = 0; i < 4; i++) {
+ unsigned tx = (i & 1) ? x1 : x0;
+ unsigned ty = (i >> 1) ? y1 : y0;
+
+ out[i] = get_texel_2d_ptr( tgsi_sampler, face, level, tx, ty );
+ }
+}
+
+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)
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+
+ 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];
+ }
+ else {
+ const unsigned tx = x % TEX_TILE_SIZE;
+ const unsigned ty = y % TEX_TILE_SIZE;
+ const struct llvmpipe_cached_tex_tile *tile;
+
+ tile = lp_get_cached_tex_tile(samp->cache,
+ tex_tile_address(x, y, z, face, level));
+
+ rgba[0][j] = ubyte_to_float(tile->color[ty][tx][0]);
+ rgba[1][j] = ubyte_to_float(tile->color[ty][tx][1]);
+ rgba[2][j] = ubyte_to_float(tile->color[ty][tx][2]);
+ rgba[3][j] = ubyte_to_float(tile->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));
+ }
+ }
+}
+
+
+/**
+ * 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]
+ */
+static INLINE void
+shadow_compare(const struct pipe_sampler_state *sampler,
+ float rgba[NUM_CHANNELS][QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ uint j)
+{
+ 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;
+ }
+
+ /* 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;
+}
+
+
+/**
+ * As above, but do four z/texture comparisons.
+ */
+static INLINE void
+shadow_compare4(const struct pipe_sampler_state *sampler,
+ float rgba[NUM_CHANNELS][QUAD_SIZE],
+ const float p[QUAD_SIZE])
+{
+ int j, k0, k1, k2, k3;
+ float val;
+
+ /* compare four texcoords vs. four texture samples */
+ switch (sampler->compare_func) {
+ case PIPE_FUNC_LESS:
+ k0 = p[0] < rgba[0][0];
+ k1 = p[1] < rgba[0][1];
+ k2 = p[2] < rgba[0][2];
+ k3 = p[3] < rgba[0][3];
+ break;
+ case PIPE_FUNC_LEQUAL:
+ k0 = p[0] <= rgba[0][0];
+ k1 = p[1] <= rgba[0][1];
+ k2 = p[2] <= rgba[0][2];
+ k3 = p[3] <= rgba[0][3];
+ break;
+ case PIPE_FUNC_GREATER:
+ k0 = p[0] > rgba[0][0];
+ k1 = p[1] > rgba[0][1];
+ k2 = p[2] > rgba[0][2];
+ k3 = p[3] > rgba[0][3];
+ break;
+ case PIPE_FUNC_GEQUAL:
+ k0 = p[0] >= rgba[0][0];
+ k1 = p[1] >= rgba[0][1];
+ k2 = p[2] >= rgba[0][2];
+ k3 = p[3] >= rgba[0][3];
+ break;
+ case PIPE_FUNC_EQUAL:
+ k0 = p[0] == rgba[0][0];
+ k1 = p[1] == rgba[0][1];
+ k2 = p[2] == rgba[0][2];
+ k3 = p[3] == rgba[0][3];
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ k0 = p[0] != rgba[0][0];
+ k1 = p[1] != rgba[0][1];
+ k2 = p[2] != rgba[0][2];
+ k3 = p[3] != rgba[0][3];
+ break;
+ case PIPE_FUNC_ALWAYS:
+ k0 = k1 = k2 = k3 = 1;
+ break;
+ case PIPE_FUNC_NEVER:
+ k0 = k1 = k2 = k3 = 0;
+ break;
+ default:
+ k0 = k1 = k2 = k3 = 0;
+ assert(0);
+ break;
+ }
+
+ /* convert four pass/fail values to an intensity in [0,1] */
+ val = 0.25F * (k0 + k1 + k2 + k3);
+
+ /* XXX returning result for default GL_DEPTH_TEXTURE_MODE = GL_LUMINANCE */
+ for (j = 0; j < 4; j++) {
+ rgba[0][j] = rgba[1][j] = rgba[2][j] = val;
+ rgba[3][j] = 1.0F;
+ }
+}
+
+
+
+static void
+lp_get_samples_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 lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = 1 << (samp->xpot - level);
+ unsigned ypot = 1 << (samp->ypot - level);
+ unsigned xmax = (xpot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, xpot) - 1; */
+ unsigned ymax = (ypot - 1) & (TEX_TILE_SIZE - 1); /* MIN2(TEX_TILE_SIZE, ypot) - 1; */
+
+ 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 uint8_t *tx[4];
+
+
+ /* Can we fetch all four at once:
+ */
+ if (x0 < xmax && y0 < ymax)
+ {
+ get_texel_quad_2d(tgsi_sampler, 0, level, x0, y0, tx);
+ }
+ else
+ {
+ unsigned x1 = (x0 + 1) & (xpot - 1);
+ unsigned y1 = (y0 + 1) & (ypot - 1);
+ get_texel_quad_2d_mt(tgsi_sampler, 0, level,
+ x0, y0, x1, y1, tx);
+ }
+
+
+ /* interpolate R, G, B, A */
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = lerp_2d(xw, yw,
+ ubyte_to_float(tx[0][c]), ubyte_to_float(tx[1][c]),
+ ubyte_to_float(tx[2][c]), ubyte_to_float(tx[3][c]));
+ }
+ }
+}
+
+
+static void
+lp_get_samples_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 lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = 1 << (samp->xpot - level);
+ unsigned ypot = 1 << (samp->ypot - 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 uint8_t *out = get_texel_2d_ptr(tgsi_sampler, 0, level, x0, y0);
+
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = ubyte_to_float(out[c]);
+ }
+ }
+}
+
+
+static void
+lp_get_samples_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 lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ unsigned j;
+ unsigned level = samp->level;
+ unsigned xpot = 1 << (samp->xpot - level);
+ unsigned ypot = 1 << (samp->ypot - level);
+
+ for (j = 0; j < QUAD_SIZE; j++) {
+ int c;
+
+ float u = s[j] * xpot;
+ float v = t[j] * ypot;
+
+ int x0, y0;
+ const uint8_t *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_ptr(tgsi_sampler, 0, level, x0, y0);
+
+ for (c = 0; c < 4; c++) {
+ rgba[c][j] = ubyte_to_float(out[c]);
+ }
+ }
+}
+
+
+static void
+lp_get_samples_2d_linear_mip_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])
+{
+ struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ int level0;
+ float lambda;
+
+ lambda = compute_lambda(tgsi_sampler, s, t, p, lodbias);
+ level0 = (int)lambda;
+
+ if (lambda < 0.0) {
+ samp->level = 0;
+ lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
+ s, t, p, 0, rgba );
+ }
+ else if (level0 >= texture->last_level) {
+ samp->level = texture->last_level;
+ lp_get_samples_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;
+
+ samp->level = level0;
+ lp_get_samples_2d_linear_repeat_POT( tgsi_sampler,
+ s, t, p, 0, rgba0 );
+
+ samp->level = level0+1;
+ lp_get_samples_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]);
+ }
+ }
+ }
+}
+
+/**
+ * Common code for sampling 1D/2D/cube textures.
+ * Could probably extend for 3D...
+ */
+static void
+lp_get_samples_2d_common(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 unsigned faces[4])
+{
+ const struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ unsigned level0, level1, j, imgFilter;
+ int width, height;
+ float levelBlend;
+
+ choose_mipmap_levels(tgsi_sampler, s, t, p,
+ 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);
+ }
+
+ 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]);
+ }
+ }
+ }
+ }
+ break;
+ case PIPE_TEX_FILTER_LINEAR:
+ case PIPE_TEX_FILTER_ANISO:
+ {
+ 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);
+ }
+
+ /* 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]);
+ }
+
+ if (level0 != level1) {
+ /* get texels from second mipmap level and blend */
+ float rgba2[4][4];
+
+ /* XXX: This is incorrect -- will often end up with (x0
+ * == x1 && y0 == y1), meaning that we fetch the same
+ * texel four times and linearly interpolate between
+ * identical values. The correct approach would be to
+ * call linear_texcoord again for the second level.
+ */
+ 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;
+ default:
+ assert(0);
+ }
+}
+
+
+static INLINE void
+lp_get_samples_1d(struct tgsi_sampler *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 const unsigned faces[4] = {0, 0, 0, 0};
+ static const float tzero[4] = {0, 0, 0, 0};
+ lp_get_samples_2d_common(sampler, s, tzero, NULL,
+ lodbias, rgba, faces);
+}
+
+
+static INLINE void
+lp_get_samples_2d(struct tgsi_sampler *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 const unsigned faces[4] = {0, 0, 0, 0};
+ lp_get_samples_2d_common(sampler, s, t, p,
+ lodbias, rgba, faces);
+}
+
+
+static INLINE void
+lp_get_samples_3d(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 lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ /* 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(tgsi_sampler, s, t, p,
+ 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;
+ default:
+ assert(0);
+ }
+}
+
+
+static void
+lp_get_samples_cube(struct tgsi_sampler *sampler,
+ const float s[QUAD_SIZE],
+ const float t[QUAD_SIZE],
+ const float p[QUAD_SIZE],
+ float lodbias,
+ float rgba[NUM_CHANNELS][QUAD_SIZE])
+{
+ 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);
+ }
+ lp_get_samples_2d_common(sampler, ssss, tttt, NULL,
+ lodbias, rgba, faces);
+}
+
+
+static void
+lp_get_samples_rect(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 lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+ const uint face = 0;
+ unsigned level0, level1, j, imgFilter;
+ int width, height;
+ float levelBlend;
+
+ choose_mipmap_levels(tgsi_sampler, s, t, p,
+ 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);
+ }
+ }
+ }
+ break;
+ case PIPE_TEX_FILTER_LINEAR:
+ case PIPE_TEX_FILTER_ANISO:
+ {
+ 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);
+ }
+ 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;
+ default:
+ assert(0);
+ }
+}
+
+
+/**
+ * Error condition handler
+ */
+static INLINE void
+lp_get_samples_null(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 i,j;
+
+ for (i = 0; i < 4; i++)
+ for (j = 0; j < 4; j++)
+ rgba[i][j] = 1.0;
+}
+
+/**
+ * Called via tgsi_sampler::get_samples() when using a sampler for the
+ * first time. Determine the actual sampler function, link it in and
+ * call it.
+ */
+void
+lp_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])
+{
+ struct lp_shader_sampler *samp = lp_shader_sampler(tgsi_sampler);
+ const struct pipe_texture *texture = samp->texture;
+ const struct pipe_sampler_state *sampler = samp->sampler;
+
+ /* Default to the 'undefined' case:
+ */
+ tgsi_sampler->get_samples = lp_get_samples_null;
+
+ if (!texture) {
+ assert(0); /* is this legal?? */
+ goto out;
+ }
+
+ if (!sampler->normalized_coords) {
+ assert (texture->target == PIPE_TEXTURE_2D);
+ tgsi_sampler->get_samples = lp_get_samples_rect;
+ goto out;
+ }
+
+ switch (texture->target) {
+ case PIPE_TEXTURE_1D:
+ tgsi_sampler->get_samples = lp_get_samples_1d;
+ break;
+ case PIPE_TEXTURE_2D:
+ tgsi_sampler->get_samples = lp_get_samples_2d;
+ break;
+ case PIPE_TEXTURE_3D:
+ tgsi_sampler->get_samples = lp_get_samples_3d;
+ break;
+ case PIPE_TEXTURE_CUBE:
+ tgsi_sampler->get_samples = lp_get_samples_cube;
+ break;
+ default:
+ assert(0);
+ break;
+ }
+
+ /* Do this elsewhere:
+ */
+ samp->xpot = util_unsigned_logbase2( samp->texture->width[0] );
+ samp->ypot = util_unsigned_logbase2( samp->texture->height[0] );
+
+ /* Try to hook in a faster sampler. Ultimately we'll have to
+ * code-generate these. Luckily most of this looks like it is
+ * orthogonal state within the sampler.
+ */
+ if (texture->target == PIPE_TEXTURE_2D &&
+ sampler->min_img_filter == sampler->mag_img_filter &&
+ sampler->wrap_s == sampler->wrap_t &&
+ sampler->compare_mode == FALSE &&
+ sampler->normalized_coords)
+ {
+ if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_NONE) {
+ samp->level = CLAMP((int) sampler->min_lod,
+ 0, (int) texture->last_level);
+
+ if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
+ switch (sampler->min_img_filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ tgsi_sampler->get_samples = lp_get_samples_2d_nearest_repeat_POT;
+ break;
+ case PIPE_TEX_FILTER_LINEAR:
+ tgsi_sampler->get_samples = lp_get_samples_2d_linear_repeat_POT;
+ break;
+ default:
+ break;
+ }
+ }
+ else if (sampler->wrap_s == PIPE_TEX_WRAP_CLAMP) {
+ switch (sampler->min_img_filter) {
+ case PIPE_TEX_FILTER_NEAREST:
+ tgsi_sampler->get_samples = lp_get_samples_2d_nearest_clamp_POT;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ else if (sampler->min_mip_filter == PIPE_TEX_MIPFILTER_LINEAR) {
+ if (sampler->wrap_s == PIPE_TEX_WRAP_REPEAT) {
+ switch (sampler->min_img_filter) {
+ case PIPE_TEX_FILTER_LINEAR:
+ tgsi_sampler->get_samples = lp_get_samples_2d_linear_mip_linear_repeat_POT;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+ else if (0) {
+ _debug_printf("target %d/%d min_mip %d/%d min_img %d/%d wrap %d/%d compare %d/%d norm %d/%d\n",
+ texture->target, PIPE_TEXTURE_2D,
+ sampler->min_mip_filter, PIPE_TEX_MIPFILTER_NONE,
+ sampler->min_img_filter, sampler->mag_img_filter,
+ sampler->wrap_s, sampler->wrap_t,
+ sampler->compare_mode, FALSE,
+ sampler->normalized_coords, TRUE);
+ }
+
+out:
+ tgsi_sampler->get_samples( tgsi_sampler, s, t, p, lodbias, rgba );
+}
+
+
+void PIPE_CDECL
+lp_fetch_texel_soa( struct tgsi_sampler **samplers,
+ uint32_t unit,
+ float *store )
+{
+ struct tgsi_sampler *sampler = samplers[unit];
+
+#if 0
+ uint j;
+
+ debug_printf("%s sampler: %p (%p) store: %p\n",
+ __FUNCTION__,
+ sampler, *sampler,
+ store );
+
+ debug_printf("lodbias %f\n", store[12]);
+
+ for (j = 0; j < 4; j++)
+ debug_printf("sample %d texcoord %f %f\n",
+ j,
+ store[0+j],
+ store[4+j]);
+#endif
+
+ {
+ float rgba[NUM_CHANNELS][QUAD_SIZE];
+ sampler->get_samples(sampler,
+ &store[0],
+ &store[4],
+ &store[8],
+ 0.0f, /*store[12], lodbias */
+ rgba);
+ memcpy(store, rgba, sizeof rgba);
+ }
+
+#if 0
+ for (j = 0; j < 4; j++)
+ debug_printf("sample %d result %f %f %f %f\n",
+ j,
+ store[0+j],
+ store[4+j],
+ store[8+j],
+ store[12+j]);
+#endif
+}
+
+
+#include "lp_bld_type.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_tgsi.h"
+
+
+struct lp_c_sampler_soa
+{
+ struct lp_build_sampler_soa base;
+
+ LLVMValueRef context_ptr;
+
+ LLVMValueRef samplers_ptr;
+
+ /** Coords/texels store */
+ LLVMValueRef store_ptr;
+};
+
+
+static void
+lp_c_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
+{
+ FREE(sampler);
+}
+
+
+static void
+lp_c_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *_sampler,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel)
+{
+ struct lp_c_sampler_soa *sampler = (struct lp_c_sampler_soa *)_sampler;
+ LLVMTypeRef vec_type = LLVMTypeOf(coords[0]);
+ LLVMValueRef args[3];
+ unsigned i;
+
+ if(!sampler->samplers_ptr)
+ sampler->samplers_ptr = lp_jit_context_samplers(builder, sampler->context_ptr);
+
+ if(!sampler->store_ptr)
+ sampler->store_ptr = LLVMBuildArrayAlloca(builder,
+ vec_type,
+ LLVMConstInt(LLVMInt32Type(), 4, 0),
+ "texel_store");
+
+ for (i = 0; i < num_coords; i++) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef coord_ptr = LLVMBuildGEP(builder, sampler->store_ptr, &index, 1, "");
+ LLVMBuildStore(builder, coords[i], coord_ptr);
+ }
+
+ args[0] = sampler->samplers_ptr;
+ args[1] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+ args[2] = sampler->store_ptr;
+
+ lp_build_intrinsic(builder, "fetch_texel", LLVMVoidType(), args, 3);
+
+ for (i = 0; i < NUM_CHANNELS; ++i) {
+ LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
+ LLVMValueRef texel_ptr = LLVMBuildGEP(builder, sampler->store_ptr, &index, 1, "");
+ texel[i] = LLVMBuildLoad(builder, texel_ptr, "");
+ }
+}
+
+
+struct lp_build_sampler_soa *
+lp_c_sampler_soa_create(LLVMValueRef context_ptr)
+{
+ struct lp_c_sampler_soa *sampler;
+
+ sampler = CALLOC_STRUCT(lp_c_sampler_soa);
+ if(!sampler)
+ return NULL;
+
+ sampler->base.destroy = lp_c_sampler_soa_destroy;
+ sampler->base.emit_fetch_texel = lp_c_sampler_soa_emit_fetch_texel;
+ sampler->context_ptr = context_ptr;
+
+ return &sampler->base;
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
new file mode 100644
index 0000000000..d2a6ae21f5
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tex_sample_llvm.c
@@ -0,0 +1,196 @@
+/**************************************************************************
+ *
+ * Copyright 2009 VMware, Inc.
+ * All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+/**
+ * Texture sampling code generation
+ *
+ * This file is nothing more than ugly glue between three largely independent
+ * entities:
+ * - TGSI -> LLVM translation (i.e., lp_build_tgsi_soa)
+ * - texture sampling code generation (i.e., lp_build_sample_soa)
+ * - LLVM pipe driver
+ *
+ * All interesting code is in the functions mentioned above. There is really
+ * nothing to see here.
+ *
+ * @author Jose Fonseca <jfonseca@vmware.com>
+ */
+
+#include "pipe/p_defines.h"
+#include "pipe/p_shader_tokens.h"
+#include "lp_bld_debug.h"
+#include "lp_bld_type.h"
+#include "lp_bld_intr.h"
+#include "lp_bld_sample.h"
+#include "lp_bld_tgsi.h"
+#include "lp_state.h"
+#include "lp_tex_sample.h"
+
+
+/**
+ * This provides the bridge between the sampler state store in lp_jit_context
+ * and lp_jit_texture and the sampler code generator. It provides the
+ * texture layout information required by the texture sampler code generator
+ * in terms of the state stored in lp_jit_context and lp_jit_texture in runtime.
+ */
+struct llvmpipe_sampler_dynamic_state
+{
+ struct lp_sampler_dynamic_state base;
+
+ const struct lp_sampler_static_state *static_state;
+
+ LLVMValueRef context_ptr;
+};
+
+
+/**
+ * This is the bridge between our sampler and the TGSI translator.
+ */
+struct lp_llvm_sampler_soa
+{
+ struct lp_build_sampler_soa base;
+
+ struct llvmpipe_sampler_dynamic_state dynamic_state;
+};
+
+
+/**
+ * Fetch the specified member of the lp_jit_texture structure.
+ *
+ * @sa http://llvm.org/docs/GetElementPtr.html
+ */
+static LLVMValueRef
+lp_llvm_texture_member(struct lp_sampler_dynamic_state *base,
+ LLVMBuilderRef builder,
+ unsigned unit,
+ unsigned member_index,
+ const char *member_name)
+{
+ struct llvmpipe_sampler_dynamic_state *state = (struct llvmpipe_sampler_dynamic_state *)base;
+ LLVMValueRef indices[4];
+ LLVMValueRef ptr;
+ LLVMValueRef res;
+
+ assert(unit < PIPE_MAX_SAMPLERS);
+
+ /* context[0] */
+ indices[0] = LLVMConstInt(LLVMInt32Type(), 0, 0);
+ /* context[0].textures */
+ indices[1] = LLVMConstInt(LLVMInt32Type(), LP_JIT_CONTEXT_TEXTURES_INDEX, 0);
+ /* context[0].textures[unit] */
+ indices[2] = LLVMConstInt(LLVMInt32Type(), unit, 0);
+ /* context[0].textures[unit].member */
+ indices[3] = LLVMConstInt(LLVMInt32Type(), member_index, 0);
+
+ ptr = LLVMBuildGEP(builder, state->context_ptr, indices, Elements(indices), "");
+
+ res = LLVMBuildLoad(builder, ptr, "");
+
+ lp_build_name(res, "context.texture%u.%s", unit, member_name);
+
+ return res;
+}
+
+
+/**
+ * Helper macro to instantiate the functions that generate the code to fetch
+ * the members of lp_jit_texture to fulfill the sampler code generator requests.
+ *
+ * This complexity is the price we have to pay to keep the texture sampler code
+ * generator a reusable module without dependencies to llvmpipe internals.
+ */
+#define LP_LLVM_TEXTURE_MEMBER(_name, _index) \
+ static LLVMValueRef \
+ lp_llvm_texture_##_name( struct lp_sampler_dynamic_state *base, \
+ LLVMBuilderRef builder, \
+ unsigned unit) \
+ { \
+ return lp_llvm_texture_member(base, builder, unit, _index, #_name ); \
+ }
+
+
+LP_LLVM_TEXTURE_MEMBER(width, LP_JIT_TEXTURE_WIDTH)
+LP_LLVM_TEXTURE_MEMBER(height, LP_JIT_TEXTURE_HEIGHT)
+LP_LLVM_TEXTURE_MEMBER(stride, LP_JIT_TEXTURE_STRIDE)
+LP_LLVM_TEXTURE_MEMBER(data_ptr, LP_JIT_TEXTURE_DATA)
+
+
+static void
+lp_llvm_sampler_soa_destroy(struct lp_build_sampler_soa *sampler)
+{
+ FREE(sampler);
+}
+
+
+static void
+lp_llvm_sampler_soa_emit_fetch_texel(struct lp_build_sampler_soa *base,
+ LLVMBuilderRef builder,
+ struct lp_type type,
+ unsigned unit,
+ unsigned num_coords,
+ const LLVMValueRef *coords,
+ LLVMValueRef lodbias,
+ LLVMValueRef *texel)
+{
+ struct lp_llvm_sampler_soa *sampler = (struct lp_llvm_sampler_soa *)base;
+
+ assert(unit < PIPE_MAX_SAMPLERS);
+
+ lp_build_sample_soa(builder,
+ &sampler->dynamic_state.static_state[unit],
+ &sampler->dynamic_state.base,
+ type,
+ unit,
+ num_coords,
+ coords,
+ lodbias,
+ texel);
+}
+
+
+struct lp_build_sampler_soa *
+lp_llvm_sampler_soa_create(const struct lp_sampler_static_state *static_state,
+ LLVMValueRef context_ptr)
+{
+ struct lp_llvm_sampler_soa *sampler;
+
+ sampler = CALLOC_STRUCT(lp_llvm_sampler_soa);
+ if(!sampler)
+ return NULL;
+
+ sampler->base.destroy = lp_llvm_sampler_soa_destroy;
+ sampler->base.emit_fetch_texel = lp_llvm_sampler_soa_emit_fetch_texel;
+ sampler->dynamic_state.base.width = lp_llvm_texture_width;
+ sampler->dynamic_state.base.height = lp_llvm_texture_height;
+ sampler->dynamic_state.base.stride = lp_llvm_texture_stride;
+ sampler->dynamic_state.base.data_ptr = lp_llvm_texture_data_ptr;
+ sampler->dynamic_state.static_state = static_state;
+ sampler->dynamic_state.context_ptr = context_ptr;
+
+ return &sampler->base;
+}
+
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c
new file mode 100644
index 0000000000..724d437833
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_texture.c
@@ -0,0 +1,429 @@
+/**************************************************************************
+ *
+ * Copyright 2006 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+ /*
+ * Authors:
+ * Keith Whitwell <keith@tungstengraphics.com>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ */
+
+#include "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 "lp_context.h"
+#include "lp_state.h"
+#include "lp_texture.h"
+#include "lp_tex_cache.h"
+#include "lp_screen.h"
+#include "lp_winsys.h"
+
+
+/* Simple, maximally packed layout.
+ */
+
+
+/* Conventional allocation path for non-display textures:
+ */
+static boolean
+llvmpipe_texture_layout(struct llvmpipe_screen *screen,
+ struct llvmpipe_texture * lpt)
+{
+ struct pipe_texture *pt = &lpt->base;
+ unsigned level;
+ unsigned width = pt->width[0];
+ unsigned height = pt->height[0];
+ unsigned depth = pt->depth[0];
+
+ unsigned buffer_size = 0;
+
+ pf_get_block(lpt->base.format, &lpt->base.block);
+
+ for (level = 0; level <= pt->last_level; level++) {
+ pt->width[level] = width;
+ pt->height[level] = height;
+ pt->depth[level] = depth;
+ pt->nblocksx[level] = pf_get_nblocksx(&pt->block, width);
+ pt->nblocksy[level] = pf_get_nblocksy(&pt->block, height);
+ lpt->stride[level] = align(pt->nblocksx[level]*pt->block.size, 16);
+
+ lpt->level_offset[level] = buffer_size;
+
+ buffer_size += (pt->nblocksy[level] *
+ ((pt->target == PIPE_TEXTURE_CUBE) ? 6 : depth) *
+ lpt->stride[level]);
+
+ width = minify(width);
+ height = minify(height);
+ depth = minify(depth);
+ }
+
+ lpt->data = align_malloc(buffer_size, 16);
+
+ return lpt->data != NULL;
+}
+
+static boolean
+llvmpipe_displaytarget_layout(struct llvmpipe_screen *screen,
+ struct llvmpipe_texture * lpt)
+{
+ struct llvmpipe_winsys *winsys = screen->winsys;
+
+ pf_get_block(lpt->base.format, &lpt->base.block);
+ lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);
+ lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);
+
+ lpt->dt = winsys->displaytarget_create(winsys,
+ lpt->base.format,
+ lpt->base.width[0],
+ lpt->base.height[0],
+ 16,
+ &lpt->stride[0] );
+
+ return lpt->dt != NULL;
+}
+
+
+
+
+
+static struct pipe_texture *
+llvmpipe_texture_create(struct pipe_screen *_screen,
+ const struct pipe_texture *templat)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_texture *lpt = CALLOC_STRUCT(llvmpipe_texture);
+ if (!lpt)
+ return NULL;
+
+ lpt->base = *templat;
+ pipe_reference_init(&lpt->base.reference, 1);
+ lpt->base.screen = &screen->base;
+
+ /* XXX: The xlib state tracker is brain-dead and will request
+ * PIPE_FORMAT_Z16_UNORM no matter how much we tell it we don't support it.
+ */
+ if(lpt->base.format == PIPE_FORMAT_Z16_UNORM)
+ lpt->base.format = PIPE_FORMAT_Z32_UNORM;
+
+ if (lpt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_PRIMARY)) {
+ if (!llvmpipe_displaytarget_layout(screen, lpt))
+ goto fail;
+ }
+ else {
+ if (!llvmpipe_texture_layout(screen, lpt))
+ goto fail;
+ }
+
+ return &lpt->base;
+
+ fail:
+ FREE(lpt);
+ return NULL;
+}
+
+
+static struct pipe_texture *
+llvmpipe_texture_blanket(struct pipe_screen * screen,
+ const struct pipe_texture *base,
+ const unsigned *stride,
+ struct pipe_buffer *buffer)
+{
+ /* FIXME */
+#if 0
+ struct llvmpipe_texture *lpt;
+ assert(screen);
+
+ /* Only supports one type */
+ if (base->target != PIPE_TEXTURE_2D ||
+ base->last_level != 0 ||
+ base->depth[0] != 1) {
+ return NULL;
+ }
+
+ lpt = CALLOC_STRUCT(llvmpipe_texture);
+ if (!lpt)
+ return NULL;
+
+ lpt->base = *base;
+ pipe_reference_init(&lpt->base.reference, 1);
+ lpt->base.screen = screen;
+ lpt->base.nblocksx[0] = pf_get_nblocksx(&lpt->base.block, lpt->base.width[0]);
+ lpt->base.nblocksy[0] = pf_get_nblocksy(&lpt->base.block, lpt->base.height[0]);
+ lpt->stride[0] = stride[0];
+
+ pipe_buffer_reference(&lpt->buffer, buffer);
+
+ return &lpt->base;
+#else
+ return NULL;
+#endif
+}
+
+
+static void
+llvmpipe_texture_destroy(struct pipe_texture *pt)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(pt->screen);
+ struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+
+ if(lpt->dt) {
+ struct llvmpipe_winsys *winsys = screen->winsys;
+ winsys->displaytarget_destroy(winsys, lpt->dt);
+ }
+ else
+ align_free(lpt->data);
+
+ FREE(lpt);
+}
+
+
+static struct pipe_surface *
+llvmpipe_get_tex_surface(struct pipe_screen *screen,
+ struct pipe_texture *pt,
+ unsigned face, unsigned level, unsigned zslice,
+ unsigned usage)
+{
+ struct llvmpipe_texture *lpt = llvmpipe_texture(pt);
+ struct pipe_surface *ps;
+
+ assert(level <= pt->last_level);
+
+ ps = CALLOC_STRUCT(pipe_surface);
+ if (ps) {
+ pipe_reference_init(&ps->reference, 1);
+ pipe_texture_reference(&ps->texture, pt);
+ ps->format = pt->format;
+ ps->width = pt->width[level];
+ ps->height = pt->height[level];
+ ps->offset = lpt->level_offset[level];
+ ps->usage = usage;
+
+ /* Because we are llvmpipe, anything that the state tracker
+ * thought was going to be done with the GPU will actually get
+ * done with the CPU. Let's adjust the flags to take that into
+ * account.
+ */
+ if (ps->usage & PIPE_BUFFER_USAGE_GPU_WRITE) {
+ /* GPU_WRITE means "render" and that can involve reads (blending) */
+ ps->usage |= PIPE_BUFFER_USAGE_CPU_WRITE | PIPE_BUFFER_USAGE_CPU_READ;
+ }
+
+ 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. */
+ lpt->timestamp++;
+ llvmpipe_screen(screen)->timestamp++;
+ }
+
+ ps->face = face;
+ ps->level = level;
+ ps->zslice = zslice;
+
+ if (pt->target == PIPE_TEXTURE_CUBE) {
+ ps->offset += face * pt->nblocksy[level] * lpt->stride[level];
+ }
+ else if (pt->target == PIPE_TEXTURE_3D) {
+ ps->offset += zslice * pt->nblocksy[level] * lpt->stride[level];
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+ }
+ return ps;
+}
+
+
+static void
+llvmpipe_tex_surface_destroy(struct pipe_surface *surf)
+{
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For llvmpipe, nothing to do.
+ */
+ assert(surf->texture);
+ pipe_texture_reference(&surf->texture, NULL);
+ FREE(surf);
+}
+
+
+static struct pipe_transfer *
+llvmpipe_get_tex_transfer(struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned face, unsigned level, unsigned zslice,
+ enum pipe_transfer_usage usage,
+ unsigned x, unsigned y, unsigned w, unsigned h)
+{
+ struct llvmpipe_texture *lptex = llvmpipe_texture(texture);
+ struct llvmpipe_transfer *lpt;
+
+ assert(texture);
+ assert(level <= texture->last_level);
+
+ lpt = CALLOC_STRUCT(llvmpipe_transfer);
+ if (lpt) {
+ struct pipe_transfer *pt = &lpt->base;
+ pipe_texture_reference(&pt->texture, texture);
+ pt->format = texture->format;
+ pt->block = texture->block;
+ pt->x = x;
+ pt->y = y;
+ pt->width = w;
+ pt->height = h;
+ pt->nblocksx = texture->nblocksx[level];
+ pt->nblocksy = texture->nblocksy[level];
+ pt->stride = lptex->stride[level];
+ pt->usage = usage;
+ pt->face = face;
+ pt->level = level;
+ pt->zslice = zslice;
+
+ lpt->offset = lptex->level_offset[level];
+
+ if (texture->target == PIPE_TEXTURE_CUBE) {
+ lpt->offset += face * pt->nblocksy * pt->stride;
+ }
+ else if (texture->target == PIPE_TEXTURE_3D) {
+ lpt->offset += zslice * pt->nblocksy * pt->stride;
+ }
+ else {
+ assert(face == 0);
+ assert(zslice == 0);
+ }
+ return pt;
+ }
+ return NULL;
+}
+
+
+static void
+llvmpipe_tex_transfer_destroy(struct pipe_transfer *transfer)
+{
+ /* Effectively do the texture_update work here - if texture images
+ * needed post-processing to put them into hardware layout, this is
+ * where it would happen. For llvmpipe, nothing to do.
+ */
+ assert (transfer->texture);
+ pipe_texture_reference(&transfer->texture, NULL);
+ FREE(transfer);
+}
+
+
+static void *
+llvmpipe_transfer_map( struct pipe_screen *_screen,
+ struct pipe_transfer *transfer )
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ ubyte *map, *xfer_map;
+ struct llvmpipe_texture *lpt;
+
+ assert(transfer->texture);
+ lpt = llvmpipe_texture(transfer->texture);
+
+ if(lpt->dt) {
+ struct llvmpipe_winsys *winsys = screen->winsys;
+ unsigned flags = 0;
+
+ if (transfer->usage != PIPE_TRANSFER_READ) {
+ flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
+ }
+
+ if (transfer->usage != PIPE_TRANSFER_WRITE) {
+ flags |= PIPE_BUFFER_USAGE_CPU_READ;
+ }
+
+ map = winsys->displaytarget_map(winsys, lpt->dt, flags);
+ if (map == NULL)
+ return NULL;
+ }
+ else
+ map = lpt->data;
+
+ /* May want to different things here depending on read/write nature
+ * of the map:
+ */
+ if (transfer->texture && transfer->usage != PIPE_TRANSFER_READ)
+ {
+ /* Do something to notify sharing contexts of a texture change.
+ * In llvmpipe, that would mean flushing the texture cache.
+ */
+ screen->timestamp++;
+ }
+
+ xfer_map = map + llvmpipe_transfer(transfer)->offset +
+ transfer->y / transfer->block.height * transfer->stride +
+ transfer->x / transfer->block.width * transfer->block.size;
+ /*printf("map = %p xfer map = %p\n", map, xfer_map);*/
+ return xfer_map;
+}
+
+
+static void
+llvmpipe_transfer_unmap(struct pipe_screen *_screen,
+ struct pipe_transfer *transfer)
+{
+ struct llvmpipe_screen *screen = llvmpipe_screen(_screen);
+ struct llvmpipe_texture *lpt;
+
+ assert(transfer->texture);
+ lpt = llvmpipe_texture(transfer->texture);
+
+ if(lpt->dt) {
+ struct llvmpipe_winsys *winsys = screen->winsys;
+ winsys->displaytarget_unmap(winsys, lpt->dt);
+ }
+}
+
+
+void
+llvmpipe_init_texture_funcs(struct llvmpipe_context *lp)
+{
+}
+
+
+void
+llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen)
+{
+ screen->texture_create = llvmpipe_texture_create;
+ screen->texture_blanket = llvmpipe_texture_blanket;
+ screen->texture_destroy = llvmpipe_texture_destroy;
+
+ screen->get_tex_surface = llvmpipe_get_tex_surface;
+ screen->tex_surface_destroy = llvmpipe_tex_surface_destroy;
+
+ screen->get_tex_transfer = llvmpipe_get_tex_transfer;
+ screen->tex_transfer_destroy = llvmpipe_tex_transfer_destroy;
+ screen->transfer_map = llvmpipe_transfer_map;
+ screen->transfer_unmap = llvmpipe_transfer_unmap;
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_texture.h b/src/gallium/drivers/llvmpipe/lp_texture.h
new file mode 100644
index 0000000000..00a20763e4
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_texture.h
@@ -0,0 +1,90 @@
+/**************************************************************************
+ *
+ * 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 LP_TEXTURE_H
+#define LP_TEXTURE_H
+
+
+#include "pipe/p_state.h"
+
+
+struct pipe_context;
+struct pipe_screen;
+struct llvmpipe_context;
+struct llvmpipe_displaytarget;
+
+struct llvmpipe_texture
+{
+ struct pipe_texture base;
+
+ unsigned long level_offset[PIPE_MAX_TEXTURE_LEVELS];
+ unsigned stride[PIPE_MAX_TEXTURE_LEVELS];
+
+ /**
+ * Display target, for textures with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET
+ * usage.
+ */
+ struct llvmpipe_displaytarget *dt;
+
+ /**
+ * Malloc'ed data for regular textures, or a mapping to dt above.
+ */
+ void *data;
+
+ unsigned timestamp;
+};
+
+struct llvmpipe_transfer
+{
+ struct pipe_transfer base;
+
+ unsigned long offset;
+};
+
+
+/** cast wrappers */
+static INLINE struct llvmpipe_texture *
+llvmpipe_texture(struct pipe_texture *pt)
+{
+ return (struct llvmpipe_texture *) pt;
+}
+
+static INLINE struct llvmpipe_transfer *
+llvmpipe_transfer(struct pipe_transfer *pt)
+{
+ return (struct llvmpipe_transfer *) pt;
+}
+
+
+extern void
+llvmpipe_init_texture_funcs( struct llvmpipe_context *llvmpipe );
+
+extern void
+llvmpipe_init_screen_texture_funcs(struct pipe_screen *screen);
+
+
+#endif /* LP_TEXTURE */
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.c b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
new file mode 100644
index 0000000000..2e576e6039
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.c
@@ -0,0 +1,302 @@
+/**************************************************************************
+ *
+ * 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_math.h"
+#include "util/u_tile.h"
+#include "util/u_rect.h"
+#include "lp_context.h"
+#include "lp_surface.h"
+#include "lp_texture.h"
+#include "lp_tile_soa.h"
+#include "lp_tile_cache.h"
+
+
+struct llvmpipe_tile_cache *
+lp_create_tile_cache( struct pipe_screen *screen )
+{
+ struct llvmpipe_tile_cache *tc;
+
+ tc = CALLOC_STRUCT( llvmpipe_tile_cache );
+ if(!tc)
+ return NULL;
+
+ tc->screen = screen;
+
+ return tc;
+}
+
+
+void
+lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc)
+{
+ struct pipe_screen *screen;
+ unsigned x, y;
+
+ for (y = 0; y < MAX_HEIGHT; y += TILE_SIZE) {
+ for (x = 0; x < MAX_WIDTH; x += TILE_SIZE) {
+ struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
+
+ if(tile->color)
+ align_free(tile->color);
+ }
+ }
+
+ if (tc->transfer) {
+ screen = tc->transfer->texture->screen;
+ screen->tex_transfer_destroy(tc->transfer);
+ }
+
+ FREE( tc );
+}
+
+
+/**
+ * Specify the surface to cache.
+ */
+void
+lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc,
+ struct pipe_surface *ps)
+{
+ if (tc->transfer) {
+ struct pipe_screen *screen = tc->transfer->texture->screen;
+
+ if (ps == tc->surface)
+ return;
+
+ if (tc->transfer_map) {
+ screen->transfer_unmap(screen, tc->transfer);
+ tc->transfer_map = NULL;
+ }
+
+ screen->tex_transfer_destroy(tc->transfer);
+ tc->transfer = NULL;
+ }
+
+ tc->surface = ps;
+
+ if (ps) {
+ struct pipe_screen *screen = ps->texture->screen;
+ unsigned x, y;
+
+ tc->transfer = screen->get_tex_transfer(screen, ps->texture, ps->face,
+ ps->level, ps->zslice,
+ PIPE_TRANSFER_READ_WRITE,
+ 0, 0, ps->width, ps->height);
+
+ for (y = 0; y < ps->height; y += TILE_SIZE) {
+ for (x = 0; x < ps->width; x += TILE_SIZE) {
+ struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
+
+ tile->status = LP_TILE_STATUS_UNDEFINED;
+
+ if(!tile->color)
+ tile->color = align_malloc( TILE_SIZE*TILE_SIZE*NUM_CHANNELS, 16 );
+ }
+ }
+ }
+}
+
+
+/**
+ * Return the transfer being cached.
+ */
+struct pipe_surface *
+lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc)
+{
+ return tc->surface;
+}
+
+
+void
+lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc)
+{
+ if (tc->transfer && !tc->transfer_map)
+ tc->transfer_map = tc->screen->transfer_map(tc->screen, tc->transfer);
+}
+
+
+void
+lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc)
+{
+ if (tc->transfer_map) {
+ tc->screen->transfer_unmap(tc->screen, tc->transfer);
+ tc->transfer_map = NULL;
+ }
+}
+
+
+/**
+ * Set a tile to a solid color.
+ */
+static void
+clear_tile(struct llvmpipe_cached_tile *tile,
+ uint8_t clear_color[4])
+{
+ if (clear_color[0] == clear_color[1] &&
+ clear_color[1] == clear_color[2] &&
+ clear_color[2] == clear_color[3]) {
+ memset(tile->color, clear_color[0], TILE_SIZE * TILE_SIZE * 4);
+ }
+ else {
+ uint x, y, chan;
+ for (y = 0; y < TILE_SIZE; y++)
+ for (x = 0; x < TILE_SIZE; x++)
+ for (chan = 0; chan < 4; ++chan)
+ TILE_PIXEL(tile->color, x, y, chan) = clear_color[chan];
+ }
+}
+
+
+/**
+ * Flush the tile cache: write all dirty tiles back to the transfer.
+ * any tiles "flagged" as cleared will be "really" cleared.
+ */
+void
+lp_flush_tile_cache(struct llvmpipe_tile_cache *tc)
+{
+ struct pipe_transfer *pt = tc->transfer;
+ unsigned x, y;
+
+ if(!pt)
+ return;
+
+ /* push the tile to all positions marked as clear */
+ for (y = 0; y < pt->height; y += TILE_SIZE) {
+ for (x = 0; x < pt->width; x += TILE_SIZE) {
+ struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
+
+ switch(tile->status) {
+ case LP_TILE_STATUS_UNDEFINED:
+ break;
+
+ case LP_TILE_STATUS_CLEAR: {
+ /**
+ * Actually clear the tiles which were flagged as being in a clear state.
+ */
+
+ struct pipe_screen *screen = pt->texture->screen;
+ unsigned tw = TILE_SIZE;
+ unsigned th = TILE_SIZE;
+ void *dst;
+
+ if (pipe_clip_tile(x, y, &tw, &th, pt))
+ continue;
+
+ dst = screen->transfer_map(screen, pt);
+ assert(dst);
+ if(!dst)
+ continue;
+
+ util_fill_rect(dst, &pt->block, pt->stride,
+ x, y, tw, th,
+ 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;
+ }
+ }
+ }
+}
+
+
+/**
+ * Get a tile from the cache.
+ * \param x, y position of tile, in pixels
+ */
+void *
+lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
+ unsigned x, unsigned y )
+{
+ struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
+ struct pipe_transfer *pt = tc->transfer;
+
+ switch(tile->status) {
+ case LP_TILE_STATUS_CLEAR:
+ /* don't get tile from framebuffer, just clear it */
+ clear_tile(tile, tc->clear_color);
+ tile->status = LP_TILE_STATUS_DEFINED;
+ break;
+
+ case LP_TILE_STATUS_UNDEFINED:
+ /* get new tile data from transfer */
+ lp_get_tile_rgba_soa(pt, x & ~(TILE_SIZE - 1), y & ~(TILE_SIZE - 1), tile->color);
+ tile->status = LP_TILE_STATUS_DEFINED;
+ break;
+
+ case LP_TILE_STATUS_DEFINED:
+ /* nothing to do */
+ break;
+ }
+
+ return tile->color;
+}
+
+
+/**
+ * When a whole surface is being cleared to a value we can avoid
+ * fetching tiles above.
+ * Save the color and set a 'clearflag' for each tile of the screen.
+ */
+void
+lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba,
+ uint clearValue)
+{
+ struct pipe_transfer *pt = tc->transfer;
+ const unsigned w = pt->width;
+ const unsigned h = pt->height;
+ unsigned x, y, chan;
+
+ for(chan = 0; chan < 4; ++chan)
+ tc->clear_color[chan] = float_to_ubyte(rgba[chan]);
+
+ tc->clear_val = clearValue;
+
+ /* 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) {
+ struct llvmpipe_cached_tile *tile = &tc->entries[y/TILE_SIZE][x/TILE_SIZE];
+ tile->status = LP_TILE_STATUS_CLEAR;
+ }
+ }
+}
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_cache.h b/src/gallium/drivers/llvmpipe/lp_tile_cache.h
new file mode 100644
index 0000000000..6d8ba5ece7
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_cache.h
@@ -0,0 +1,106 @@
+/**************************************************************************
+ *
+ * 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 LP_TILE_CACHE_H
+#define LP_TILE_CACHE_H
+
+
+#include "pipe/p_compiler.h"
+#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 */
+};
+
+
+extern struct llvmpipe_tile_cache *
+lp_create_tile_cache( struct pipe_screen *screen );
+
+extern void
+lp_destroy_tile_cache(struct llvmpipe_tile_cache *tc);
+
+extern void
+lp_tile_cache_set_surface(struct llvmpipe_tile_cache *tc,
+ struct pipe_surface *lps);
+
+extern struct pipe_surface *
+lp_tile_cache_get_surface(struct llvmpipe_tile_cache *tc);
+
+extern void
+lp_tile_cache_map_transfers(struct llvmpipe_tile_cache *tc);
+
+extern void
+lp_tile_cache_unmap_transfers(struct llvmpipe_tile_cache *tc);
+
+extern void
+lp_flush_tile_cache(struct llvmpipe_tile_cache *tc);
+
+extern void
+lp_tile_cache_clear(struct llvmpipe_tile_cache *tc, const float *rgba,
+ uint clearValue);
+
+extern void *
+lp_get_cached_tile(struct llvmpipe_tile_cache *tc,
+ unsigned x, unsigned y );
+
+
+#endif /* LP_TILE_CACHE_H */
+
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.c b/src/gallium/drivers/llvmpipe/lp_tile_soa.c
new file mode 100644
index 0000000000..4e4ccb31cc
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.c
@@ -0,0 +1,931 @@
+/**************************************************************************
+ *
+ * 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.
+ *
+ **************************************************************************/
+
+/**
+ * RGBA/float tile get/put functions.
+ * Usable both by drivers and state trackers.
+ */
+
+
+#include "pipe/p_defines.h"
+#include "pipe/p_inlines.h"
+
+#include "util/u_math.h"
+#include "util/u_memory.h"
+#include "util/u_rect.h"
+#include "util/u_tile.h"
+#include "lp_tile_cache.h"
+#include "lp_tile_soa.h"
+
+
+const unsigned char
+tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH] = {
+ { 0, 1, 4, 5, 8, 9, 12, 13},
+ { 2, 3, 6, 7, 10, 11, 14, 15}
+};
+
+
+
+/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
+
+static void
+a8r8g8b8_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const unsigned pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = (pixel >> 16) & 0xff;
+ TILE_PIXEL(p, j, i, 1) = (pixel >> 8) & 0xff;
+ TILE_PIXEL(p, j, i, 2) = (pixel >> 0) & 0xff;
+ TILE_PIXEL(p, j, i, 3) = (pixel >> 24) & 0xff;
+ }
+ }
+}
+
+
+static void
+a8r8g8b8_put_tile_rgba(unsigned *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b, a;
+ r = TILE_PIXEL(p, j, i, 0);
+ g = TILE_PIXEL(p, j, i, 1);
+ b = TILE_PIXEL(p, j, i, 2);
+ a = TILE_PIXEL(p, j, i, 3);
+ *dst++ = (a << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_A8R8G8B8_UNORM ***/
+
+static void
+x8r8g8b8_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const unsigned pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = (pixel >> 16) & 0xff;
+ TILE_PIXEL(p, j, i, 1) = (pixel >> 8) & 0xff;
+ TILE_PIXEL(p, j, i, 2) = (pixel >> 0) & 0xff;
+ TILE_PIXEL(p, j, i, 3) = 0xff;
+ }
+ }
+}
+
+
+static void
+x8r8g8b8_put_tile_rgba(unsigned *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b;
+ r = TILE_PIXEL(p, j, i, 0);
+ g = TILE_PIXEL(p, j, i, 1);
+ b = TILE_PIXEL(p, j, i, 2);
+ *dst++ = (0xff << 24) | (r << 16) | (g << 8) | b;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_B8G8R8A8_UNORM ***/
+
+static void
+b8g8r8a8_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const unsigned pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = (pixel >> 8) & 0xff;
+ TILE_PIXEL(p, j, i, 1) = (pixel >> 16) & 0xff;
+ TILE_PIXEL(p, j, i, 2) = (pixel >> 24) & 0xff;
+ TILE_PIXEL(p, j, i, 3) = (pixel >> 0) & 0xff;
+ }
+ }
+}
+
+
+static void
+b8g8r8a8_put_tile_rgba(unsigned *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b, a;
+ r = TILE_PIXEL(p, j, i, 0);
+ g = TILE_PIXEL(p, j, i, 1);
+ b = TILE_PIXEL(p, j, i, 2);
+ a = TILE_PIXEL(p, j, i, 3);
+ *dst++ = (b << 24) | (g << 16) | (r << 8) | a;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_A1R5G5B5_UNORM ***/
+
+static void
+a1r5g5b5_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const ushort pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = ((pixel >> 10) & 0x1f) * 255 / 31;
+ TILE_PIXEL(p, j, i, 1) = ((pixel >> 5) & 0x1f) * 255 / 31;
+ TILE_PIXEL(p, j, i, 2) = ((pixel ) & 0x1f) * 255 / 31;
+ TILE_PIXEL(p, j, i, 3) = ((pixel >> 15) ) * 255;
+ }
+ }
+}
+
+
+static void
+a1r5g5b5_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b, a;
+ r = TILE_PIXEL(p, j, i, 0);
+ g = TILE_PIXEL(p, j, i, 1);
+ b = TILE_PIXEL(p, j, i, 2);
+ a = TILE_PIXEL(p, j, i, 3);
+ r = r >> 3; /* 5 bits */
+ g = g >> 3; /* 5 bits */
+ b = b >> 3; /* 5 bits */
+ a = a >> 7; /* 1 bit */
+ *dst++ = (a << 15) | (r << 10) | (g << 5) | b;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_A4R4G4B4_UNORM ***/
+
+static void
+a4r4g4b4_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const ushort pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = ((pixel >> 8) & 0xf) * 255 / 15;
+ TILE_PIXEL(p, j, i, 1) = ((pixel >> 4) & 0xf) * 255 / 15;
+ TILE_PIXEL(p, j, i, 2) = ((pixel ) & 0xf) * 255 / 15;
+ TILE_PIXEL(p, j, i, 3) = ((pixel >> 12) ) * 255 / 15;
+ }
+ }
+}
+
+
+static void
+a4r4g4b4_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, g, b, a;
+ r = TILE_PIXEL(p, j, i, 0);
+ g = TILE_PIXEL(p, j, i, 1);
+ b = TILE_PIXEL(p, j, i, 2);
+ a = TILE_PIXEL(p, j, i, 3);
+ r >>= 4;
+ g >>= 4;
+ b >>= 4;
+ a >>= 4;
+ *dst++ = (a << 12) | (r << 16) | (g << 4) | b;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_R5G6B5_UNORM ***/
+
+static void
+r5g6b5_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ const ushort pixel = *src++;
+ TILE_PIXEL(p, j, i, 0) = ((pixel >> 11) & 0x1f) * 255 / 31;
+ TILE_PIXEL(p, j, i, 1) = ((pixel >> 5) & 0x3f) * 255 / 63;
+ TILE_PIXEL(p, j, i, 2) = ((pixel ) & 0x1f) * 255 / 31;
+ TILE_PIXEL(p, j, i, 3) = 255;
+ }
+ }
+}
+
+
+static void
+r5g6b5_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ uint r = (uint) TILE_PIXEL(p, j, i, 0) * 31 / 255;
+ uint g = (uint) TILE_PIXEL(p, j, i, 1) * 63 / 255;
+ uint b = (uint) TILE_PIXEL(p, j, i, 2) * 31 / 255;
+ *dst++ = (r << 11) | (g << 5) | (b);
+ }
+ }
+}
+
+
+
+/*** PIPE_FORMAT_Z16_UNORM ***/
+
+/**
+ * Return each Z value as four floats in [0,1].
+ */
+static void
+z16_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ const float scale = 1.0f / 65535.0f;
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = *src++ * scale;
+ }
+ }
+}
+
+
+
+
+/*** PIPE_FORMAT_L8_UNORM ***/
+
+static void
+l8_get_tile_rgba(const ubyte *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, src++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) = *src;
+ TILE_PIXEL(p, j, i, 3) = 255;
+ }
+ }
+}
+
+
+static void
+l8_put_tile_rgba(ubyte *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r;
+ r = TILE_PIXEL(p, j, i, 0);
+ *dst++ = (ubyte) r;
+ }
+ }
+}
+
+
+
+/*** PIPE_FORMAT_A8_UNORM ***/
+
+static void
+a8_get_tile_rgba(const ubyte *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, src++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) = 0;
+ TILE_PIXEL(p, j, i, 3) = *src;
+ }
+ }
+}
+
+
+static void
+a8_put_tile_rgba(ubyte *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned a;
+ a = TILE_PIXEL(p, j, i, 3);
+ *dst++ = (ubyte) a;
+ }
+ }
+}
+
+
+
+/*** PIPE_FORMAT_R16_SNORM ***/
+
+static void
+r16_get_tile_rgba(const short *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, src++) {
+ TILE_PIXEL(p, j, i, 0) = MAX2(src[0] >> 7, 0);
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) = 0;
+ TILE_PIXEL(p, j, i, 3) = 255;
+ }
+ }
+}
+
+
+static void
+r16_put_tile_rgba(short *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, dst++) {
+ dst[0] = TILE_PIXEL(p, j, i, 0) << 7;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_R16G16B16A16_SNORM ***/
+
+static void
+r16g16b16a16_get_tile_rgba(const short *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, src += 4) {
+ TILE_PIXEL(p, j, i, 0) = src[0] >> 8;
+ TILE_PIXEL(p, j, i, 1) = src[1] >> 8;
+ TILE_PIXEL(p, j, i, 2) = src[2] >> 8;
+ TILE_PIXEL(p, j, i, 3) = src[3] >> 8;
+ }
+ }
+}
+
+
+static void
+r16g16b16a16_put_tile_rgba(short *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, dst += 4) {
+ dst[0] = TILE_PIXEL(p, j, i, 0) << 8;
+ dst[1] = TILE_PIXEL(p, j, i, 1) << 8;
+ dst[2] = TILE_PIXEL(p, j, i, 2) << 8;
+ dst[3] = TILE_PIXEL(p, j, i, 3) << 8;
+ }
+ }
+}
+
+
+
+/*** PIPE_FORMAT_I8_UNORM ***/
+
+static void
+i8_get_tile_rgba(const ubyte *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++, src++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = *src;
+ }
+ }
+}
+
+
+static void
+i8_put_tile_rgba(ubyte *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r;
+ r = TILE_PIXEL(p, j, i, 0);
+ *dst++ = (ubyte) r;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_A8L8_UNORM ***/
+
+static void
+a8l8_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ ushort ra = *src++;
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) = ra & 0xff;
+ TILE_PIXEL(p, j, i, 3) = ra >> 8;
+ }
+ }
+}
+
+
+static void
+a8l8_put_tile_rgba(ushort *dst,
+ unsigned w, unsigned h,
+ const uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ unsigned r, a;
+ r = TILE_PIXEL(p, j, i, 0);
+ a = TILE_PIXEL(p, j, i, 3);
+ *dst++ = (a << 8) | r;
+ }
+ }
+}
+
+
+
+
+/*** PIPE_FORMAT_Z32_UNORM ***/
+
+/**
+ * Return each Z value as four floats in [0,1].
+ */
+static void
+z32_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ const double scale = 1.0 / (double) 0xffffffff;
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = (float) (*src++ * scale);
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_S8Z24_UNORM ***/
+
+/**
+ * Return Z component as four float in [0,1]. Stencil part ignored.
+ */
+static void
+s8z24_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ const double scale = 1.0 / ((1 << 24) - 1);
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = (float) (scale * (*src++ & 0xffffff));
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_Z24S8_UNORM ***/
+
+/**
+ * Return Z component as four float in [0,1]. Stencil part ignored.
+ */
+static void
+z24s8_get_tile_rgba(const unsigned *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ const double scale = 1.0 / ((1 << 24) - 1);
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = (float) (scale * (*src++ >> 8));
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_Z32_FLOAT ***/
+
+/**
+ * Return each Z value as four floats in [0,1].
+ */
+static void
+z32f_get_tile_rgba(const float *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = *src++;
+ }
+ }
+}
+
+
+/*** PIPE_FORMAT_YCBCR / PIPE_FORMAT_YCBCR_REV ***/
+
+/**
+ * Convert YCbCr (or YCrCb) to RGBA.
+ */
+static void
+ycbcr_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p,
+ boolean rev)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ /* do two texels at a time */
+ for (j = 0; j < (w & ~1); j += 2, src += 2) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ const ubyte y1 = (t1 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ TILE_PIXEL(p, j, i, 0) = r;
+ TILE_PIXEL(p, j, i, 1) = g;
+ TILE_PIXEL(p, j, i, 2) = b;
+ TILE_PIXEL(p, j, i, 3) = 255;
+
+ /* odd pixel: use y1,cr,cb */
+ r = 1.164f * (y1-16) + 1.596f * (cr-128);
+ g = 1.164f * (y1-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y1-16) + 2.018f * (cb-128);
+ TILE_PIXEL(p, j + 1, i, 0) = r;
+ TILE_PIXEL(p, j + 1, i, 1) = g;
+ TILE_PIXEL(p, j + 1, i, 2) = b;
+ TILE_PIXEL(p, j + 1, i, 3) = 255;
+ }
+ /* do the last texel */
+ if (w & 1) {
+ const ushort t0 = src[0];
+ const ushort t1 = src[1];
+ const ubyte y0 = (t0 >> 8) & 0xff; /* luminance */
+ ubyte cb, cr;
+ float r, g, b;
+
+ if (rev) {
+ cb = t1 & 0xff; /* chroma U */
+ cr = t0 & 0xff; /* chroma V */
+ }
+ else {
+ cb = t0 & 0xff; /* chroma U */
+ cr = t1 & 0xff; /* chroma V */
+ }
+
+ /* even pixel: y0,cr,cb */
+ r = 1.164f * (y0-16) + 1.596f * (cr-128);
+ g = 1.164f * (y0-16) - 0.813f * (cr-128) - 0.391f * (cb-128);
+ b = 1.164f * (y0-16) + 2.018f * (cb-128);
+ TILE_PIXEL(p, j, i, 0) = r;
+ TILE_PIXEL(p, j, i, 1) = g;
+ TILE_PIXEL(p, j, i, 2) = b;
+ TILE_PIXEL(p, j, i, 3) = 255;
+ }
+ }
+}
+
+
+static void
+fake_get_tile_rgba(const ushort *src,
+ unsigned w, unsigned h,
+ uint8_t *p)
+{
+ unsigned i, j;
+
+ for (i = 0; i < h; i++) {
+ for (j = 0; j < w; j++) {
+ TILE_PIXEL(p, j, i, 0) =
+ TILE_PIXEL(p, j, i, 1) =
+ TILE_PIXEL(p, j, i, 2) =
+ TILE_PIXEL(p, j, i, 3) = (i ^ j) & 1 ? 255 : 0;
+ }
+ }
+}
+
+
+static void
+lp_tile_raw_to_rgba_soa(enum pipe_format format,
+ void *src,
+ uint w, uint h,
+ uint8_t *p)
+{
+ switch (format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ a8r8g8b8_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ x8r8g8b8_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ b8g8r8a8_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ a1r5g5b5_get_tile_rgba((ushort *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ a4r4g4b4_get_tile_rgba((ushort *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ r5g6b5_get_tile_rgba((ushort *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_L8_UNORM:
+ l8_get_tile_rgba((ubyte *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_A8_UNORM:
+ a8_get_tile_rgba((ubyte *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_I8_UNORM:
+ i8_get_tile_rgba((ubyte *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_A8L8_UNORM:
+ a8l8_get_tile_rgba((ushort *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_R16_SNORM:
+ r16_get_tile_rgba((short *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ r16g16b16a16_get_tile_rgba((short *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_Z16_UNORM:
+ z16_get_tile_rgba((ushort *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_Z32_UNORM:
+ z32_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ s8z24_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ z24s8_get_tile_rgba((unsigned *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_Z32_FLOAT:
+ z32f_get_tile_rgba((float *) src, w, h, p);
+ break;
+ case PIPE_FORMAT_YCBCR:
+ ycbcr_get_tile_rgba((ushort *) src, w, h, p, FALSE);
+ break;
+ case PIPE_FORMAT_YCBCR_REV:
+ ycbcr_get_tile_rgba((ushort *) src, w, h, p, TRUE);
+ break;
+ default:
+ debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(format));
+ fake_get_tile_rgba(src, w, h, p);
+ }
+}
+
+
+void
+lp_get_tile_rgba_soa(struct pipe_transfer *pt,
+ uint x, uint y,
+ uint8_t *p)
+{
+ uint w = TILE_SIZE, h = TILE_SIZE;
+ void *packed;
+
+ if (pipe_clip_tile(x, y, &w, &h, pt))
+ return;
+
+ packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
+
+ if (!packed)
+ return;
+
+ if(pt->format == PIPE_FORMAT_YCBCR || pt->format == PIPE_FORMAT_YCBCR_REV)
+ assert((x & 1) == 0);
+
+ pipe_get_tile_raw(pt, x, y, w, h, packed, 0);
+
+ lp_tile_raw_to_rgba_soa(pt->format, packed, w, h, p);
+
+ FREE(packed);
+}
+
+
+void
+lp_put_tile_rgba_soa(struct pipe_transfer *pt,
+ uint x, uint y,
+ const uint8_t *p)
+{
+ uint w = TILE_SIZE, h = TILE_SIZE;
+ void *packed;
+
+ if (pipe_clip_tile(x, y, &w, &h, pt))
+ return;
+
+ packed = MALLOC(pf_get_nblocks(&pt->block, w, h) * pt->block.size);
+
+ if (!packed)
+ return;
+
+ switch (pt->format) {
+ case PIPE_FORMAT_A8R8G8B8_UNORM:
+ a8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_X8R8G8B8_UNORM:
+ x8r8g8b8_put_tile_rgba((unsigned *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_B8G8R8A8_UNORM:
+ b8g8r8a8_put_tile_rgba((unsigned *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_A1R5G5B5_UNORM:
+ a1r5g5b5_put_tile_rgba((ushort *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_R5G6B5_UNORM:
+ r5g6b5_put_tile_rgba((ushort *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_R8G8B8A8_UNORM:
+ assert(0);
+ break;
+ case PIPE_FORMAT_A4R4G4B4_UNORM:
+ a4r4g4b4_put_tile_rgba((ushort *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_L8_UNORM:
+ l8_put_tile_rgba((ubyte *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_A8_UNORM:
+ a8_put_tile_rgba((ubyte *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_I8_UNORM:
+ i8_put_tile_rgba((ubyte *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_A8L8_UNORM:
+ a8l8_put_tile_rgba((ushort *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_R16_SNORM:
+ r16_put_tile_rgba((short *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_R16G16B16A16_SNORM:
+ r16g16b16a16_put_tile_rgba((short *) packed, w, h, p);
+ break;
+ case PIPE_FORMAT_Z16_UNORM:
+ /*z16_put_tile_rgba((ushort *) packed, w, h, p);*/
+ break;
+ case PIPE_FORMAT_Z32_UNORM:
+ /*z32_put_tile_rgba((unsigned *) packed, w, h, p);*/
+ break;
+ case PIPE_FORMAT_S8Z24_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ /*s8z24_put_tile_rgba((unsigned *) packed, w, h, p);*/
+ break;
+ case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
+ /*z24s8_put_tile_rgba((unsigned *) packed, w, h, p);*/
+ break;
+ default:
+ debug_printf("%s: unsupported format %s\n", __FUNCTION__, pf_name(pt->format));
+ }
+
+ pipe_put_tile_raw(pt, x, y, w, h, packed, 0);
+
+ FREE(packed);
+}
+
+
diff --git a/src/gallium/drivers/llvmpipe/lp_tile_soa.h b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
new file mode 100644
index 0000000000..3d8c703b73
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_tile_soa.h
@@ -0,0 +1,81 @@
+/**************************************************************************
+ *
+ * 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 LP_TILE_SOA_H
+#define LP_TILE_SOA_H
+
+#include "pipe/p_compiler.h"
+#include "tgsi/tgsi_exec.h" // for NUM_CHANNELS
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct pipe_transfer;
+
+
+/**
+ * Cache tile size (width and height). This needs to be a power of two.
+ */
+#define TILE_SIZE 64
+
+
+#define TILE_VECTOR_HEIGHT 2
+#define TILE_VECTOR_WIDTH 8
+
+extern const unsigned char
+tile_offset[TILE_VECTOR_HEIGHT][TILE_VECTOR_WIDTH];
+
+#define TILE_C_STRIDE (TILE_VECTOR_HEIGHT*TILE_VECTOR_WIDTH)
+#define TILE_X_STRIDE (NUM_CHANNELS*TILE_C_STRIDE)
+#define TILE_Y_STRIDE (TILE_VECTOR_HEIGHT*TILE_SIZE*NUM_CHANNELS)
+
+#define TILE_PIXEL(_p, _x, _y, _c) \
+ ((_p)[((_y)/TILE_VECTOR_HEIGHT)*TILE_Y_STRIDE + \
+ ((_x)/TILE_VECTOR_WIDTH)*TILE_X_STRIDE + \
+ (_c)*TILE_C_STRIDE + \
+ tile_offset[(_y) % TILE_VECTOR_HEIGHT][(_x) % TILE_VECTOR_WIDTH]])
+
+
+void
+lp_get_tile_rgba_soa(struct pipe_transfer *pt,
+ uint x, uint y,
+ uint8_t *p);
+
+void
+lp_put_tile_rgba_soa(struct pipe_transfer *pt,
+ uint x, uint y,
+ const uint8_t *p);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/gallium/drivers/llvmpipe/lp_winsys.h b/src/gallium/drivers/llvmpipe/lp_winsys.h
new file mode 100644
index 0000000000..595481c2cb
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/lp_winsys.h
@@ -0,0 +1,128 @@
+/**************************************************************************
+ *
+ * Copyright 2007-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.
+ *
+ **************************************************************************/
+
+/**
+ * @file
+ * llvmpipe public interface.
+ */
+
+
+#ifndef LP_WINSYS_H
+#define LP_WINSYS_H
+
+
+#include "pipe/p_compiler.h" // for boolean
+#include "pipe/p_format.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+struct pipe_screen;
+struct pipe_context;
+
+
+/**
+ * Opaque pointer.
+ */
+struct llvmpipe_displaytarget;
+
+
+/**
+ * This is the interface that llvmpipe expects any window system
+ * hosting it to implement.
+ *
+ * llvmpipe is for the most part a self sufficient driver. The only thing it
+ * does not know is how to display a surface.
+ */
+struct llvmpipe_winsys
+{
+ void
+ (*destroy)( struct llvmpipe_winsys *ws );
+
+ boolean
+ (*is_displaytarget_format_supported)( struct llvmpipe_winsys *ws,
+ enum pipe_format format );
+
+ /**
+ * Allocate storage for a render target.
+ *
+ * Often surfaces which are meant to be blitted to the front screen (i.e.,
+ * display targets) must be allocated with special characteristics, memory
+ * pools, or obtained directly from the windowing system.
+ *
+ * This callback is invoked by the pipe_screen when creating a texture marked
+ * with the PIPE_TEXTURE_USAGE_DISPLAY_TARGET flag to get the underlying
+ * storage.
+ */
+ struct llvmpipe_displaytarget *
+ (*displaytarget_create)( struct llvmpipe_winsys *ws,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride );
+
+ void *
+ (*displaytarget_map)( struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt,
+ unsigned flags );
+
+ void
+ (*displaytarget_unmap)( struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt );
+
+ /**
+ * @sa pipe_screen:flush_frontbuffer.
+ *
+ * This call will likely become asynchronous eventually.
+ */
+ void
+ (*displaytarget_display)( struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt,
+ void *context_private );
+
+ void
+ (*displaytarget_destroy)( struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt );
+};
+
+
+struct pipe_context *
+llvmpipe_create( struct pipe_screen * );
+
+
+struct pipe_screen *
+llvmpipe_create_screen( struct llvmpipe_winsys * );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* LP_WINSYS_H */
diff --git a/src/gallium/drivers/llvmpipe/sp2lp.sh b/src/gallium/drivers/llvmpipe/sp2lp.sh
new file mode 100755
index 0000000000..c45a81ce3c
--- /dev/null
+++ b/src/gallium/drivers/llvmpipe/sp2lp.sh
@@ -0,0 +1,34 @@
+#!/bin/sh
+#
+# Port changes from softpipe to llvmpipe. Invoke as
+#
+# sp2lp.sh <commit>
+#
+# Note that this will only affect llvmpipe -- you still need to actually
+# cherry-pick/merge the softpipe changes themselves if they affect directories
+# outside src/gallium/drivers/softpipe
+
+git format-patch \
+ --keep-subject \
+ --relative=src/gallium/drivers/softpipe \
+ --src-prefix=a/src/gallium/drivers/llvmpipe/ \
+ --dst-prefix=b/src/gallium/drivers/llvmpipe/ \
+ --stdout "$1^1..$1" \
+| sed \
+ -e 's/\<softpipe\>/llvmpipe/g' \
+ -e 's/\<sp\>/lp/g' \
+ -e 's/\<softpipe_/llvmpipe_/g' \
+ -e 's/\<sp_/lp_/g' \
+ -e 's/\<SP_/LP_/g' \
+ -e 's/\<SOFTPIPE_/LLVMPIPE_/g' \
+ -e 's/\<spt\>/lpt/g' \
+ -e 's/\<sps\>/lps/g' \
+ -e 's/\<spfs\>/lpfs/g' \
+ -e 's/\<sptex\>/lptex/g' \
+ -e 's/\<setup_\(point\|line\|tri\)\>/llvmpipe_\0/g' \
+ -e 's/\<llvmpipe_cached_tile\>/llvmpipe_cached_tex_tile/g' \
+ -e 's/_get_cached_tile_tex\>/_get_cached_tex_tile/g' \
+ -e 's/\<TILE_SIZE\>/TEX_TILE_SIZE/g' \
+ -e 's/\<tile_address\>/tex_tile_address/g' \
+ -e 's/\<tile->data\.color\>/tile->color/g' \
+| patch -p1
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c
index 832366e646..e4cf91c005 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.c
+++ b/src/gallium/drivers/nouveau/nouveau_screen.c
@@ -4,6 +4,8 @@
#include <util/u_memory.h>
+#include <errno.h>
+
#include "nouveau/nouveau_bo.h"
#include "nouveau_winsys.h"
#include "nouveau_screen.h"
@@ -141,12 +143,13 @@ nouveau_screen_bo_map_range(struct pipe_screen *pscreen, struct pipe_buffer *pb,
unsigned offset, unsigned length, unsigned usage)
{
struct nouveau_bo *bo = nouveau_bo(pb);
+ uint32_t flags = nouveau_screen_map_flags(usage);
int ret;
- ret = nouveau_bo_map_range(bo, offset, length,
- nouveau_screen_map_flags(usage));
+ ret = nouveau_bo_map_range(bo, offset, length, flags);
if (ret) {
- debug_printf("map_range failed: %d\n", ret);
+ if (!(flags & NOUVEAU_BO_NOWAIT) || ret != -EBUSY)
+ debug_printf("map_range failed: %d\n", ret);
return NULL;
}
diff --git a/src/gallium/drivers/nouveau/nouveau_screen.h b/src/gallium/drivers/nouveau/nouveau_screen.h
index 9968b07896..ebfc67ad1c 100644
--- a/src/gallium/drivers/nouveau/nouveau_screen.h
+++ b/src/gallium/drivers/nouveau/nouveau_screen.h
@@ -22,4 +22,15 @@ nouveau_bo(struct pipe_buffer *pb)
int nouveau_screen_init(struct nouveau_screen *, struct nouveau_device *);
void nouveau_screen_fini(struct nouveau_screen *);
+struct nouveau_miptree {
+ struct pipe_texture base;
+ struct nouveau_bo *bo;
+};
+
+static inline struct nouveau_miptree *
+nouveau_miptree(struct pipe_texture *pt)
+{
+ return (struct nouveau_miptree *)pt;
+}
+
#endif
diff --git a/src/gallium/drivers/nv04/nv04_screen.c b/src/gallium/drivers/nv04/nv04_screen.c
index ff2febb668..170ce3eb7e 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/nv04/nv04_surface_2d.c b/src/gallium/drivers/nv04/nv04_surface_2d.c
index f315cf54f0..f88e138c79 100644
--- a/src/gallium/drivers/nv04/nv04_surface_2d.c
+++ b/src/gallium/drivers/nv04/nv04_surface_2d.c
@@ -15,11 +15,13 @@ nv04_surface_format(enum pipe_format format)
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y8;
case PIPE_FORMAT_R16_SNORM:
case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
return NV04_CONTEXT_SURFACES_2D_FORMAT_R5G6B5;
case PIPE_FORMAT_X8R8G8B8_UNORM:
case PIPE_FORMAT_A8R8G8B8_UNORM:
return NV04_CONTEXT_SURFACES_2D_FORMAT_A8R8G8B8;
case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
return NV04_CONTEXT_SURFACES_2D_FORMAT_Y32;
default:
return -1;
@@ -33,9 +35,11 @@ nv04_rect_format(enum pipe_format format)
case PIPE_FORMAT_A8_UNORM:
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
case PIPE_FORMAT_R5G6B5_UNORM:
+ case PIPE_FORMAT_Z16_UNORM:
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A16R5G6B5;
case PIPE_FORMAT_A8R8G8B8_UNORM:
case PIPE_FORMAT_Z24S8_UNORM:
+ case PIPE_FORMAT_Z24X8_UNORM:
return NV04_GDI_RECTANGLE_TEXT_COLOR_FORMAT_A8R8G8B8;
default:
return -1;
@@ -110,10 +114,10 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
unsigned cx;
unsigned cy;
- /* POT or GTFO */
- assert(!(w & (w - 1)) && !(h & (h - 1)));
+#if 0
/* That's the way she likes it */
assert(src_pitch == ((struct nv04_surface *)dst)->pitch);
+#endif
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_DMA_IMAGE, 1);
OUT_RELOCo(chan, dst_bo,
@@ -133,7 +137,7 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
for (cy = 0; cy < h; cy += sub_h) {
for (cx = 0; cx < w; cx += sub_w) {
BEGIN_RING(chan, swzsurf, NV04_SWIZZLED_SURFACE_OFFSET, 1);
- OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx, cy) *
+ OUT_RELOCl(chan, dst_bo, dst->offset + nv04_swizzle_bits(cx+dx, cy+dy) *
dst->texture->block.size, NOUVEAU_BO_GART |
NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
@@ -153,8 +157,8 @@ nv04_surface_copy_swizzle(struct nv04_surface_2d *ctx,
OUT_RING (chan, src_pitch |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_ORIGIN_CENTER |
NV04_SCALED_IMAGE_FROM_MEMORY_FORMAT_FILTER_POINT_SAMPLE);
- OUT_RELOCl(chan, src_bo, src->offset + cy * src_pitch +
- cx * src->texture->block.size, NOUVEAU_BO_GART |
+ OUT_RELOCl(chan, src_bo, src->offset + (cy+sy) * src_pitch +
+ (cx+sx) * src->texture->block.size, NOUVEAU_BO_GART |
NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
OUT_RING (chan, 0);
}
@@ -210,6 +214,43 @@ nv04_surface_copy_m2mf(struct nv04_surface_2d *ctx,
}
static int
+nv04_surface_copy_m2mf_swizzle(struct nv04_surface_2d *ctx,
+ struct pipe_surface *dst, int dx, int dy,
+ struct pipe_surface *src, int sx, int sy)
+{
+ struct nouveau_channel *chan = ctx->m2mf->channel;
+ struct nouveau_grobj *m2mf = ctx->m2mf;
+ struct nouveau_bo *src_bo = nouveau_bo(ctx->buf(src));
+ struct nouveau_bo *dst_bo = nouveau_bo(ctx->buf(dst));
+ unsigned src_pitch = ((struct nv04_surface *)src)->pitch;
+ unsigned dst_pitch = ((struct nv04_surface *)dst)->pitch;
+ unsigned dst_offset = dst->offset + nv04_swizzle_bits(dx, dy) *
+ dst->texture->block.size;
+ unsigned src_offset = src->offset + sy * src_pitch +
+ sx * src->texture->block.size;
+
+ BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_BUFFER_IN, 2);
+ OUT_RELOCo(chan, src_bo,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_RD);
+ OUT_RELOCo(chan, dst_bo,
+ NOUVEAU_BO_GART | NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ BEGIN_RING(chan, m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
+ OUT_RELOCl(chan, src_bo, src_offset,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD);
+ OUT_RELOCl(chan, dst_bo, dst_offset,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_WR);
+ OUT_RING (chan, src_pitch);
+ OUT_RING (chan, dst_pitch);
+ OUT_RING (chan, 1 * src->texture->block.size);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0x0101);
+ OUT_RING (chan, 0);
+
+ return 0;
+}
+
+static int
nv04_surface_copy_blit(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
int dx, int dy, struct pipe_surface *src, int sx, int sy,
int w, int h)
@@ -258,8 +299,59 @@ nv04_surface_copy(struct nv04_surface_2d *ctx, struct pipe_surface *dst,
assert(src->format == dst->format);
/* Setup transfer to swizzle the texture to vram if needed */
- if (src_linear && !dst_linear && w > 1 && h > 1) {
- nv04_surface_copy_swizzle(ctx, dst, dx, dy, src, sx, sy, w, h);
+ if (src_linear && !dst_linear) {
+ int x,y;
+
+ if ((w>1) && (h>1)) {
+ int potWidth = 1<<log2i(w);
+ int potHeight = 1<<log2i(h);
+ int remainWidth = w-potWidth;
+ int remainHeight = h-potHeight;
+ int squareDim = (potWidth>potHeight ? potHeight : potWidth);
+
+ /* top left is always POT, but we can only swizzle squares */
+ for (y=0; y<potHeight; y+=squareDim) {
+ for (x=0; x<potWidth; x+= squareDim) {
+ nv04_surface_copy_swizzle(ctx, dst, dx+x, dy+y,
+ src, sx+x, sy+y,
+ squareDim, squareDim);
+ }
+ }
+
+ /* top right */
+ if (remainWidth>0) {
+ nv04_surface_copy(ctx, dst, dx+potWidth, dy,
+ src, sx+potWidth, sy,
+ remainWidth, potHeight);
+ }
+
+ /* bottom left */
+ if (remainHeight>0) {
+ nv04_surface_copy(ctx, dst, dx, dy+potHeight,
+ src, sx, sy+potHeight,
+ potWidth, remainHeight);
+ }
+
+ /* bottom right */
+ if ((remainWidth>0) && (remainHeight>0)) {
+ nv04_surface_copy(ctx, dst, dx+potWidth, dy+potHeight,
+ src, sx+potWidth, sy+potHeight,
+ remainWidth, remainHeight);
+ }
+ } else if (w==1) {
+ /* We have a column to copy to a swizzled texture */
+ for (y=0; y<h; y++) {
+ nv04_surface_copy_m2mf_swizzle(ctx, dst, dx, dy+y,
+ src, sx, sy+y);
+ }
+ } else if (h==1) {
+ /* We have a row to copy to a swizzled texture */
+ for (x=0; x<w; x++) {
+ nv04_surface_copy_m2mf_swizzle(ctx, dst, dx+x, dy,
+ src, sx+x, sy);
+ }
+ }
+
return;
}
diff --git a/src/gallium/drivers/nv10/nv10_screen.c b/src/gallium/drivers/nv10/nv10_screen.c
index 4469b22d91..ee5901e743 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 e6924ad71e..4eeacd1afd 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 c8b40784b0..41af38450b 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:
@@ -95,7 +93,7 @@ nv30_screen_surface_format_supported(struct pipe_screen *pscreen,
}
} else
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
- switch (tex_usage) {
+ switch (format) {
case PIPE_FORMAT_Z24S8_UNORM:
case PIPE_FORMAT_Z24X8_UNORM:
case PIPE_FORMAT_Z16_UNORM:
diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c
index 5d2a4216c5..bd13dfddd1 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 e02afc4be9..fca078b174 100644
--- a/src/gallium/drivers/nv50/nv50_context.c
+++ b/src/gallium/drivers/nv50/nv50_context.c
@@ -31,15 +31,24 @@ static void
nv50_flush(struct pipe_context *pipe, unsigned flags,
struct pipe_fence_handle **fence)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
-
- FIRE_RING(nv50->screen->base.channel);
+ struct nv50_context *nv50 = nv50_context(pipe);
+ struct nouveau_channel *chan = nv50->screen->base.channel;
+ struct nouveau_grobj *eng2d = nv50->screen->eng2d;
+
+ /* 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, 2);
+ BEGIN_RING(chan, eng2d, 0x0110, 1);
+ OUT_RING (chan, 0);
+
+ if (flags & PIPE_FLUSH_FRAME)
+ FIRE_RING(chan);
}
static void
nv50_destroy(struct pipe_context *pipe)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
draw_destroy(nv50->draw);
FREE(nv50);
@@ -102,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);
@@ -112,5 +124,3 @@ nv50_create(struct pipe_screen *pscreen, unsigned pctx_id)
return &nv50->pipe;
}
-
-
diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h
index 9b8cc4d37d..4608854d71 100644
--- a/src/gallium/drivers/nv50/nv50_context.h
+++ b/src/gallium/drivers/nv50/nv50_context.h
@@ -71,12 +71,11 @@ struct nv50_sampler_stateobj {
struct nv50_miptree_level {
int *image_offset;
unsigned pitch;
+ unsigned tile_mode;
};
struct nv50_miptree {
- struct pipe_texture base;
-
- struct nouveau_bo *bo;
+ struct nouveau_miptree base;
struct nv50_miptree_level level[PIPE_MAX_TEXTURE_LEVELS];
int image_nr;
@@ -117,8 +116,10 @@ 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;
};
struct nv50_context {
@@ -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_miptree.c b/src/gallium/drivers/nv50/nv50_miptree.c
index 22465e0227..93479a0314 100644
--- a/src/gallium/drivers/nv50/nv50_miptree.c
+++ b/src/gallium/drivers/nv50/nv50_miptree.c
@@ -31,20 +31,25 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct nv50_miptree *mt = CALLOC_STRUCT(nv50_miptree);
- struct pipe_texture *pt = &mt->base;
+ struct pipe_texture *pt = &mt->base.base;
unsigned width = tmp->width[0], height = tmp->height[0];
unsigned depth = tmp->depth[0];
uint32_t tile_mode, tile_flags, tile_h;
int ret, i, l;
- mt->base = *tmp;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
+ *pt = *tmp;
+ pipe_reference_init(&pt->reference, 1);
+ pt->screen = pscreen;
switch (pt->format) {
- case PIPE_FORMAT_Z24X8_UNORM:
+ case PIPE_FORMAT_Z32_FLOAT:
+ tile_flags = 0x4800;
+ break;
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
+ tile_flags = 0x1800;
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
tile_flags = 0x2800;
break;
default:
@@ -82,20 +87,27 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
lvl->image_offset = CALLOC(mt->image_nr, sizeof(int));
lvl->pitch = align(pt->width[l] * pt->block.size, 64);
+ lvl->tile_mode = tile_mode;
width = MAX2(1, width >> 1);
height = MAX2(1, height >> 1);
depth = MAX2(1, depth >> 1);
+
+ if (tile_mode && height <= (tile_h >> 1)) {
+ tile_mode--;
+ tile_h >>= 1;
+ }
}
for (i = 0; i < mt->image_nr; i++) {
for (l = 0; l <= pt->last_level; l++) {
struct nv50_miptree_level *lvl = &mt->level[l];
int size;
+ tile_h = 1 << (lvl->tile_mode + 2);
size = align(pt->width[l], 8) * pt->block.size;
size = align(size, 64);
- size *= align(pt->height[l], tile_h) * pt->block.size;
+ size *= align(pt->height[l], tile_h);
lvl->image_offset[i] = mt->total_size;
@@ -104,13 +116,14 @@ nv50_miptree_create(struct pipe_screen *pscreen, const struct pipe_texture *tmp)
}
ret = nouveau_bo_new_tile(dev, NOUVEAU_BO_VRAM, 256, mt->total_size,
- tile_mode, tile_flags, &mt->bo);
+ mt->level[0].tile_mode, tile_flags,
+ &mt->base.bo);
if (ret) {
FREE(mt);
return NULL;
}
-
- return &mt->base;
+
+ return pt;
}
static struct pipe_texture *
@@ -129,15 +142,16 @@ nv50_miptree_blanket(struct pipe_screen *pscreen, const struct pipe_texture *pt,
if (!mt)
return NULL;
- mt->base = *pt;
- pipe_reference_init(&mt->base.reference, 1);
- mt->base.screen = pscreen;
+ mt->base.base = *pt;
+ pipe_reference_init(&mt->base.base.reference, 1);
+ mt->base.base.screen = pscreen;
mt->image_nr = 1;
mt->level[0].pitch = *stride;
mt->level[0].image_offset = CALLOC(1, sizeof(unsigned));
+ mt->level[0].tile_mode = bo->tile_mode;
- nouveau_bo_ref(bo, &mt->bo);
- return &mt->base;
+ nouveau_bo_ref(bo, &mt->base.bo);
+ return &mt->base.base;
}
static void
@@ -145,8 +159,8 @@ nv50_miptree_destroy(struct pipe_texture *pt)
{
struct nv50_miptree *mt = nv50_miptree(pt);
- nouveau_bo_ref(NULL, &mt->bo);
- FREE(mt);
+ nouveau_bo_ref(NULL, &mt->base.bo);
+ FREE(mt);
}
static struct pipe_surface *
@@ -189,8 +203,8 @@ nv50_miptree_surface_del(struct pipe_surface *ps)
{
struct nv50_surface *s = nv50_surface(ps);
- pipe_texture_reference(&ps->texture, NULL);
- FREE(s);
+ pipe_texture_reference(&ps->texture, NULL);
+ FREE(s);
}
void
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 4ec9c03305..eb90d5e66f 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -112,6 +112,10 @@ 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;
@@ -124,6 +128,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)
{
@@ -184,11 +207,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;
}
@@ -251,13 +271,11 @@ alloc_temp4(struct nv50_pc *pc, struct nv50_reg *dst[4], int idx)
if (pc->r_temp[idx] || pc->r_temp[idx + 1] ||
pc->r_temp[idx + 2] || pc->r_temp[idx + 3])
- return alloc_temp4(pc, dst, idx + 1);
+ 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];
}
@@ -296,7 +314,7 @@ kill_temp_temp(struct nv50_pc *pc)
static int
ctor_immd(struct nv50_pc *pc, float x, float y, float z, float w)
{
- pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * r * sizeof(float)),
+ pc->immd_buf = REALLOC(pc->immd_buf, (pc->immd_nr * 4 * sizeof(float)),
(pc->immd_nr + 1) * 4 * sizeof(float));
pc->immd_buf[(pc->immd_nr * 4) + 0] = x;
pc->immd_buf[(pc->immd_nr * 4) + 1] = y;
@@ -309,7 +327,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 +337,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;
}
@@ -786,6 +802,9 @@ 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
@@ -795,7 +814,7 @@ emit_precossin(struct nv50_pc *pc, struct nv50_reg *dst, struct nv50_reg *src)
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 +823,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,49 +840,80 @@ 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);
- 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)
{
@@ -890,6 +940,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)
@@ -1014,6 +1070,7 @@ emit_tex(struct nv50_pc *pc, struct nv50_reg **dst, unsigned mask,
break;
}
+ /* some cards need t[0]'s hw index to be a multiple of 4 */
alloc_temp4(pc, t, 0);
if (proj) {
@@ -1105,10 +1162,10 @@ convert_to_long(struct nv50_pc *pc, struct nv50_program_exec *e)
m = 0xffff7fff;
break;
case 0x8:
- /* INTERP */
- m = ~0x02000000;
- if (e->inst[0] & 0x02000000)
- q = 0x00020000;
+ /* INTERP (move centroid, perspective and flat bits) */
+ m = ~0x03000100;
+ q = (e->inst[0] & (3 << 24)) >> (24 - 16);
+ q |= (e->inst[0] & (1 << 8)) << (18 - 8);
break;
case 0x9:
/* RCP */
@@ -1158,6 +1215,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)
{
@@ -1257,93 +1378,126 @@ 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 boolean
-nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
+nv50_program_tx_insn(struct nv50_pc *pc,
+ const struct tgsi_full_instruction *inst)
{
- const struct tgsi_full_instruction *inst = &tok->FullInstruction;
- struct nv50_reg *rdst[4], *dst[4], *src[3][4], *temp;
+ 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)
+ if (!(mask & (1 << 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)
- 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++) {
@@ -1359,74 +1513,56 @@ 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_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);
+ }
+ 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_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++) {
@@ -1449,19 +1585,12 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
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);
@@ -1494,6 +1623,7 @@ nv50_program_tx_insn(struct nv50_pc *pc, const union tgsi_full_token *tok)
}
break;
case TGSI_OPCODE_MOV:
+ case TGSI_OPCODE_SWZ:
for (c = 0; c < 4; c++) {
if (!(mask & (1 << c)))
continue;
@@ -1508,31 +1638,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))
@@ -1542,28 +1659,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:
@@ -1581,6 +1699,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);
+ }
+ break;
case TGSI_OPCODE_XPD:
temp = temp_temp(pc);
if (mask & (1 << 0)) {
@@ -1605,17 +1731,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++) {
@@ -1624,9 +1755,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]);
}
}
@@ -1634,180 +1762,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)
+prep_inspect_insn(struct nv50_pc *pc, const struct tgsi_full_instruction *insn)
{
- 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])
-{
- 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;
+
+ /* no danger if src is copied to TEMP first */
+ if ((s != TGSI_UTIL_SIGN_KEEP) &&
+ (s != TGSI_UTIL_SIGN_TOGGLE || !neg_supp))
+ continue;
- pc->p->cfg.fp.map[(*mid) / 4] |= oid << (8 * ((*mid) % 4));
- (*mid)++;
- pc->p->cfg.fp.regs[1] += 0x00010001;
+ 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);
- /* count (centroid) perspective interpolations */
- unsigned centroid_loads = 0;
- unsigned perspect_loads = 0;
+ deqs = nv50_revdep_reorder(m, rdep);
- /* track register access for temps and attrs */
- unsigned *r_usage[2];
- r_usage[0] = NULL;
- r_usage[1] = NULL;
+ for (i = 0; i < 4; ++i) {
+ assert(pc->r_dst[m[i]] == NULL);
- depr = fcol = bcol = fcrd = 0xffff;
+ insn.FullDstRegisters[0].DstRegister.WriteMask =
+ fd->DstRegister.WriteMask & (1 << m[i]);
- if (pc->p->type == PIPE_SHADER_FRAGMENT) {
- pc->p->cfg.fp.regs[0] = 0x01000404;
- pc->p->cfg.fp.regs[1] = 0x00000400;
+ 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;
}
- tgsi_parse_init(&p, pc->p->pipe.tokens);
- while (!tgsi_parse_end_of_tokens(&p)) {
- const union tgsi_full_token *tok = &p.FullToken;
+ 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);
+ }
- tgsi_parse_token(&p);
+ return TRUE;
+}
+
+static void
+load_interpolant(struct nv50_pc *pc, struct nv50_reg *reg)
+{
+ struct nv50_reg *iv, **ppiv;
+ unsigned mode = pc->interp_mode[reg->index];
+
+ 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.
+ */
+ }
+
+ 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(&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,
@@ -1818,78 +2037,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++)
@@ -1897,8 +2099,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;
@@ -1911,182 +2111,155 @@ 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;
+ for (i = 0, rid = 0; i < pc->result_nr; ++i) {
+ p->cfg.io[i].hw = rid;
+ p->cfg.io[i].id_vp = i;
- 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]);
- }
- }
-
- 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;
+
+ 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;
- 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;
+ 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;
}
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;
}
@@ -2108,6 +2281,88 @@ 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 boolean
nv50_program_tx(struct nv50_program *p)
{
struct tgsi_parse_context parse;
@@ -2118,8 +2373,10 @@ nv50_program_tx(struct nv50_program *p)
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)
@@ -2139,7 +2396,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,8 +2407,8 @@ nv50_program_tx(struct nv50_program *p)
if (p->type == PIPE_SHADER_FRAGMENT) {
struct nv50_reg out;
+ ctor_reg(&out, P_TEMP, -1, -1);
- out.type = P_TEMP;
for (k = 0; k < pc->result_nr * 4; k++) {
if (pc->result[k].rhw == -1)
continue;
@@ -2221,9 +2478,9 @@ nv50_program_upload_data(struct nv50_context *nv50, float *map,
while (count) {
unsigned nr = count > 2047 ? 2047 : count;
- BEGIN_RING(chan, tesla, 0x00000f00, 1);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
OUT_RING (chan, (cbuf << 0) | (start << 8));
- BEGIN_RING(chan, tesla, 0x40000f04, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr);
OUT_RINGp (chan, map, nr);
map += nr;
@@ -2256,30 +2513,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]);
}
}
@@ -2301,32 +2547,30 @@ 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 (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 (p->data[0] && p->data[0]->start != p->data_start[0])
+ 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;
- if (p->data[1])
- p->data_start[1] = p->data[1]->start;
+ for (e = p->exec_head; e; e = e->next) {
+ unsigned ei, ci, bs;
- 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;
+ if (bs == 0)
+ ci += p->data[bs]->start;
+
+ 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");
@@ -2345,7 +2589,7 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
}
so = so_new(4,2);
- so_method(so, nv50->screen->tesla, 0x1280, 3);
+ so_method(so, nv50->screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, p->bo, 0, flags | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PUPLOAD << 16) | 0x0800); //(p->exec_size * 4));
@@ -2364,9 +2608,9 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
continue;
}
- BEGIN_RING(chan, tesla, 0x0f00, 1);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_ADDR, 1);
OUT_RING (chan, (start << 8) | NV50_CB_PUPLOAD);
- BEGIN_RING(chan, tesla, 0x40000f04, nr);
+ BEGIN_RING(chan, tesla, NV50TCL_CB_DATA(0) | 0x40000000, nr);
OUT_RINGp (chan, up + start, nr);
start += nr;
@@ -2399,15 +2643,15 @@ nv50_vertprog_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, 0x1650, 2);
- so_data (so, p->cfg.vp.attr[0]);
- so_data (so, p->cfg.vp.attr[1]);
- so_method(so, tesla, 0x16b8, 1);
+ so_method(so, tesla, NV50TCL_VP_ATTR_EN_0, 2);
+ 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, 0x16ac, 2);
+ so_method(so, tesla, NV50TCL_VP_RESULT_MAP_SIZE, 2);
so_data (so, p->cfg.high_result); //8);
so_data (so, p->cfg.high_temp);
- so_method(so, tesla, 0x140c, 1);
+ so_method(so, tesla, NV50TCL_VP_START_ID, 1);
so_data (so, 0); /* program start offset */
so_ref(so, &nv50->state.vertprog);
so_ref(NULL, &so);
@@ -2419,7 +2663,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);
@@ -2436,29 +2679,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, 0x1904, 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, 0x16bc, 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, 0x1988, 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, 0x1298, 1);
+ so_method(so, tesla, NV50TCL_FP_RESULT_COUNT, 1);
so_data (so, p->cfg.high_result);
- so_method(so, tesla, 0x19a8, 1);
- so_data (so, p->cfg.fp.regs[2]);
- so_method(so, tesla, 0x196c, 1);
- so_data (so, p->cfg.fp.regs[3]);
- so_method(so, tesla, 0x1414, 1);
+ so_method(so, tesla, NV50TCL_FP_CTRL_UNK19A8, 1);
+ so_data (so, p->cfg.regs[2]);
+ so_method(so, tesla, NV50TCL_FP_CTRL_UNK196C, 1);
+ 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)
{
@@ -2474,8 +2874,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 096e0476aa..d78dee083f 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_query.c b/src/gallium/drivers/nv50/nv50_query.c
index 940e04365f..5305c93d59 100644
--- a/src/gallium/drivers/nv50/nv50_query.c
+++ b/src/gallium/drivers/nv50/nv50_query.c
@@ -94,7 +94,7 @@ nv50_query_end(struct pipe_context *pipe, struct pipe_query *pq)
struct nv50_query *q = nv50_query(pq);
WAIT_RING (chan, 5);
- BEGIN_RING(chan, tesla, 0x1b00, 4);
+ BEGIN_RING(chan, tesla, NV50TCL_QUERY_ADDRESS_HIGH, 4);
OUT_RELOCh(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RELOCl(chan, q->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
OUT_RING (chan, 0x00000000);
@@ -107,13 +107,13 @@ nv50_query_result(struct pipe_context *pipe, struct pipe_query *pq,
boolean wait, uint64_t *result)
{
struct nv50_query *q = nv50_query(pq);
-
- /*XXX: Want to be able to return FALSE here instead of blocking
- * until the result is available..
- */
+ int ret;
if (!q->ready) {
- nouveau_bo_map(q->bo, NOUVEAU_BO_RD);
+ ret = nouveau_bo_map(q->bo, NOUVEAU_BO_RD |
+ wait ? 0 : NOUVEAU_BO_NOWAIT);
+ if (ret)
+ return false;
q->result = ((uint32_t *)q->bo->map)[1];
q->ready = TRUE;
nouveau_bo_unmap(q->bo);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ce8f906b15..3b08e1b89f 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -44,9 +44,10 @@ nv50_screen_is_format_supported(struct pipe_screen *pscreen,
} else
if (tex_usage & PIPE_TEXTURE_USAGE_DEPTH_STENCIL) {
switch (format) {
+ case PIPE_FORMAT_Z32_FLOAT:
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- case PIPE_FORMAT_Z16_UNORM:
+ case PIPE_FORMAT_X8Z24_UNORM:
+ case PIPE_FORMAT_S8Z24_UNORM:
return TRUE;
default:
break;
@@ -86,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:
@@ -188,7 +187,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
nv50_transfer_init_screen_functions(pscreen);
/* DMA engine object */
- ret = nouveau_grobj_alloc(chan, 0xbeef5039, 0x5039, &screen->m2mf);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5039,
+ NV50_MEMORY_TO_MEMORY_FORMAT, &screen->m2mf);
if (ret) {
NOUVEAU_ERR("Error creating M2MF object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -197,7 +197,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
BIND_RING(chan, screen->m2mf, 1);
/* 2D object */
- ret = nouveau_grobj_alloc(chan, 0xbeef502d, 0x502d, &screen->eng2d);
+ ret = nouveau_grobj_alloc(chan, 0xbeef502d, NV50_2D, &screen->eng2d);
if (ret) {
NOUVEAU_ERR("Error creating 2D object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -208,14 +208,15 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* 3D object */
switch (chipset & 0xf0) {
case 0x50:
- tesla_class = 0x5097;
+ tesla_class = NV50TCL;
break;
case 0x80:
case 0x90:
- tesla_class = 0x8297;
+ /* this stupid name should be corrected. */
+ tesla_class = NV54TCL;
break;
case 0xa0:
- tesla_class = 0x8397;
+ tesla_class = NVA0TCL;
break;
default:
NOUVEAU_ERR("Not a known NV50 chipset: NV%02x\n", chipset);
@@ -229,7 +230,8 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class, &screen->tesla);
+ ret = nouveau_grobj_alloc(chan, 0xbeef5097, tesla_class,
+ &screen->tesla);
if (ret) {
NOUVEAU_ERR("Error creating 3D object: %d\n", ret);
nv50_screen_destroy(pscreen);
@@ -247,7 +249,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* Static M2MF init */
so = so_new(32, 0);
- so_method(so, screen->m2mf, 0x0180, 3);
+ so_method(so, screen->m2mf, NV04_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 3);
so_data (so, screen->sync->handle);
so_data (so, chan->vram->handle);
so_data (so, chan->vram->handle);
@@ -290,9 +292,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, 0x13bc, 1);
so_data (so, 0x54);
+ /* origin is top left (set to 1 for bottom left) */
so_method(so, screen->tesla, 0x13ac, 1);
- so_data (so, 1);
- so_method(so, screen->tesla, 0x16b8, 1);
+ so_data (so, 0);
+ so_method(so, screen->tesla, NV50TCL_VP_REG_ALLOC_RESULT, 1);
so_data (so, 8);
/* constant buffers for immediates and VP/FP parameters */
@@ -330,33 +333,33 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_data (so, 0x000BBNP1);
*/
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_misc[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PMISC << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000001 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000031 | (NV50_CB_PMISC << 12));
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_parm[0], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PVP << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000101 | (NV50_CB_PVP << 12));
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->constbuf_parm[1], 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_PFP << 16) | 0x00000800);
- so_method(so, screen->tesla, 0x1694, 1);
+ so_method(so, screen->tesla, NV50TCL_SET_PROGRAM_CB, 1);
so_data (so, 0x00000131 | (NV50_CB_PFP << 12));
/* Texture sampler/image unit setup - we abuse the constant buffer
@@ -370,13 +373,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_TIC << 16) | 0x0800);
- so_method(so, screen->tesla, 0x1574, 3);
+ so_method(so, screen->tesla, NV50TCL_TIC_ADDRESS_HIGH, 3);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tic, 0, NOUVEAU_BO_VRAM |
@@ -389,13 +392,13 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
return NULL;
}
- so_method(so, screen->tesla, 0x1280, 3);
+ so_method(so, screen->tesla, NV50TCL_CB_DEF_ADDRESS_HIGH, 3);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
so_data (so, (NV50_CB_TSC << 16) | 0x0800);
- so_method(so, screen->tesla, 0x155c, 3);
+ so_method(so, screen->tesla, NV50TCL_TSC_ADDRESS_HIGH, 3);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
NOUVEAU_BO_RD | NOUVEAU_BO_HIGH, 0, 0);
so_reloc (so, screen->tsc, 0, NOUVEAU_BO_VRAM |
@@ -405,7 +408,7 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
/* Vertex array limits - max them out */
for (i = 0; i < 16; i++) {
- so_method(so, screen->tesla, 0x1080 + (i * 8), 2);
+ so_method(so, screen->tesla, NV50TCL_UNK1080_OFFSET_HIGH(i), 2);
so_data (so, 0x000000ff);
so_data (so, 0xffffffff);
}
@@ -417,6 +420,10 @@ nv50_screen_create(struct pipe_winsys *ws, struct nouveau_device *dev)
so_method(so, screen->tesla, 0x1234, 1);
so_data (so, 1);
+ /* activate first scissor rectangle */
+ so_method(so, screen->tesla, NV50TCL_SCISSOR_ENABLE, 1);
+ so_data (so, 1);
+
so_emit(chan, so);
so_ref (so, &screen->static_init);
so_ref (NULL, &so);
diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c
index 116866a8e7..81fa3e34c5 100644
--- a/src/gallium/drivers/nv50/nv50_state.c
+++ b/src/gallium/drivers/nv50/nv50_state.c
@@ -205,11 +205,16 @@ nv50_sampler_state_create(struct pipe_context *pipe,
}
limit = CLAMP(cso->lod_bias, -16.0, 15.0);
- tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 11;
+ tsc[1] |= ((int)(limit * 256.0) & 0x1fff) << 12;
tsc[2] |= ((int)CLAMP(cso->max_lod, 0.0, 15.0) << 20) |
((int)CLAMP(cso->min_lod, 0.0, 15.0) << 8);
+ tsc[4] = fui(cso->border_color[0]);
+ tsc[5] = fui(cso->border_color[1]);
+ tsc[6] = fui(cso->border_color[2]);
+ tsc[7] = fui(cso->border_color[3]);
+
sso->normalized = cso->normalized_coords;
return (void *)sso;
}
@@ -268,6 +273,11 @@ nv50_rasterizer_state_create(struct pipe_context *pipe,
so_method(so, tesla, NV50TCL_SHADE_MODEL, 1);
so_data (so, cso->flatshade ? NV50TCL_SHADE_MODEL_FLAT :
NV50TCL_SHADE_MODEL_SMOOTH);
+ 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));
@@ -287,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));
@@ -404,35 +417,35 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe,
so_data (so, 0);
}
- /*XXX: yes, I know they're backwards.. header needs fixing */
+ /* XXX: keep hex values until header is updated (names reversed) */
if (cso->stencil[0].enabled) {
- so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 5);
+ so_method(so, tesla, 0x1380, 8);
so_data (so, 1);
so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op));
so_data (so, nvgl_comparison_op(cso->stencil[0].func));
- so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3);
so_data (so, cso->stencil[0].ref_value);
so_data (so, cso->stencil[0].writemask);
so_data (so, cso->stencil[0].valuemask);
} else {
- so_method(so, tesla, NV50TCL_STENCIL_BACK_ENABLE, 1);
+ so_method(so, tesla, 0x1380, 1);
so_data (so, 0);
}
if (cso->stencil[1].enabled) {
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8);
+ so_method(so, tesla, 0x1594, 5);
so_data (so, 1);
so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op));
so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op));
so_data (so, nvgl_comparison_op(cso->stencil[1].func));
+ so_method(so, tesla, 0x0f54, 3);
so_data (so, cso->stencil[1].ref_value);
so_data (so, cso->stencil[1].writemask);
so_data (so, cso->stencil[1].valuemask);
} else {
- so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 1);
+ so_method(so, tesla, 0x1594, 1);
so_data (so, 0);
}
diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c
index d313e9de4f..5a3559ed18 100644
--- a/src/gallium/drivers/nv50/nv50_state_validate.c
+++ b/src/gallium/drivers/nv50/nv50_state_validate.c
@@ -33,7 +33,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
for (i = 0; i < fb->nr_cbufs; i++) {
struct pipe_texture *pt = fb->cbufs[i]->texture;
- struct nouveau_bo *bo = nv50_miptree(pt)->bo;
+ struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
if (!gw) {
w = fb->cbufs[i]->width;
@@ -55,18 +55,19 @@ nv50_state_validate_fb(struct nv50_context *nv50)
NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->cbufs[i]->format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- so_data(so, 0xcf);
+ so_data(so, NV50TCL_RT_FORMAT_A8R8G8B8_UNORM);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
- so_data(so, 0xe8);
+ so_data(so, NV50TCL_RT_FORMAT_R5G6B5_UNORM);
break;
default:
NOUVEAU_ERR("AIIII unknown format %s\n",
pf_name(fb->cbufs[i]->format));
- so_data(so, 0xe6);
+ so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM);
break;
}
- so_data(so, bo->tile_mode << 4);
+ so_data(so, nv50_miptree(pt)->
+ level[fb->cbufs[i]->level].tile_mode << 4);
so_data(so, 0x00000000);
so_method(so, tesla, 0x1224, 1);
@@ -75,7 +76,7 @@ nv50_state_validate_fb(struct nv50_context *nv50)
if (fb->zsbuf) {
struct pipe_texture *pt = fb->zsbuf->texture;
- struct nouveau_bo *bo = nv50_miptree(pt)->bo;
+ struct nouveau_bo *bo = nv50_miptree(pt)->base.bo;
if (!gw) {
w = fb->zsbuf->width;
@@ -92,25 +93,31 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_reloc (so, bo, fb->zsbuf->offset, NOUVEAU_BO_VRAM |
NOUVEAU_BO_LOW | NOUVEAU_BO_RDWR, 0, 0);
switch (fb->zsbuf->format) {
+ case PIPE_FORMAT_Z32_FLOAT:
+ so_data(so, NV50TCL_ZETA_FORMAT_Z32_FLOAT);
+ break;
case PIPE_FORMAT_Z24S8_UNORM:
- case PIPE_FORMAT_Z24X8_UNORM:
- so_data(so, 0x16);
+ so_data(so, NV50TCL_ZETA_FORMAT_Z24S8_UNORM);
+ break;
+ case PIPE_FORMAT_X8Z24_UNORM:
+ so_data(so, NV50TCL_ZETA_FORMAT_X8Z24_UNORM);
break;
- case PIPE_FORMAT_Z16_UNORM:
- so_data(so, 0x15);
+ case PIPE_FORMAT_S8Z24_UNORM:
+ so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM);
break;
default:
NOUVEAU_ERR("AIIII unknown format %s\n",
pf_name(fb->zsbuf->format));
- so_data(so, 0x16);
+ so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM);
break;
}
- so_data(so, bo->tile_mode << 4);
+ so_data(so, nv50_miptree(pt)->
+ level[fb->zsbuf->level].tile_mode << 4);
so_data(so, 0x00000000);
so_method(so, tesla, 0x1538, 1);
so_data (so, 1);
- so_method(so, tesla, 0x1228, 3);
+ so_method(so, tesla, NV50TCL_ZETA_HORIZ, 3);
so_data (so, fb->zsbuf->width);
so_data (so, fb->zsbuf->height);
so_data (so, 0x00010001);
@@ -119,12 +126,18 @@ nv50_state_validate_fb(struct nv50_context *nv50)
so_method(so, tesla, NV50TCL_VIEWPORT_HORIZ, 2);
so_data (so, w << 16);
so_data (so, h << 16);
- so_method(so, tesla, 0x0e04, 2);
+ /* set window lower left corner */
+ so_method(so, tesla, NV50TCL_WINDOW_LEFT, 2);
+ so_data (so, 0);
+ so_data (so, 0);
+ /* set screen scissor rectangle */
+ so_method(so, tesla, NV50TCL_SCREEN_SCISSOR_HORIZ, 2);
so_data (so, w << 16);
so_data (so, h << 16);
- so_method(so, tesla, 0xdf8, 2);
- so_data (so, 0);
- so_data (so, h);
+
+ /* we set scissors to framebuffer size when they're 'turned off' */
+ nv50->dirty |= NV50_NEW_SCISSOR;
+ so_ref(NULL, &nv50->state.scissor);
so_ref(so, &nv50->state.fb);
so_ref(NULL, &so);
@@ -137,7 +150,32 @@ nv50_state_emit(struct nv50_context *nv50)
struct nouveau_channel *chan = screen->base.channel;
if (nv50->pctx_id != screen->cur_pctx) {
- nv50->state.dirty |= 0xffffffff;
+ if (nv50->state.fb)
+ nv50->state.dirty |= NV50_NEW_FRAMEBUFFER;
+ if (nv50->state.blend)
+ nv50->state.dirty |= NV50_NEW_BLEND;
+ if (nv50->state.zsa)
+ nv50->state.dirty |= NV50_NEW_ZSA;
+ if (nv50->state.vertprog)
+ nv50->state.dirty |= NV50_NEW_VERTPROG;
+ if (nv50->state.fragprog)
+ nv50->state.dirty |= NV50_NEW_FRAGPROG;
+ if (nv50->state.rast)
+ nv50->state.dirty |= NV50_NEW_RASTERIZER;
+ if (nv50->state.blend_colour)
+ nv50->state.dirty |= NV50_NEW_BLEND_COLOUR;
+ if (nv50->state.stipple)
+ nv50->state.dirty |= NV50_NEW_STIPPLE;
+ if (nv50->state.scissor)
+ nv50->state.dirty |= NV50_NEW_SCISSOR;
+ if (nv50->state.viewport)
+ nv50->state.dirty |= NV50_NEW_VIEWPORT;
+ if (nv50->state.tsc_upload)
+ nv50->state.dirty |= NV50_NEW_SAMPLER;
+ if (nv50->state.tic_upload)
+ nv50->state.dirty |= NV50_NEW_TEXTURE;
+ if (nv50->state.vtxfmt && nv50->state.vtxbuf)
+ nv50->state.dirty |= NV50_NEW_ARRAYS;
screen->cur_pctx = nv50->pctx_id;
}
@@ -151,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)
@@ -168,8 +208,16 @@ nv50_state_emit(struct nv50_context *nv50)
if (nv50->state.dirty & NV50_NEW_ARRAYS) {
so_emit(chan, nv50->state.vtxfmt);
so_emit(chan, nv50->state.vtxbuf);
+ if (nv50->state.vtxattr)
+ 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);
@@ -200,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);
@@ -233,13 +284,13 @@ nv50_state_validate(struct nv50_context *nv50)
nv50->state.scissor_enabled = rast->scissor;
so = so_new(3, 0);
- so_method(so, tesla, 0x0ff4, 2);
+ so_method(so, tesla, NV50TCL_SCISSOR_HORIZ, 2);
if (nv50->state.scissor_enabled) {
- so_data(so, ((s->maxx - s->minx) << 16) | s->minx);
- so_data(so, ((s->maxy - s->miny) << 16) | s->miny);
+ so_data(so, (s->maxx << 16) | s->minx);
+ so_data(so, (s->maxy << 16) | s->miny);
} else {
- so_data(so, (8192 << 16));
- so_data(so, (8192 << 16));
+ so_data(so, (nv50->framebuffer.width << 16));
+ so_data(so, (nv50->framebuffer.height << 16));
}
so_ref(so, &nv50->state.scissor);
so_ref(NULL, &so);
@@ -263,20 +314,22 @@ scissor_uptodate:
so = so_new(12, 0);
if (!bypass) {
- so_method(so, tesla, NV50TCL_VIEWPORT_UNK1(0), 3);
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSLATE(0), 3);
so_data (so, fui(nv50->viewport.translate[0]));
so_data (so, fui(nv50->viewport.translate[1]));
so_data (so, fui(nv50->viewport.translate[2]));
- so_method(so, tesla, NV50TCL_VIEWPORT_UNK0(0), 3);
+ so_method(so, tesla, NV50TCL_VIEWPORT_SCALE(0), 3);
so_data (so, fui(nv50->viewport.scale[0]));
- so_data (so, fui(-nv50->viewport.scale[1]));
+ so_data (so, fui(nv50->viewport.scale[1]));
so_data (so, fui(nv50->viewport.scale[2]));
- so_method(so, tesla, 0x192c, 1);
+
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 1);
+ /* no idea what 0f90 does */
so_method(so, tesla, 0x0f90, 1);
so_data (so, 0);
} else {
- so_method(so, tesla, 0x192c, 1);
+ so_method(so, tesla, NV50TCL_VIEWPORT_TRANSFORM_EN, 1);
so_data (so, 0);
so_method(so, tesla, 0x0f90, 1);
so_data (so, 1);
@@ -292,9 +345,10 @@ viewport_uptodate:
int i;
so = so_new(nv50->sampler_nr * 8 + 3, 0);
- so_method(so, tesla, 0x0f00, 1);
+ so_method(so, tesla, NV50TCL_CB_ADDR, 1);
so_data (so, NV50_CB_TSC);
- so_method(so, tesla, 0x40000f04, nv50->sampler_nr * 8);
+ so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000,
+ nv50->sampler_nr * 8);
for (i = 0; i < nv50->sampler_nr; i++)
so_datap (so, nv50->sampler[i]->tsc, 8);
so_ref(so, &nv50->state.tsc_upload);
diff --git a/src/gallium/drivers/nv50/nv50_surface.c b/src/gallium/drivers/nv50/nv50_surface.c
index 3da9d6e728..6bf6f773b0 100644
--- a/src/gallium/drivers/nv50/nv50_surface.c
+++ b/src/gallium/drivers/nv50/nv50_surface.c
@@ -35,13 +35,13 @@ nv50_format(enum pipe_format format)
{
switch (format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
- return NV50_2D_DST_FORMAT_32BPP;
+ return NV50_2D_DST_FORMAT_A8R8G8B8_UNORM;
case PIPE_FORMAT_X8R8G8B8_UNORM:
- return NV50_2D_DST_FORMAT_24BPP;
+ return NV50_2D_DST_FORMAT_X8R8G8B8_UNORM;
case PIPE_FORMAT_R5G6B5_UNORM:
- return NV50_2D_DST_FORMAT_16BPP;
+ return NV50_2D_DST_FORMAT_R5G6B5_UNORM;
case PIPE_FORMAT_A8_UNORM:
- return NV50_2D_DST_FORMAT_8BPP;
+ return NV50_2D_DST_FORMAT_R8_UNORM;
default:
return -1;
}
@@ -53,20 +53,20 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
struct nv50_miptree *mt = nv50_miptree(ps->texture);
struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
- struct nouveau_bo *bo = nv50_miptree(ps->texture)->bo;
+ struct nouveau_bo *bo = nv50_miptree(ps->texture)->base.bo;
int format, mthd = dst ? NV50_2D_DST_FORMAT : NV50_2D_SRC_FORMAT;
int flags = NOUVEAU_BO_VRAM | (dst ? NOUVEAU_BO_WR : NOUVEAU_BO_RD);
format = nv50_format(ps->format);
if (format < 0)
return 1;
-
+
if (!bo->tile_flags) {
BEGIN_RING(chan, eng2d, mthd, 2);
OUT_RING (chan, format);
OUT_RING (chan, 1);
BEGIN_RING(chan, eng2d, mthd + 0x14, 5);
- OUT_RING (chan, mt->level[0].pitch);
+ OUT_RING (chan, mt->level[ps->level].pitch);
OUT_RING (chan, ps->width);
OUT_RING (chan, ps->height);
OUT_RELOCh(chan, bo, ps->offset, flags);
@@ -75,7 +75,7 @@ nv50_surface_set(struct nv50_screen *screen, struct pipe_surface *ps, int dst)
BEGIN_RING(chan, eng2d, mthd, 5);
OUT_RING (chan, format);
OUT_RING (chan, 0);
- OUT_RING (chan, bo->tile_mode << 4);
+ OUT_RING (chan, mt->level[ps->level].tile_mode << 4);
OUT_RING (chan, 1);
OUT_RING (chan, 0);
BEGIN_RING(chan, eng2d, mthd + 0x18, 4);
@@ -144,7 +144,7 @@ nv50_surface_copy(struct pipe_context *pipe,
struct pipe_surface *src, unsigned srcx, unsigned srcy,
unsigned width, unsigned height)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_screen *screen = nv50->screen;
assert(src->format == dest->format);
@@ -158,7 +158,7 @@ nv50_surface_fill(struct pipe_context *pipe, struct pipe_surface *dest,
unsigned destx, unsigned desty, unsigned width,
unsigned height, unsigned value)
{
- struct nv50_context *nv50 = (struct nv50_context *)pipe;
+ struct nv50_context *nv50 = nv50_context(pipe);
struct nv50_screen *screen = nv50->screen;
struct nouveau_channel *chan = screen->eng2d->channel;
struct nouveau_grobj *eng2d = screen->eng2d;
diff --git a/src/gallium/drivers/nv50/nv50_tex.c b/src/gallium/drivers/nv50/nv50_tex.c
index ff40c2ad81..033cb50c11 100644
--- a/src/gallium/drivers/nv50/nv50_tex.c
+++ b/src/gallium/drivers/nv50/nv50_tex.c
@@ -29,33 +29,33 @@ static int
nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
struct nv50_miptree *mt, int unit)
{
- switch (mt->base.format) {
+ switch (mt->base.base.format) {
case PIPE_FORMAT_A8R8G8B8_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_8_8_8_8);
break;
case PIPE_FORMAT_A1R5G5B5_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_1_5_5_5);
break;
case PIPE_FORMAT_A4R4G4B4_UNORM:
so_data(so, NV50TIC_0_0_MAPA_C3 | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_4_4_4_4);
break;
case PIPE_FORMAT_R5G6B5_UNORM:
so_data(so, NV50TIC_0_0_MAPA_ONE | NV50TIC_0_0_TYPEA_UNORM |
- NV50TIC_0_0_MAPR_C0 | NV50TIC_0_0_TYPER_UNORM |
+ NV50TIC_0_0_MAPR_C2 | NV50TIC_0_0_TYPER_UNORM |
NV50TIC_0_0_MAPG_C1 | NV50TIC_0_0_TYPEG_UNORM |
- NV50TIC_0_0_MAPB_C2 | NV50TIC_0_0_TYPEB_UNORM |
+ NV50TIC_0_0_MAPB_C0 | NV50TIC_0_0_TYPEB_UNORM |
NV50TIC_0_0_FMT_5_6_5);
break;
case PIPE_FORMAT_L8_UNORM:
@@ -118,18 +118,18 @@ nv50_tex_construct(struct nv50_context *nv50, struct nouveau_stateobj *so,
return 1;
}
- so_reloc(so, mt->bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
+ so_reloc(so, mt->base.bo, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_LOW |
NOUVEAU_BO_RD, 0, 0);
if (nv50->sampler[unit]->normalized)
- so_data (so, 0xd0005000 | mt->bo->tile_mode << 22);
+ so_data (so, 0xd0005000 | mt->base.bo->tile_mode << 22);
else
- so_data (so, 0x5001d000 | mt->bo->tile_mode << 22);
+ so_data (so, 0x5001d000 | mt->base.bo->tile_mode << 22);
so_data (so, 0x00300000);
- so_data (so, mt->base.width[0]);
- so_data (so, (mt->base.last_level << 28) |
- (mt->base.depth[0] << 16) | mt->base.height[0]);
+ so_data (so, mt->base.base.width[0]);
+ so_data (so, (mt->base.base.last_level << 28) |
+ (mt->base.base.depth[0] << 16) | mt->base.base.height[0]);
so_data (so, 0x03000000);
- so_data (so, mt->base.last_level << 4);
+ so_data (so, mt->base.base.last_level << 4);
return 0;
}
@@ -145,25 +145,28 @@ nv50_tex_validate(struct nv50_context *nv50)
push += MAX2(nv50->miptree_nr, nv50->state.miptree_nr) * 2;
so = so_new(push, nv50->miptree_nr * 2);
- so_method(so, tesla, 0x0f00, 1);
+ so_method(so, tesla, NV50TCL_CB_ADDR, 1);
so_data (so, NV50_CB_TIC);
for (unit = 0; unit < nv50->miptree_nr; unit++) {
struct nv50_miptree *mt = nv50->miptree[unit];
- so_method(so, tesla, 0x40000f04, 8);
+ so_method(so, tesla, NV50TCL_CB_DATA(0) | 0x40000000, 8);
if (nv50_tex_construct(nv50, so, mt, unit)) {
NOUVEAU_ERR("failed tex validate\n");
so_ref(NULL, &so);
return;
}
- so_method(so, tesla, 0x1458, 1);
- so_data (so, (unit << 9) | (unit << 1) | 1);
+ so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
+ so_data (so, (unit << NV50TCL_SET_SAMPLER_TEX_TIC_SHIFT) |
+ (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) |
+ NV50TCL_SET_SAMPLER_TEX_VALID);
}
for (; unit < nv50->state.miptree_nr; unit++) {
- so_method(so, tesla, 0x1458, 1);
- so_data (so, (unit << 1) | 0);
+ so_method(so, tesla, NV50TCL_SET_SAMPLER_TEX, 1);
+ so_data (so,
+ (unit << NV50TCL_SET_SAMPLER_TEX_SAMPLER_SHIFT) | 0);
}
so_ref(so, &nv50->state.tic_upload);
diff --git a/src/gallium/drivers/nv50/nv50_texture.h b/src/gallium/drivers/nv50/nv50_texture.h
index aca622c73b..207fb039f7 100644
--- a/src/gallium/drivers/nv50/nv50_texture.h
+++ b/src/gallium/drivers/nv50/nv50_texture.h
@@ -14,13 +14,13 @@
#define NV50TIC_0_0_MAPA_C2 0x20000000
#define NV50TIC_0_0_MAPA_C3 0x28000000
#define NV50TIC_0_0_MAPA_ONE 0x38000000
-#define NV50TIC_0_0_MAPR_MASK 0x07000000
-#define NV50TIC_0_0_MAPR_ZERO 0x00000000
-#define NV50TIC_0_0_MAPR_C0 0x02000000
-#define NV50TIC_0_0_MAPR_C1 0x03000000
-#define NV50TIC_0_0_MAPR_C2 0x04000000
-#define NV50TIC_0_0_MAPR_C3 0x05000000
-#define NV50TIC_0_0_MAPR_ONE 0x07000000
+#define NV50TIC_0_0_MAPB_MASK 0x07000000
+#define NV50TIC_0_0_MAPB_ZERO 0x00000000
+#define NV50TIC_0_0_MAPB_C0 0x02000000
+#define NV50TIC_0_0_MAPB_C1 0x03000000
+#define NV50TIC_0_0_MAPB_C2 0x04000000
+#define NV50TIC_0_0_MAPB_C3 0x05000000
+#define NV50TIC_0_0_MAPB_ONE 0x07000000
#define NV50TIC_0_0_MAPG_MASK 0x00e00000
#define NV50TIC_0_0_MAPG_ZERO 0x00000000
#define NV50TIC_0_0_MAPG_C0 0x00400000
@@ -28,31 +28,49 @@
#define NV50TIC_0_0_MAPG_C2 0x00800000
#define NV50TIC_0_0_MAPG_C3 0x00a00000
#define NV50TIC_0_0_MAPG_ONE 0x00e00000
-#define NV50TIC_0_0_MAPB_MASK 0x001c0000
-#define NV50TIC_0_0_MAPB_ZERO 0x00000000
-#define NV50TIC_0_0_MAPB_C0 0x00080000
-#define NV50TIC_0_0_MAPB_C1 0x000c0000
-#define NV50TIC_0_0_MAPB_C2 0x00100000
-#define NV50TIC_0_0_MAPB_C3 0x00140000
-#define NV50TIC_0_0_MAPB_ONE 0x001c0000
+#define NV50TIC_0_0_MAPR_MASK 0x001c0000
+#define NV50TIC_0_0_MAPR_ZERO 0x00000000
+#define NV50TIC_0_0_MAPR_C0 0x00080000
+#define NV50TIC_0_0_MAPR_C1 0x000c0000
+#define NV50TIC_0_0_MAPR_C2 0x00100000
+#define NV50TIC_0_0_MAPR_C3 0x00140000
+#define NV50TIC_0_0_MAPR_ONE 0x001c0000
#define NV50TIC_0_0_TYPEA_MASK 0x00038000
#define NV50TIC_0_0_TYPEA_UNORM 0x00010000
-#define NV50TIC_0_0_TYPER_MASK 0x00007000
-#define NV50TIC_0_0_TYPER_UNORM 0x00002000
+#define NV50TIC_0_0_TYPEA_SNORM 0x00008000
+#define NV50TIC_0_0_TYPEA_FLOAT 0x00038000
+#define NV50TIC_0_0_TYPEB_MASK 0x00007000
+#define NV50TIC_0_0_TYPEB_UNORM 0x00002000
+#define NV50TIC_0_0_TYPEB_SNORM 0x00001000
+#define NV50TIC_0_0_TYPEB_FLOAT 0x00007000
#define NV50TIC_0_0_TYPEG_MASK 0x00000e00
#define NV50TIC_0_0_TYPEG_UNORM 0x00000400
-#define NV50TIC_0_0_TYPEB_MASK 0x000001c0
-#define NV50TIC_0_0_TYPEB_UNORM 0x00000080
-#define NV50TIC_0_0_FMT_MASK 0x0000003c
+#define NV50TIC_0_0_TYPEG_SNORM 0x00000200
+#define NV50TIC_0_0_TYPEG_FLOAT 0x00000e00
+#define NV50TIC_0_0_TYPER_MASK 0x000001c0
+#define NV50TIC_0_0_TYPER_UNORM 0x00000080
+#define NV50TIC_0_0_TYPER_SNORM 0x00000040
+#define NV50TIC_0_0_TYPER_FLOAT 0x000001c0
+#define NV50TIC_0_0_FMT_MASK 0x0000003f
+#define NV50TIC_0_0_FMT_32_32_32_32 0x00000001
+#define NV50TIC_0_0_FMT_16_16_16_16 0x00000003
+#define NV50TIC_0_0_FMT_32_32 0x00000004
#define NV50TIC_0_0_FMT_8_8_8_8 0x00000008
+#define NV50TIC_0_0_FMT_2_10_10_10 0x00000009
+#define NV50TIC_0_0_FMT_32 0x0000000f
#define NV50TIC_0_0_FMT_4_4_4_4 0x00000012
-#define NV50TIC_0_0_FMT_1_5_5_5 0x00000013
+/* #define NV50TIC_0_0_FMT_1_5_5_5 0x00000013 */
+#define NV50TIC_0_0_FMT_1_5_5_5 0x00000014
#define NV50TIC_0_0_FMT_5_6_5 0x00000015
#define NV50TIC_0_0_FMT_8_8 0x00000018
+#define NV50TIC_0_0_FMT_16 0x0000001b
#define NV50TIC_0_0_FMT_8 0x0000001d
+#define NV50TIC_0_0_FMT_10_11_11 0x00000021
#define NV50TIC_0_0_FMT_DXT1 0x00000024
#define NV50TIC_0_0_FMT_DXT3 0x00000025
#define NV50TIC_0_0_FMT_DXT5 0x00000026
+#define NV50TIC_0_0_FMT_RGTC1 0x00000027
+#define NV50TIC_0_0_FMT_RGTC2 0x00000028
#define NV50TIC_0_1_OFFSET_LOW_MASK 0xffffffff
#define NV50TIC_0_1_OFFSET_LOW_SHIFT 0
@@ -102,6 +120,7 @@
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_EDGE 0x00000140
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP_TO_BORDER 0x00000180
#define NV50TSC_1_0_WRAPR_MIRROR_CLAMP 0x000001c0
+#define NV50TSC_1_0_MAX_ANISOTROPY_MASK 0x00700000
#define NV50TSC_1_1_MAGF_MASK 0x00000003
#define NV50TSC_1_1_MAGF_NEAREST 0x00000001
@@ -113,17 +132,19 @@
#define NV50TSC_1_1_MIPF_NONE 0x00000040
#define NV50TSC_1_1_MIPF_NEAREST 0x00000080
#define NV50TSC_1_1_MIPF_LINEAR 0x000000c0
+#define NV50TSC_1_1_LOD_BIAS_MASK 0x01fff000
-#define NV50TSC_1_2_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_2_MIN_LOD_MASK 0x00000f00
+#define NV50TSC_1_2_MAX_LOD_MASK 0x00f00000
#define NV50TSC_1_3_UNKNOWN_MASK 0xffffffff
-#define NV50TSC_1_4_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_4_BORDER_COLOR_RED_MASK 0xffffffff
-#define NV50TSC_1_5_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_5_BORDER_COLOR_GREEN_MASK 0xffffffff
-#define NV50TSC_1_6_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_6_BORDER_COLOR_BLUE_MASK 0xffffffff
-#define NV50TSC_1_7_UNKNOWN_MASK 0xffffffff
+#define NV50TSC_1_7_BORDER_COLOR_ALPHA_MASK 0xffffffff
#endif
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index d0b7f0bef4..bb7731855c 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -8,6 +8,7 @@ struct nv50_transfer {
struct pipe_transfer base;
struct nouveau_bo *bo;
unsigned level_offset;
+ unsigned level_tiling;
int level_pitch;
int level_width;
int level_height;
@@ -16,11 +17,14 @@ struct nv50_transfer {
};
static void
-nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
- unsigned src_offset, int src_pitch, int sx, int sy,
- int sw, int sh, struct nouveau_bo *dst_bo,
- unsigned dst_offset, int dst_pitch, int dx, int dy,
- int dw, int dh, int cpp, int width, int height,
+nv50_transfer_rect_m2mf(struct pipe_screen *pscreen,
+ struct nouveau_bo *src_bo, unsigned src_offset,
+ int src_pitch, unsigned src_tile_mode,
+ int sx, int sy, int sw, int sh,
+ struct nouveau_bo *dst_bo, unsigned dst_offset,
+ int dst_pitch, unsigned dst_tile_mode,
+ int dx, int dy, int dw, int dh,
+ int cpp, int width, int height,
unsigned src_reloc, unsigned dst_reloc)
{
struct nv50_screen *screen = nv50_screen(pscreen);
@@ -33,15 +37,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
WAIT_RING (chan, 14);
if (!src_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0200, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 1);
OUT_RING (chan, 1);
- BEGIN_RING(chan, m2mf, 0x0314, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_IN, 1);
OUT_RING (chan, src_pitch);
src_offset += (sy * src_pitch) + (sx * cpp);
} else {
- BEGIN_RING(chan, m2mf, 0x0200, 6);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_IN, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, src_bo->tile_mode << 4);
+ OUT_RING (chan, src_tile_mode << 4);
OUT_RING (chan, sw * cpp);
OUT_RING (chan, sh);
OUT_RING (chan, 1);
@@ -49,15 +56,18 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
}
if (!dst_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x021c, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 1);
OUT_RING (chan, 1);
- BEGIN_RING(chan, m2mf, 0x0318, 1);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_PITCH_OUT, 1);
OUT_RING (chan, dst_pitch);
dst_offset += (dy * dst_pitch) + (dx * cpp);
} else {
- BEGIN_RING(chan, m2mf, 0x021c, 6);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINEAR_OUT, 6);
OUT_RING (chan, 0);
- OUT_RING (chan, dst_bo->tile_mode << 4);
+ OUT_RING (chan, dst_tile_mode << 4);
OUT_RING (chan, dw * cpp);
OUT_RING (chan, dh);
OUT_RING (chan, 1);
@@ -68,25 +78,30 @@ nv50_transfer_rect_m2mf(struct pipe_screen *pscreen, struct nouveau_bo *src_bo,
int line_count = height > 2047 ? 2047 : height;
WAIT_RING (chan, 15);
- BEGIN_RING(chan, m2mf, 0x0238, 2);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN_HIGH, 2);
OUT_RELOCh(chan, src_bo, src_offset, src_reloc);
OUT_RELOCh(chan, dst_bo, dst_offset, dst_reloc);
- BEGIN_RING(chan, m2mf, 0x030c, 2);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 2);
OUT_RELOCl(chan, src_bo, src_offset, src_reloc);
OUT_RELOCl(chan, dst_bo, dst_offset, dst_reloc);
if (src_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0218, 1);
- OUT_RING (chan, (dy << 16) | sx);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_IN, 1);
+ OUT_RING (chan, (sy << 16) | (sx * cpp));
} else {
src_offset += (line_count * src_pitch);
}
if (dst_bo->tile_flags) {
- BEGIN_RING(chan, m2mf, 0x0234, 1);
- OUT_RING (chan, (sy << 16) | dx);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_TILING_POSITION_OUT, 1);
+ OUT_RING (chan, (dy << 16) | (dx * cpp));
} else {
dst_offset += (line_count * dst_pitch);
}
- BEGIN_RING(chan, m2mf, 0x031c, 4);
+ BEGIN_RING(chan, m2mf,
+ NV50_MEMORY_TO_MEMORY_FORMAT_LINE_LENGTH_IN, 4);
OUT_RING (chan, width * cpp);
OUT_RING (chan, line_count);
OUT_RING (chan, 0x00000101);
@@ -133,9 +148,10 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
tx->base.usage = usage;
tx->level_pitch = lvl->pitch;
- tx->level_width = mt->base.width[level];
- tx->level_height = mt->base.height[level];
+ tx->level_width = mt->base.base.width[level];
+ tx->level_height = mt->base.base.height[level];
tx->level_offset = lvl->image_offset[image];
+ tx->level_tiling = lvl->tile_mode;
tx->level_x = x;
tx->level_y = y;
ret = nouveau_bo_new(dev, NOUVEAU_BO_GART | NOUVEAU_BO_MAP, 0,
@@ -146,10 +162,12 @@ nv50_transfer_new(struct pipe_screen *pscreen, struct pipe_texture *pt,
}
if (usage != PIPE_TRANSFER_WRITE) {
- nv50_transfer_rect_m2mf(pscreen, mt->bo, tx->level_offset,
- tx->level_pitch, x, y, tx->level_width,
- tx->level_height, tx->bo, 0,
- tx->base.stride, 0, 0,
+ nv50_transfer_rect_m2mf(pscreen, mt->base.bo, tx->level_offset,
+ tx->level_pitch, tx->level_tiling,
+ x, y,
+ tx->level_width, tx->level_height,
+ tx->bo, 0, tx->base.stride,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
tx->base.block.size, w, h,
NOUVEAU_BO_VRAM | NOUVEAU_BO_GART,
@@ -168,12 +186,14 @@ nv50_transfer_del(struct pipe_transfer *ptx)
if (ptx->usage != PIPE_TRANSFER_READ) {
struct pipe_screen *pscreen = ptx->texture->screen;
nv50_transfer_rect_m2mf(pscreen, tx->bo, 0, tx->base.stride,
- 0, 0, tx->base.width, tx->base.height,
- mt->bo, tx->level_offset,
- tx->level_pitch, tx->level_x,
- tx->level_y, tx->level_width,
- tx->level_height, tx->base.block.size,
+ tx->bo->tile_mode, 0, 0,
tx->base.width, tx->base.height,
+ mt->base.bo, tx->level_offset,
+ tx->level_pitch, tx->level_tiling,
+ tx->level_x, tx->level_y,
+ tx->level_width, tx->level_height,
+ tx->base.block.size, tx->base.width,
+ tx->base.height,
NOUVEAU_BO_GART, NOUVEAU_BO_VRAM |
NOUVEAU_BO_GART);
}
diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c
index f81929f238..eeed148c7b 100644
--- a/src/gallium/drivers/nv50/nv50_vbo.c
+++ b/src/gallium/drivers/nv50/nv50_vbo.c
@@ -49,6 +49,82 @@ nv50_prim(unsigned mode)
return NV50TCL_VERTEX_BEGIN_POINTS;
}
+static INLINE uint32_t
+nv50_vbo_type_to_hw(unsigned type)
+{
+ switch (type) {
+ case PIPE_FORMAT_TYPE_FLOAT:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_FLOAT;
+ case PIPE_FORMAT_TYPE_UNORM:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UNORM;
+ case PIPE_FORMAT_TYPE_SNORM:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SNORM;
+ case PIPE_FORMAT_TYPE_USCALED:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_USCALED;
+ case PIPE_FORMAT_TYPE_SSCALED:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SSCALED;
+ /*
+ case PIPE_FORMAT_TYPE_UINT:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_UINT;
+ case PIPE_FORMAT_TYPE_SINT:
+ return NV50TCL_VERTEX_ARRAY_ATTRIB_TYPE_SINT; */
+ default:
+ return 0;
+ }
+}
+
+static INLINE uint32_t
+nv50_vbo_size_to_hw(unsigned size, unsigned nr_c)
+{
+ static const uint32_t hw_values[] = {
+ 0, 0, 0, 0,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_8_8_8_8,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_16_16_16_16,
+ 0, 0, 0, 0,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32,
+ NV50TCL_VERTEX_ARRAY_ATTRIB_SIZE_32_32_32_32 };
+
+ /* we'd also have R11G11B10 and R10G10B10A2 */
+
+ assert(nr_c > 0 && nr_c <= 4);
+
+ if (size > 32)
+ return 0;
+ size >>= (3 - 2);
+
+ return hw_values[size + (nr_c - 1)];
+}
+
+static INLINE uint32_t
+nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve)
+{
+ uint32_t hw_type, hw_size;
+ enum pipe_format pf = ve->src_format;
+ unsigned size = pf_size_x(pf) << pf_exp2(pf);
+
+ hw_type = nv50_vbo_type_to_hw(pf_type(pf));
+ hw_size = nv50_vbo_size_to_hw(size, ve->nr_components);
+
+ if (!hw_type || !hw_size) {
+ NOUVEAU_ERR("unsupported vbo format: %s\n", pf_name(pf));
+ abort();
+ return 0x24e80000;
+ }
+
+ if (pf_swizzle_x(pf) == 2) /* BGRA */
+ hw_size |= (1 << 31); /* no real swizzle bits :-( */
+
+ return (hw_type | hw_size);
+}
+
boolean
nv50_draw_arrays(struct pipe_context *pipe, unsigned mode, unsigned start,
unsigned count)
@@ -102,7 +178,7 @@ nv50_draw_elements_inline_u08(struct nv50_context *nv50, uint8_t *map,
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[1] << 16) | map[0]);
+ OUT_RING (chan, (map[i + 1] << 16) | map[i]);
count -= nr;
map += nr;
@@ -131,7 +207,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
BEGIN_RING(chan, tesla, 0x400015f0, nr >> 1);
for (i = 0; i < nr; i += 2)
- OUT_RING (chan, (map[1] << 16) | map[0]);
+ OUT_RING (chan, (map[i + 1] << 16) | map[i]);
count -= nr;
map += nr;
@@ -139,7 +215,7 @@ nv50_draw_elements_inline_u16(struct nv50_context *nv50, uint16_t *map,
}
static INLINE void
-nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint8_t *map,
+nv50_draw_elements_inline_u32(struct nv50_context *nv50, uint32_t *map,
unsigned start, unsigned count)
{
struct nouveau_channel *chan = nv50->screen->tesla->channel;
@@ -201,49 +277,101 @@ nv50_draw_elements(struct pipe_context *pipe,
return TRUE;
}
+static INLINE boolean
+nv50_vbo_static_attrib(struct nv50_context *nv50, unsigned attrib,
+ struct nouveau_stateobj **pso,
+ struct pipe_vertex_element *ve,
+ struct pipe_vertex_buffer *vb)
+
+{
+ struct nouveau_stateobj *so;
+ struct nouveau_grobj *tesla = nv50->screen->tesla;
+ struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ float *v;
+ int ret;
+ enum pipe_format pf = ve->src_format;
+
+ if ((pf_type(pf) != PIPE_FORMAT_TYPE_FLOAT) ||
+ (pf_size_x(pf) << pf_exp2(pf)) != 32)
+ return FALSE;
+
+ ret = nouveau_bo_map(bo, NOUVEAU_BO_RD);
+ if (ret)
+ return FALSE;
+ v = (float *)(bo->map + (vb->buffer_offset + ve->src_offset));
+
+ so = *pso;
+ if (!so)
+ *pso = so = so_new(nv50->vtxelt_nr * 5, 0);
+
+ switch (ve->nr_components) {
+ case 4:
+ so_method(so, tesla, NV50TCL_VTX_ATTR_4F_X(attrib), 4);
+ so_data (so, fui(v[0]));
+ so_data (so, fui(v[1]));
+ so_data (so, fui(v[2]));
+ so_data (so, fui(v[3]));
+ break;
+ case 3:
+ so_method(so, tesla, NV50TCL_VTX_ATTR_3F_X(attrib), 3);
+ so_data (so, fui(v[0]));
+ so_data (so, fui(v[1]));
+ so_data (so, fui(v[2]));
+ break;
+ case 2:
+ so_method(so, tesla, NV50TCL_VTX_ATTR_2F_X(attrib), 2);
+ so_data (so, fui(v[0]));
+ so_data (so, fui(v[1]));
+ break;
+ case 1:
+ so_method(so, tesla, NV50TCL_VTX_ATTR_1F(attrib), 1);
+ so_data (so, fui(v[0]));
+ break;
+ default:
+ nouveau_bo_unmap(bo);
+ return FALSE;
+ }
+
+ nouveau_bo_unmap(bo);
+ return TRUE;
+}
+
void
nv50_vbo_validate(struct nv50_context *nv50)
{
struct nouveau_grobj *tesla = nv50->screen->tesla;
- struct nouveau_stateobj *vtxbuf, *vtxfmt;
- int i;
+ struct nouveau_stateobj *vtxbuf, *vtxfmt, *vtxattr;
+ unsigned i;
+
+ /* don't validate if Gallium took away our buffers */
+ if (nv50->vtxbuf_nr == 0)
+ return;
- vtxbuf = so_new(nv50->vtxelt_nr * 4, nv50->vtxelt_nr * 2);
+ vtxattr = NULL;
+ vtxbuf = so_new(nv50->vtxelt_nr * 7, nv50->vtxelt_nr * 4);
vtxfmt = so_new(nv50->vtxelt_nr + 1, 0);
- so_method(vtxfmt, tesla, 0x1ac0, nv50->vtxelt_nr);
+ so_method(vtxfmt, tesla, NV50TCL_VERTEX_ARRAY_ATTRIB(0),
+ nv50->vtxelt_nr);
for (i = 0; i < nv50->vtxelt_nr; i++) {
struct pipe_vertex_element *ve = &nv50->vtxelt[i];
struct pipe_vertex_buffer *vb =
&nv50->vtxbuf[ve->vertex_buffer_index];
struct nouveau_bo *bo = nouveau_bo(vb->buffer);
+ uint32_t hw = nv50_vbo_vtxelt_to_hw(ve);
- switch (ve->src_format) {
- case PIPE_FORMAT_R32G32B32A32_FLOAT:
- so_data(vtxfmt, 0x7e080000 | i);
- break;
- case PIPE_FORMAT_R32G32B32_FLOAT:
- so_data(vtxfmt, 0x7e100000 | i);
- break;
- case PIPE_FORMAT_R32G32_FLOAT:
- so_data(vtxfmt, 0x7e200000 | i);
- break;
- case PIPE_FORMAT_R32_FLOAT:
- so_data(vtxfmt, 0x7e900000 | i);
- break;
- case PIPE_FORMAT_R8G8B8A8_UNORM:
- so_data(vtxfmt, 0x24500000 | i);
- break;
- default:
- {
- NOUVEAU_ERR("invalid vbo format %s\n",
- pf_name(ve->src_format));
- assert(0);
- return;
- }
+ if (!vb->stride &&
+ nv50_vbo_static_attrib(nv50, i, &vtxattr, ve, vb)) {
+ so_data(vtxfmt, hw | (1 << 4));
+
+ so_method(vtxbuf, tesla,
+ NV50TCL_VERTEX_ARRAY_FORMAT(i), 1);
+ so_data (vtxbuf, 0);
+ continue;
}
+ so_data(vtxfmt, hw | i);
- so_method(vtxbuf, tesla, 0x900 + (i * 16), 3);
+ so_method(vtxbuf, tesla, NV50TCL_VERTEX_ARRAY_FORMAT(i), 3);
so_data (vtxbuf, 0x20000000 | vb->stride);
so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
@@ -251,11 +379,22 @@ nv50_vbo_validate(struct nv50_context *nv50)
so_reloc (vtxbuf, bo, vb->buffer_offset +
ve->src_offset, NOUVEAU_BO_VRAM | NOUVEAU_BO_GART |
NOUVEAU_BO_RD | NOUVEAU_BO_LOW, 0, 0);
+
+ /* vertex array limits */
+ so_method(vtxbuf, tesla, 0x1080 + (i * 8), 2);
+ so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
+ NOUVEAU_BO_HIGH, 0, 0);
+ so_reloc (vtxbuf, bo, vb->buffer->size - 1,
+ NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | NOUVEAU_BO_RD |
+ NOUVEAU_BO_LOW, 0, 0);
}
so_ref (vtxfmt, &nv50->state.vtxfmt);
so_ref (vtxbuf, &nv50->state.vtxbuf);
+ so_ref (vtxattr, &nv50->state.vtxattr);
so_ref (NULL, &vtxbuf);
so_ref (NULL, &vtxfmt);
+ so_ref (NULL, &vtxattr);
}
diff --git a/src/gallium/drivers/r300/Makefile b/src/gallium/drivers/r300/Makefile
index faceec9842..93c2152edc 100644
--- a/src/gallium/drivers/r300/Makefile
+++ b/src/gallium/drivers/r300/Makefile
@@ -21,6 +21,22 @@ C_SOURCES = \
r300_state_invariant.c \
r300_vs.c \
r300_surface.c \
- r300_texture.c
+ r300_texture.c \
+ r300_tgsi_to_rc.c
+
+LIBRARY_INCLUDES = \
+ -I$(TOP)/src/mesa/drivers/dri/r300/compiler \
+ -I$(TOP)/src/mesa \
+ -I$(TOP)/include
+
+COMPILER_ARCHIVE = $(TOP)/src/mesa/drivers/dri/r300/compiler/libr300compiler.a
+
+EXTRA_OBJECTS = \
+ $(COMPILER_ARCHIVE)
include ../../Makefile.template
+
+.PHONY : $(COMPILER_ARCHIVE)
+
+$(COMPILER_ARCHIVE):
+ cd $(TOP)/src/mesa/drivers/dri/r300/compiler; make
diff --git a/src/gallium/drivers/r300/r300_chipset.c b/src/gallium/drivers/r300/r300_chipset.c
index 00fae8d26f..d138866d33 100644
--- a/src/gallium/drivers/r300/r300_chipset.c
+++ b/src/gallium/drivers/r300/r300_chipset.c
@@ -30,9 +30,11 @@
void r300_parse_chipset(struct r300_capabilities* caps)
{
/* Reasonable defaults */
+ caps->num_vert_fpus = 4;
caps->has_tcl = getenv("RADEON_NO_TCL") ? FALSE : TRUE;
caps->is_r500 = FALSE;
- caps->num_vert_fpus = 4;
+ caps->high_second_pipe = FALSE;
+
/* Note: These are not ordered by PCI ID. I leave that task to GCC,
* which will perform the ordering while collating jump tables. Instead,
@@ -40,6 +42,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
switch (caps->pci_id) {
case 0x4144:
caps->family = CHIP_FAMILY_R300;
+ caps->high_second_pipe = TRUE;
break;
case 0x4145:
@@ -50,6 +53,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x4E46:
case 0x4E47:
caps->family = CHIP_FAMILY_R300;
+ caps->high_second_pipe = TRUE;
break;
case 0x4150:
@@ -66,6 +70,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x4E54:
case 0x4E56:
caps->family = CHIP_FAMILY_RV350;
+ caps->high_second_pipe = TRUE;
break;
case 0x4148:
@@ -76,10 +81,12 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x4E49:
case 0x4E4B:
caps->family = CHIP_FAMILY_R350;
+ caps->high_second_pipe = TRUE;
break;
case 0x4E4A:
caps->family = CHIP_FAMILY_R360;
+ caps->high_second_pipe = TRUE;
break;
case 0x5460:
@@ -91,6 +98,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x5B64:
case 0x5B65:
caps->family = CHIP_FAMILY_RV370;
+ caps->high_second_pipe = TRUE;
break;
case 0x3150:
@@ -99,6 +107,7 @@ void r300_parse_chipset(struct r300_capabilities* caps)
case 0x3E50:
case 0x3E54:
caps->family = CHIP_FAMILY_RV380;
+ caps->high_second_pipe = TRUE;
break;
case 0x4A48:
diff --git a/src/gallium/drivers/r300/r300_chipset.h b/src/gallium/drivers/r300/r300_chipset.h
index 5b2e1f0568..322d4a57e4 100644
--- a/src/gallium/drivers/r300/r300_chipset.h
+++ b/src/gallium/drivers/r300/r300_chipset.h
@@ -34,6 +34,8 @@ struct r300_capabilities {
int family;
/* The number of vertex floating-point units */
int num_vert_fpus;
+ /* The number of fragment pipes */
+ int num_frag_pipes;
/* Whether or not TCL is physically present */
boolean has_tcl;
/* Whether or not this is an RV515 or newer; R500s have many differences
@@ -42,6 +44,8 @@ struct r300_capabilities {
* - Blend color is split across two registers
* - Universal Shader (US) block used for fragment shaders */
boolean is_r500;
+ /* Whether or not the second pixel pipe is accessed with the high bit */
+ boolean high_second_pipe;
};
/* Enumerations for legibility and telling which card we're running on. */
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 233a32b53c..9cc455135d 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -22,6 +22,9 @@
#include "r300_context.h"
+#include "r300_flush.h"
+#include "r300_state_invariant.h"
+
static boolean r300_draw_range_elements(struct pipe_context* pipe,
struct pipe_buffer* indexBuffer,
unsigned indexSize,
@@ -52,7 +55,7 @@ static boolean r300_draw_range_elements(struct pipe_context* pipe,
draw_set_mapped_constant_buffer(r300->draw,
r300->shader_constants[PIPE_SHADER_VERTEX].constants,
- r300->shader_constants[PIPE_SHADER_VERTEX].user_count *
+ r300->shader_constants[PIPE_SHADER_VERTEX].count *
(sizeof(float) * 4));
draw_arrays(r300->draw, mode, start, count);
@@ -88,9 +91,21 @@ static boolean r300_draw_arrays(struct pipe_context* pipe, unsigned mode,
static void r300_destroy_context(struct pipe_context* context) {
struct r300_context* r300 = r300_context(context);
+ struct r300_query* query, * temp;
draw_destroy(r300->draw);
+ /* Free the OQ BO. */
+ context->screen->buffer_destroy(r300->oqbo);
+
+ /* If there are any queries pending or not destroyed, remove them now. */
+ if (r300->query_list) {
+ foreach_s(query, temp, r300->query_list) {
+ remove_from_list(query);
+ FREE(query);
+ }
+ }
+
FREE(r300->blend_color_state);
FREE(r300->rs_block);
FREE(r300->scissor_state);
@@ -134,6 +149,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.winsys = (struct pipe_winsys*)r300_winsys;
r300->context.screen = r300_screen(screen);
+ r300_init_debug(r300);
+
r300->context.destroy = r300_destroy_context;
r300->context.clear = r300_clear;
@@ -145,6 +162,11 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
r300->context.is_texture_referenced = r300_is_texture_referenced;
r300->context.is_buffer_referenced = r300_is_buffer_referenced;
+ r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
+ r300->rs_block = CALLOC_STRUCT(r300_rs_block);
+ r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
+ r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
+
/* Create a Draw. This is used for vert collation and SW TCL. */
r300->draw = draw_create();
/* Enable our renderer. */
@@ -155,10 +177,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
* transform in hardware, always. */
draw_set_viewport_state(r300->draw, &r300_viewport_identity);
- r300->blend_color_state = CALLOC_STRUCT(r300_blend_color_state);
- r300->rs_block = CALLOC_STRUCT(r300_rs_block);
- r300->scissor_state = CALLOC_STRUCT(r300_scissor_state);
- r300->viewport_state = CALLOC_STRUCT(r300_viewport_state);
+ /* Open up the OQ BO. */
+ r300->oqbo = screen->buffer_create(screen, 4096,
+ PIPE_BUFFER_USAGE_VERTEX, 4096);
r300_init_flush_functions(r300);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index d891fd6265..52b1c9a6b2 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -25,15 +25,22 @@
#include "draw/draw_context.h"
#include "draw/draw_vertex.h"
+
#include "pipe/p_context.h"
+
#include "tgsi/tgsi_scan.h"
+
#include "util/u_memory.h"
+#include "util/u_simple_list.h"
#include "r300_clear.h"
#include "r300_query.h"
#include "r300_screen.h"
#include "r300_winsys.h"
+struct r300_fragment_shader;
+struct r300_vertex_shader;
+
struct r300_blend_state {
uint32_t blend_control; /* R300_RB3D_CBLEND: 0x4e04 */
uint32_t alpha_blend_control; /* R300_RB3D_ABLEND: 0x4e08 */
@@ -143,69 +150,31 @@ struct r300_constant_buffer {
/* Buffer of constants */
/* XXX first number should be raised */
float constants[32][4];
- /* Number of user-defined constants */
- unsigned user_count;
/* Total number of constants */
unsigned count;
};
-struct r300_fragment_shader {
- /* Parent class */
- struct pipe_shader_state state;
- struct tgsi_shader_info info;
-
- /* Has this shader been translated yet? */
- boolean translated;
-
- /* Pixel stack size */
- int stack_size;
-
- /* Are there immediates in this shader?
- * If not, we can heavily optimize recompilation. */
- boolean uses_imms;
-};
-
-struct r3xx_fragment_shader {
- /* Parent class */
- struct r300_fragment_shader shader;
-
- /* Number of ALU instructions */
- int alu_instruction_count;
-
- /* Number of texture instructions */
- int tex_instruction_count;
-
- /* Number of texture indirections */
- int indirections;
-
- /* Indirection node offsets */
- int alu_offset[4];
-
- /* Machine instructions */
- struct {
- uint32_t alu_rgb_inst;
- uint32_t alu_rgb_addr;
- uint32_t alu_alpha_inst;
- uint32_t alu_alpha_addr;
- } instructions[64]; /* XXX magic num */
-};
-
-struct r5xx_fragment_shader {
- /* Parent class */
- struct r300_fragment_shader shader;
-
- /* Number of used instructions */
- int instruction_count;
-
- /* Machine instructions */
- struct {
- uint32_t inst0;
- uint32_t inst1;
- uint32_t inst2;
- uint32_t inst3;
- uint32_t inst4;
- uint32_t inst5;
- } instructions[256]; /*< XXX magic number */
+/* Query object.
+ *
+ * This is not a subclass of pipe_query because pipe_query is never
+ * actually fully defined. So, rather than have it as a member, and do
+ * subclass-style casting, we treat pipe_query as an opaque, and just
+ * trust that our state tracker does not ever mess up query objects.
+ */
+struct r300_query {
+ /* The kind of query. Currently only OQ is supported. */
+ unsigned type;
+ /* Whether this query is currently active. Only active queries will
+ * get emitted into the command stream, and only active queries get
+ * tallied. */
+ boolean active;
+ /* The current count of this query. Required to be at least 32 bits. */
+ unsigned int count;
+ /* The offset of this query into the query buffer, in bytes. */
+ unsigned offset;
+ /* Linked list members. */
+ struct r300_query* prev;
+ struct r300_query* next;
};
struct r300_texture {
@@ -215,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;
@@ -242,37 +218,7 @@ struct r300_vertex_format {
int fs_tab[16];
};
-struct r300_vertex_shader {
- /* Parent class */
- struct pipe_shader_state state;
- struct tgsi_shader_info info;
-
- /* Fallback shader, because Draw has issues */
- struct draw_vertex_shader* draw;
-
- /* Has this shader been translated yet? */
- boolean translated;
-
- /* Are there immediates in this shader?
- * If not, we can heavily optimize recompilation. */
- boolean uses_imms;
-
- /* Number of used instructions */
- int instruction_count;
-
- /* Machine instructions */
- struct {
- uint32_t inst0;
- uint32_t inst1;
- uint32_t inst2;
- uint32_t inst3;
- } instructions[128]; /*< XXX magic number */
-};
-
-static struct pipe_viewport_state r300_viewport_identity = {
- .scale = {1.0, 1.0, 1.0, 1.0},
- .translate = {0.0, 0.0, 0.0, 0.0},
-};
+extern struct pipe_viewport_state r300_viewport_identity;
struct r300_context {
/* Parent class */
@@ -288,6 +234,11 @@ struct r300_context {
/* Offset into the VBO. */
size_t vbo_offset;
+ /* Occlusion query buffer. */
+ struct pipe_buffer* oqbo;
+ /* Query list. */
+ struct r300_query* query_list;
+
/* Various CSO state objects. */
/* Blend state. */
struct r300_blend_state* blend_state;
@@ -328,6 +279,9 @@ struct r300_context {
uint32_t dirty_state;
/* Flag indicating whether or not the HW is dirty. */
uint32_t dirty_hw;
+
+ /** Combination of DBG_xxx flags */
+ unsigned debug;
};
/* Convenience cast wrapper. */
@@ -341,4 +295,40 @@ struct draw_stage* r300_draw_stage(struct r300_context* r300);
void r300_init_state_functions(struct r300_context* r300);
void r300_init_surface_functions(struct r300_context* r300);
+/* Debug functionality. */
+
+/**
+ * Debug flags to disable/enable certain groups of debugging outputs.
+ *
+ * \note These may be rather coarse, and the grouping may be impractical.
+ * If you find, while debugging the driver, that a different grouping
+ * of these flags would be beneficial, just feel free to change them
+ * but make sure to update the documentation in r300_debug.c to reflect
+ * those changes.
+ */
+/*@{*/
+#define DBG_HELP 0x0000001
+#define DBG_FP 0x0000002
+#define DBG_VP 0x0000004
+#define DBG_CS 0x0000008
+#define DBG_DRAW 0x0000010
+/*@}*/
+
+static INLINE boolean DBG_ON(struct r300_context * ctx, unsigned flags)
+{
+ return (ctx->debug & flags) ? true : false;
+}
+
+static INLINE void DBG(struct r300_context * ctx, unsigned flags, const char * fmt, ...)
+{
+ if (DBG_ON(ctx, flags)) {
+ va_list va;
+ va_start(va, fmt);
+ debug_vprintf(fmt, va);
+ va_end(va);
+ }
+}
+
+void r300_init_debug(struct r300_context * ctx);
+
#endif /* R300_CONTEXT_H */
diff --git a/src/gallium/drivers/r300/r300_cs.h b/src/gallium/drivers/r300/r300_cs.h
index 71b142c0db..0a7e470363 100644
--- a/src/gallium/drivers/r300/r300_cs.h
+++ b/src/gallium/drivers/r300/r300_cs.h
@@ -49,7 +49,8 @@
(RADEON_CP_PACKET0 | ((count) << 16) | ((register) >> 2))
#define CS_LOCALS(context) \
- struct r300_winsys* cs_winsys = context->winsys; \
+ struct r300_context* const cs_context_copy = (context); \
+ struct r300_winsys* cs_winsys = cs_context_copy->winsys; \
int cs_count = 0;
#define CHECK_CS(size) \
@@ -58,7 +59,7 @@
#define BEGIN_CS(size) do { \
CHECK_CS(size); \
if (VERY_VERBOSE_CS) { \
- debug_printf("r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
+ DBG(cs_context_copy, DBG_CS, "r300: BEGIN_CS, count %d, in %s (%s:%d)\n", \
size, __FUNCTION__, __FILE__, __LINE__); \
} \
cs_winsys->begin_cs(cs_winsys, (size), \
@@ -78,7 +79,7 @@
#define OUT_CS_REG(register, value) do { \
if (VERY_VERBOSE_REGISTERS) \
- debug_printf("r300: writing 0x%08X to register 0x%04X\n", \
+ DBG(cs_context_copy, DBG_CS, "r300: writing 0x%08X to register 0x%04X\n", \
value, register); \
assert(register); \
OUT_CS(CP_PACKET0(register, 0)); \
@@ -89,14 +90,14 @@
* not the actual packet0 count! */
#define OUT_CS_REG_SEQ(register, count) do { \
if (VERY_VERBOSE_REGISTERS) \
- debug_printf("r300: writing register sequence of %d to 0x%04X\n", \
+ DBG(cs_context_copy, DBG_CS, "r300: writing register sequence of %d to 0x%04X\n", \
count, register); \
assert(register); \
OUT_CS(CP_PACKET0(register, ((count) - 1))); \
} while (0)
#define OUT_CS_RELOC(bo, offset, rd, wd, flags) do { \
- debug_printf("r300: writing relocation for buffer %p, offset %d, " \
+ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for buffer %p, offset %d, " \
"domains (%d, %d, %d)\n", \
bo, offset, rd, wd, flags); \
assert(bo); \
@@ -107,7 +108,7 @@
#define END_CS do { \
if (VERY_VERBOSE_CS) { \
- debug_printf("r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
+ DBG(cs_context_copy, DBG_CS, "r300: END_CS in %s (%s:%d)\n", __FUNCTION__, \
__FILE__, __LINE__); \
} \
if (cs_count != 0) \
@@ -117,7 +118,7 @@
#define FLUSH_CS do { \
if (VERY_VERBOSE_CS) { \
- debug_printf("r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \
+ DBG(cs_context_copy, DBG_CS, "r300: FLUSH_CS in %s (%s:%d)\n\n", __FUNCTION__, \
__FILE__, __LINE__); \
} \
cs_winsys->flush_cs(cs_winsys); \
@@ -127,7 +128,7 @@
#define OUT_CS_ONE_REG(register, count) do { \
if (VERY_VERBOSE_REGISTERS) \
- debug_printf("r300: writing data sequence of %d to 0x%04X\n", \
+ DBG(cs_context_copy, DBG_CS, "r300: writing data sequence of %d to 0x%04X\n", \
count, register); \
assert(register); \
OUT_CS(CP_PACKET0(register, ((count) - 1)) | RADEON_ONE_REG_WR); \
@@ -141,7 +142,7 @@
} while (0)
#define OUT_CS_INDEX_RELOC(bo, offset, count, rd, wd, flags) do { \
- debug_printf("r300: writing relocation for index buffer %p," \
+ DBG(cs_context_copy, DBG_CS, "r300: writing relocation for index buffer %p," \
"offset %d\n", bo, offset); \
assert(bo); \
OUT_CS(offset); \
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index c83e8526cf..15308dda1d 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2009 Nicolai Haehnle <nhaehnle@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -20,179 +20,69 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
-#include "r300_debug.h"
+#include "r300_context.h"
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs)
-{
- int i;
+#include <ctype.h>
- for (i = 0; i < fs->alu_instruction_count; i++) {
- }
-}
-void r5xx_fs_dump(struct r5xx_fragment_shader* fs)
-{
- int i;
- uint32_t inst;
+struct debug_option {
+ const char * name;
+ unsigned flag;
+ const char * description;
+};
- for (i = 0; i < fs->instruction_count; i++) {
- inst = fs->instructions[i].inst0;
- debug_printf("%d: 0: CMN_INST 0x%08x:", i, inst);
- switch (inst & 0x3) {
- case R500_INST_TYPE_ALU:
- debug_printf("ALU ");
- break;
- case R500_INST_TYPE_OUT:
- debug_printf("OUT ");
- break;
- case R500_INST_TYPE_FC:
- debug_printf("FC ");
- break;
- case R500_INST_TYPE_TEX:
- debug_printf("TEX ");
- break;
- }
- debug_printf("%s %s %s %s ",
- inst & R500_INST_TEX_SEM_WAIT ? "TEX_WAIT" : "",
- inst & R500_INST_LAST ? "LAST" : "",
- inst & R500_INST_NOP ? "NOP" : "",
- inst & R500_INST_ALU_WAIT ? "ALU_WAIT" : "");
- debug_printf("wmask: %s omask: %s\n",
- r5xx_fs_mask[(inst >> 11) & 0xf],
- r5xx_fs_mask[(inst >> 15) & 0xf]);
- switch (inst & 0x3) {
- case R500_INST_TYPE_ALU:
- case R500_INST_TYPE_OUT:
- inst = fs->instructions[i].inst1;
- debug_printf(" 1: RGB_ADDR 0x%08x:", inst);
- debug_printf("Addr0: %d%c, Addr1: %d%c, "
- "Addr2: %d%c, srcp:%d\n",
- inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
- (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
- (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
- (inst >> 30));
+static struct debug_option debug_options[] = {
+ { "help", DBG_HELP, "Helpful meta-information about the driver" },
+ { "fp", DBG_FP, "Fragment program handling" },
+ { "vp", DBG_VP, "Vertex program handling" },
+ { "cs", DBG_CS, "Command submissions" },
+ { "draw", DBG_DRAW, "Draw and emit" },
- inst = fs->instructions[i].inst2;
- debug_printf(" 2: ALPHA_ADDR 0x%08x:", inst);
- debug_printf("Addr0: %d%c, Addr1: %d%c, "
- "Addr2: %d%c, srcp:%d\n",
- inst & 0xff, (inst & (1 << 8)) ? 'c' : 't',
- (inst >> 10) & 0xff, (inst & (1 << 18)) ? 'c' : 't',
- (inst >> 20) & 0xff, (inst & (1 << 28)) ? 'c' : 't',
- (inst >> 30));
+ { "all", ~0, "Convenience option that enables all debug flags" },
- inst = fs->instructions[i].inst3;
- debug_printf(" 3: RGB_INST 0x%08x:", inst);
- debug_printf("rgb_A_src:%d %s/%s/%s %d "
- "rgb_B_src:%d %s/%s/%s %d\n",
- inst & 0x3, r5xx_fs_swiz[(inst >> 2) & 0x7],
- r5xx_fs_swiz[(inst >> 5) & 0x7],
- r5xx_fs_swiz[(inst >> 8) & 0x7],
- (inst >> 11) & 0x3, (inst >> 13) & 0x3,
- r5xx_fs_swiz[(inst >> 15) & 0x7],
- r5xx_fs_swiz[(inst >> 18) & 0x7],
- r5xx_fs_swiz[(inst >> 21) & 0x7],
- (inst >> 24) & 0x3);
+ /* must be last */
+ { 0, 0, 0 }
+};
- inst = fs->instructions[i].inst4;
- debug_printf(" 4: ALPHA_INST 0x%08x:", inst);
- debug_printf("%s dest:%d%s alp_A_src:%d %s %d "
- "alp_B_src:%d %s %d w:%d\n",
- r5xx_fs_op_alpha[inst & 0xf], (inst >> 4) & 0x7f,
- inst & (1<<11) ? "(rel)":"", (inst >> 12) & 0x3,
- r5xx_fs_swiz[(inst >> 14) & 0x7], (inst >> 17) & 0x3,
- (inst >> 19) & 0x3, r5xx_fs_swiz[(inst >> 21) & 0x7],
- (inst >> 24) & 0x3, (inst >> 31) & 0x1);
+void r300_init_debug(struct r300_context * ctx)
+{
+ const char * options = debug_get_option("RADEON_DEBUG", 0);
+ boolean printhint = false;
- inst = fs->instructions[i].inst5;
- debug_printf(" 5: RGBA_INST 0x%08x:", inst);
- debug_printf("%s dest:%d%s rgb_C_src:%d %s/%s/%s %d "
- "alp_C_src:%d %s %d\n",
- r5xx_fs_op_rgb[inst & 0xf], (inst >> 4) & 0x7f,
- inst & (1 << 11) ? "(rel)":"", (inst >> 12) & 0x3,
- r5xx_fs_swiz[(inst >> 14) & 0x7],
- r5xx_fs_swiz[(inst >> 17) & 0x7],
- r5xx_fs_swiz[(inst >> 20) & 0x7],
- (inst >> 23) & 0x3, (inst >> 25) & 0x3,
- r5xx_fs_swiz[(inst >> 27) & 0x7], (inst >> 30) & 0x3);
- break;
- case R500_INST_TYPE_FC:
- /* XXX don't even bother yet */
- break;
- case R500_INST_TYPE_TEX:
- inst = fs->instructions[i].inst1;
- debug_printf(" 1: TEX_INST 0x%08x: id: %d "
- "op:%s, %s, %s %s\n",
- inst, (inst >> 16) & 0xf,
- r5xx_fs_tex[(inst >> 22) & 0x7],
- (inst & (1 << 25)) ? "ACQ" : "",
- (inst & (1 << 26)) ? "IGNUNC" : "",
- (inst & (1 << 27)) ? "UNSCALED" : "SCALED");
+ if (options) {
+ while(*options) {
+ if (*options == ' ' || *options == ',') {
+ options++;
+ continue;
+ }
- inst = fs->instructions[i].inst2;
- debug_printf(" 2: TEX_ADDR 0x%08x: "
- "src: %d%s %s/%s/%s/%s dst: %d%s %s/%s/%s/%s\n",
- inst, inst & 0x7f, inst & (1 << 7) ? "(rel)" : "",
- r5xx_fs_swiz[(inst >> 8) & 0x3],
- r5xx_fs_swiz[(inst >> 10) & 0x3],
- r5xx_fs_swiz[(inst >> 12) & 0x3],
- r5xx_fs_swiz[(inst >> 14) & 0x3],
- (inst >> 16) & 0x7f, inst & (1 << 23) ? "(rel)" : "",
- r5xx_fs_swiz[(inst >> 24) & 0x3],
- r5xx_fs_swiz[(inst >> 26) & 0x3],
- r5xx_fs_swiz[(inst >> 28) & 0x3],
- r5xx_fs_swiz[(inst >> 30) & 0x3]);
-
- inst = fs->instructions[i].inst3;
- debug_printf(" 3: TEX_DXDY 0x%08x\n", inst);
- break;
- }
- }
-}
+ size_t length = strcspn(options, " ,");
+ struct debug_option * opt;
-static void r300_vs_op_dump(uint32_t op)
-{
- debug_printf(" dst: %d%s op: ",
- (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
- if (op & 0x80) {
- if (op & 0x1) {
- debug_printf("PVS_MACRO_OP_2CLK_M2X_ADD\n");
- } else {
- debug_printf(" PVS_MACRO_OP_2CLK_MADD\n");
- }
- } else if (op & 0x40) {
- debug_printf("%s\n", r300_vs_me_ops[op & 0x1f]);
- } else {
- debug_printf("%s\n", r300_vs_ve_ops[op & 0x1f]);
- }
-}
+ for(opt = debug_options; opt->name; ++opt) {
+ if (!strncmp(options, opt->name, length)) {
+ ctx->debug |= opt->flag;
+ break;
+ }
+ }
-void r300_vs_src_dump(uint32_t src)
-{
- debug_printf(" reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
- (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
- src & (1 << 25) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 13) & 0x7],
- src & (1 << 26) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 16) & 0x7],
- src & (1 << 27) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 19) & 0x7],
- src & (1 << 28) ? "-" : " ",
- r300_vs_swiz_debug[(src >> 22) & 0x7]);
-}
+ if (!opt->name) {
+ debug_printf("Unknown debug option: %s\n", options);
+ printhint = true;
+ }
-void r300_vs_dump(struct r300_vertex_shader* vs)
-{
- int i;
+ options += length;
+ }
- for (i = 0; i < vs->instruction_count; i++) {
- debug_printf("%d: op: 0x%08x", i, vs->instructions[i].inst0);
- r300_vs_op_dump(vs->instructions[i].inst0);
- debug_printf(" src0: 0x%08x", vs->instructions[i].inst1);
- r300_vs_src_dump(vs->instructions[i].inst1);
- debug_printf(" src1: 0x%08x", vs->instructions[i].inst2);
- r300_vs_src_dump(vs->instructions[i].inst2);
- debug_printf(" src2: 0x%08x", vs->instructions[i].inst3);
- r300_vs_src_dump(vs->instructions[i].inst3);
+ if (!ctx->debug)
+ printhint = true;
+ }
+
+ if (printhint || ctx->debug & DBG_HELP) {
+ debug_printf("You can enable debug output by setting the RADEON_DEBUG environment variable\n"
+ "to a comma-separated list of debug options. Available options are:\n");
+ for(struct debug_option * opt = debug_options; opt->name; ++opt) {
+ debug_printf(" %s: %s\n", opt->name, opt->description);
+ }
}
}
diff --git a/src/gallium/drivers/r300/r300_debug.h b/src/gallium/drivers/r300/r300_debug.h
deleted file mode 100644
index 6b58c1e250..0000000000
--- a/src/gallium/drivers/r300/r300_debug.h
+++ /dev/null
@@ -1,211 +0,0 @@
-/*
- * Copyright 2009 Corbin Simpson <MostAwesomeDude@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef R300_DEBUG_H
-#define R300_DEBUG_H
-
-#include "r300_reg.h"
-#include "r300_fs.h"
-#include "r300_vs.h"
-
-static char* r5xx_fs_swiz[] = {
- " R",
- " G",
- " B",
- " A",
- " 0",
- ".5",
- " 1",
- " U",
-};
-
-static char* r5xx_fs_op_rgb[] = {
- "MAD",
- "DP3",
- "DP4",
- "D2A",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "SOP",
- "MDH",
- "MDV",
-};
-
-static char* r5xx_fs_op_alpha[] = {
- "MAD",
- " DP",
- "MIN",
- "MAX",
- "---",
- "CND",
- "CMP",
- "FRC",
- "EX2",
- "LN2",
- "RCP",
- "RSQ",
- "SIN",
- "COS",
- "MDH",
- "MDV",
-};
-
-static char* r5xx_fs_mask[] = {
- "NONE",
- "R ",
- " G ",
- "RG ",
- " B ",
- "R B ",
- " GB ",
- "RGB ",
- " A",
- "R A",
- " G A",
- "RG A",
- " BA",
- "R BA",
- " GBA",
- "RGBA",
-};
-
-static char* r5xx_fs_tex[] = {
- " NOP",
- " LD",
- "TEXKILL",
- " PROJ",
- "LODBIAS",
- " LOD",
- " DXDY",
-};
-
-static char* r300_vs_ve_ops[] = {
- /* R300 vector ops */
- " VE_NO_OP",
- " VE_DOT_PRODUCT",
- " VE_MULTIPLY",
- " VE_ADD",
- " VE_MULTIPLY_ADD",
- " VE_DISTANCE_FACTOR",
- " VE_FRACTION",
- " VE_MAXIMUM",
- " VE_MINIMUM",
- "VE_SET_GREATER_THAN_EQUAL",
- " VE_SET_LESS_THAN",
- " VE_MULTIPLYX2_ADD",
- " VE_MULTIPLY_CLAMP",
- " VE_FLT2FIX_DX",
- " VE_FLT2FIX_DX_RND",
- /* R500 vector ops */
- " VE_PRED_SET_EQ_PUSH",
- " VE_PRED_SET_GT_PUSH",
- " VE_PRED_SET_GTE_PUSH",
- " VE_PRED_SET_NEQ_PUSH",
- " VE_COND_WRITE_EQ",
- " VE_COND_WRITE_GT",
- " VE_COND_WRITE_GTE",
- " VE_COND_WRITE_NEQ",
- " VE_SET_GREATER_THAN",
- " VE_SET_EQUAL",
- " VE_SET_NOT_EQUAL",
- " (reserved)",
- " (reserved)",
- " (reserved)",
-};
-
-static char* r300_vs_me_ops[] = {
- /* R300 math ops */
- " ME_NO_OP",
- " ME_EXP_BASE2_DX",
- " ME_LOG_BASE2_DX",
- " ME_EXP_BASEE_FF",
- " ME_LIGHT_COEFF_DX",
- " ME_POWER_FUNC_FF",
- " ME_RECIP_DX",
- " ME_RECIP_FF",
- " ME_RECIP_SQRT_DX",
- " ME_RECIP_SQRT_FF",
- " ME_MULTIPLY",
- " ME_EXP_BASE2_FULL_DX",
- " ME_LOG_BASE2_FULL_DX",
- " ME_POWER_FUNC_FF_CLAMP_B",
- "ME_POWER_FUNC_FF_CLAMP_B1",
- "ME_POWER_FUNC_FF_CLAMP_01",
- " ME_SIN",
- " ME_COS",
- /* R500 math ops */
- " ME_LOG_BASE2_IEEE",
- " ME_RECIP_IEEE",
- " ME_RECIP_SQRT_IEEE",
- " ME_PRED_SET_EQ",
- " ME_PRED_SET_GT",
- " ME_PRED_SET_GTE",
- " ME_PRED_SET_NEQ",
- " ME_PRED_SET_CLR",
- " ME_PRED_SET_INV",
- " ME_PRED_SET_POP",
- " ME_PRED_SET_RESTORE",
- " (reserved)",
- " (reserved)",
- " (reserved)",
-};
-
-/* XXX refactor to avoid clashing symbols */
-static char* r300_vs_src_debug[] = {
- "t",
- "i",
- "c",
- "a",
-};
-
-static char* r300_vs_dst_debug[] = {
- "t",
- "a0",
- "o",
- "ox",
- "a",
- "i",
- "u",
- "u",
-};
-
-static char* r300_vs_swiz_debug[] = {
- "X",
- "Y",
- "Z",
- "W",
- "0",
- "1",
- "U",
- "U",
-};
-
-void r5xx_fs_dump(struct r5xx_fragment_shader* fs);
-void r3xx_dump_fs(struct r3xx_fragment_shader* fs);
-
-void r300_vs_dump(struct r300_vertex_shader* vs);
-
-#endif /* R300_DEBUG_H */
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 7ba56cdc1d..a1b36ba2ed 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -24,6 +24,10 @@
#include "r300_emit.h"
+#include "r300_fs.h"
+#include "r300_state_derived.h"
+#include "r300_vs.h"
+
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend)
{
@@ -109,73 +113,158 @@ void r300_emit_dsa_state(struct r300_context* r300,
END_CS;
}
-void r300_emit_fragment_shader(struct r300_context* r300,
- struct r3xx_fragment_shader* fs)
+static const float * get_shader_constant(
+ struct r300_context * r300,
+ struct rc_constant * constant,
+ struct r300_constant_buffer * externals)
{
+ static const float zero[4] = { 0.0, 0.0, 0.0, 0.0 };
+ switch(constant->Type) {
+ case RC_CONSTANT_EXTERNAL:
+ return externals->constants[constant->u.External];
+
+ case RC_CONSTANT_IMMEDIATE:
+ return constant->u.Immediate;
+
+ default:
+ debug_printf("r300: Implementation error: Unhandled constant type %i\n",
+ constant->Type);
+ return zero;
+ }
+}
+
+/* Convert a normal single-precision float into the 7.16 format
+ * used by the R300 fragment shader.
+ */
+static uint32_t pack_float24(float f)
+{
+ union {
+ float fl;
+ uint32_t u;
+ } u;
+ float mantissa;
+ int exponent;
+ uint32_t float24 = 0;
+
+ if (f == 0.0)
+ return 0;
+
+ u.fl = f;
+
+ mantissa = frexpf(f, &exponent);
+
+ /* Handle -ve */
+ if (mantissa < 0) {
+ float24 |= (1 << 23);
+ mantissa = mantissa * -1.0;
+ }
+ /* Handle exponent, bias of 63 */
+ exponent += 62;
+ float24 |= (exponent << 16);
+ /* Kill 7 LSB of mantissa */
+ float24 |= (u.u & 0x7FFFFF) >> 7;
+
+ return float24;
+}
+
+void r300_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals)
+{
+ struct r300_fragment_program_code * code = &generic_code->code.r300;
+ struct rc_constant_list * constants = &generic_code->constants;
int i;
CS_LOCALS(r300);
- BEGIN_CS(22);
-
- OUT_CS_REG(R300_US_CONFIG, fs->indirections);
- OUT_CS_REG(R300_US_PIXSIZE, fs->shader.stack_size);
- /* XXX figure out exactly how big the sizes are on this reg */
- OUT_CS_REG(R300_US_CODE_OFFSET, 0x40);
- /* XXX figure these ones out a bit better kthnx */
- OUT_CS_REG(R300_US_CODE_ADDR_0, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_1, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_2, 0x0);
- OUT_CS_REG(R300_US_CODE_ADDR_3, 0x40 | R300_RGBA_OUT);
-
- for (i = 0; i < fs->alu_instruction_count; i++) {
- OUT_CS_REG(R300_US_ALU_RGB_INST_0 + (4 * i),
- fs->instructions[i].alu_rgb_inst);
- OUT_CS_REG(R300_US_ALU_RGB_ADDR_0 + (4 * i),
- fs->instructions[i].alu_rgb_addr);
- OUT_CS_REG(R300_US_ALU_ALPHA_INST_0 + (4 * i),
- fs->instructions[i].alu_alpha_inst);
- OUT_CS_REG(R300_US_ALU_ALPHA_ADDR_0 + (4 * i),
- fs->instructions[i].alu_alpha_addr);
+ BEGIN_CS(15 +
+ code->alu.length * 4 +
+ (code->tex.length ? (1 + code->tex.length) : 0) +
+ (constants->Count ? (1 + constants->Count * 4) : 0));
+
+ OUT_CS_REG(R300_US_CONFIG, code->config);
+ OUT_CS_REG(R300_US_PIXSIZE, code->pixsize);
+ OUT_CS_REG(R300_US_CODE_OFFSET, code->code_offset);
+
+ OUT_CS_REG_SEQ(R300_US_CODE_ADDR_0, 4);
+ for(i = 0; i < 4; ++i)
+ OUT_CS(code->code_addr[i]);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_RGB_INST_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].rgb_inst);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_RGB_ADDR_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].rgb_addr);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_INST_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].alpha_inst);
+
+ OUT_CS_REG_SEQ(R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
+ for (i = 0; i < code->alu.length; i++)
+ OUT_CS(code->alu.inst[i].alpha_addr);
+
+ if (code->tex.length) {
+ OUT_CS_REG_SEQ(R300_US_TEX_INST_0, code->tex.length);
+ for(i = 0; i < code->tex.length; ++i)
+ OUT_CS(code->tex.inst[i]);
+ }
+
+ if (constants->Count) {
+ OUT_CS_ONE_REG(R300_PFS_PARAM_0_X, constants->Count * 4);
+ for(i = 0; i < constants->Count; ++i) {
+ const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+ OUT_CS(pack_float24(data[0]));
+ OUT_CS(pack_float24(data[1]));
+ OUT_CS(pack_float24(data[2]));
+ OUT_CS(pack_float24(data[3]));
+ }
}
END_CS;
}
-void r500_emit_fragment_shader(struct r300_context* r300,
- struct r5xx_fragment_shader* fs)
+void r500_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals)
{
+ struct r500_fragment_program_code * code = &generic_code->code.r500;
+ struct rc_constant_list * constants = &generic_code->constants;
int i;
- struct r300_constant_buffer* constants =
- &r300->shader_constants[PIPE_SHADER_FRAGMENT];
CS_LOCALS(r300);
- BEGIN_CS(9 + (fs->instruction_count * 6) + (constants->count ? 3 : 0) +
- (constants->count * 4));
- OUT_CS_REG(R500_US_CONFIG, R500_ZERO_TIMES_ANYTHING_EQUALS_ZERO);
- OUT_CS_REG(R500_US_PIXSIZE, fs->shader.stack_size);
- OUT_CS_REG(R500_US_CODE_ADDR, R500_US_CODE_START_ADDR(0) |
- R500_US_CODE_END_ADDR(fs->instruction_count));
+ BEGIN_CS(13 +
+ ((code->inst_end + 1) * 6) +
+ (constants->Count ? (3 + (constants->Count * 4)) : 0));
+ OUT_CS_REG(R500_US_CONFIG, 0);
+ OUT_CS_REG(R500_US_PIXSIZE, code->max_temp_idx);
+ OUT_CS_REG(R500_US_CODE_RANGE,
+ R500_US_CODE_RANGE_ADDR(0) | R500_US_CODE_RANGE_SIZE(code->inst_end));
+ OUT_CS_REG(R500_US_CODE_OFFSET, 0);
+ OUT_CS_REG(R500_US_CODE_ADDR,
+ R500_US_CODE_START_ADDR(0) | R500_US_CODE_END_ADDR(code->inst_end));
OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_INSTR);
- OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, fs->instruction_count * 6);
- for (i = 0; i < fs->instruction_count; i++) {
- OUT_CS(fs->instructions[i].inst0);
- OUT_CS(fs->instructions[i].inst1);
- OUT_CS(fs->instructions[i].inst2);
- OUT_CS(fs->instructions[i].inst3);
- OUT_CS(fs->instructions[i].inst4);
- OUT_CS(fs->instructions[i].inst5);
- }
-
- if (constants->count) {
- OUT_CS_REG(R500_GA_US_VECTOR_INDEX,
- R500_GA_US_VECTOR_INDEX_TYPE_CONST);
- OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->count * 4);
- for (i = 0; i < constants->count; i++) {
- OUT_CS_32F(constants->constants[i][0]);
- OUT_CS_32F(constants->constants[i][1]);
- OUT_CS_32F(constants->constants[i][2]);
- OUT_CS_32F(constants->constants[i][3]);
+ OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, (code->inst_end + 1) * 6);
+ for (i = 0; i <= code->inst_end; i++) {
+ OUT_CS(code->inst[i].inst0);
+ OUT_CS(code->inst[i].inst1);
+ OUT_CS(code->inst[i].inst2);
+ OUT_CS(code->inst[i].inst3);
+ OUT_CS(code->inst[i].inst4);
+ OUT_CS(code->inst[i].inst5);
+ }
+
+ if (constants->Count) {
+ OUT_CS_REG(R500_GA_US_VECTOR_INDEX, R500_GA_US_VECTOR_INDEX_TYPE_CONST);
+ OUT_CS_ONE_REG(R500_GA_US_VECTOR_DATA, constants->Count * 4);
+ for (i = 0; i < constants->Count; i++) {
+ const float * data = get_shader_constant(r300, &constants->Constants[i], externals);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
}
}
@@ -190,17 +279,19 @@ void r300_emit_fb_state(struct r300_context* r300,
int i;
CS_LOCALS(r300);
- BEGIN_CS((8 * fb->nr_cbufs) + (fb->zsbuf ? 8 : 0) + 4);
+ BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 4);
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);
- OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), pixpitch |
- r300_translate_colorformat(tex->tex.format));
+ OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1);
+ OUT_CS_RELOC(tex->buffer, pixpitch |
+ r300_translate_colorformat(tex->tex.format), 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i),
r300_translate_out_fmt(fb->cbufs[i]->format));
@@ -209,14 +300,15 @@ 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);
OUT_CS_REG(R300_ZB_FORMAT, r300_translate_zsformat(tex->tex.format));
- OUT_CS_REG(R300_ZB_DEPTHPITCH, pixpitch);
+ OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1);
+ OUT_CS_RELOC(tex->buffer, pixpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
}
OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT,
@@ -228,6 +320,79 @@ void r300_emit_fb_state(struct r300_context* r300,
END_CS;
}
+void r300_emit_query_begin(struct r300_context* r300,
+ struct r300_query* query)
+{
+ CS_LOCALS(r300);
+
+ /* XXX This will almost certainly not return good results
+ * for overlapping queries. */
+ BEGIN_CS(2);
+ OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
+ END_CS;
+}
+
+void r300_emit_query_end(struct r300_context* r300,
+ struct r300_query* query)
+{
+ struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
+ CS_LOCALS(r300);
+
+ if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
+ 0, RADEON_GEM_DOMAIN_GTT)) {
+ debug_printf("r300: There wasn't room for the OQ buffer!?"
+ " Oh noes!\n");
+ }
+
+ assert(caps->num_frag_pipes);
+ BEGIN_CS(6 * caps->num_frag_pipes + 2);
+ /* I'm not so sure I like this switch, but it's hard to be elegant
+ * when there's so many special cases...
+ *
+ * So here's the basic idea. For each pipe, enable writes to it only,
+ * then put out the relocation for ZPASS_ADDR, taking into account a
+ * 4-byte offset for each pipe. RV380 and older are special; they have
+ * only two pipes, and the second pipe's enable is on bit 3, not bit 1,
+ * so there's a chipset cap for that. */
+ switch (caps->num_frag_pipes) {
+ case 4:
+ /* pipe 3 only */
+ OUT_CS_REG(R300_SU_REG_DEST, 1 << 3);
+ OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 3),
+ 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 3:
+ /* pipe 2 only */
+ OUT_CS_REG(R300_SU_REG_DEST, 1 << 2);
+ OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 2),
+ 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 2:
+ /* pipe 1 only */
+ /* As mentioned above, accomodate RV380 and older. */
+ OUT_CS_REG(R300_SU_REG_DEST,
+ 1 << (caps->high_second_pipe ? 3 : 1));
+ OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 1),
+ 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 1:
+ /* pipe 0 only */
+ OUT_CS_REG(R300_SU_REG_DEST, 1 << 0);
+ OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_CS_RELOC(r300->oqbo, query->offset + (sizeof(uint32_t) * 0),
+ 0, RADEON_GEM_DOMAIN_GTT, 0);
+ default:
+ debug_printf("r300: Implementation error: Chipset reports %d"
+ " pixel pipes!\n", caps->num_frag_pipes);
+ assert(0);
+ }
+
+ /* And, finally, reset it to normal... */
+ OUT_CS_REG(R300_SU_REG_DEST, 0xF);
+ END_CS;
+
+}
+
void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs)
{
CS_LOCALS(r300);
@@ -326,7 +491,7 @@ void r300_emit_vertex_buffer(struct r300_context* r300)
{
CS_LOCALS(r300);
- debug_printf("r300: Preparing vertex buffer %p for render, "
+ DBG(r300, DBG_DRAW, "r300: Preparing vertex buffer %p for render, "
"vertex size %d\n", r300->vbo,
r300->vertex_info.vinfo.size);
/* Set the pointer to our vertex buffer. The emitted values are this:
@@ -380,13 +545,13 @@ void r300_emit_vertex_format_state(struct r300_context* r300)
END_CS;
}
-void r300_emit_vertex_shader(struct r300_context* r300,
- struct r300_vertex_shader* vs)
+void r300_emit_vertex_program_code(struct r300_context* r300,
+ struct r300_vertex_program_code* code,
+ struct r300_constant_buffer* constants)
{
int i;
struct r300_screen* r300screen = r300_screen(r300->context.screen);
- struct r300_constant_buffer* constants =
- &r300->shader_constants[PIPE_SHADER_VERTEX];
+ unsigned instruction_count = code->length / 4;
CS_LOCALS(r300);
if (!r300screen->caps->has_tcl) {
@@ -395,10 +560,10 @@ void r300_emit_vertex_shader(struct r300_context* r300,
return;
}
- if (constants->count) {
- BEGIN_CS(14 + (vs->instruction_count * 4) + (constants->count * 4));
+ if (code->constants.Count) {
+ BEGIN_CS(14 + code->length + (code->constants.Count * 4));
} else {
- BEGIN_CS(11 + (vs->instruction_count * 4));
+ BEGIN_CS(11 + code->length);
}
/* R300_VAP_PVS_CODE_CNTL_0
@@ -408,30 +573,27 @@ void r300_emit_vertex_shader(struct r300_context* r300,
* XXX these could be optimized to select better values... */
OUT_CS_REG_SEQ(R300_VAP_PVS_CODE_CNTL_0, 3);
OUT_CS(R300_PVS_FIRST_INST(0) |
- R300_PVS_XYZW_VALID_INST(vs->instruction_count - 1) |
- R300_PVS_LAST_INST(vs->instruction_count - 1));
- OUT_CS(R300_PVS_MAX_CONST_ADDR(constants->count - 1));
- OUT_CS(vs->instruction_count - 1);
+ R300_PVS_XYZW_VALID_INST(instruction_count - 1) |
+ R300_PVS_LAST_INST(instruction_count - 1));
+ OUT_CS(R300_PVS_MAX_CONST_ADDR(code->constants.Count - 1));
+ OUT_CS(instruction_count - 1);
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG, 0);
- OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, vs->instruction_count * 4);
- for (i = 0; i < vs->instruction_count; i++) {
- OUT_CS(vs->instructions[i].inst0);
- OUT_CS(vs->instructions[i].inst1);
- OUT_CS(vs->instructions[i].inst2);
- OUT_CS(vs->instructions[i].inst3);
- }
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->length);
+ for (i = 0; i < code->length; i++)
+ OUT_CS(code->body.d[i]);
- if (constants->count) {
+ if (code->constants.Count) {
OUT_CS_REG(R300_VAP_PVS_VECTOR_INDX_REG,
(r300screen->caps->is_r500 ?
R500_PVS_CONST_START : R300_PVS_CONST_START));
- OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, constants->count * 4);
- for (i = 0; i < constants->count; i++) {
- OUT_CS_32F(constants->constants[i][0]);
- OUT_CS_32F(constants->constants[i][1]);
- OUT_CS_32F(constants->constants[i][2]);
- OUT_CS_32F(constants->constants[i][3]);
+ OUT_CS_ONE_REG(R300_VAP_PVS_UPLOAD_DATA, code->constants.Count * 4);
+ for (i = 0; i < code->constants.Count; i++) {
+ const float * data = get_shader_constant(r300, &code->constants.Constants[i], constants);
+ OUT_CS_32F(data[0]);
+ OUT_CS_32F(data[1]);
+ OUT_CS_32F(data[2]);
+ OUT_CS_32F(data[3]);
}
}
@@ -443,6 +605,12 @@ void r300_emit_vertex_shader(struct r300_context* r300,
END_CS;
}
+void r300_emit_vertex_shader(struct r300_context* r300,
+ struct r300_vertex_shader* vs)
+{
+ r300_emit_vertex_program_code(r300, &vs->code, &r300->shader_constants[PIPE_SHADER_VERTEX]);
+}
+
void r300_emit_viewport_state(struct r300_context* r300,
struct r300_viewport_state* viewport)
{
@@ -521,6 +689,12 @@ validate:
goto validate;
}
}
+ /* ...occlusion query buffer... */
+ if (!r300->winsys->add_buffer(r300->winsys, r300->oqbo,
+ 0, RADEON_GEM_DOMAIN_GTT)) {
+ r300->context.flush(&r300->context, 0, NULL);
+ goto validate;
+ }
/* ...and vertex buffer. */
if (r300->vbo) {
if (!r300->winsys->add_buffer(r300->winsys, r300->vbo,
@@ -531,10 +705,11 @@ validate:
} else {
debug_printf("No VBO while emitting dirty state!\n");
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
/* Well, hell. */
+ debug_printf("r300: Stuck in validation loop, gonna quit now.");
exit(1);
}
invalid = TRUE;
@@ -563,11 +738,9 @@ validate:
if (r300->dirty_state & R300_NEW_FRAGMENT_SHADER) {
if (r300screen->caps->is_r500) {
- r500_emit_fragment_shader(r300,
- (struct r5xx_fragment_shader*)r300->fs);
+ r500_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
} else {
- r300_emit_fragment_shader(r300,
- (struct r3xx_fragment_shader*)r300->fs);
+ r300_emit_fragment_program_code(r300, &r300->fs->code, &r300->shader_constants[PIPE_SHADER_FRAGMENT]);
}
r300->dirty_state &= ~R300_NEW_FRAGMENT_SHADER;
}
diff --git a/src/gallium/drivers/r300/r300_emit.h b/src/gallium/drivers/r300/r300_emit.h
index fda26f3948..c4002b8e5d 100644
--- a/src/gallium/drivers/r300/r300_emit.h
+++ b/src/gallium/drivers/r300/r300_emit.h
@@ -30,6 +30,9 @@
#include "r300_screen.h"
#include "r300_state_inlines.h"
+struct rX00_fragment_program_code;
+struct r300_vertex_program_code;
+
void r300_emit_blend_state(struct r300_context* r300,
struct r300_blend_state* blend);
@@ -42,15 +45,22 @@ void r300_emit_clip_state(struct r300_context* r300,
void r300_emit_dsa_state(struct r300_context* r300,
struct r300_dsa_state* dsa);
-void r300_emit_fragment_shader(struct r300_context* r300,
- struct r3xx_fragment_shader* fs);
+void r300_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals);
-void r500_emit_fragment_shader(struct r300_context* r300,
- struct r5xx_fragment_shader* fs);
+void r500_emit_fragment_program_code(struct r300_context* r300,
+ struct rX00_fragment_program_code* generic_code,
+ struct r300_constant_buffer* externals);
void r300_emit_fb_state(struct r300_context* r300,
struct pipe_framebuffer_state* fb);
+void r300_emit_query_begin(struct r300_context* r300,
+ struct r300_query* query);
+void r300_emit_query_end(struct r300_context* r300,
+ struct r300_query* query);
+
void r300_emit_rs_state(struct r300_context* r300, struct r300_rs_state* rs);
void r300_emit_rs_block_state(struct r300_context* r300,
@@ -68,6 +78,10 @@ void r300_emit_vertex_buffer(struct r300_context* r300);
void r300_emit_vertex_format_state(struct r300_context* r300);
+void r300_emit_vertex_program_code(struct r300_context* r300,
+ struct r300_vertex_program_code* code,
+ struct r300_constant_buffer* constants);
+
void r300_emit_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_fs.c b/src/gallium/drivers/r300/r300_fs.c
index 8672e211bc..a0e848a59a 100644
--- a/src/gallium/drivers/r300/r300_fs.c
+++ b/src/gallium/drivers/r300/r300_fs.c
@@ -23,86 +23,115 @@
#include "r300_fs.h"
-void r300_translate_fragment_shader(struct r300_context* r300,
- struct r300_fragment_shader* fs)
+#include "r300_tgsi_to_rc.h"
+
+#include "radeon_compiler.h"
+
+static void find_output_registers(struct r300_fragment_program_compiler * compiler,
+ struct r300_fragment_shader * fs)
{
- struct tgsi_parse_context parser;
- int i;
- boolean is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
- struct r300_constant_buffer* consts =
- &r300->shader_constants[PIPE_SHADER_FRAGMENT];
+ unsigned i;
- struct r300_fs_asm* assembler = CALLOC_STRUCT(r300_fs_asm);
- if (assembler == NULL) {
- return;
- }
- /* Setup starting offset for immediates. */
- assembler->imm_offset = consts->user_count;
- /* Enable depth writes, if needed. */
- assembler->writes_depth = fs->info.writes_z;
-
- /* Make sure we start at the beginning of the shader. */
- if (is_r500) {
- ((struct r5xx_fragment_shader*)fs)->instruction_count = 0;
- }
+ /* Mark the outputs as not present initially */
+ compiler->OutputColor = fs->info.num_outputs;
+ compiler->OutputDepth = fs->info.num_outputs;
- tgsi_parse_init(&parser, fs->state.tokens);
+ /* Now see where they really are. */
+ for(i = 0; i < fs->info.num_outputs; ++i) {
+ switch(fs->info.output_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ compiler->OutputColor = i;
+ break;
+ case TGSI_SEMANTIC_POSITION:
+ compiler->OutputDepth = i;
+ break;
+ }
+ }
+}
- while (!tgsi_parse_end_of_tokens(&parser)) {
- tgsi_parse_token(&parser);
+static void allocate_hardware_inputs(
+ struct r300_fragment_program_compiler * c,
+ void (*allocate)(void * data, unsigned input, unsigned hwreg),
+ void * mydata)
+{
+ struct tgsi_shader_info* info = &((struct r300_fragment_shader*)c->UserData)->info;
+ int total_colors = 0;
+ int colors = 0;
+ int total_generic = 0;
+ int generic = 0;
+ int i;
- /* This is seriously the lamest way to create fragment programs ever.
- * I blame TGSI. */
- switch (parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- /* Allocated registers sitting at the beginning
- * of the program. */
- r300_fs_declare(assembler, &parser.FullToken.FullDeclaration);
+ for (i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ total_colors++;
break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- debug_printf("r300: Emitting immediate to constant buffer, "
- "position %d\n",
- assembler->imm_offset + assembler->imm_count);
- /* I am not amused by the length of these. */
- for (i = 0; i < 4; i++) {
- consts->constants[assembler->imm_offset +
- assembler->imm_count][i] =
- parser.FullToken.FullImmediate.u[i].Float;
- }
- assembler->imm_count++;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ total_generic++;
break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- if (is_r500) {
- r5xx_fs_instruction((struct r5xx_fragment_shader*)fs,
- assembler, &parser.FullToken.FullInstruction);
- } else {
- r3xx_fs_instruction((struct r3xx_fragment_shader*)fs,
- assembler, &parser.FullToken.FullInstruction);
- }
+ }
+ }
+
+ for(i = 0; i < info->num_inputs; i++) {
+ switch (info->input_semantic_name[i]) {
+ case TGSI_SEMANTIC_COLOR:
+ allocate(mydata, i, colors);
+ colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ allocate(mydata, i, total_colors + generic);
+ generic++;
break;
}
}
+}
+
+void r300_translate_fragment_shader(struct r300_context* r300,
+ struct r300_fragment_shader* fs)
+{
+ struct r300_fragment_program_compiler compiler;
+ struct tgsi_to_rc ttr;
+
+ memset(&compiler, 0, sizeof(compiler));
+ rc_init(&compiler.Base);
+ compiler.Base.Debug = DBG_ON(r300, DBG_FP);
+
+ compiler.code = &fs->code;
+ compiler.is_r500 = r300_screen(r300->context.screen)->caps->is_r500;
+ compiler.AllocateHwInputs = &allocate_hardware_inputs;
+ compiler.UserData = fs;
+
+ /* TODO: Program compilation depends on texture compare modes,
+ * which are sampler state. Therefore, programs need to be recompiled
+ * depending on this state as in the classic Mesa driver.
+ *
+ * This is not yet handled correctly.
+ */
- debug_printf("r300: fs: %d texs and %d colors, first free reg is %d\n",
- assembler->tex_count, assembler->color_count,
- assembler->tex_count + assembler->color_count);
-
- consts->count = consts->user_count + assembler->imm_count;
- fs->uses_imms = assembler->imm_count;
- debug_printf("r300: fs: %d total constants, "
- "%d from user and %d from immediates\n", consts->count,
- consts->user_count, assembler->imm_count);
- r3xx_fs_finalize(fs, assembler);
- if (is_r500) {
- r5xx_fs_finalize((struct r5xx_fragment_shader*)fs, assembler);
+ find_output_registers(&compiler, fs);
+
+ if (compiler.Base.Debug) {
+ debug_printf("r300: Initial fragment program\n");
+ tgsi_dump(fs->state.tokens, 0);
}
- tgsi_dump(fs->state.tokens, 0);
- /* XXX finish r300 dumper too */
- if (is_r500) {
- r5xx_fs_dump((struct r5xx_fragment_shader*)fs);
+ /* Translate TGSI to our internal representation */
+ ttr.compiler = &compiler.Base;
+ ttr.info = &fs->info;
+
+ r300_tgsi_to_rc(&ttr, fs->state.tokens);
+
+ /* Invoke the compiler */
+ r3xx_compile_fragment_program(&compiler);
+ if (compiler.Base.Error) {
+ /* Todo: Fail gracefully */
+ fprintf(stderr, "r300 FP: Compiler error\n");
+ abort();
}
- tgsi_parse_free(&parser);
- FREE(assembler);
+ /* And, finally... */
+ rc_destroy(&compiler.Base);
+ fs->translated = TRUE;
}
diff --git a/src/gallium/drivers/r300/r300_fs.h b/src/gallium/drivers/r300/r300_fs.h
index 18deb7a05e..9fab789402 100644
--- a/src/gallium/drivers/r300/r300_fs.h
+++ b/src/gallium/drivers/r300/r300_fs.h
@@ -30,6 +30,21 @@
#include "r3xx_fs.h"
#include "r5xx_fs.h"
+#include "radeon_code.h"
+
+struct r300_fragment_shader {
+ /* Parent class */
+ struct pipe_shader_state state;
+ struct tgsi_shader_info info;
+
+ /* Has this shader been translated yet? */
+ boolean translated;
+
+ /* Compiled code */
+ struct rX00_fragment_program_code code;
+};
+
+
void r300_translate_fragment_shader(struct r300_context* r300,
struct r300_fragment_shader* fs);
diff --git a/src/gallium/drivers/r300/r300_fs_inlines.h b/src/gallium/drivers/r300/r300_fs_inlines.h
deleted file mode 100644
index be4be9465e..0000000000
--- a/src/gallium/drivers/r300/r300_fs_inlines.h
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
- * Joakim Sindholt <opensource@zhasha.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE. */
-
-#ifndef R300_FS_INLINES_H
-#define R300_FS_INLINES_H
-
-#include "tgsi/tgsi_parse.h"
-
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
-
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_fs_asm {
- /* Pipe context. */
- struct r300_context* r300;
- /* Number of colors. */
- unsigned color_count;
- /* Number of texcoords. */
- unsigned tex_count;
- /* Offset for temporary registers. Inputs and temporaries have no
- * distinguishing markings, so inputs start at 0 and the first usable
- * temporary register is after all inputs. */
- unsigned temp_offset;
- /* Number of requested temporary registers. */
- unsigned temp_count;
- /* Offset for immediate constants. Neither R300 nor R500 can do four
- * inline constants per source, so instead we copy immediates into the
- * constant buffer. */
- unsigned imm_offset;
- /* Number of immediate constants. */
- unsigned imm_count;
- /* Are depth writes enabled? */
- boolean writes_depth;
- /* Depth write offset. This is the TGSI output that corresponds to
- * depth writes. */
- unsigned depth_output;
-};
-
-static INLINE void r300_fs_declare(struct r300_fs_asm* assembler,
- struct tgsi_full_declaration* decl)
-{
- switch (decl->Declaration.File) {
- case TGSI_FILE_INPUT:
- switch (decl->Semantic.SemanticName) {
- case TGSI_SEMANTIC_COLOR:
- assembler->color_count++;
- break;
- case TGSI_SEMANTIC_FOG:
- case TGSI_SEMANTIC_GENERIC:
- assembler->tex_count++;
- break;
- default:
- debug_printf("r300: fs: Bad semantic declaration %d\n",
- decl->Semantic.SemanticName);
- break;
- }
- break;
- case TGSI_FILE_OUTPUT:
- /* Depth write. Mark the position of the output so we can
- * identify it later. */
- if (decl->Semantic.SemanticName == TGSI_SEMANTIC_POSITION) {
- assembler->depth_output = decl->DeclarationRange.First;
- }
- break;
- case TGSI_FILE_CONSTANT:
- break;
- case TGSI_FILE_TEMPORARY:
- assembler->temp_count++;
- break;
- default:
- debug_printf("r300: fs: Bad file %d\n", decl->Declaration.File);
- break;
- }
-
- assembler->temp_offset = assembler->color_count + assembler->tex_count;
-}
-
-static INLINE unsigned r300_fs_src(struct r300_fs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- return 0;
- case TGSI_FILE_INPUT:
- /* XXX may be wrong */
- return src->Index;
- break;
- case TGSI_FILE_TEMPORARY:
- return src->Index + assembler->temp_offset;
- break;
- case TGSI_FILE_IMMEDIATE:
- return (src->Index + assembler->imm_offset) | (1 << 8);
- break;
- case TGSI_FILE_CONSTANT:
- /* XXX magic */
- return src->Index | (1 << 8);
- break;
- default:
- debug_printf("r300: fs: Unimplemented src %d\n", src->File);
- break;
- }
- return 0;
-}
-
-static INLINE unsigned r300_fs_dst(struct r300_fs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- switch (dst->File) {
- case TGSI_FILE_NULL:
- /* This happens during KIL instructions. */
- return 0;
- break;
- case TGSI_FILE_OUTPUT:
- return 0;
- break;
- case TGSI_FILE_TEMPORARY:
- return dst->Index + assembler->temp_offset;
- break;
- default:
- debug_printf("r300: fs: Unimplemented dst %d\n", dst->File);
- break;
- }
- return 0;
-}
-
-static INLINE boolean r300_fs_is_depr(struct r300_fs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- return (assembler->writes_depth &&
- (dst->File == TGSI_FILE_OUTPUT) &&
- (dst->Index == assembler->depth_output));
-}
-
-#endif /* R300_FS_INLINES_H */
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 8fc61c2dec..2880d34877 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -22,17 +22,35 @@
#include "r300_query.h"
+#include "r300_emit.h"
+
static struct pipe_query* r300_create_query(struct pipe_context* pipe,
unsigned query_type)
{
- struct r300_query* q = CALLOC_STRUCT(r300_query);
+ struct r300_context* r300 = r300_context(pipe);
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
+ unsigned query_size = r300screen->caps->num_frag_pipes * 4;
+ struct r300_query* q, * qptr;
+
+ q = CALLOC_STRUCT(r300_query);
q->type = query_type;
assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
- /* XXX this is to force winsys to give us a GTT buffer */
- q->buf = pipe->screen->buffer_create(pipe->screen, 64,
- PIPE_BUFFER_USAGE_VERTEX, 64);
+ q->active = FALSE;
+
+ if (!r300->query_list) {
+ r300->query_list = q;
+ } else if (!is_empty_list(r300->query_list)) {
+ qptr = last_elem(r300->query_list);
+ q->offset = qptr->offset + query_size;
+ insert_at_tail(r300->query_list, q);
+ }
+
+ /* XXX */
+ if (q->offset >= 4096) {
+ q->offset = 0;
+ }
return (struct pipe_query*)q;
}
@@ -40,6 +58,9 @@ static struct pipe_query* r300_create_query(struct pipe_context* pipe,
static void r300_destroy_query(struct pipe_context* pipe,
struct pipe_query* query)
{
+ struct r300_query* q = (struct r300_query*)query;
+
+ remove_from_list(q);
FREE(query);
}
@@ -49,15 +70,15 @@ static void r300_begin_query(struct pipe_context* pipe,
uint32_t* map;
struct r300_context* r300 = r300_context(pipe);
struct r300_query* q = (struct r300_query*)query;
- CS_LOCALS(r300);
- map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_WRITE);
+ map = pipe->screen->buffer_map(pipe->screen, r300->oqbo,
+ PIPE_BUFFER_USAGE_CPU_WRITE);
+ map += q->offset / 4;
*map = ~0;
- pipe_buffer_unmap(pipe->screen, q->buf);
+ pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
- BEGIN_CS(2);
- OUT_CS_REG(R300_ZB_ZPASS_DATA, 0);
- END_CS;
+ r300_emit_dirty_state(r300);
+ r300_emit_query_begin(r300, q);
}
static void r300_end_query(struct pipe_context* pipe,
@@ -65,12 +86,9 @@ static void r300_end_query(struct pipe_context* pipe,
{
struct r300_context* r300 = r300_context(pipe);
struct r300_query* q = (struct r300_query*)query;
- CS_LOCALS(r300);
- BEGIN_CS(4);
- OUT_CS_REG_SEQ(R300_ZB_ZPASS_ADDR, 1);
- OUT_CS_RELOC(q->buf, 0, 0, RADEON_GEM_DOMAIN_GTT, 0);
- END_CS;
+ r300_emit_dirty_state(r300);
+ r300_emit_query_end(r300, q);
}
static boolean r300_get_query_result(struct pipe_context* pipe,
@@ -78,22 +96,38 @@ static boolean r300_get_query_result(struct pipe_context* pipe,
boolean wait,
uint64_t* result)
{
+ struct r300_context* r300 = r300_context(pipe);
+ struct r300_screen* r300screen = r300_screen(r300->context.screen);
struct r300_query* q = (struct r300_query*)query;
+ unsigned flags = PIPE_BUFFER_USAGE_CPU_READ;
uint32_t* map;
uint32_t temp;
+ unsigned i;
if (wait) {
- /* Well, we're expected to just sit here and spin, so let's go ahead
- * and flush so we can be sure that the card's spinning... */
- /* XXX double-check these params */
pipe->flush(pipe, 0, NULL);
+ } else {
+ flags |= PIPE_BUFFER_USAGE_DONTBLOCK;
}
- map = pipe_buffer_map(pipe->screen, q->buf, PIPE_BUFFER_USAGE_CPU_READ);
- temp = *map;
- pipe_buffer_unmap(pipe->screen, q->buf);
+ map = pipe->screen->buffer_map(pipe->screen, r300->oqbo, flags);
+ map += q->offset / 4;
+ for (i = 0; i < r300screen->caps->num_frag_pipes; i++) {
+ if (*map == ~0) {
+ /* Looks like our results aren't ready yet. */
+ if (wait) {
+ debug_printf("r300: Despite waiting, OQ results haven't"
+ " come in yet.\n");
+ }
+ temp = ~0;
+ break;
+ }
+ temp += *map;
+ map++;
+ }
+ pipe->screen->buffer_unmap(pipe->screen, r300->oqbo);
- if (temp < 0) {
+ if (temp == ~0) {
/* Our results haven't been written yet... */
return FALSE;
}
diff --git a/src/gallium/drivers/r300/r300_query.h b/src/gallium/drivers/r300/r300_query.h
index 6a7646087a..4f50e8f844 100644
--- a/src/gallium/drivers/r300/r300_query.h
+++ b/src/gallium/drivers/r300/r300_query.h
@@ -29,13 +29,6 @@
struct r300_context;
-struct r300_query {
- /* The kind of query. Currently only OQ is supported. */
- unsigned type;
- /* Buffer object where we want our results to reside. */
- struct pipe_buffer* buf;
-};
-
static INLINE struct r300_query* r300_query(struct pipe_query* q)
{
return (struct r300_query*)q;
diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h
index 6825d99870..03cd219cde 100644
--- a/src/gallium/drivers/r300/r300_reg.h
+++ b/src/gallium/drivers/r300/r300_reg.h
@@ -3312,6 +3312,10 @@ enum {
#define R200_3D_DRAW_IMMD_2 0xC0003500
+/* XXX Oh look, stuff not brought over from docs yet */
+
+#define R300_SU_REG_DEST 0x42C8
+
#endif /* _R300_REG_H */
/* *INDENT-ON* */
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index cd458d019a..737396d8d9 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -26,15 +26,17 @@
#include "r300_cs.h"
#include "r300_context.h"
+#include "r300_emit.h"
#include "r300_reg.h"
#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 */
struct vbuf_render base;
-
+
/* Pipe context */
struct r300_context* r300;
@@ -45,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*
@@ -74,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;
}
@@ -96,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,
@@ -106,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,
@@ -162,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);
}
@@ -182,9 +195,9 @@ static void r300_render_draw_arrays(struct vbuf_render* render,
CS_LOCALS(r300);
- prepare_render(r300render, count);
+ r300_prepare_render(r300render, count);
- debug_printf("r300: Doing vbuf render, count %d\n", count);
+ DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
BEGIN_CS(2);
OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
@@ -207,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,
@@ -216,23 +229,6 @@ 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(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) |
@@ -271,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 da1d5ffe2f..3b5b1bbd37 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:
@@ -147,6 +145,8 @@ static int r300_get_param(struct pipe_screen* pscreen, int param)
case PIPE_CAP_TGSI_CONT_SUPPORTED:
/* XXX */
return 0;
+ case PIPE_CAP_BLEND_EQUATION_SEPARATE:
+ return 1;
default:
debug_printf("r300: Implementation error: Bad param %d\n",
param);
@@ -320,13 +320,15 @@ r300_get_tex_transfer(struct pipe_screen *screen,
trans = CALLOC_STRUCT(r300_transfer);
if (trans) {
pipe_texture_reference(&trans->transfer.texture, texture);
- trans->transfer.format = trans->transfer.format;
+ 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 = tex->stride;
+ trans->transfer.stride = r300_texture_get_stride(tex, level);
trans->transfer.usage = usage;
trans->offset = offset;
}
@@ -353,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) {
@@ -389,6 +391,7 @@ struct pipe_screen* r300_create_screen(struct r300_winsys* r300_winsys)
return NULL;
caps->pci_id = r300_winsys->pci_id;
+ caps->num_frag_pipes = r300_winsys->gb_pipes;
r300_parse_chipset(caps);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 68da0aa4cb..88cb9af6fb 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -20,10 +20,11 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#include "util/u_debug.h"
#include "util/u_math.h"
#include "util/u_pack_color.h"
-#include "util/u_debug.h"
+#include "tgsi/tgsi_parse.h"
#include "pipe/p_config.h"
#include "pipe/internal/p_winsys_screen.h"
@@ -32,6 +33,7 @@
#include "r300_reg.h"
#include "r300_state_inlines.h"
#include "r300_fs.h"
+#include "r300_vs.h"
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@@ -137,7 +139,6 @@ static void
const struct pipe_constant_buffer* buffer)
{
struct r300_context* r300 = r300_context(pipe);
- int i = r300->shader_constants[shader].user_count;
/* This entire chunk of code seems ever-so-slightly baked.
* It's as if I've got pipe_buffer* matryoshkas... */
@@ -148,26 +149,13 @@ static void
map, buffer->buffer->size);
pipe->winsys->buffer_unmap(pipe->winsys, buffer->buffer);
- r300->shader_constants[shader].user_count =
+ r300->shader_constants[shader].count =
buffer->buffer->size / (sizeof(float) * 4);
} else {
- r300->shader_constants[shader].user_count = 0;
+ r300->shader_constants[shader].count = 0;
}
r300->dirty_state |= R300_NEW_CONSTANTS;
-
- /* If the number of constants have changed, invalidate the shader. */
- if (r300->shader_constants[shader].user_count != i) {
- if (shader == PIPE_SHADER_FRAGMENT && r300->fs &&
- r300->fs->uses_imms) {
- r300->fs->translated = FALSE;
- r300_translate_fragment_shader(r300, r300->fs);
- } else if (shader == PIPE_SHADER_VERTEX && r300->vs &&
- r300->vs->uses_imms) {
- r300->vs->translated = FALSE;
- r300_translate_vertex_shader(r300, r300->vs);
- }
- }
}
/* Create a new depth, stencil, and alpha state based on the CSO dsa state.
@@ -237,7 +225,8 @@ static void*
dsa->alpha_reference = CLAMP(state->alpha.ref_value * 1023.0f,
0, 1023);
} else {
- dsa->z_buffer_top = R300_ZTOP_ENABLE;
+ /* XXX need to fix this to be dynamically set
+ dsa->z_buffer_top = R300_ZTOP_ENABLE; */
}
return (void*)dsa;
@@ -284,14 +273,9 @@ static void
static void* r300_create_fs_state(struct pipe_context* pipe,
const struct pipe_shader_state* shader)
{
- struct r300_context* r300 = r300_context(pipe);
struct r300_fragment_shader* fs = NULL;
- if (r300_screen(r300->context.screen)->caps->is_r500) {
- fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r5xx_fragment_shader);
- } else {
- fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r3xx_fragment_shader);
- }
+ fs = (struct r300_fragment_shader*)CALLOC_STRUCT(r300_fragment_shader);
/* Copy state directly into shader. */
fs->state = *shader;
@@ -315,7 +299,6 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
r300_translate_fragment_shader(r300, fs);
}
- fs->translated = TRUE;
r300->fs = fs;
r300->dirty_state |= R300_NEW_FRAGMENT_SHADER;
@@ -325,6 +308,7 @@ static void r300_bind_fs_state(struct pipe_context* pipe, void* shader)
static void r300_delete_fs_state(struct pipe_context* pipe, void* shader)
{
struct r300_fragment_shader* fs = (struct r300_fragment_shader*)shader;
+ rc_constants_destroy(&fs->code.constants);
FREE(fs->state.tokens);
FREE(shader);
}
@@ -446,6 +430,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
r300->rs_state = rs;
r300->dirty_state |= R300_NEW_RASTERIZER;
+ r300->dirty_state |= R300_NEW_RS_BLOCK;
+ r300->dirty_state |= R300_NEW_SCISSOR;
+ r300->dirty_state |= R300_NEW_VIEWPORT;
}
/* Free rasterizer state. */
@@ -555,16 +542,16 @@ static void r300_set_scissor_state(struct pipe_context* pipe,
(state->minx << R300_SCISSORS_X_SHIFT) |
(state->miny << R300_SCISSORS_Y_SHIFT);
r300->scissor_state->scissor_bottom_right =
- (state->maxx << R300_SCISSORS_X_SHIFT) |
- (state->maxy << R300_SCISSORS_Y_SHIFT);
+ ((state->maxx - 1) << R300_SCISSORS_X_SHIFT) |
+ ((state->maxy - 1) << R300_SCISSORS_Y_SHIFT);
} else {
/* Offset of 1440 in non-R500 chipsets. */
r300->scissor_state->scissor_top_left =
((state->minx + 1440) << R300_SCISSORS_X_SHIFT) |
((state->miny + 1440) << R300_SCISSORS_Y_SHIFT);
r300->scissor_state->scissor_bottom_right =
- ((state->maxx + 1440) << R300_SCISSORS_X_SHIFT) |
- ((state->maxy + 1440) << R300_SCISSORS_Y_SHIFT);
+ (((state->maxx - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((state->maxy - 1) + 1440) << R300_SCISSORS_Y_SHIFT);
}
r300->dirty_state |= R300_NEW_SCISSOR;
@@ -688,6 +675,7 @@ static void r300_delete_vs_state(struct pipe_context* pipe, void* shader)
if (r300_screen(pipe->screen)->caps->has_tcl) {
struct r300_vertex_shader* vs = (struct r300_vertex_shader*)shader;
+ rc_constants_destroy(&vs->code.constants);
draw_delete_vertex_shader(r300->draw, vs->draw);
FREE(vs->state.tokens);
FREE(shader);
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index 2477b30822..5f6b225d34 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -22,6 +22,10 @@
#include "r300_state_derived.h"
+#include "r300_fs.h"
+#include "r300_state_inlines.h"
+#include "r300_vs.h"
+
/* r300_state_derived: Various bits of state which are dependent upon
* currently bound CSO data. */
@@ -46,59 +50,63 @@ static void r300_vs_tab_routes(struct r300_context* r300,
assert(info->num_inputs <= 16);
- if (r300screen->caps->has_tcl) {
- /* Just copy vert attribs over as-is. */
+ if (!r300screen->caps->has_tcl || !r300->rs_state->enable_vte)
+ {
for (i = 0; i < info->num_inputs; i++) {
- tab[i] = i;
- }
- for (i = 0; i < info->num_outputs; i++) {
- switch (info->output_semantic_name[i]) {
+ switch (info->input_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
+ tab[i] = 0;
break;
case TGSI_SEMANTIC_COLOR:
+ tab[i] = 2 + cols;
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
psize = TRUE;
+ tab[i] = 15;
break;
case TGSI_SEMANTIC_FOG:
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
+ tab[i] = 6 + texs;
texs++;
break;
default:
- debug_printf("r300: Unknown vertex output %d\n",
- info->output_semantic_name[i]);
+ debug_printf("r300: Unknown vertex input %d\n",
+ info->input_semantic_name[i]);
break;
}
}
- } else {
+ }
+ else
+ {
+ /* Just copy vert attribs over as-is. */
for (i = 0; i < info->num_inputs; i++) {
- switch (info->input_semantic_name[i]) {
+ tab[i] = i;
+ }
+
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
case TGSI_SEMANTIC_POSITION:
pos = TRUE;
- tab[i] = 0;
break;
case TGSI_SEMANTIC_COLOR:
- tab[i] = 2 + cols;
cols++;
break;
case TGSI_SEMANTIC_PSIZE:
psize = TRUE;
- tab[i] = 15;
break;
case TGSI_SEMANTIC_FOG:
fog = TRUE;
/* Fall through */
case TGSI_SEMANTIC_GENERIC:
- tab[i] = 6 + texs;
texs++;
break;
default:
- debug_printf("r300: Unknown vertex input %d\n",
- info->input_semantic_name[i]);
+ debug_printf("r300: Unknown vertex output %d\n",
+ info->output_semantic_name[i]);
break;
}
}
@@ -188,13 +196,13 @@ static void r300_vertex_psc(struct r300_context* r300,
* and not on attrib information. */
if (r300screen->caps->has_tcl) {
attrib_count = r300->vs->info.num_inputs;
- debug_printf("r300: routing %d attribs in psc for vs\n",
+ DBG(r300, DBG_DRAW, "r300: routing %d attribs in psc for vs\n",
attrib_count);
} else {
attrib_count = vinfo->num_attribs;
- debug_printf("r300: attrib count: %d\n", attrib_count);
+ DBG(r300, DBG_DRAW, "r300: attrib count: %d\n", attrib_count);
for (i = 0; i < attrib_count; i++) {
- debug_printf("r300: attrib: offset %d, interp %d, size %d,"
+ DBG(r300, DBG_DRAW, "r300: attrib: offset %d, interp %d, size %d,"
" tab %d\n", vinfo->attrib[i].src_index,
vinfo->attrib[i].interp_mode, vinfo->attrib[i].emit,
tab[i]);
@@ -292,18 +300,18 @@ static void r300_update_fs_tab(struct r300_context* r300)
}
/* Now that we know where everything is... */
- debug_printf("r300: fp input count: %d\n", info->num_inputs);
+ DBG(r300, DBG_DRAW, "r300: fp input count: %d\n", info->num_inputs);
for (i = 0; i < info->num_inputs; i++) {
switch (tab[i]) {
case INTERP_LINEAR:
- debug_printf("r300: attrib: "
+ DBG(r300, DBG_DRAW, "r300: attrib: "
"stack offset %d, color, tab %d\n",
i, cols_emitted);
tab[i] = cols_emitted;
cols_emitted++;
break;
case INTERP_PERSPECTIVE:
- debug_printf("r300: attrib: "
+ DBG(r300, DBG_DRAW, "r300: attrib: "
"stack offset %d, texcoord, tab %d\n",
i, cols + texs);
tab[i] = cols + texs;
diff --git a/src/gallium/drivers/r300/r300_state_derived.h b/src/gallium/drivers/r300/r300_state_derived.h
index 63ae8eb8d0..71a4a47b00 100644
--- a/src/gallium/drivers/r300/r300_state_derived.h
+++ b/src/gallium/drivers/r300/r300_state_derived.h
@@ -23,11 +23,7 @@
#ifndef R300_STATE_DERIVED_H
#define R300_STATE_DERIVED_H
-#include "draw/draw_vertex.h"
-
-#include "r300_context.h"
-#include "r300_reg.h"
-#include "r300_state_inlines.h"
+struct r300_context;
void r300_update_derived_state(struct r300_context* r300);
diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h
index 22c8e199ae..91b93fc367 100644
--- a/src/gallium/drivers/r300/r300_state_inlines.h
+++ b/src/gallium/drivers/r300/r300_state_inlines.h
@@ -353,6 +353,25 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format)
/* Non-CSO state. (For now.) */
+static INLINE uint32_t r300_translate_gb_pipes(int pipe_count)
+{
+ switch (pipe_count) {
+ case 1:
+ return R300_GB_TILE_PIPE_COUNT_RV300;
+ break;
+ case 2:
+ return R300_GB_TILE_PIPE_COUNT_R300;
+ break;
+ case 3:
+ return R300_GB_TILE_PIPE_COUNT_R420_3P;
+ break;
+ case 4:
+ return R300_GB_TILE_PIPE_COUNT_R420;
+ break;
+ }
+ return 0;
+}
+
static INLINE uint32_t translate_vertex_data_type(int type) {
switch (type) {
case EMIT_1F:
diff --git a/src/gallium/drivers/r300/r300_state_invariant.c b/src/gallium/drivers/r300/r300_state_invariant.c
index 430129d5bd..3865730d63 100644
--- a/src/gallium/drivers/r300/r300_state_invariant.c
+++ b/src/gallium/drivers/r300/r300_state_invariant.c
@@ -23,6 +23,12 @@
#include "r300_state_invariant.h"
+
+struct pipe_viewport_state r300_viewport_identity = {
+ .scale = {1.0, 1.0, 1.0, 1.0},
+ .translate = {0.0, 0.0, 0.0, 0.0},
+};
+
/* Calculate and emit invariant state. This is data that the 3D engine
* will probably want at the beginning of every CS, but it's not currently
* handled by any CSO setup, and in addition it doesn't really change much.
@@ -34,11 +40,13 @@ void r300_emit_invariant_state(struct r300_context* r300)
struct r300_capabilities* caps = r300_screen(r300->context.screen)->caps;
CS_LOCALS(r300);
- BEGIN_CS(22 + (caps->has_tcl ? 2: 0));
+ BEGIN_CS(24 + (caps->has_tcl ? 2: 0));
/*** Graphics Backend (GB) ***/
/* Various GB enables */
- OUT_CS_REG(R300_GB_ENABLE, 0x0);
+ OUT_CS_REG(R300_GB_ENABLE, R300_GB_POINT_STUFF_ENABLE |
+ R300_GB_LINE_STUFF_ENABLE |
+ R300_GB_TRIANGLE_STUFF_ENABLE);
/* Subpixel multisampling for AA
* These are commented out because glisse's CS checker doesn't like them.
* I presume these will be re-enabled later.
@@ -56,6 +64,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
OUT_CS_REG(R300_FG_FOG_COLOR_G, 0x0);
OUT_CS_REG(R300_FG_FOG_COLOR_B, 0x0);
OUT_CS_REG(R300_FG_DEPTH_SRC, 0x0);
+ OUT_CS_REG(R300_US_W_FMT, 0x0);
/*** VAP ***/
/* Max and min vertex index clamp. */
@@ -72,7 +81,7 @@ void r300_emit_invariant_state(struct r300_context* r300)
END_CS;
/* XXX unsorted stuff from surface_fill */
- BEGIN_CS(71 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
+ BEGIN_CS(64 + (caps->has_tcl ? 5 : 0) + (caps->is_r500 ? 4 : 0));
/* Flush PVS. */
OUT_CS_REG(R300_VAP_PVS_STATE_FLUSH_REG, 0x0);
@@ -132,11 +141,5 @@ void r300_emit_invariant_state(struct r300_context* r300)
/* XXX */
OUT_CS_REG(R300_SC_CLIP_RULE, 0xaaaa);
- OUT_CS_REG_SEQ(R300_US_OUT_FMT_0, 4);
- OUT_CS(R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS(R300_US_OUT_FMT_UNUSED);
- OUT_CS_REG(R300_US_W_FMT, R300_W_FMT_W0);
END_CS;
}
diff --git a/src/gallium/drivers/r300/r300_surface.c b/src/gallium/drivers/r300/r300_surface.c
index fdabe4d9cf..cc6288cb51 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);
@@ -37,7 +37,7 @@ static void r300_surface_setup(struct r300_context* r300,
r300_emit_dsa_state(r300, &dsa_clear_state);
r300_emit_rs_state(r300, &rs_clear_state);
- BEGIN_CS(24);
+ BEGIN_CS(26);
/* Viewport setup */
OUT_CS_REG_SEQ(R300_SE_VPORT_XSCALE, 6);
@@ -58,13 +58,13 @@ static void r300_surface_setup(struct r300_context* r300,
OUT_CS_REG_SEQ(R300_SC_SCISSORS_TL, 2);
if (caps->is_r500) {
OUT_CS((x << R300_SCISSORS_X_SHIFT) | (y << R300_SCISSORS_Y_SHIFT));
- OUT_CS((w << R300_SCISSORS_X_SHIFT) | (h << R300_SCISSORS_Y_SHIFT));
+ OUT_CS(((w - 1) << R300_SCISSORS_X_SHIFT) | ((h - 1) << R300_SCISSORS_Y_SHIFT));
} else {
/* Non-R500 chipsets have an offset of 1440 in their scissors. */
OUT_CS(((x + 1440) << R300_SCISSORS_X_SHIFT) |
((y + 1440) << R300_SCISSORS_Y_SHIFT));
- OUT_CS(((w + 1440) << R300_SCISSORS_X_SHIFT) |
- ((h + 1440) << R300_SCISSORS_Y_SHIFT));
+ OUT_CS((((w - 1) + 1440) << R300_SCISSORS_X_SHIFT) |
+ (((h - 1) + 1440) << R300_SCISSORS_Y_SHIFT));
}
/* Flush colorbuffer and blend caches. */
@@ -78,8 +78,10 @@ static void r300_surface_setup(struct r300_context* r300,
/* Setup colorbuffer. */
OUT_CS_REG_SEQ(R300_RB3D_COLOROFFSET0, 1);
OUT_CS_RELOC(dest->buffer, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- OUT_CS_REG(R300_RB3D_COLORPITCH0, pixpitch |
- r300_translate_colorformat(dest->tex.format));
+ OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0, 1);
+ OUT_CS_RELOC(dest->buffer, pixpitch |
+ r300_translate_colorformat(dest->tex.format), 0,
+ RADEON_GEM_DOMAIN_VRAM, 0);
OUT_CS_REG(RB3D_COLOR_CHANNEL_MASK, 0xf);
END_CS;
@@ -98,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);
@@ -125,9 +127,10 @@ validate:
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
+ debug_printf("r300: Stuck in validation loop, gonna fallback.");
goto fallback;
}
invalid = TRUE;
@@ -138,10 +141,14 @@ validate:
/* Vertex shader setup */
if (caps->has_tcl) {
- r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+ r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
} else {
BEGIN_CS(4);
- OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
+ OUT_CS_REG(R300_VAP_CNTL_STATUS,
+#ifdef PIPE_ARCH_BIG_ENDIAN
+ R300_VC_32BIT_SWAP |
+#endif
+ R300_VAP_TCL_BYPASS);
OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
R300_PVS_NUM_CNTLRS(5) |
R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
@@ -151,10 +158,10 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
- r500_emit_fragment_shader(r300, &r5xx_passthrough_fragment_shader);
+ r500_emit_fragment_program_code(r300, &r5xx_passthrough_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r5xx_rs_block_clear_state);
} else {
- r300_emit_fragment_shader(r300, &r3xx_passthrough_fragment_shader);
+ r300_emit_fragment_program_code(r300, &r3xx_passthrough_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r3xx_rs_block_clear_state);
}
@@ -226,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);
@@ -256,9 +263,10 @@ validate:
r300->context.flush(&r300->context, 0, NULL);
goto validate;
}
- if (r300->winsys->validate(r300->winsys)) {
+ if (!r300->winsys->validate(r300->winsys)) {
r300->context.flush(&r300->context, 0, NULL);
if (invalid) {
+ debug_printf("r300: Stuck in validation loop, gonna fallback.");
goto fallback;
}
invalid = TRUE;
@@ -275,10 +283,14 @@ validate:
/* Vertex shader setup */
if (caps->has_tcl) {
- r300_emit_vertex_shader(r300, &r300_passthrough_vertex_shader);
+ r300_emit_vertex_program_code(r300, &r300_passthrough_vertex_shader, 0);
} else {
BEGIN_CS(4);
- OUT_CS_REG(R300_VAP_CNTL_STATUS, R300_VAP_TCL_BYPASS);
+ OUT_CS_REG(R300_VAP_CNTL_STATUS,
+#ifdef PIPE_ARCH_BIG_ENDIAN
+ R300_VC_32BIT_SWAP |
+#endif
+ R300_VAP_TCL_BYPASS);
OUT_CS_REG(R300_VAP_CNTL, R300_PVS_NUM_SLOTS(5) |
R300_PVS_NUM_CNTLRS(5) |
R300_PVS_NUM_FPUS(caps->num_vert_fpus) |
@@ -288,10 +300,10 @@ validate:
/* Fragment shader setup */
if (caps->is_r500) {
- r500_emit_fragment_shader(r300, &r5xx_texture_fragment_shader);
+ r500_emit_fragment_program_code(r300, &r5xx_texture_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r5xx_rs_block_copy_state);
} else {
- r300_emit_fragment_shader(r300, &r3xx_texture_fragment_shader);
+ r300_emit_fragment_program_code(r300, &r3xx_texture_fragment_shader, 0);
r300_emit_rs_block_state(r300, &r3xx_rs_block_copy_state);
}
diff --git a/src/gallium/drivers/r300/r300_surface.h b/src/gallium/drivers/r300/r300_surface.h
index d01f0b143f..f9e98b2ec9 100644
--- a/src/gallium/drivers/r300/r300_surface.h
+++ b/src/gallium/drivers/r300/r300_surface.h
@@ -73,9 +73,9 @@ static struct r300_rs_state rs_clear_state = {
};
static struct r300_rs_block r3xx_rs_block_clear_state = {
- .ip[0] = R500_RS_SEL_S(R300_RS_SEL_K0) |
- R500_RS_SEL_T(R300_RS_SEL_K0) |
- R500_RS_SEL_R(R300_RS_SEL_K0) |
+ .ip[0] = R500_RS_SEL_S(R300_RS_SEL_C0) |
+ R500_RS_SEL_T(R300_RS_SEL_C0) |
+ R500_RS_SEL_R(R300_RS_SEL_C0) |
R500_RS_SEL_Q(R300_RS_SEL_K1),
.inst[0] = R300_RS_INST_COL_CN_WRITE,
.count = R300_IT_COUNT(0) | R300_IC_COUNT(1) | R300_HIRES_EN,
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index 11c7858d42..7c041d17f7 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -22,17 +22,9 @@
#include "r300_texture.h"
-/* XXX maths need to go to util */
-
-static int minify(int i)
-{
- return MAX2(1, i >> 1);
-}
-
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;
@@ -45,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. */
@@ -55,12 +47,32 @@ static void r300_setup_texture_state(struct r300_texture* tex,
if (height > 2048) {
state->format2 |= R500_TXHEIGHT_BIT11;
}
+
+ 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++) {
@@ -71,23 +83,23 @@ static void r300_setup_miptree(struct r300_texture* tex)
}
base->nblocksx[i] = pf_get_nblocksx(&base->block, base->width[i]);
- base->nblocksy[i] = pf_get_nblocksy(&base->block, base->width[i]);
+ base->nblocksy[i] = pf_get_nblocksy(&base->block, base->height[i]);
/* Radeons enjoy things in multiples of 64.
*
* XXX
* POT, uncompressed, unmippmapped textures can be aligned to 32,
* instead of 64. */
- stride = align(base->nblocksx[i] * base->block.size, 64);
+ stride = r300_texture_get_stride(tex, i);
size = stride * base->nblocksy[i] * base->depth[i];
- tex->offset[i] = align(tex->size, 64);
+ tex->offset[i] = align(tex->size, 32);
tex->size = tex->offset[i] + size;
- /* Save stride of first level to the texture. */
- if (i == 0) {
- tex->stride = stride;
- }
+ debug_printf("r300: Texture miptree: Level %d "
+ "(%dx%dx%d px, pitch %d bytes)\n",
+ i, base->width[i], base->height[i], base->depth[i],
+ stride);
}
}
@@ -109,9 +121,9 @@ 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, 64,
+ tex->buffer = screen->buffer_create(screen, 1024,
PIPE_BUFFER_USAGE_PIXEL,
tex->size);
@@ -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 3b56f0307c..3109af5bac 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)
{
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.c b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
new file mode 100644
index 0000000000..0913ca1bd5
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "r300_tgsi_to_rc.h"
+
+#include "radeon_compiler.h"
+#include "radeon_program.h"
+
+#include "tgsi/tgsi_parse.h"
+#include "tgsi/tgsi_scan.h"
+#include "tgsi/tgsi_util.h"
+
+
+static unsigned translate_opcode(unsigned opcode)
+{
+ switch(opcode) {
+ case TGSI_OPCODE_ARL: return OPCODE_ARL;
+ case TGSI_OPCODE_MOV: return OPCODE_MOV;
+ case TGSI_OPCODE_LIT: return OPCODE_LIT;
+ case TGSI_OPCODE_RCP: return OPCODE_RCP;
+ case TGSI_OPCODE_RSQ: return OPCODE_RSQ;
+ case TGSI_OPCODE_EXP: return OPCODE_EXP;
+ case TGSI_OPCODE_LOG: return OPCODE_LOG;
+ case TGSI_OPCODE_MUL: return OPCODE_MUL;
+ case TGSI_OPCODE_ADD: return OPCODE_ADD;
+ case TGSI_OPCODE_DP3: return OPCODE_DP3;
+ case TGSI_OPCODE_DP4: return OPCODE_DP4;
+ case TGSI_OPCODE_DST: return OPCODE_DST;
+ case TGSI_OPCODE_MIN: return OPCODE_MIN;
+ case TGSI_OPCODE_MAX: return OPCODE_MAX;
+ case TGSI_OPCODE_SLT: return OPCODE_SLT;
+ case TGSI_OPCODE_SGE: return OPCODE_SGE;
+ case TGSI_OPCODE_MAD: return OPCODE_MAD;
+ case TGSI_OPCODE_SUB: return OPCODE_SUB;
+ case TGSI_OPCODE_LRP: return OPCODE_LRP;
+ /* case TGSI_OPCODE_CND: return OPCODE_CND; */
+ case TGSI_OPCODE_DP2A: return OPCODE_DP2A;
+ /* gap */
+ case TGSI_OPCODE_FRC: return OPCODE_FRC;
+ /* case TGSI_OPCODE_CLAMP: return OPCODE_CLAMP; */
+ case TGSI_OPCODE_FLR: return OPCODE_FLR;
+ /* case TGSI_OPCODE_ROUND: return OPCODE_ROUND; */
+ case TGSI_OPCODE_EX2: return OPCODE_EX2;
+ case TGSI_OPCODE_LG2: return OPCODE_LG2;
+ case TGSI_OPCODE_POW: return OPCODE_POW;
+ case TGSI_OPCODE_XPD: return OPCODE_XPD;
+ /* gap */
+ case TGSI_OPCODE_ABS: return OPCODE_ABS;
+ case TGSI_OPCODE_RCC: return OPCODE_RCC;
+ case TGSI_OPCODE_DPH: return OPCODE_DPH;
+ case TGSI_OPCODE_COS: return OPCODE_COS;
+ case TGSI_OPCODE_DDX: return OPCODE_DDX;
+ case TGSI_OPCODE_DDY: return OPCODE_DDY;
+ /* case TGSI_OPCODE_KILP: return OPCODE_KILP; */
+ case TGSI_OPCODE_PK2H: return OPCODE_PK2H;
+ case TGSI_OPCODE_PK2US: return OPCODE_PK2US;
+ case TGSI_OPCODE_PK4B: return OPCODE_PK4B;
+ case TGSI_OPCODE_PK4UB: return OPCODE_PK4UB;
+ case TGSI_OPCODE_RFL: return OPCODE_RFL;
+ case TGSI_OPCODE_SEQ: return OPCODE_SEQ;
+ case TGSI_OPCODE_SFL: return OPCODE_SFL;
+ case TGSI_OPCODE_SGT: return OPCODE_SGT;
+ case TGSI_OPCODE_SIN: return OPCODE_SIN;
+ case TGSI_OPCODE_SLE: return OPCODE_SLE;
+ case TGSI_OPCODE_SNE: return OPCODE_SNE;
+ case TGSI_OPCODE_STR: return OPCODE_STR;
+ case TGSI_OPCODE_TEX: return OPCODE_TEX;
+ case TGSI_OPCODE_TXD: return OPCODE_TXD;
+ case TGSI_OPCODE_TXP: return OPCODE_TXP;
+ case TGSI_OPCODE_UP2H: return OPCODE_UP2H;
+ case TGSI_OPCODE_UP2US: return OPCODE_UP2US;
+ case TGSI_OPCODE_UP4B: return OPCODE_UP4B;
+ case TGSI_OPCODE_UP4UB: return OPCODE_UP4UB;
+ case TGSI_OPCODE_X2D: return OPCODE_X2D;
+ case TGSI_OPCODE_ARA: return OPCODE_ARA;
+ case TGSI_OPCODE_ARR: return OPCODE_ARR;
+ case TGSI_OPCODE_BRA: return OPCODE_BRA;
+ case TGSI_OPCODE_CAL: return OPCODE_CAL;
+ case TGSI_OPCODE_RET: return OPCODE_RET;
+ case TGSI_OPCODE_SSG: return OPCODE_SSG;
+ case TGSI_OPCODE_CMP: return OPCODE_CMP;
+ case TGSI_OPCODE_SCS: return OPCODE_SCS;
+ case TGSI_OPCODE_TXB: return OPCODE_TXB;
+ /* case TGSI_OPCODE_NRM: return OPCODE_NRM; */
+ /* case TGSI_OPCODE_DIV: return OPCODE_DIV; */
+ case TGSI_OPCODE_DP2: return OPCODE_DP2;
+ case TGSI_OPCODE_TXL: return OPCODE_TXL;
+ case TGSI_OPCODE_BRK: return OPCODE_BRK;
+ case TGSI_OPCODE_IF: return OPCODE_IF;
+ /* case TGSI_OPCODE_LOOP: return OPCODE_LOOP; */
+ /* case TGSI_OPCODE_REP: return OPCODE_REP; */
+ case TGSI_OPCODE_ELSE: return OPCODE_ELSE;
+ case TGSI_OPCODE_ENDIF: return OPCODE_ENDIF;
+ case TGSI_OPCODE_ENDLOOP: return OPCODE_ENDLOOP;
+ /* case TGSI_OPCODE_ENDREP: return OPCODE_ENDREP; */
+ case TGSI_OPCODE_PUSHA: return OPCODE_PUSHA;
+ case TGSI_OPCODE_POPA: return OPCODE_POPA;
+ /* case TGSI_OPCODE_CEIL: return OPCODE_CEIL; */
+ /* case TGSI_OPCODE_I2F: return OPCODE_I2F; */
+ case TGSI_OPCODE_NOT: return OPCODE_NOT;
+ case TGSI_OPCODE_TRUNC: return OPCODE_TRUNC;
+ /* case TGSI_OPCODE_SHL: return OPCODE_SHL; */
+ /* case TGSI_OPCODE_SHR: return OPCODE_SHR; */
+ case TGSI_OPCODE_AND: return OPCODE_AND;
+ case TGSI_OPCODE_OR: return OPCODE_OR;
+ /* case TGSI_OPCODE_MOD: return OPCODE_MOD; */
+ case TGSI_OPCODE_XOR: return OPCODE_XOR;
+ /* case TGSI_OPCODE_SAD: return OPCODE_SAD; */
+ /* case TGSI_OPCODE_TXF: return OPCODE_TXF; */
+ /* case TGSI_OPCODE_TXQ: return OPCODE_TXQ; */
+ case TGSI_OPCODE_CONT: return OPCODE_CONT;
+ /* case TGSI_OPCODE_EMIT: return OPCODE_EMIT; */
+ /* case TGSI_OPCODE_ENDPRIM: return OPCODE_ENDPRIM; */
+ /* case TGSI_OPCODE_BGNLOOP2: return OPCODE_BGNLOOP2; */
+ case TGSI_OPCODE_BGNSUB: return OPCODE_BGNSUB;
+ /* case TGSI_OPCODE_ENDLOOP2: return OPCODE_ENDLOOP2; */
+ case TGSI_OPCODE_ENDSUB: return OPCODE_ENDSUB;
+ case TGSI_OPCODE_NOISE1: return OPCODE_NOISE1;
+ case TGSI_OPCODE_NOISE2: return OPCODE_NOISE2;
+ case TGSI_OPCODE_NOISE3: return OPCODE_NOISE3;
+ case TGSI_OPCODE_NOISE4: return OPCODE_NOISE4;
+ case TGSI_OPCODE_NOP: return OPCODE_NOP;
+ /* gap */
+ case TGSI_OPCODE_NRM4: return OPCODE_NRM4;
+ /* case TGSI_OPCODE_CALLNZ: return OPCODE_CALLNZ; */
+ /* case TGSI_OPCODE_IFC: return OPCODE_IFC; */
+ /* case TGSI_OPCODE_BREAKC: return OPCODE_BREAKC; */
+ case TGSI_OPCODE_KIL: return OPCODE_KIL;
+ case TGSI_OPCODE_END: return OPCODE_END;
+ case TGSI_OPCODE_SWZ: return OPCODE_SWZ;
+ }
+
+ fprintf(stderr, "Unknown opcode: %i\n", opcode);
+ abort();
+}
+
+static unsigned translate_saturate(unsigned saturate)
+{
+ switch(saturate) {
+ case TGSI_SAT_NONE: return SATURATE_OFF;
+ case TGSI_SAT_ZERO_ONE: return SATURATE_ZERO_ONE;
+ }
+
+ fprintf(stderr, "Unknown saturate mode: %i\n", saturate);
+ abort();
+}
+
+static unsigned translate_register_file(unsigned file)
+{
+ switch(file) {
+ case TGSI_FILE_CONSTANT: return PROGRAM_CONSTANT;
+ case TGSI_FILE_IMMEDIATE: return PROGRAM_CONSTANT;
+ case TGSI_FILE_INPUT: return PROGRAM_INPUT;
+ case TGSI_FILE_OUTPUT: return PROGRAM_OUTPUT;
+ case TGSI_FILE_TEMPORARY: return PROGRAM_TEMPORARY;
+ case TGSI_FILE_ADDRESS: return PROGRAM_ADDRESS;
+ }
+
+ fprintf(stderr, "Unhandled register file: %i\n", file);
+ abort();
+}
+
+static int translate_register_index(
+ struct tgsi_to_rc * ttr,
+ unsigned file,
+ int index)
+{
+ if (file == TGSI_FILE_IMMEDIATE)
+ return ttr->immediate_offset + index;
+
+ return index;
+}
+
+static void transform_dstreg(
+ struct tgsi_to_rc * ttr,
+ struct prog_dst_register * dst,
+ struct tgsi_full_dst_register * src)
+{
+ dst->File = translate_register_file(src->DstRegister.File);
+ dst->Index = translate_register_index(ttr, src->DstRegister.File, src->DstRegister.Index);
+ dst->WriteMask = src->DstRegister.WriteMask;
+ dst->RelAddr = src->DstRegister.Indirect;
+}
+
+static void transform_srcreg(
+ struct tgsi_to_rc * ttr,
+ struct prog_src_register * dst,
+ struct tgsi_full_src_register * src)
+{
+ dst->File = translate_register_file(src->SrcRegister.File);
+ dst->Index = translate_register_index(ttr, src->SrcRegister.File, src->SrcRegister.Index);
+ dst->RelAddr = src->SrcRegister.Indirect;
+ dst->Swizzle = tgsi_util_get_full_src_register_extswizzle(src, 0);
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 1) << 3;
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 2) << 6;
+ dst->Swizzle |= tgsi_util_get_full_src_register_extswizzle(src, 3) << 9;
+ dst->Abs = src->SrcRegisterExtMod.Absolute;
+ dst->Negate =
+ src->SrcRegisterExtSwz.NegateX |
+ (src->SrcRegisterExtSwz.NegateY << 1) |
+ (src->SrcRegisterExtSwz.NegateZ << 2) |
+ (src->SrcRegisterExtSwz.NegateW << 3);
+ dst->Negate ^= src->SrcRegister.Negate ? NEGATE_XYZW : 0;
+}
+
+static void transform_texture(struct rc_instruction * dst, struct tgsi_instruction_ext_texture src)
+{
+ switch(src.Texture) {
+ case TGSI_TEXTURE_1D:
+ dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+ break;
+ case TGSI_TEXTURE_2D:
+ dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+ break;
+ case TGSI_TEXTURE_3D:
+ dst->I.TexSrcTarget = TEXTURE_3D_INDEX;
+ break;
+ case TGSI_TEXTURE_CUBE:
+ dst->I.TexSrcTarget = TEXTURE_CUBE_INDEX;
+ break;
+ case TGSI_TEXTURE_RECT:
+ dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+ break;
+ case TGSI_TEXTURE_SHADOW1D:
+ dst->I.TexSrcTarget = TEXTURE_1D_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ case TGSI_TEXTURE_SHADOW2D:
+ dst->I.TexSrcTarget = TEXTURE_2D_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ case TGSI_TEXTURE_SHADOWRECT:
+ dst->I.TexSrcTarget = TEXTURE_RECT_INDEX;
+ dst->I.TexShadow = 1;
+ break;
+ }
+}
+
+static void transform_instruction(struct tgsi_to_rc * ttr, struct tgsi_full_instruction * src)
+{
+ if (src->Instruction.Opcode == TGSI_OPCODE_END)
+ return;
+
+ struct rc_instruction * dst = rc_insert_new_instruction(ttr->compiler, ttr->compiler->Program.Instructions.Prev);
+ int i;
+
+ dst->I.Opcode = translate_opcode(src->Instruction.Opcode);
+ dst->I.SaturateMode = translate_saturate(src->Instruction.Saturate);
+
+ if (src->Instruction.NumDstRegs)
+ transform_dstreg(ttr, &dst->I.DstReg, &src->FullDstRegisters[0]);
+
+ for(i = 0; i < src->Instruction.NumSrcRegs; ++i) {
+ if (src->FullSrcRegisters[i].SrcRegister.File == TGSI_FILE_SAMPLER)
+ dst->I.TexSrcUnit = src->FullSrcRegisters[i].SrcRegister.Index;
+ else
+ transform_srcreg(ttr, &dst->I.SrcReg[i], &src->FullSrcRegisters[i]);
+ }
+
+ /* Texturing. */
+ transform_texture(dst, src->InstructionExtTexture);
+}
+
+static void handle_immediate(struct tgsi_to_rc * ttr, struct tgsi_full_immediate * imm)
+{
+ struct rc_constant constant;
+ int i;
+
+ constant.Type = RC_CONSTANT_IMMEDIATE;
+ constant.Size = 4;
+ for(i = 0; i < 4; ++i)
+ constant.u.Immediate[i] = imm->u[i].Float;
+ rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+}
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens)
+{
+ struct tgsi_parse_context parser;
+ int i;
+
+ /* Allocate constants placeholders.
+ *
+ * Note: What if declared constants are not contiguous? */
+ for(i = 0; i <= ttr->info->file_max[TGSI_FILE_CONSTANT]; ++i) {
+ struct rc_constant constant;
+ memset(&constant, 0, sizeof(constant));
+ constant.Type = RC_CONSTANT_EXTERNAL;
+ constant.Size = 4;
+ constant.u.External = i;
+ rc_constants_add(&ttr->compiler->Program.Constants, &constant);
+ }
+
+ ttr->immediate_offset = ttr->compiler->Program.Constants.Count;
+
+ tgsi_parse_init(&parser, tokens);
+
+ while (!tgsi_parse_end_of_tokens(&parser)) {
+ tgsi_parse_token(&parser);
+
+ switch (parser.FullToken.Token.Type) {
+ case TGSI_TOKEN_TYPE_DECLARATION:
+ break;
+ case TGSI_TOKEN_TYPE_IMMEDIATE:
+ handle_immediate(ttr, &parser.FullToken.FullImmediate);
+ break;
+ case TGSI_TOKEN_TYPE_INSTRUCTION:
+ transform_instruction(ttr, &parser.FullToken.FullInstruction);
+ break;
+ }
+ }
+
+ tgsi_parse_free(&parser);
+
+ rc_calculate_inputs_outputs(ttr->compiler);
+}
+
diff --git a/src/gallium/drivers/r300/r300_tgsi_to_rc.h b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
new file mode 100644
index 0000000000..93e90ec6d2
--- /dev/null
+++ b/src/gallium/drivers/r300/r300_tgsi_to_rc.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef R300_TGSI_TO_RC_H
+#define R300_TGSI_TO_RC_H
+
+struct radeon_compiler;
+
+struct tgsi_full_declaration;
+struct tgsi_shader_info;
+struct tgsi_token;
+
+struct tgsi_to_rc {
+ struct radeon_compiler * compiler;
+ const struct tgsi_shader_info * info;
+
+ int immediate_offset;
+};
+
+void r300_tgsi_to_rc(struct tgsi_to_rc * ttr, const struct tgsi_token * tokens);
+
+#endif /* R300_TGSI_TO_RC_H */
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index a664a316e8..12a6e37be6 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -22,390 +22,213 @@
#include "r300_vs.h"
-static void r300_vs_declare(struct r300_vs_asm* assembler,
- struct tgsi_full_declaration* decl)
-{
- switch (decl->Declaration.File) {
- case TGSI_FILE_INPUT:
- break;
- case TGSI_FILE_OUTPUT:
- switch (decl->Semantic.SemanticName) {
- case TGSI_SEMANTIC_POSITION:
- assembler->tab[decl->DeclarationRange.First] = 0;
- break;
- case TGSI_SEMANTIC_COLOR:
- assembler->tab[decl->DeclarationRange.First] =
- (assembler->point_size ? 1 : 0) +
- assembler->out_colors;
- break;
- case TGSI_SEMANTIC_FOG:
- case TGSI_SEMANTIC_GENERIC:
- /* XXX multiple? */
- assembler->tab[decl->DeclarationRange.First] =
- (assembler->point_size ? 1 : 0) +
- assembler->out_colors +
- assembler->out_texcoords;
- break;
- case TGSI_SEMANTIC_PSIZE:
- assembler->tab[decl->DeclarationRange.First] = 1;
- break;
- default:
- debug_printf("r300: vs: Bad semantic declaration %d\n",
- decl->Semantic.SemanticName);
- break;
- }
- break;
- case TGSI_FILE_CONSTANT:
- break;
- case TGSI_FILE_TEMPORARY:
- assembler->temp_count++;
- break;
- default:
- debug_printf("r300: vs: Bad file %d\n", decl->Declaration.File);
- break;
- }
-}
+#include "r300_context.h"
+#include "r300_tgsi_to_rc.h"
-static INLINE unsigned r300_vs_src_type(struct r300_vs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- case TGSI_FILE_INPUT:
- /* Probably a zero or one swizzle */
- return R300_PVS_SRC_REG_INPUT;
- case TGSI_FILE_TEMPORARY:
- return R300_PVS_SRC_REG_TEMPORARY;
- case TGSI_FILE_CONSTANT:
- case TGSI_FILE_IMMEDIATE:
- return R300_PVS_SRC_REG_CONSTANT;
- default:
- debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
- break;
- }
- return 0;
-}
+#include "tgsi/tgsi_dump.h"
+#include "tgsi/tgsi_parse.h"
-static INLINE unsigned r300_vs_src(struct r300_vs_asm* assembler,
- struct tgsi_src_register* src)
-{
- switch (src->File) {
- case TGSI_FILE_NULL:
- case TGSI_FILE_INPUT:
- case TGSI_FILE_TEMPORARY:
- case TGSI_FILE_CONSTANT:
- return src->Index;
- case TGSI_FILE_IMMEDIATE:
- return src->Index + assembler->imm_offset;
- default:
- debug_printf("r300: vs: Unimplemented src type %d\n", src->File);
- break;
- }
- return 0;
-}
+#include "radeon_compiler.h"
-static INLINE unsigned r300_vs_dst_type(struct r300_vs_asm* assembler,
- struct tgsi_dst_register* dst)
-{
- switch (dst->File) {
- case TGSI_FILE_TEMPORARY:
- return R300_PVS_DST_REG_TEMPORARY;
- case TGSI_FILE_OUTPUT:
- return R300_PVS_DST_REG_OUT;
- default:
- debug_printf("r300: vs: Unimplemented dst type %d\n", dst->File);
- break;
- }
- return 0;
-}
-static INLINE unsigned r300_vs_dst(struct r300_vs_asm* assembler,
- struct tgsi_dst_register* dst)
+static void set_vertex_inputs_outputs(struct r300_vertex_program_compiler * c)
{
- switch (dst->File) {
- case TGSI_FILE_TEMPORARY:
- return dst->Index;
- case TGSI_FILE_OUTPUT:
- return assembler->tab[dst->Index];
- default:
- debug_printf("r300: vs: Unimplemented dst %d\n", dst->File);
- break;
- }
- return 0;
-}
+ struct r300_vertex_shader * vs = c->UserData;
+ struct tgsi_shader_info* info = &vs->info;
+ boolean pointsize = false;
+ int out_colors = 0;
+ int colors = 0;
+ int out_generic = 0;
+ int generic = 0;
+ int i;
-static uint32_t r300_vs_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- return R300_VE_DOT_PRODUCT;
- case TGSI_OPCODE_MUL:
- return R300_VE_MULTIPLY;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SUB:
- case TGSI_OPCODE_SWZ:
- return R300_VE_ADD;
- case TGSI_OPCODE_MAX:
- return R300_VE_MAXIMUM;
- case TGSI_OPCODE_SLT:
- return R300_VE_SET_LESS_THAN;
- case TGSI_OPCODE_RSQ:
- return R300_PVS_DST_MATH_INST | R300_ME_RECIP_DX;
- case TGSI_OPCODE_MAD:
- return R300_PVS_DST_MACRO_INST | R300_PVS_MACRO_OP_2CLK_MADD;
- default:
- break;
- }
- return 0;
-}
+ /* Fill in the input mapping */
+ for (i = 0; i < info->num_inputs; i++)
+ c->code->inputs[i] = i;
-static uint32_t r300_vs_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegisterExtSwz.ExtSwizzleX |
- (reg->SrcRegisterExtSwz.ExtSwizzleY << 3) |
- (reg->SrcRegisterExtSwz.ExtSwizzleZ << 6) |
- (reg->SrcRegisterExtSwz.ExtSwizzleW << 9);
- } else {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 3) |
- (reg->SrcRegister.SwizzleZ << 6) |
- (reg->SrcRegister.SwizzleW << 9);
+ /* Fill in the output mapping */
+ for (i = 0; i < info->num_outputs; i++) {
+ switch (info->output_semantic_name[i]) {
+ case TGSI_SEMANTIC_PSIZE:
+ pointsize = true;
+ break;
+ case TGSI_SEMANTIC_COLOR:
+ out_colors++;
+ break;
+ case TGSI_SEMANTIC_FOG:
+ case TGSI_SEMANTIC_GENERIC:
+ out_generic++;
+ break;
+ }
}
-}
-/* XXX icky icky icky icky */
-static uint32_t r300_vs_scalar_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegisterExtSwz.ExtSwizzleX |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 3) |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 6) |
- (reg->SrcRegisterExtSwz.ExtSwizzleX << 9);
- } else {
- return (reg->SrcRegister.Negate ? (0xf << 12) : 0) |
- reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleX << 3) |
- (reg->SrcRegister.SwizzleX << 6) |
- (reg->SrcRegister.SwizzleX << 9);
- }
-}
+ struct tgsi_parse_context parser;
-/* XXX scalar stupidity */
-static void r300_vs_emit_inst(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count,
- boolean is_scalar)
-{
- int i = vs->instruction_count;
- vs->instructions[i].inst0 = R300_PVS_DST_OPCODE(r300_vs_op(op)) |
- R300_PVS_DST_REG_TYPE(r300_vs_dst_type(assembler, &dst->DstRegister)) |
- R300_PVS_DST_OFFSET(r300_vs_dst(assembler, &dst->DstRegister)) |
- R300_PVS_DST_WE(dst->DstRegister.WriteMask);
- switch (count) {
- case 3:
- vs->instructions[i].inst3 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[2].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[2].SrcRegister)) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[2]));
- /* Fall through */
- case 2:
- vs->instructions[i].inst2 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[1].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[1].SrcRegister)) |
- R300_PVS_SRC_SWIZZLE(r300_vs_swiz(&src[1]));
- /* Fall through */
- case 1:
- vs->instructions[i].inst1 =
- R300_PVS_SRC_REG_TYPE(r300_vs_src_type(assembler,
- &src[0].SrcRegister)) |
- R300_PVS_SRC_OFFSET(r300_vs_src(assembler,
- &src[0].SrcRegister)) |
- /* XXX the icky, it burns */
- R300_PVS_SRC_SWIZZLE(is_scalar ? r300_vs_scalar_swiz(&src[0])
- : r300_vs_swiz(&src[0]));
- break;
- }
- vs->instruction_count++;
-}
+ tgsi_parse_init(&parser, vs->state.tokens);
-static void r300_vs_instruction(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- switch (inst->Instruction.Opcode) {
- case TGSI_OPCODE_RSQ:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 1, TRUE);
- break;
- case TGSI_OPCODE_SUB:
- inst->FullSrcRegisters[1].SrcRegister.Negate =
- !inst->FullSrcRegisters[1].SrcRegister.Negate;
- /* Fall through */
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_MAX:
- case TGSI_OPCODE_SLT:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_DP3:
- /* Set alpha swizzle to zero for src0 and src1 */
- if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
- inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ZERO;
- if (!inst->FullSrcRegisters[1].SrcRegister.Extended) {
- inst->FullSrcRegisters[1].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[1].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[1].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ZERO;
- /* Fall through */
- case TGSI_OPCODE_DP4:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- inst->FullSrcRegisters[1] = r300_constant_zero;
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 2, FALSE);
- break;
- case TGSI_OPCODE_MAD:
- r300_vs_emit_inst(vs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode,
- 3, FALSE);
- break;
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: vs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-}
+ while (!tgsi_parse_end_of_tokens(&parser)) {
+ tgsi_parse_token(&parser);
-static void r300_vs_init(struct r300_vertex_shader* vs,
- struct r300_vs_asm* assembler)
-{
- struct tgsi_shader_info* info = &vs->info;
- int i;
+ if (parser.FullToken.Token.Type != TGSI_TOKEN_TYPE_DECLARATION)
+ continue;
- for (i = 0; i < info->num_outputs; i++) {
- switch (info->output_semantic_name[i]) {
+ struct tgsi_full_declaration * decl = &parser.FullToken.FullDeclaration;
+
+ if (decl->Declaration.File != TGSI_FILE_OUTPUT)
+ continue;
+
+ switch (decl->Semantic.SemanticName) {
+ case TGSI_SEMANTIC_POSITION:
+ c->code->outputs[decl->DeclarationRange.First] = 0;
+ break;
case TGSI_SEMANTIC_PSIZE:
- assembler->point_size = TRUE;
+ c->code->outputs[decl->DeclarationRange.First] = 1;
break;
case TGSI_SEMANTIC_COLOR:
- assembler->out_colors++;
+ c->code->outputs[decl->DeclarationRange.First] = 1 +
+ (pointsize ? 1 : 0) +
+ colors++;
break;
case TGSI_SEMANTIC_FOG:
case TGSI_SEMANTIC_GENERIC:
- assembler->out_texcoords++;
+ c->code->outputs[decl->DeclarationRange.First] = 1 +
+ (pointsize ? 1 : 0) +
+ out_colors +
+ generic++;
+ break;
+ default:
+ debug_printf("r300: vs: Bad semantic declaration %d\n",
+ decl->Semantic.SemanticName);
break;
}
}
- vs->instruction_count = 0;
+ tgsi_parse_free(&parser);
}
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs)
{
- struct tgsi_parse_context parser;
- int i;
- struct r300_constant_buffer* consts =
- &r300->shader_constants[PIPE_SHADER_VERTEX];
+ struct r300_vertex_program_compiler compiler;
+ struct tgsi_to_rc ttr;
- struct r300_vs_asm* assembler = CALLOC_STRUCT(r300_vs_asm);
- if (assembler == NULL) {
- return;
- }
+ /* Setup the compiler */
+ rc_init(&compiler.Base);
- /* Init assembler. */
- r300_vs_init(vs, assembler);
+ compiler.Base.Debug = DBG_ON(r300, DBG_VP);
+ compiler.code = &vs->code;
+ compiler.UserData = vs;
- /* Setup starting offset for immediates. */
- assembler->imm_offset = consts->user_count;
+ if (compiler.Base.Debug) {
+ debug_printf("r300: Initial vertex program\n");
+ tgsi_dump(vs->state.tokens, 0);
+ }
- tgsi_parse_init(&parser, vs->state.tokens);
+ /* Translate TGSI to our internal representation */
+ ttr.compiler = &compiler.Base;
+ ttr.info = &vs->info;
- while (!tgsi_parse_end_of_tokens(&parser)) {
- tgsi_parse_token(&parser);
+ r300_tgsi_to_rc(&ttr, vs->state.tokens);
- /* This is seriously the lamest way to create fragment programs ever.
- * I blame TGSI. */
- switch (parser.FullToken.Token.Type) {
- case TGSI_TOKEN_TYPE_DECLARATION:
- /* Allocated registers sitting at the beginning
- * of the program. */
- r300_vs_declare(assembler, &parser.FullToken.FullDeclaration);
- break;
- case TGSI_TOKEN_TYPE_IMMEDIATE:
- debug_printf("r300: Emitting immediate to constant buffer, "
- "position %d\n",
- assembler->imm_offset + assembler->imm_count);
- /* I am not amused by the length of these. */
- for (i = 0; i < 4; i++) {
- consts->constants[assembler->imm_offset +
- assembler->imm_count][i] =
- parser.FullToken.FullImmediate.u[i].Float;
- }
- assembler->imm_count++;
- break;
- case TGSI_TOKEN_TYPE_INSTRUCTION:
- r300_vs_instruction(vs, assembler,
- &parser.FullToken.FullInstruction);
- break;
- }
- }
+ compiler.RequiredOutputs = ~(~0 << vs->info.num_outputs);
+ compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
- debug_printf("r300: vs: %d texs and %d colors, first free reg is %d\n",
- assembler->tex_count, assembler->color_count,
- assembler->tex_count + assembler->color_count);
+ /* Invoke the compiler */
+ r3xx_compile_vertex_program(&compiler);
+ if (compiler.Base.Error) {
+ /* Todo: Fail gracefully */
+ fprintf(stderr, "r300 VP: Compiler error\n");
+ abort();
+ }
- consts->count = consts->user_count + assembler->imm_count;
- vs->uses_imms = assembler->imm_count;
- debug_printf("r300: vs: %d total constants, "
- "%d from user and %d from immediates\n", consts->count,
- consts->user_count, assembler->imm_count);
+ /* And, finally... */
+ rc_destroy(&compiler.Base);
+ vs->translated = TRUE;
+}
- debug_printf("r300: vs: tab: %d %d %d %d\n", assembler->tab[0],
- assembler->tab[1], assembler->tab[2], assembler->tab[3]);
- tgsi_dump(vs->state.tokens, 0);
- /* XXX finish r300 vertex shader dumper */
- r300_vs_dump(vs);
+/* XXX get these to r300_reg */
+#define R300_PVS_DST_OPCODE(x) ((x) << 0)
+# define R300_VE_DOT_PRODUCT 1
+# define R300_VE_MULTIPLY 2
+# define R300_VE_ADD 3
+# define R300_VE_MAXIMUM 7
+# define R300_VE_SET_LESS_THAN 10
+#define R300_PVS_DST_MATH_INST (1 << 6)
+# define R300_ME_RECIP_DX 6
+#define R300_PVS_DST_MACRO_INST (1 << 7)
+# define R300_PVS_MACRO_OP_2CLK_MADD 0
+#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
+# define R300_PVS_DST_REG_TEMPORARY 0
+# define R300_PVS_DST_REG_A0 1
+# define R300_PVS_DST_REG_OUT 2
+# define R300_PVS_DST_REG_OUT_REPL_X 3
+# define R300_PVS_DST_REG_ALT_TEMPORARY 4
+# define R300_PVS_DST_REG_INPUT 5
+#define R300_PVS_DST_OFFSET(x) ((x) << 13)
+#define R300_PVS_DST_WE(x) ((x) << 20)
+#define R300_PVS_DST_WE_XYZW (0xf << 20)
+
+#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
+# define R300_PVS_SRC_REG_TEMPORARY 0
+# define R300_PVS_SRC_REG_INPUT 1
+# define R300_PVS_SRC_REG_CONSTANT 2
+# define R300_PVS_SRC_REG_ALT_TEMPORARY 3
+#define R300_PVS_SRC_OFFSET(x) ((x) << 5)
+#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13)
+# define R300_PVS_SRC_SELECT_X 0
+# define R300_PVS_SRC_SELECT_Y 1
+# define R300_PVS_SRC_SELECT_Z 2
+# define R300_PVS_SRC_SELECT_W 3
+# define R300_PVS_SRC_SELECT_FORCE_0 4
+# define R300_PVS_SRC_SELECT_FORCE_1 5
+# define R300_PVS_SRC_SWIZZLE_XYZW \
+ ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
+ (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
+# define R300_PVS_SRC_SWIZZLE_ZERO \
+ ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
+ (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
+ (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
+# define R300_PVS_SRC_SWIZZLE_ONE \
+ ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
+ (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
+ (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
+#define R300_PVS_MODIFIER_X (1 << 25)
+#define R300_PVS_MODIFIER_Y (1 << 26)
+#define R300_PVS_MODIFIER_Z (1 << 27)
+#define R300_PVS_MODIFIER_W (1 << 28)
+#define R300_PVS_NEGATE_XYZW \
+ (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
+ R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+
+struct r300_vertex_program_code r300_passthrough_vertex_shader = {
+ .length = 8, /* two instructions */
+
+ /* MOV out[0], in[0] */
+ .body.d[0] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+ R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+ R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
+ .body.d[1] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+ R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
+ .body.d[2] = R300_PVS_SRC_SWIZZLE_ZERO,
+ .body.d[3] = 0x0,
+
+ /* MOV out[1], in[1] */
+ .body.d[4] = R300_PVS_DST_OPCODE(R300_VE_ADD) |
+ R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
+ R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
+ .body.d[5] = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
+ R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
+ .body.d[6] = R300_PVS_SRC_SWIZZLE_ZERO,
+ .body.d[7] = 0x0,
+
+ .inputs[0] = 0,
+ .inputs[1] = 1,
+ .outputs[0] = 0,
+ .outputs[1] = 1,
+
+ .InputsRead = 3,
+ .OutputsWritten = 3
+};
- tgsi_parse_free(&parser);
- FREE(assembler);
-}
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 165d717812..2a4ce315e3 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -23,134 +23,31 @@
#ifndef R300_VS_H
#define R300_VS_H
-#include "tgsi/tgsi_parse.h"
-#include "tgsi/tgsi_dump.h"
+#include "pipe/p_state.h"
+#include "tgsi/tgsi_scan.h"
-#include "r300_context.h"
-#include "r300_debug.h"
-#include "r300_reg.h"
-#include "r300_screen.h"
-#include "r300_shader_inlines.h"
+#include "radeon_code.h"
-/* XXX get these to r300_reg */
-#define R300_PVS_DST_OPCODE(x) ((x) << 0)
-# define R300_VE_DOT_PRODUCT 1
-# define R300_VE_MULTIPLY 2
-# define R300_VE_ADD 3
-# define R300_VE_MAXIMUM 7
-# define R300_VE_SET_LESS_THAN 10
-#define R300_PVS_DST_MATH_INST (1 << 6)
-# define R300_ME_RECIP_DX 6
-#define R300_PVS_DST_MACRO_INST (1 << 7)
-# define R300_PVS_MACRO_OP_2CLK_MADD 0
-#define R300_PVS_DST_REG_TYPE(x) ((x) << 8)
-# define R300_PVS_DST_REG_TEMPORARY 0
-# define R300_PVS_DST_REG_A0 1
-# define R300_PVS_DST_REG_OUT 2
-# define R300_PVS_DST_REG_OUT_REPL_X 3
-# define R300_PVS_DST_REG_ALT_TEMPORARY 4
-# define R300_PVS_DST_REG_INPUT 5
-#define R300_PVS_DST_OFFSET(x) ((x) << 13)
-#define R300_PVS_DST_WE(x) ((x) << 20)
-#define R300_PVS_DST_WE_XYZW (0xf << 20)
+struct r300_context;
-#define R300_PVS_SRC_REG_TYPE(x) ((x) << 0)
-# define R300_PVS_SRC_REG_TEMPORARY 0
-# define R300_PVS_SRC_REG_INPUT 1
-# define R300_PVS_SRC_REG_CONSTANT 2
-# define R300_PVS_SRC_REG_ALT_TEMPORARY 3
-#define R300_PVS_SRC_OFFSET(x) ((x) << 5)
-#define R300_PVS_SRC_SWIZZLE(x) ((x) << 13)
-# define R300_PVS_SRC_SELECT_X 0
-# define R300_PVS_SRC_SELECT_Y 1
-# define R300_PVS_SRC_SELECT_Z 2
-# define R300_PVS_SRC_SELECT_W 3
-# define R300_PVS_SRC_SELECT_FORCE_0 4
-# define R300_PVS_SRC_SELECT_FORCE_1 5
-# define R300_PVS_SRC_SWIZZLE_XYZW \
- ((R300_PVS_SRC_SELECT_X | (R300_PVS_SRC_SELECT_Y << 3) | \
- (R300_PVS_SRC_SELECT_Z << 6) | (R300_PVS_SRC_SELECT_W << 9)) << 13)
-# define R300_PVS_SRC_SWIZZLE_ZERO \
- ((R300_PVS_SRC_SELECT_FORCE_0 | (R300_PVS_SRC_SELECT_FORCE_0 << 3) | \
- (R300_PVS_SRC_SELECT_FORCE_0 << 6) | \
- (R300_PVS_SRC_SELECT_FORCE_0 << 9)) << 13)
-# define R300_PVS_SRC_SWIZZLE_ONE \
- ((R300_PVS_SRC_SELECT_FORCE_1 | (R300_PVS_SRC_SELECT_FORCE_1 << 3) | \
- (R300_PVS_SRC_SELECT_FORCE_1 << 6) | \
- (R300_PVS_SRC_SELECT_FORCE_1 << 9)) << 13)
-#define R300_PVS_MODIFIER_X (1 << 25)
-#define R300_PVS_MODIFIER_Y (1 << 26)
-#define R300_PVS_MODIFIER_Z (1 << 27)
-#define R300_PVS_MODIFIER_W (1 << 28)
-#define R300_PVS_NEGATE_XYZW \
- (R300_PVS_MODIFIER_X | R300_PVS_MODIFIER_Y | \
- R300_PVS_MODIFIER_Z | R300_PVS_MODIFIER_W)
+struct r300_vertex_shader {
+ /* Parent class */
+ struct pipe_shader_state state;
+ struct tgsi_shader_info info;
-/* Temporary struct used to hold assembly state while putting together
- * fragment programs. */
-struct r300_vs_asm {
- /* Pipe context. */
- struct r300_context* r300;
- /* Number of colors. */
- unsigned color_count;
- /* Number of texcoords. */
- unsigned tex_count;
- /* Number of requested temporary registers. */
- unsigned temp_count;
- /* Offset for immediate constants. Neither R300 nor R500 can do four
- * inline constants per source, so instead we copy immediates into the
- * constant buffer. */
- unsigned imm_offset;
- /* Number of immediate constants. */
- unsigned imm_count;
- /* Number of colors to write. */
- unsigned out_colors;
- /* Number of texcoords to write. */
- unsigned out_texcoords;
- /* Whether to emit point size. */
- boolean point_size;
- /* Tab of declared outputs to OVM outputs. */
- unsigned tab[16];
-};
+ /* Fallback shader, because Draw has issues */
+ struct draw_vertex_shader* draw;
-static struct r300_vertex_shader r300_passthrough_vertex_shader = {
- /* XXX translate these back into normal instructions */
- .instruction_count = 2,
- .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
- .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[0].inst3 = 0x0,
- .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
- .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[1].inst3 = 0x0,
-};
+ /* Has this shader been translated yet? */
+ boolean translated;
-static struct r300_vertex_shader r300_texture_vertex_shader = {
- /* XXX translate these back into normal instructions */
- .instruction_count = 2,
- .instructions[0].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(0) | R300_PVS_DST_WE_XYZW,
- .instructions[0].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(0) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[0].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[0].inst3 = 0x0,
- .instructions[1].inst0 = R300_PVS_DST_OPCODE(R300_VE_ADD) |
- R300_PVS_DST_REG_TYPE(R300_PVS_DST_REG_OUT) |
- R300_PVS_DST_OFFSET(1) | R300_PVS_DST_WE_XYZW,
- .instructions[1].inst1 = R300_PVS_SRC_REG_TYPE(R300_PVS_SRC_REG_INPUT) |
- R300_PVS_SRC_OFFSET(1) | R300_PVS_SRC_SWIZZLE_XYZW,
- .instructions[1].inst2 = R300_PVS_SRC_SWIZZLE_ZERO,
- .instructions[1].inst3 = 0x0,
+ /* Machine code (if translated) */
+ struct r300_vertex_program_code code;
};
+
+extern struct r300_vertex_program_code r300_passthrough_vertex_shader;
+
void r300_translate_vertex_shader(struct r300_context* r300,
struct r300_vertex_shader* vs);
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index d2893c3b9d..f18ad75a47 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -45,6 +45,9 @@ struct r300_winsys {
/* PCI ID */
uint32_t pci_id;
+ /* GB pipe count */
+ uint32_t gb_pipes;
+
/* GART size. */
uint32_t gart_size;
diff --git a/src/gallium/drivers/r300/r3xx_fs.c b/src/gallium/drivers/r300/r3xx_fs.c
index 6e05d76977..c1c1194d58 100644
--- a/src/gallium/drivers/r300/r3xx_fs.c
+++ b/src/gallium/drivers/r300/r3xx_fs.c
@@ -23,74 +23,52 @@
#include "r3xx_fs.h"
-static INLINE uint32_t r3xx_rgb_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_MOV:
- return R300_ALU_OUTC_CMP;
- default:
- return 0;
- }
-}
+#include "r300_reg.h"
-static INLINE uint32_t r3xx_alpha_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_MOV:
- return R300_ALU_OUTA_CMP;
- default:
- return 0;
- }
-}
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader = {
+ .code.r300.alu.length = 1,
+ .code.r300.tex.length = 0,
-static INLINE void r3xx_emit_maths(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->alu_instruction_count;
+ .code.r300.config = 0,
+ .code.r300.pixsize = 0,
+ .code.r300.code_offset = 0,
+ .code.r300.code_addr[3] = R300_RGBA_OUT,
- fs->instructions[i].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- r3xx_rgb_op(op);
- fs->instructions[i].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ;
- fs->instructions[i].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALU_OUTC_CMP,
+ .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+ .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- r3xx_alpha_op(op);
- fs->instructions[i].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT;
+ R300_ALU_OUTA_CMP,
+ .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
- fs->alu_instruction_count++;
-}
+struct rX00_fragment_program_code r3xx_texture_fragment_shader = {
+ .code.r300.alu.length = 1,
+ .code.r300.tex.length = 1,
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
- struct r300_fs_asm* assembler)
-{
- fs->stack_size = assembler->temp_count + assembler->temp_offset + 1;
-}
+ .code.r300.config = R300_PFS_CNTL_FIRST_NODE_HAS_TEX,
+ .code.r300.pixsize = 0,
+ .code.r300.code_offset = 0,
+ .code.r300.code_addr[3] = R300_RGBA_OUT,
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- switch (inst->Instruction.Opcode) {
- case TGSI_OPCODE_MOV:
- /* src0 -> src1 and src2 forced to zero */
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r3xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: fs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-}
+ .code.r300.tex.inst[0] = R300_TEX_OP_LD << R300_TEX_INST_SHIFT,
+
+ .code.r300.alu.inst[0].rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
+ R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
+ R300_ALU_OUTC_CMP,
+ .code.r300.alu.inst[0].rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
+ R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
+ .code.r300.alu.inst[0].alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
+ R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
+ R300_ALU_OUTA_CMP,
+ .code.r300.alu.inst[0].alpha_addr = R300_ALPHA_ADDR0(0) |
+ R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
+};
diff --git a/src/gallium/drivers/r300/r3xx_fs.h b/src/gallium/drivers/r300/r3xx_fs.h
index 3da39ec252..51cd245724 100644
--- a/src/gallium/drivers/r300/r3xx_fs.h
+++ b/src/gallium/drivers/r300/r3xx_fs.h
@@ -24,53 +24,9 @@
#ifndef R3XX_FS_H
#define R3XX_FS_H
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
-static struct r3xx_fragment_shader r3xx_passthrough_fragment_shader = {
- .alu_instruction_count = 1,
- .tex_instruction_count = 0,
- .indirections = 0,
- .shader.stack_size = 1,
-
- .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- R300_ALU_OUTC_CMP,
- .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
- .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- R300_ALU_OUTA_CMP,
- .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-static struct r3xx_fragment_shader r3xx_texture_fragment_shader = {
- .alu_instruction_count = 1,
- .tex_instruction_count = 0,
- .indirections = 0,
- .shader.stack_size = 1,
-
- .instructions[0].alu_rgb_inst = R300_RGB_SWIZA(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZB(R300_ALU_ARGC_SRC0C_XYZ) |
- R300_RGB_SWIZC(R300_ALU_ARGC_ZERO) |
- R300_ALU_OUTC_CMP,
- .instructions[0].alu_rgb_addr = R300_RGB_ADDR0(0) | R300_RGB_ADDR1(0) |
- R300_RGB_ADDR2(0) | R300_ALU_DSTC_OUTPUT_XYZ,
- .instructions[0].alu_alpha_inst = R300_ALPHA_SWIZA(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZB(R300_ALU_ARGA_SRC0A) |
- R300_ALPHA_SWIZC(R300_ALU_ARGA_ZERO) |
- R300_ALU_OUTA_CMP,
- .instructions[0].alu_alpha_addr = R300_ALPHA_ADDR0(0) |
- R300_ALPHA_ADDR1(0) | R300_ALPHA_ADDR2(0) | R300_ALU_DSTA_OUTPUT,
-};
-
-void r3xx_fs_finalize(struct r300_fragment_shader* fs,
- struct r300_fs_asm* assembler);
-
-void r3xx_fs_instruction(struct r3xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r3xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r3xx_texture_fragment_shader;
#endif /* R3XX_FS_H */
diff --git a/src/gallium/drivers/r300/r5xx_fs.c b/src/gallium/drivers/r300/r5xx_fs.c
index 99d826278c..f072deab0d 100644
--- a/src/gallium/drivers/r300/r5xx_fs.c
+++ b/src/gallium/drivers/r300/r5xx_fs.c
@@ -23,445 +23,103 @@
#include "r5xx_fs.h"
-static INLINE unsigned r5xx_fix_swiz(unsigned s)
-{
- /* For historical reasons, the swizzle values x, y, z, w, and 0 are
- * equivalent to the actual machine code, but 1 is not. Thus, we just
- * adjust it a bit... */
- if (s == TGSI_EXTSWIZZLE_ONE) {
- return R500_SWIZZLE_ONE;
- } else {
- return s;
- }
-}
-
-static uint32_t r5xx_rgba_swiz(struct tgsi_full_src_register* reg)
-{
- if (reg->SrcRegister.Extended) {
- return r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleX) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleY) << 3) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleZ) << 6) |
- (r5xx_fix_swiz(reg->SrcRegisterExtSwz.ExtSwizzleW) << 9);
- } else {
- return reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 3) |
- (reg->SrcRegister.SwizzleZ << 6) |
- (reg->SrcRegister.SwizzleW << 9);
- }
-}
-
-static uint32_t r5xx_strq_swiz(struct tgsi_full_src_register* reg)
-{
- return reg->SrcRegister.SwizzleX |
- (reg->SrcRegister.SwizzleY << 2) |
- (reg->SrcRegister.SwizzleZ << 4) |
- (reg->SrcRegister.SwizzleW << 6);
-}
-
-static INLINE uint32_t r5xx_rgb_swiz(struct tgsi_full_src_register* reg)
-{
- /* Only the first 9 bits... */
- return (r5xx_rgba_swiz(reg) & 0x1ff) |
- (reg->SrcRegister.Negate ? (1 << 9) : 0) |
- (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_alpha_swiz(struct tgsi_full_src_register* reg)
-{
- /* Only the last 3 bits... */
- return (r5xx_rgba_swiz(reg) >> 9) |
- (reg->SrcRegister.Negate ? (1 << 9) : 0) |
- (reg->SrcRegisterExtMod.Absolute ? (1 << 10) : 0);
-}
-
-static INLINE uint32_t r5xx_rgba_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_COS:
- case TGSI_OPCODE_EX2:
- case TGSI_OPCODE_LG2:
- case TGSI_OPCODE_RCP:
- case TGSI_OPCODE_RSQ:
- case TGSI_OPCODE_SIN:
- return R500_ALU_RGBA_OP_SOP;
- case TGSI_OPCODE_DDX:
- return R500_ALU_RGBA_OP_MDH;
- case TGSI_OPCODE_DDY:
- return R500_ALU_RGBA_OP_MDV;
- case TGSI_OPCODE_FRC:
- return R500_ALU_RGBA_OP_FRC;
- case TGSI_OPCODE_DP3:
- return R500_ALU_RGBA_OP_DP3;
- case TGSI_OPCODE_DP4:
- case TGSI_OPCODE_DPH:
- return R500_ALU_RGBA_OP_DP4;
- case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_CMP:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- return R500_ALU_RGBA_OP_CMP;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MAD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_SUB:
- return R500_ALU_RGBA_OP_MAD;
- default:
- return 0;
- }
-}
-
-static INLINE uint32_t r5xx_alpha_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_COS:
- return R500_ALPHA_OP_COS;
- case TGSI_OPCODE_EX2:
- return R500_ALPHA_OP_EX2;
- case TGSI_OPCODE_LG2:
- return R500_ALPHA_OP_LN2;
- case TGSI_OPCODE_RCP:
- return R500_ALPHA_OP_RCP;
- case TGSI_OPCODE_RSQ:
- return R500_ALPHA_OP_RSQ;
- case TGSI_OPCODE_FRC:
- return R500_ALPHA_OP_FRC;
- case TGSI_OPCODE_SIN:
- return R500_ALPHA_OP_SIN;
- case TGSI_OPCODE_DDX:
- return R500_ALPHA_OP_MDH;
- case TGSI_OPCODE_DDY:
- return R500_ALPHA_OP_MDV;
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- case TGSI_OPCODE_DPH:
- return R500_ALPHA_OP_DP;
- case TGSI_OPCODE_ABS:
- case TGSI_OPCODE_CMP:
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- return R500_ALPHA_OP_CMP;
- case TGSI_OPCODE_ADD:
- case TGSI_OPCODE_MAD:
- case TGSI_OPCODE_MUL:
- case TGSI_OPCODE_SUB:
- return R500_ALPHA_OP_MAD;
- default:
- return 0;
- }
-}
-
-static INLINE uint32_t r5xx_tex_op(unsigned op)
-{
- switch (op) {
- case TGSI_OPCODE_KIL:
- return R500_TEX_INST_TEXKILL;
- case TGSI_OPCODE_TEX:
- return R500_TEX_INST_LD;
- case TGSI_OPCODE_TXB:
- return R500_TEX_INST_LODBIAS;
- case TGSI_OPCODE_TXP:
- return R500_TEX_INST_PROJ;
- default:
- return 0;
- }
-}
-
-/* Setup an ALU operation. */
-static INLINE void r5xx_emit_maths(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- unsigned op,
- unsigned count)
-{
- int i = fs->instruction_count;
-
- if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
- fs->instructions[i].inst0 = R500_INST_TYPE_OUT;
- if (r300_fs_is_depr(assembler, dst)) {
- fs->instructions[i].inst4 = R500_W_OMASK;
- } else {
- fs->instructions[i].inst0 |=
- R500_ALU_OMASK(dst->DstRegister.WriteMask);
- }
- } else {
- fs->instructions[i].inst0 = R500_INST_TYPE_ALU |
- R500_ALU_WMASK(dst->DstRegister.WriteMask);
- }
-
- fs->instructions[i].inst0 |= R500_INST_TEX_SEM_WAIT;
-
- fs->instructions[i].inst4 |=
- R500_ALPHA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
- fs->instructions[i].inst5 =
- R500_ALU_RGBA_ADDRD(r300_fs_dst(assembler, &dst->DstRegister));
-
- switch (count) {
- case 3:
- fs->instructions[i].inst1 =
- R500_RGB_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
- fs->instructions[i].inst2 =
- R500_ALPHA_ADDR2(r300_fs_src(assembler, &src[2].SrcRegister));
- fs->instructions[i].inst5 |=
- R500_ALU_RGBA_SEL_C_SRC2 |
- R500_SWIZ_RGBA_C(r5xx_rgb_swiz(&src[2])) |
- R500_ALU_RGBA_ALPHA_SEL_C_SRC2 |
- R500_SWIZ_ALPHA_C(r5xx_alpha_swiz(&src[2]));
- case 2:
- fs->instructions[i].inst1 |=
- R500_RGB_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
- fs->instructions[i].inst2 |=
- R500_ALPHA_ADDR1(r300_fs_src(assembler, &src[1].SrcRegister));
- fs->instructions[i].inst3 =
- R500_ALU_RGB_SEL_B_SRC1 |
- R500_SWIZ_RGB_B(r5xx_rgb_swiz(&src[1]));
- fs->instructions[i].inst4 |=
- R500_ALPHA_SEL_B_SRC1 |
- R500_SWIZ_ALPHA_B(r5xx_alpha_swiz(&src[1]));
- case 1:
- case 0:
- default:
- fs->instructions[i].inst1 |=
- R500_RGB_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
- fs->instructions[i].inst2 |=
- R500_ALPHA_ADDR0(r300_fs_src(assembler, &src[0].SrcRegister));
- fs->instructions[i].inst3 |=
- R500_ALU_RGB_SEL_A_SRC0 |
- R500_SWIZ_RGB_A(r5xx_rgb_swiz(&src[0]));
- fs->instructions[i].inst4 |=
- R500_ALPHA_SEL_A_SRC0 |
- R500_SWIZ_ALPHA_A(r5xx_alpha_swiz(&src[0]));
- break;
- }
-
- fs->instructions[i].inst4 |= r5xx_alpha_op(op);
- fs->instructions[i].inst5 |= r5xx_rgba_op(op);
-
- fs->instruction_count++;
-}
-
-static INLINE void r5xx_emit_tex(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_src_register* src,
- struct tgsi_full_dst_register* dst,
- uint32_t op)
-{
- int i = fs->instruction_count;
-
- fs->instructions[i].inst0 = R500_INST_TYPE_TEX |
- R500_TEX_WMASK(dst->DstRegister.WriteMask) |
- R500_INST_TEX_SEM_WAIT;
- fs->instructions[i].inst1 = R500_TEX_ID(0) |
- R500_TEX_SEM_ACQUIRE | //R500_TEX_IGNORE_UNCOVERED |
- r5xx_tex_op(op);
- fs->instructions[i].inst2 =
- R500_TEX_SRC_ADDR(r300_fs_src(assembler, &src->SrcRegister)) |
- R500_SWIZ_TEX_STRQ(r5xx_strq_swiz(src)) |
- R500_TEX_DST_ADDR(r300_fs_dst(assembler, &dst->DstRegister)) |
+#include "r300_reg.h"
+
+/* XXX this all should find its way back to r300_reg */
+/* Swizzle tools */
+#define R500_SWIZZLE_ZERO 4
+#define R500_SWIZZLE_HALF 5
+#define R500_SWIZZLE_ONE 6
+#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
+#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
+#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
+#define R500_SWIZ_MOD_NEG 1
+#define R500_SWIZ_MOD_ABS 2
+#define R500_SWIZ_MOD_NEG_ABS 3
+/* Swizzles for inst2 */
+#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
+#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
+/* Swizzles for inst3 */
+#define R500_SWIZ_RGB_A(x) ((x) << 2)
+#define R500_SWIZ_RGB_B(x) ((x) << 15)
+/* Swizzles for inst4 */
+#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
+/* Swizzle for inst5 */
+#define R500_SWIZ_RGBA_C(x) ((x) << 14)
+#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
+/* Writemasks */
+#define R500_TEX_WMASK(x) ((x) << 11)
+#define R500_ALU_WMASK(x) ((x) << 11)
+#define R500_ALU_OMASK(x) ((x) << 15)
+#define R500_W_OMASK (1 << 31)
+
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader = {
+ .code.r500.max_temp_idx = 0,
+ .code.r500.inst_end = 0,
+
+ .code.r500.inst[0].inst0 = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+ R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[0].inst1 =
+ R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+ .code.r500.inst[0].inst2 =
+ R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+ .code.r500.inst[0].inst3 =
+ R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+ R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+ .code.r500.inst[0].inst4 =
+ R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+ .code.r500.inst[0].inst5 =
+ R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0,
+};
+
+struct rX00_fragment_program_code r5xx_texture_fragment_shader = {
+ .code.r500.max_temp_idx = 0,
+ .code.r500.inst_end = 1,
+
+ .code.r500.inst[0].inst0 = R500_INST_TYPE_TEX |
+ R500_INST_TEX_SEM_WAIT |
+ R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
+ R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
+ .code.r500.inst[0].inst2 = R500_TEX_SRC_ADDR(0) |
+ R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
+ R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
+ R500_TEX_DST_ADDR(0) |
R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
- R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
-
- if (dst->DstRegister.File == TGSI_FILE_OUTPUT) {
- fs->instructions[i].inst2 |=
- R500_TEX_DST_ADDR(assembler->temp_count +
- assembler->temp_offset);
-
- fs->instruction_count++;
-
- /* Setup and emit a MOV. */
- src[0].SrcRegister.Index = assembler->temp_count;
- src[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
-
- src[1] = src[0];
- src[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, src, dst, TGSI_OPCODE_MOV, 3);
- } else {
- fs->instruction_count++;
- }
-}
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler)
-{
- /* XXX should this just go with OPCODE_END? */
- fs->instructions[fs->instruction_count - 1].inst0 |=
- R500_INST_LAST;
-}
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst)
-{
- /* Switch between opcodes. When possible, prefer using the official
- * AMD/ATI names for opcodes, please, as it facilitates using the
- * documentation. */
- switch (inst->Instruction.Opcode) {
- /* XXX trig needs extra prep */
- case TGSI_OPCODE_COS:
- case TGSI_OPCODE_SIN:
- /* The simple scalar ops. */
- case TGSI_OPCODE_EX2:
- case TGSI_OPCODE_LG2:
- case TGSI_OPCODE_RCP:
- case TGSI_OPCODE_RSQ:
- /* Copy red swizzle to alpha for src0 */
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- /* Fall through */
- case TGSI_OPCODE_DDX:
- case TGSI_OPCODE_DDY:
- case TGSI_OPCODE_FRC:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 1);
- break;
-
- /* The dot products. */
- case TGSI_OPCODE_DPH:
- /* Set alpha swizzle to one for src0 */
- if (!inst->FullSrcRegisters[0].SrcRegister.Extended) {
- inst->FullSrcRegisters[0].SrcRegister.Extended = TRUE;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleY =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY;
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleZ =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ;
- }
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- TGSI_EXTSWIZZLE_ONE;
- /* Fall through */
- case TGSI_OPCODE_DP3:
- case TGSI_OPCODE_DP4:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 2);
- break;
-
- /* Simple three-source operations. */
- case TGSI_OPCODE_CMP:
- /* Swap src0 and src2 */
- inst->FullSrcRegisters[3] = inst->FullSrcRegisters[2];
- inst->FullSrcRegisters[2] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[0] = inst->FullSrcRegisters[3];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The MAD variants. */
- case TGSI_OPCODE_SUB:
- /* Just like ADD, but flip the negation on src1 first */
- inst->FullSrcRegisters[1].SrcRegister.Negate =
- !inst->FullSrcRegisters[1].SrcRegister.Negate;
- /* Fall through */
- case TGSI_OPCODE_ADD:
- /* Force src0 to one, move all registers over */
- inst->FullSrcRegisters[2] = inst->FullSrcRegisters[1];
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[0] = r300_constant_one;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_MUL:
- /* Force our src2 to zero */
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
- case TGSI_OPCODE_MAD:
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The MOV variants. */
- case TGSI_OPCODE_ABS:
- /* Set absolute value modifiers. */
- inst->FullSrcRegisters[0].SrcRegisterExtMod.Absolute = TRUE;
- /* Fall through */
- case TGSI_OPCODE_MOV:
- case TGSI_OPCODE_SWZ:
- /* src0 -> src1 and src2 forced to zero */
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[0];
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], inst->Instruction.Opcode, 3);
- break;
-
- /* The compound and hybrid insts. */
- case TGSI_OPCODE_LRP:
- /* LRP DST A, B, C -> MAD TMP -A, C, C; MAD DST A, B, TMP */
- inst->FullSrcRegisters[3] = inst->FullSrcRegisters[1];
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[2];
- inst->FullSrcRegisters[0].SrcRegister.Negate =
- !(inst->FullSrcRegisters[0].SrcRegister.Negate);
- inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
- inst->FullDstRegisters[0].DstRegister.Index =
- assembler->temp_count;
- inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
- inst->FullSrcRegisters[2].SrcRegister.Index =
- assembler->temp_count;
- inst->FullSrcRegisters[2].SrcRegister.File = TGSI_FILE_TEMPORARY;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
- inst->FullSrcRegisters[2].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
- inst->FullSrcRegisters[1] = inst->FullSrcRegisters[3];
- inst->FullSrcRegisters[0].SrcRegister.Negate =
- !(inst->FullSrcRegisters[0].SrcRegister.Negate);
- inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MAD, 3);
- break;
- case TGSI_OPCODE_POW:
- /* POW DST A, B -> LG2 TMP A; MUL TMP TMP, B; EX2 DST TMP */
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleW =
- inst->FullSrcRegisters[0].SrcRegisterExtSwz.ExtSwizzleX;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW =
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX;
- inst->FullDstRegisters[1] = inst->FullDstRegisters[0];
- inst->FullDstRegisters[0].DstRegister.Index =
- assembler->temp_count;
- inst->FullDstRegisters[0].DstRegister.File = TGSI_FILE_TEMPORARY;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_LG2, 1);
- inst->FullSrcRegisters[0].SrcRegister.Index =
- assembler->temp_count;
- inst->FullSrcRegisters[0].SrcRegister.File = TGSI_FILE_TEMPORARY;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleX = TGSI_SWIZZLE_X;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleY = TGSI_SWIZZLE_Y;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleZ = TGSI_SWIZZLE_Z;
- inst->FullSrcRegisters[0].SrcRegister.SwizzleW = TGSI_SWIZZLE_W;
- inst->FullSrcRegisters[2] = r300_constant_zero;
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_MUL, 3);
- inst->FullDstRegisters[0] = inst->FullDstRegisters[1];
- r5xx_emit_maths(fs, assembler, inst->FullSrcRegisters,
- &inst->FullDstRegisters[0], TGSI_OPCODE_EX2, 1);
- break;
-
- /* The texture instruction set. */
- case TGSI_OPCODE_KIL:
- case TGSI_OPCODE_TEX:
- case TGSI_OPCODE_TXB:
- case TGSI_OPCODE_TXP:
- r5xx_emit_tex(fs, assembler, &inst->FullSrcRegisters[0],
- &inst->FullDstRegisters[0], inst->Instruction.Opcode);
- break;
-
- /* This is the end. My only friend, the end. */
- case TGSI_OPCODE_END:
- break;
- default:
- debug_printf("r300: fs: Bad opcode %d\n",
- inst->Instruction.Opcode);
- break;
- }
-
- /* Clamp, if saturation flags are set. */
- if (inst->Instruction.Saturate == TGSI_SAT_ZERO_ONE) {
- fs->instructions[fs->instruction_count - 1].inst0 |=
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP;
- }
-}
+ R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
+ .code.r500.inst[0].inst3 = 0x0,
+ .code.r500.inst[0].inst4 = 0x0,
+ .code.r500.inst[0].inst5 = 0x0,
+
+ .code.r500.inst[1].inst0 = R500_INST_TYPE_OUT |
+ R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
+ R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
+ R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
+ .code.r500.inst[1].inst1 =
+ R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
+ R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
+ .code.r500.inst[1].inst2 =
+ R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
+ R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
+ .code.r500.inst[1].inst3 =
+ R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
+ R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
+ R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
+ R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
+ .code.r500.inst[1].inst4 =
+ R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
+ .code.r500.inst[1].inst5 =
+ R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
+ R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
+ R500_ALU_RGBA_A_SWIZ_0,
+};
diff --git a/src/gallium/drivers/r300/r5xx_fs.h b/src/gallium/drivers/r300/r5xx_fs.h
index 629e587be4..a4addde32b 100644
--- a/src/gallium/drivers/r300/r5xx_fs.h
+++ b/src/gallium/drivers/r300/r5xx_fs.h
@@ -24,109 +24,9 @@
#ifndef R5XX_FS_H
#define R5XX_FS_H
-#include "r300_fs_inlines.h"
+#include "radeon_code.h"
-/* XXX this all should find its way back to r300_reg */
-/* Swizzle tools */
-#define R500_SWIZZLE_ZERO 4
-#define R500_SWIZZLE_HALF 5
-#define R500_SWIZZLE_ONE 6
-#define R500_SWIZ_RGB_ZERO ((4 << 0) | (4 << 3) | (4 << 6))
-#define R500_SWIZ_RGB_ONE ((6 << 0) | (6 << 3) | (6 << 6))
-#define R500_SWIZ_RGB_RGB ((0 << 0) | (1 << 3) | (2 << 6))
-#define R500_SWIZ_MOD_NEG 1
-#define R500_SWIZ_MOD_ABS 2
-#define R500_SWIZ_MOD_NEG_ABS 3
-/* Swizzles for inst2 */
-#define R500_SWIZ_TEX_STRQ(x) ((x) << 8)
-#define R500_SWIZ_TEX_RGBA(x) ((x) << 24)
-/* Swizzles for inst3 */
-#define R500_SWIZ_RGB_A(x) ((x) << 2)
-#define R500_SWIZ_RGB_B(x) ((x) << 15)
-/* Swizzles for inst4 */
-#define R500_SWIZ_ALPHA_A(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_B(x) ((x) << 21)
-/* Swizzle for inst5 */
-#define R500_SWIZ_RGBA_C(x) ((x) << 14)
-#define R500_SWIZ_ALPHA_C(x) ((x) << 27)
-/* Writemasks */
-#define R500_TEX_WMASK(x) ((x) << 11)
-#define R500_ALU_WMASK(x) ((x) << 11)
-#define R500_ALU_OMASK(x) ((x) << 15)
-#define R500_W_OMASK (1 << 31)
-
-static struct r5xx_fragment_shader r5xx_passthrough_fragment_shader = {
- .shader.stack_size = 0,
- .instruction_count = 1,
- .instructions[0].inst0 = R500_INST_TYPE_OUT |
- R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[0].inst1 =
- R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
- R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
- .instructions[0].inst2 =
- R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
- R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
- .instructions[0].inst3 =
- R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
- R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
- R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
- R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
- .instructions[0].inst4 =
- R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
- .instructions[0].inst5 =
- R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
- R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
- R500_ALU_RGBA_A_SWIZ_0,
-};
-
-static struct r5xx_fragment_shader r5xx_texture_fragment_shader = {
- .shader.stack_size = 1,
- .instruction_count = 2,
- .instructions[0].inst0 = R500_INST_TYPE_TEX |
- R500_INST_TEX_SEM_WAIT |
- R500_INST_RGB_WMASK_RGB | R500_INST_ALPHA_WMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[0].inst1 = R500_TEX_ID(0) | R500_TEX_INST_LD |
- R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED,
- .instructions[0].inst2 = R500_TEX_SRC_ADDR(0) |
- R500_TEX_SRC_S_SWIZ_R | R500_TEX_SRC_T_SWIZ_G |
- R500_TEX_SRC_R_SWIZ_B | R500_TEX_SRC_Q_SWIZ_A |
- R500_TEX_DST_ADDR(0) |
- R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G |
- R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A,
- .instructions[0].inst3 = 0x0,
- .instructions[0].inst4 = 0x0,
- .instructions[0].inst5 = 0x0,
- .instructions[1].inst0 = R500_INST_TYPE_OUT |
- R500_INST_TEX_SEM_WAIT | R500_INST_LAST |
- R500_INST_RGB_OMASK_RGB | R500_INST_ALPHA_OMASK |
- R500_INST_RGB_CLAMP | R500_INST_ALPHA_CLAMP,
- .instructions[1].inst1 =
- R500_RGB_ADDR0(0) | R500_RGB_ADDR1(0) | R500_RGB_ADDR1_CONST |
- R500_RGB_ADDR2(0) | R500_RGB_ADDR2_CONST,
- .instructions[1].inst2 =
- R500_ALPHA_ADDR0(0) | R500_ALPHA_ADDR1(0) | R500_ALPHA_ADDR1_CONST |
- R500_ALPHA_ADDR2(0) | R500_ALPHA_ADDR2_CONST,
- .instructions[1].inst3 =
- R500_ALU_RGB_SEL_A_SRC0 | R500_ALU_RGB_R_SWIZ_A_R |
- R500_ALU_RGB_G_SWIZ_A_G | R500_ALU_RGB_B_SWIZ_A_B |
- R500_ALU_RGB_SEL_B_SRC0 | R500_ALU_RGB_R_SWIZ_B_R |
- R500_ALU_RGB_B_SWIZ_B_G | R500_ALU_RGB_G_SWIZ_B_B,
- .instructions[1].inst4 =
- R500_ALPHA_OP_CMP | R500_ALPHA_SWIZ_A_A | R500_ALPHA_SWIZ_B_A,
- .instructions[1].inst5 =
- R500_ALU_RGBA_OP_CMP | R500_ALU_RGBA_R_SWIZ_0 |
- R500_ALU_RGBA_G_SWIZ_0 | R500_ALU_RGBA_B_SWIZ_0 |
- R500_ALU_RGBA_A_SWIZ_0,
-};
-
-void r5xx_fs_finalize(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler);
-
-void r5xx_fs_instruction(struct r5xx_fragment_shader* fs,
- struct r300_fs_asm* assembler,
- struct tgsi_full_instruction* inst);
+struct rX00_fragment_program_code r5xx_passthrough_fragment_shader;
+struct rX00_fragment_program_code r5xx_texture_fragment_shader;
#endif /* R5XX_FS_H */
diff --git a/src/gallium/drivers/softpipe/sp_clear.c b/src/gallium/drivers/softpipe/sp_clear.c
index fa59277438..8fac8e6e05 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"
@@ -85,5 +83,7 @@ softpipe_clear(struct pipe_context *pipe, unsigned buffers, const float *rgba,
/* non-cached surface */
pipe->surface_fill(pipe, ps, 0, 0, ps->width, ps->height, cv);
#endif
- }
+ }
+
+ softpipe->dirty_render_cache = TRUE;
}
diff --git a/src/gallium/drivers/softpipe/sp_clear.h b/src/gallium/drivers/softpipe/sp_clear.h
index 2e450672f5..9be3b86fe9 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 c4b8b33c6a..e1e31ab047 100644
--- a/src/gallium/drivers/softpipe/sp_context.c
+++ b/src/gallium/drivers/softpipe/sp_context.c
@@ -81,7 +81,8 @@ softpipe_unmap_transfers(struct softpipe_context *sp)
}
-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;
@@ -109,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,
@@ -117,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 */
@@ -133,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)
@@ -140,6 +153,7 @@ softpipe_is_buffer_referenced( struct pipe_context *pipe,
return PIPE_UNREFERENCED;
}
+
struct pipe_context *
softpipe_create( struct pipe_screen *screen )
{
@@ -210,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.
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index 6178c4ac7e..6cf45cded2 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:
@@ -141,6 +139,7 @@ softpipe_is_format_supported( struct pipe_screen *screen,
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_state_derived.c b/src/gallium/drivers/softpipe/sp_state_derived.c
index 856c9ce176..1faeca1c2a 100644
--- a/src/gallium/drivers/softpipe/sp_state_derived.c
+++ b/src/gallium/drivers/softpipe/sp_state_derived.c
@@ -89,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,
@@ -104,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:
@@ -112,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:
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index ba9b91a378..21031c11b8 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -1526,7 +1526,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
unsigned face;
float sc, tc, ma;
- if (arx > ary && arx > arz) {
+ if (arx >= ary && arx >= arz) {
if (rx >= 0.0F) {
face = PIPE_TEX_FACE_POS_X;
sc = -rz;
@@ -1540,7 +1540,7 @@ sample_cube(struct tgsi_sampler *tgsi_sampler,
ma = arx;
}
}
- else if (ary > arx && ary > arz) {
+ else if (ary >= arx && ary >= arz) {
if (ry >= 0.0F) {
face = PIPE_TEX_FACE_POS_Y;
sc = rx;
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index a3a54dada4..49b51afda7 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -30,31 +30,21 @@
* Michel Dänzer <michel@tungstengraphics.com>
*/
-#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.
- */
-
-static unsigned minify( unsigned d )
-{
- return MAX2(1, d>>1);
-}
-
-
-/* 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,
@@ -94,12 +84,17 @@ 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)
{
unsigned usage = (PIPE_BUFFER_USAGE_CPU_READ_WRITE |
PIPE_BUFFER_USAGE_GPU_READ_WRITE);
+ unsigned tex_usage = spt->base.tex_usage;
spt->base.nblocksx[0] = pf_get_nblocksx(&spt->base.block, spt->base.width[0]);
spt->base.nblocksy[0] = pf_get_nblocksy(&spt->base.block, spt->base.height[0]);
@@ -109,15 +104,13 @@ softpipe_displaytarget_layout(struct pipe_screen *screen,
spt->base.height[0],
spt->base.format,
usage,
+ tex_usage,
&spt->stride[0]);
return spt->buffer != NULL;
}
-
-
-
static struct pipe_texture *
softpipe_texture_create(struct pipe_screen *screen,
const struct pipe_texture *template)
@@ -134,7 +127,8 @@ softpipe_texture_create(struct pipe_screen *screen,
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) {
+ if (spt->base.tex_usage & (PIPE_TEXTURE_USAGE_DISPLAY_TARGET |
+ PIPE_TEXTURE_USAGE_PRIMARY)) {
if (!softpipe_displaytarget_layout(screen, spt))
goto fail;
}
@@ -355,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;
@@ -373,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;
@@ -381,12 +374,11 @@ softpipe_transfer_unmap(struct pipe_screen *screen,
spt = softpipe_texture(transfer->texture);
pipe_buffer_unmap( screen, spt->buffer );
-}
-
-void
-softpipe_init_texture_funcs(struct softpipe_context *sp)
-{
+ if (transfer->usage != PIPE_TRANSFER_READ) {
+ /* Mark the texture as dirty to expire the tile caches. */
+ spt->timestamp++;
+ }
}
@@ -412,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 4dd0c1239e..2537ab6a40 100644
--- a/src/gallium/drivers/softpipe/sp_texture.h
+++ b/src/gallium/drivers/softpipe/sp_texture.h
@@ -78,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/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c
index 4ab718f233..ae0af4d055 100644
--- a/src/gallium/drivers/trace/tr_context.c
+++ b/src/gallium/drivers/trace/tr_context.c
@@ -1277,8 +1277,10 @@ trace_context_create(struct pipe_screen *_screen,
tr_ctx->base.set_sampler_textures = trace_context_set_sampler_textures;
tr_ctx->base.set_vertex_buffers = trace_context_set_vertex_buffers;
tr_ctx->base.set_vertex_elements = trace_context_set_vertex_elements;
- tr_ctx->base.surface_copy = trace_context_surface_copy;
- tr_ctx->base.surface_fill = trace_context_surface_fill;
+ if (pipe->surface_copy)
+ tr_ctx->base.surface_copy = trace_context_surface_copy;
+ if (pipe->surface_fill)
+ tr_ctx->base.surface_fill = trace_context_surface_fill;
tr_ctx->base.clear = trace_context_clear;
tr_ctx->base.flush = trace_context_flush;
tr_ctx->base.is_texture_referenced = trace_is_texture_referenced;
diff --git a/src/gallium/drivers/trace/tr_drm.c b/src/gallium/drivers/trace/tr_drm.c
index 98ac75e3fa..781ca5d3bc 100644
--- a/src/gallium/drivers/trace/tr_drm.c
+++ b/src/gallium/drivers/trace/tr_drm.c
@@ -49,7 +49,7 @@ trace_drm_api(struct drm_api *_api)
static struct pipe_screen *
trace_drm_create_screen(struct drm_api *_api, int fd,
- struct drm_create_screen_arg *arg)
+ struct drm_create_screen_arg *arg)
{
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct drm_api *api = tr_api->api;
@@ -63,11 +63,11 @@ trace_drm_create_screen(struct drm_api *_api, int fd,
screen = api->create_screen(api, fd, arg);
return trace_screen_create(screen);
-};
+}
static struct pipe_context *
trace_drm_create_context(struct drm_api *_api,
- struct pipe_screen *_screen)
+ struct pipe_screen *_screen)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_drm_api *tr_api = trace_drm_api(_api);
@@ -82,91 +82,67 @@ trace_drm_create_context(struct drm_api *_api,
pipe = trace_context_create(_screen, pipe);
return pipe;
-};
-
-static boolean
-trace_drm_buffer_from_texture(struct drm_api *_api,
- struct pipe_texture *_texture,
- struct pipe_buffer **_buffer,
- unsigned *stride)
-{
- struct trace_texture *tr_texture = trace_texture(_texture);
- struct trace_drm_api *tr_api = trace_drm_api(_api);
- struct pipe_texture *texture = tr_texture->texture;
- struct drm_api *api = tr_api->api;
- struct pipe_buffer *buffer = NULL;
- boolean result;
-
- /* TODO trace call */
-
- result = api->buffer_from_texture(api, texture, &buffer, stride);
-
- if (result && _buffer)
- buffer = trace_buffer_create(trace_screen(texture->screen), buffer);
-
- if (_buffer)
- *_buffer = buffer;
- else
- pipe_buffer_reference(&buffer, NULL);
-
- return result;
}
-static struct pipe_buffer *
-trace_drm_buffer_from_handle(struct drm_api *_api,
- struct pipe_screen *_screen,
- const char *name,
- unsigned handle)
+static struct pipe_texture *
+trace_drm_texture_from_shared_handle(struct drm_api *_api,
+ struct pipe_screen *_screen,
+ struct pipe_texture *templ,
+ const char *name,
+ unsigned stride,
+ unsigned handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
struct drm_api *api = tr_api->api;
- struct pipe_buffer *result;
+ struct pipe_texture *result;
/* TODO trace call */
- result = api->buffer_from_handle(api, screen, name, handle);
+ result = api->texture_from_shared_handle(api, screen, templ, name, stride, handle);
- result = trace_buffer_create(trace_screen(_screen), result);
+ result = trace_texture_create(trace_screen(_screen), result);
return result;
}
static boolean
-trace_drm_handle_from_buffer(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_buffer *_buffer,
- unsigned *handle)
+trace_drm_shared_handle_from_texture(struct drm_api *_api,
+ struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ unsigned *stride,
+ unsigned *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_buffer *tr_buffer = trace_buffer(_buffer);
+ struct trace_texture *tr_texture = trace_texture(_texture);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
- struct pipe_buffer *buffer = tr_buffer->buffer;
+ struct pipe_texture *texture = tr_texture->texture;
struct drm_api *api = tr_api->api;
/* TODO trace call */
- return api->handle_from_buffer(api, screen, buffer, handle);
+ return api->shared_handle_from_texture(api, screen, texture, stride, handle);
}
static boolean
-trace_drm_global_handle_from_buffer(struct drm_api *_api,
- struct pipe_screen *_screen,
- struct pipe_buffer *_buffer,
- unsigned *handle)
+trace_drm_local_handle_from_texture(struct drm_api *_api,
+ struct pipe_screen *_screen,
+ struct pipe_texture *_texture,
+ unsigned *stride,
+ unsigned *handle)
{
struct trace_screen *tr_screen = trace_screen(_screen);
- struct trace_buffer *tr_buffer = trace_buffer(_buffer);
+ struct trace_texture *tr_texture = trace_texture(_texture);
struct trace_drm_api *tr_api = trace_drm_api(_api);
struct pipe_screen *screen = tr_screen->screen;
- struct pipe_buffer *buffer = tr_buffer->buffer;
+ struct pipe_texture *texture = tr_texture->texture;
struct drm_api *api = tr_api->api;
/* TODO trace call */
- return api->global_handle_from_buffer(api, screen, buffer, handle);
+ return api->local_handle_from_texture(api, screen, texture, stride, handle);
}
static void
@@ -197,10 +173,9 @@ trace_drm_create(struct drm_api *api)
tr_api->base.create_screen = trace_drm_create_screen;
tr_api->base.create_context = trace_drm_create_context;
- tr_api->base.buffer_from_texture = trace_drm_buffer_from_texture;
- tr_api->base.buffer_from_handle = trace_drm_buffer_from_handle;
- tr_api->base.handle_from_buffer = trace_drm_handle_from_buffer;
- tr_api->base.global_handle_from_buffer = trace_drm_global_handle_from_buffer;
+ tr_api->base.texture_from_shared_handle = trace_drm_texture_from_shared_handle;
+ tr_api->base.shared_handle_from_texture = trace_drm_shared_handle_from_texture;
+ tr_api->base.local_handle_from_texture = trace_drm_local_handle_from_texture;
tr_api->base.destroy = trace_drm_destroy;
tr_api->api = api;
diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c
index 643587ab42..7e2ccbcfdc 100644
--- a/src/gallium/drivers/trace/tr_dump.c
+++ b/src/gallium/drivers/trace/tr_dump.c
@@ -351,7 +351,7 @@ void trace_dump_call_begin_locked(const char *klass, const char *method)
trace_dump_indent(1);
trace_dump_writes("<call no=\'");
trace_dump_writef("%lu", call_no);
- trace_dump_writes("\' class =\'");
+ trace_dump_writes("\' class=\'");
trace_dump_escape(klass);
trace_dump_writes("\' method=\'");
trace_dump_escape(method);
diff --git a/src/gallium/drivers/trace/tr_screen.c b/src/gallium/drivers/trace/tr_screen.c
index 5b1e26a52d..26f1c04594 100644
--- a/src/gallium/drivers/trace/tr_screen.c
+++ b/src/gallium/drivers/trace/tr_screen.c
@@ -462,6 +462,7 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *pstride)
{
struct trace_screen *tr_scr = trace_screen(_screen);
@@ -476,11 +477,13 @@ trace_screen_surface_buffer_create(struct pipe_screen *_screen,
trace_dump_arg(uint, height);
trace_dump_arg(format, format);
trace_dump_arg(uint, usage);
+ trace_dump_arg(uint, tex_usage);
result = screen->surface_buffer_create(screen,
width, height,
format,
usage,
+ tex_usage,
pstride);
stride = *pstride;
diff --git a/src/gallium/include/pipe/internal/p_winsys_screen.h b/src/gallium/include/pipe/internal/p_winsys_screen.h
index f4a29e63c7..a1542dada7 100644
--- a/src/gallium/include/pipe/internal/p_winsys_screen.h
+++ b/src/gallium/include/pipe/internal/p_winsys_screen.h
@@ -140,6 +140,7 @@ struct pipe_winsys
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride);
diff --git a/src/gallium/include/pipe/p_compiler.h b/src/gallium/include/pipe/p_compiler.h
index e6a67f8c2f..c13cffceb0 100644
--- a/src/gallium/include/pipe/p_compiler.h
+++ b/src/gallium/include/pipe/p_compiler.h
@@ -93,9 +93,11 @@ typedef int _Bool;
#endif
+#ifndef __HAIKU__
typedef unsigned int uint;
-typedef unsigned char ubyte;
typedef unsigned short ushort;
+#endif
+typedef unsigned char ubyte;
#if 0
#define boolean bool
diff --git a/src/gallium/include/pipe/p_config.h b/src/gallium/include/pipe/p_config.h
index 4152d6ac36..de99957d9d 100644
--- a/src/gallium/include/pipe/p_config.h
+++ b/src/gallium/include/pipe/p_config.h
@@ -140,6 +140,9 @@
#define PIPE_OS_WINDOWS
#endif
+#if defined(__HAIKU__)
+#define PIPE_OS_HAIKU
+#endif
/*
* Subsystem.
diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h
index 57e966ac3b..39620a7198 100644
--- a/src/gallium/include/pipe/p_context.h
+++ b/src/gallium/include/pipe/p_context.h
@@ -98,7 +98,7 @@ struct pipe_context {
*/
/*@{*/
struct pipe_query *(*create_query)( struct pipe_context *pipe,
- unsigned query_type );
+ unsigned query_type );
void (*destroy_query)(struct pipe_context *pipe,
struct pipe_query *q);
@@ -215,10 +215,12 @@ struct pipe_context {
/**
* Clear the specified set of currently bound buffers to specified values.
+ * The entire buffers are cleared (no scissor, no colormask, etc).
*
- * buffers is a bitfield of PIPE_CLEAR_* values.
- *
- * rgba is a pointer to an array of one float for each of r, g, b, a.
+ * \param buffers bitfield of PIPE_CLEAR_* values.
+ * \param rgba pointer to an array of one float for each of r, g, b, a.
+ * \param depth depth clear value in [0,1].
+ * \param stencil stencil clear value
*/
void (*clear)(struct pipe_context *pipe,
unsigned buffers,
@@ -226,7 +228,9 @@ struct pipe_context {
double depth,
unsigned stencil);
- /** Flush rendering (flags = bitmask of PIPE_FLUSH_x tokens) */
+ /** Flush rendering
+ * \param flags bitmask of PIPE_FLUSH_x tokens)
+ */
void (*flush)( struct pipe_context *pipe,
unsigned flags,
struct pipe_fence_handle **fence );
@@ -242,10 +246,10 @@ struct pipe_context {
* \param texture texture to check.
* \param face cubemap face. Use 0 for non-cubemap texture.
*/
-
unsigned int (*is_texture_referenced) (struct pipe_context *pipe,
struct pipe_texture *texture,
unsigned face, unsigned level);
+
/**
* Check whether a buffer is referenced by an unflushed hw command.
* The state-tracker uses this function to optimize away unnecessary
@@ -255,7 +259,6 @@ struct pipe_context {
* checked.
* \param buf Buffer to check.
*/
-
unsigned int (*is_buffer_referenced) (struct pipe_context *pipe,
struct pipe_buffer *buf);
};
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index bc4bc70759..f252d6df00 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -191,9 +191,9 @@ enum pipe_texture_target {
* Transfer object usage flags
*/
enum pipe_transfer_usage {
- PIPE_TRANSFER_READ,
- PIPE_TRANSFER_WRITE,
- PIPE_TRANSFER_READ_WRITE /**< Read/modify/write */
+ PIPE_TRANSFER_READ = (1 << 0),
+ PIPE_TRANSFER_WRITE = (1 << 1),
+ PIPE_TRANSFER_READ_WRITE = PIPE_TRANSFER_READ | PIPE_TRANSFER_WRITE /**< Read/modify/write */
};
@@ -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 cf176c9209..30a4aaf409 100644
--- a/src/gallium/include/pipe/p_inlines.h
+++ b/src/gallium/include/pipe/p_inlines.h
@@ -63,6 +63,13 @@ pipe_buffer_map(struct pipe_screen *screen,
if(screen->buffer_map_range) {
unsigned offset = 0;
unsigned length = buf->size;
+
+ /* XXX: Actually we should be using/detecting DISCARD
+ * instead of assuming that WRITE implies discard */
+ if((usage & PIPE_BUFFER_USAGE_CPU_WRITE) &&
+ !(usage & PIPE_BUFFER_USAGE_DISCARD))
+ usage |= PIPE_BUFFER_USAGE_CPU_READ;
+
return screen->buffer_map_range(screen, buf, offset, length, usage);
}
else
@@ -111,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);
@@ -122,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);
}
@@ -134,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);
@@ -143,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_screen.h b/src/gallium/include/pipe/p_screen.h
index 6cbdd75943..3f30c52a16 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -194,6 +194,7 @@ struct pipe_screen {
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride);
diff --git a/src/gallium/include/pipe/p_shader_tokens.h b/src/gallium/include/pipe/p_shader_tokens.h
index 3dfc914269..5fa6c9af30 100644
--- a/src/gallium/include/pipe/p_shader_tokens.h
+++ b/src/gallium/include/pipe/p_shader_tokens.h
@@ -78,6 +78,7 @@ enum tgsi_file_type {
TGSI_FILE_SAMPLER =5,
TGSI_FILE_ADDRESS =6,
TGSI_FILE_IMMEDIATE =7,
+ TGSI_FILE_LOOP =8,
TGSI_FILE_COUNT /**< how many TGSI_FILE_ types */
};
@@ -157,8 +158,11 @@ union tgsi_immediate_data
float Float;
};
-/*
- * GL_NV_vertex_program
+/* TGSI opcodes.
+ *
+ * For more information on semantics of opcodes and
+ * which APIs are known to use which opcodes, see
+ * auxiliary/tgsi/tgsi-instruction-set.txt
*/
#define TGSI_OPCODE_ARL 0
#define TGSI_OPCODE_MOV 1
@@ -177,62 +181,32 @@ union tgsi_immediate_data
#define TGSI_OPCODE_SLT 14
#define TGSI_OPCODE_SGE 15
#define TGSI_OPCODE_MAD 16
-
-/*
- * GL_ATI_fragment_shader
- */
#define TGSI_OPCODE_SUB 17
-/*#define TGSI_OPCODE_DOT3 TGSI_OPCODE_DP3*/
-/*#define TGSI_OPCODE_DOT4 TGSI_OPCODE_DP4*/
#define TGSI_OPCODE_LRP 18
#define TGSI_OPCODE_CND 19
-#define TGSI_OPCODE_CND0 20
+ /* gap */
#define TGSI_OPCODE_DP2A 21
-
-/*
- * GL_EXT_vertex_shader
- */
-#define TGSI_OPCODE_INDEX 22 /* considered for removal */
-#define TGSI_OPCODE_NEGATE 23 /* considered for removal */
-/*#define TGSI_OPCODE_MADD TGSI_OPCODE_MAD*/
+ /* gap */
#define TGSI_OPCODE_FRC 24
-/*#define TGSI_OPCODE_SETGE TGSI_OPCODE_SGE*/
-/*#define TGSI_OPCODE_SETLT TGSI_OPCODE_SLT*/
#define TGSI_OPCODE_CLAMP 25
#define TGSI_OPCODE_FLR 26
#define TGSI_OPCODE_ROUND 27
#define TGSI_OPCODE_EX2 28
#define TGSI_OPCODE_LG2 29
#define TGSI_OPCODE_POW 30
-/*#define TGSI_OPCODE_RECIP TGSI_OPCODE_RCP*/
-/*#define TGSI_OPCODE_RECIPSQRT TGSI_OPCODE_RSQ*/
#define TGSI_OPCODE_XPD 31
-#define TGSI_OPCODE_MULTIPLYMATRIX 32 /* considered for removal */
-
-/*
- * GL_NV_vertex_program1_1
- */
+ /* gap */
#define TGSI_OPCODE_ABS 33
#define TGSI_OPCODE_RCC 34
#define TGSI_OPCODE_DPH 35
-
-/*
- * GL_NV_fragment_program
- */
#define TGSI_OPCODE_COS 36
#define TGSI_OPCODE_DDX 37
#define TGSI_OPCODE_DDY 38
-/*#define TGSI_OPCODE_EX2 TGSI_OPCODE_EXPBASE2*/
-/*#define TGSI_OPCODE_FLR TGSI_OPCODE_FLOOR*/
-/*#define TGSI_OPCODE_FRC TGSI_OPCODE_FRAC*/
#define TGSI_OPCODE_KILP 39 /* predicated kill */
-/*#define TGSI_OPCODE_LG2 TGSI_OPCODE_LOGBASE2*/
-/*#define TGSI_OPCODE_LRP TGSI_OPCODE_LERP*/
#define TGSI_OPCODE_PK2H 40
#define TGSI_OPCODE_PK2US 41
#define TGSI_OPCODE_PK4B 42
#define TGSI_OPCODE_PK4UB 43
-/*#define TGSI_OPCODE_POW TGSI_OPCODE_POWER*/
#define TGSI_OPCODE_RFL 44
#define TGSI_OPCODE_SEQ 45
#define TGSI_OPCODE_SFL 46
@@ -249,66 +223,29 @@ union tgsi_immediate_data
#define TGSI_OPCODE_UP4B 57
#define TGSI_OPCODE_UP4UB 58
#define TGSI_OPCODE_X2D 59
-
-/*
- * GL_NV_vertex_program2
- */
#define TGSI_OPCODE_ARA 60
#define TGSI_OPCODE_ARR 61
#define TGSI_OPCODE_BRA 62
#define TGSI_OPCODE_CAL 63
#define TGSI_OPCODE_RET 64
-#define TGSI_OPCODE_SSG 65
-
-/*
- * GL_ARB_vertex_program
- */
-#define TGSI_OPCODE_SWZ 118
-/*#define TGSI_OPCODE_XPD TGSI_OPCODE_CROSSPRODUCT*/
-
-/*
- * GL_ARB_fragment_program
- */
+#define TGSI_OPCODE_SSG 65 /* SGN */
#define TGSI_OPCODE_CMP 66
-#define TGSI_OPCODE_KIL 116 /* conditional kill */
#define TGSI_OPCODE_SCS 67
#define TGSI_OPCODE_TXB 68
-
-/*
- * GL_NV_fragment_program_option
- */
-/* No new opcode */
-
-/*
- * GL_NV_fragment_program2
- */
#define TGSI_OPCODE_NRM 69
#define TGSI_OPCODE_DIV 70
#define TGSI_OPCODE_DP2 71
-/*#define TGSI_OPCODE_DP2A TGSI_OPCODE_DOT2ADD*/
#define TGSI_OPCODE_TXL 72
#define TGSI_OPCODE_BRK 73
#define TGSI_OPCODE_IF 74
-#define TGSI_OPCODE_LOOP 75
+#define TGSI_OPCODE_BGNFOR 75
#define TGSI_OPCODE_REP 76
#define TGSI_OPCODE_ELSE 77
#define TGSI_OPCODE_ENDIF 78
-#define TGSI_OPCODE_ENDLOOP 79
+#define TGSI_OPCODE_ENDFOR 79
#define TGSI_OPCODE_ENDREP 80
-
-/*
- * GL_NV_vertex_program2_option
- */
-
-/*
- * GL_NV_vertex_program3
- */
#define TGSI_OPCODE_PUSHA 81
#define TGSI_OPCODE_POPA 82
-
-/*
- * GL_NV_gpu_program4
- */
#define TGSI_OPCODE_CEIL 83
#define TGSI_OPCODE_I2F 84
#define TGSI_OPCODE_NOT 85
@@ -323,103 +260,25 @@ union tgsi_immediate_data
#define TGSI_OPCODE_TXF 94
#define TGSI_OPCODE_TXQ 95
#define TGSI_OPCODE_CONT 96
-
-/*
- * GL_NV_vertex_program4
- */
-/* Same as GL_NV_gpu_program4 */
-
-/*
- * GL_NV_fragment_program4
- */
-/* Same as GL_NV_gpu_program4 */
-
-/*
- * GL_NV_geometry_program4
- */
-/* Same as GL_NV_gpu_program4 */
#define TGSI_OPCODE_EMIT 97
#define TGSI_OPCODE_ENDPRIM 98
-
-/*
- * GLSL
- */
-#define TGSI_OPCODE_BGNLOOP2 99
+#define TGSI_OPCODE_BGNLOOP 99
#define TGSI_OPCODE_BGNSUB 100
-#define TGSI_OPCODE_ENDLOOP2 101
+#define TGSI_OPCODE_ENDLOOP 101
#define TGSI_OPCODE_ENDSUB 102
-/*#define TGSI_OPCODE_INT TGSI_OPCODE_TRUNC*/
#define TGSI_OPCODE_NOISE1 103
#define TGSI_OPCODE_NOISE2 104
#define TGSI_OPCODE_NOISE3 105
#define TGSI_OPCODE_NOISE4 106
#define TGSI_OPCODE_NOP 107
-
-/*
- * ps_1_1
- */
-/*#define TGSI_OPCODE_TEXKILL TGSI_OPCODE_KIL*/
-
-/*
- * ps_1_2
- */
-/* CMP - use TGSI_OPCODE_CND0 */
-
-/*
- * ps_1_3
- */
-/* CMP - use TGSI_OPCODE_CND0 */
-
-/*
- * ps_1_4
- */
-/*#define TGSI_OPCODE_TEXLD TGSI_OPCODE_TEX*/
-
-/*
- * ps_2_0
- */
-/*#define TGSI_OPCODE_M4X4 TGSI_OPCODE_MULTIPLYMATRIX*/
-#define TGSI_OPCODE_M4X3 108
-#define TGSI_OPCODE_M3X4 109
-#define TGSI_OPCODE_M3X3 110
-#define TGSI_OPCODE_M3X2 111
-/*#define TGSI_OPCODE_CRS TGSI_OPCODE_XPD*/
+ /* gap */
#define TGSI_OPCODE_NRM4 112
-/*#define TGSI_OPCODE_SINCOS TGSI_OPCODE_SCS*/
-/*#define TGSI_OPCODE_TEXLDB TGSI_OPCODE_TXB*/
-/*#define TGSI_OPCODE_DP2ADD TGSI_OPCODE_DP2A*/
-
-/*
- * ps_2_x
- */
-/*#define TGSI_OPCODE_CALL TGSI_OPCODE_CAL*/
#define TGSI_OPCODE_CALLNZ 113
#define TGSI_OPCODE_IFC 114
-/*#define TGSI_OPCODE_BREAK TGSI_OPCODE_BRK*/
#define TGSI_OPCODE_BREAKC 115
-/*#define TGSI_OPCODE_DSX TGSI_OPCODE_DDX*/
-/*#define TGSI_OPCODE_DSY TGSI_OPCODE_DDY*/
-/*#define TGSI_OPCODE_TEXLDD TGSI_OPCODE_TXD*/
-
-/*
- * vs_1_1
- */
-/*#define TGSI_OPCODE_EXPP TGSI_OPCODE_EXP*/
-/*#define TGSI_OPCODE_LOGP TGSI_OPCODE_LG2*/
-
-/*
- * vs_2_0
- */
-/*#define TGSI_OPCODE_SGN TGSI_OPCODE_SSG*/
-/*#define TGSI_OPCODE_MOVA TGSI_OPCODE_ARR*/
-/* EXPP - use TGSI_OPCODE_EX2 */
-
-/*
- * vs_2_x
- */
-
+#define TGSI_OPCODE_KIL 116 /* conditional kill */
#define TGSI_OPCODE_END 117 /* aka HALT */
-
+#define TGSI_OPCODE_SWZ 118
#define TGSI_OPCODE_LAST 119
#define TGSI_SAT_NONE 0 /* do not saturate */
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 626bedb35a..b59d6b7ae3 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 96e8e08744..25e4148232 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)
+#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)
+#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)
+#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)
+#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)
+#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/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index 7a38b508fb..4d1259e1ee 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -42,21 +42,22 @@ struct drm_api
* Special buffer functions
*/
/*@{*/
- boolean (*buffer_from_texture)(struct drm_api *api,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
- struct pipe_buffer* (*buffer_from_handle)(struct drm_api *api,
- struct pipe_screen *screen,
- const char *name,
- unsigned handle);
- boolean (*handle_from_buffer)(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle);
- boolean (*global_handle_from_buffer)(struct drm_api *api,
+ struct pipe_texture*
+ (*texture_from_shared_handle)(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *templ,
+ const char *name,
+ unsigned stride,
+ unsigned handle);
+ boolean (*shared_handle_from_texture)(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle);
+ boolean (*local_handle_from_texture)(struct drm_api *api,
struct pipe_screen *screen,
- struct pipe_buffer *buffer,
+ struct pipe_texture *texture,
+ unsigned *stride,
unsigned *handle);
/*@}*/
diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c
index 6c617197ec..8819936fca 100644
--- a/src/gallium/state_trackers/dri/dri_context.c
+++ b/src/gallium/state_trackers/dri/dri_context.c
@@ -100,7 +100,6 @@ void
dri_destroy_context(__DRIcontextPrivate * cPriv)
{
struct dri_context *ctx = dri_context(cPriv);
- struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
/* No particular reason to wait for command completion before
* destroying a context, but it is probably worthwhile flushing it
@@ -109,9 +108,6 @@ dri_destroy_context(__DRIcontextPrivate * cPriv)
*/
st_flush(ctx->st, 0, NULL);
- if (screen->dummyContext == ctx)
- screen->dummyContext = NULL;
-
/* Also frees ctx->pipe?
*/
st_destroy_context(ctx->st);
@@ -143,7 +139,6 @@ dri_make_current(__DRIcontextPrivate * cPriv,
{
if (cPriv) {
struct dri_context *ctx = dri_context(cPriv);
- struct dri_screen *screen = dri_screen(cPriv->driScreenPriv);
struct dri_drawable *draw = dri_drawable(driDrawPriv);
struct dri_drawable *read = dri_drawable(driReadPriv);
struct st_context *old_st = st_get_current();
@@ -153,11 +148,6 @@ dri_make_current(__DRIcontextPrivate * cPriv,
++ctx->bind_count;
- /* This is for situations in which we need a rendering context but
- * there may not be any currently bound.
- */
- screen->dummyContext = ctx;
-
if (ctx->dPriv != driDrawPriv) {
ctx->dPriv = driDrawPriv;
ctx->d_stamp = driDrawPriv->lastStamp - 1;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c
index 1d91fbb89f..5cec9e329d 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.c
+++ b/src/gallium/state_trackers/dri/dri_drawable.c
@@ -36,6 +36,8 @@
#include "pipe/p_context.h"
#include "pipe/p_screen.h"
#include "pipe/p_inlines.h"
+#include "main/mtypes.h"
+#include "main/renderbuffer.h"
#include "state_tracker/drm_api.h"
#include "state_tracker/dri1_api.h"
#include "state_tracker/st_public.h"
@@ -44,14 +46,6 @@
#include "util/u_memory.h"
-static void
-dri_copy_to_front(__DRIdrawablePrivate * dPriv,
- struct pipe_surface *from,
- int x, int y, unsigned w, unsigned h)
-{
- /* TODO send a message to the Xserver to copy to the real front buffer */
-}
-
static struct pipe_surface *
dri_surface_from_handle(struct drm_api *api,
struct pipe_screen *screen,
@@ -62,11 +56,6 @@ dri_surface_from_handle(struct drm_api *api,
struct pipe_surface *surface = NULL;
struct pipe_texture *texture = NULL;
struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
-
- buf = api->buffer_from_handle(api, screen, "dri2 buffer", handle);
- if (!buf)
- return NULL;
memset(&templat, 0, sizeof(templat));
templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
@@ -78,13 +67,13 @@ dri_surface_from_handle(struct drm_api *api,
templat.height[0] = height;
pf_get_block(templat.format, &templat.block);
- texture = screen->texture_blanket(screen, &templat, &pitch, buf);
-
- /* we don't need the buffer from this point on */
- pipe_buffer_reference(&buf, NULL);
+ texture = api->texture_from_shared_handle(api, screen, &templat,
+ "dri2 buffer", pitch, handle);
- if (!texture)
+ if (!texture) {
+ debug_printf("%s: Failed to blanket the buffer with a texture\n", __func__);
return NULL;
+ }
surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
PIPE_BUFFER_USAGE_GPU_READ |
@@ -96,6 +85,35 @@ dri_surface_from_handle(struct drm_api *api,
}
/**
+ * Pixmaps have will have the same name of fake front and front.
+ */
+static boolean
+dri2_check_if_pixmap(__DRIbuffer *buffers, int count)
+{
+ boolean found = FALSE;
+ boolean is_pixmap = FALSE;
+ unsigned name;
+ int i;
+
+ for (i = 0; i < count; i++) {
+ switch (buffers[i].attachment) {
+ case __DRI_BUFFER_FRONT_LEFT:
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ if (found) {
+ is_pixmap = buffers[i].name == name;
+ } else {
+ name = buffers[i].name;
+ found = TRUE;
+ }
+ default:
+ continue;
+ }
+ }
+
+ return is_pixmap;
+}
+
+/**
* This will be called a drawable is known to have been resized.
*/
void
@@ -153,15 +171,15 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
memcpy(drawable->old, buffers, sizeof(__DRIbuffer) * count);
}
+ drawable->is_pixmap = dri2_check_if_pixmap(buffers, count);
+
for (i = 0; i < count; i++) {
enum pipe_format format = 0;
int index = 0;
switch (buffers[i].attachment) {
case __DRI_BUFFER_FRONT_LEFT:
- index = ST_SURFACE_FRONT_LEFT;
- format = drawable->color_format;
- break;
+ continue;
case __DRI_BUFFER_FAKE_FRONT_LEFT:
index = ST_SURFACE_FRONT_LEFT;
format = drawable->color_format;
@@ -171,12 +189,10 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
format = drawable->color_format;
break;
case __DRI_BUFFER_DEPTH:
- index = ST_SURFACE_DEPTH;
- format = drawable->depth_format;
- break;
+ case __DRI_BUFFER_DEPTH_STENCIL:
case __DRI_BUFFER_STENCIL:
index = ST_SURFACE_DEPTH;
- format = drawable->stencil_format;
+ format = drawable->depth_stencil_format;
break;
case __DRI_BUFFER_ACCUM:
default:
@@ -197,6 +213,18 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
dri_drawable->w,
dri_drawable->h, buffers[i].pitch);
+ switch (buffers[i].attachment) {
+ case __DRI_BUFFER_FAKE_FRONT_LEFT:
+ case __DRI_BUFFER_BACK_LEFT:
+ drawable->color_format = surface->format;
+ break;
+ case __DRI_BUFFER_DEPTH:
+ case __DRI_BUFFER_DEPTH_STENCIL:
+ case __DRI_BUFFER_STENCIL:
+ drawable->depth_stencil_format = surface->format;
+ break;
+ }
+
st_set_framebuffer_surface(drawable->stfb, index, surface);
pipe_surface_reference(&surface, NULL);
}
@@ -204,13 +232,60 @@ dri_get_buffers(__DRIdrawablePrivate * dPriv)
st_resize_framebuffer(drawable->stfb, dri_drawable->w, dri_drawable->h);
}
+/**
+ * These are used for GLX_EXT_texture_from_pixmap
+ */
+void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint format, __DRIdrawable *dPriv)
+{
+ struct dri_drawable *drawable = dri_drawable(dPriv);
+ struct pipe_surface *ps;
+
+ if (!drawable->stfb->Base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer) {
+ struct gl_renderbuffer *rb =
+ st_new_renderbuffer_fb(drawable->color_format, 0 /*XXX*/, FALSE);
+ _mesa_add_renderbuffer(&drawable->stfb->Base, BUFFER_FRONT_LEFT, rb);
+ }
+
+ dri_get_buffers(drawable->dPriv);
+ st_get_framebuffer_surface(drawable->stfb, ST_SURFACE_FRONT_LEFT, &ps);
+
+ st_bind_texture_surface(ps, target == GL_TEXTURE_2D ? ST_TEXTURE_2D :
+ ST_TEXTURE_RECT, 0, drawable->color_format);
+}
+
+void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv)
+{
+ dri2_set_tex_buffer2(pDRICtx, target, GLX_TEXTURE_FORMAT_RGBA_EXT, dPriv);
+}
+
void
dri_flush_frontbuffer(struct pipe_screen *screen,
struct pipe_surface *surf, void *context_private)
{
struct dri_context *ctx = (struct dri_context *)context_private;
+ struct dri_drawable *drawable = dri_drawable(ctx->dPriv);
+ __DRIdrawable *dri_drawable = ctx->dPriv;
+ __DRIscreen *dri_screen = ctx->sPriv;
+
+ /* XXX Does this function get called with DRI1? */
+
+ if (ctx->dPriv == NULL) {
+ debug_printf("%s: no drawable bound to context\n", __func__);
+ return;
+ }
- dri_copy_to_front(ctx->dPriv, surf, 0, 0, surf->width, surf->height);
+#if 0
+ /* TODO if rendering to pixmaps is slow enable this code. */
+ if (drawable->is_pixmap)
+ return;
+#else
+ (void)drawable;
+#endif
+
+ (*dri_screen->dri2.loader->flushFrontBuffer)(dri_drawable,
+ dri_drawable->loaderPrivate);
}
/**
@@ -232,52 +307,43 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
if (drawable == NULL)
goto fail;
- drawable->color_format = (visual->redBits == 8) ?
- PIPE_FORMAT_A8R8G8B8_UNORM : PIPE_FORMAT_R5G6B5_UNORM;
-
- debug_printf("Red bits is %d\n", visual->redBits);
+ if (visual->redBits == 8) {
+ if (visual->alphaBits == 8)
+ drawable->color_format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ else
+ drawable->color_format = PIPE_FORMAT_X8R8G8B8_UNORM;
+ } else {
+ drawable->color_format = PIPE_FORMAT_R5G6B5_UNORM;
+ }
switch(visual->depthBits) {
default:
case 0:
- debug_printf("Depth buffer 0.\n");
- drawable->depth_format = PIPE_FORMAT_NONE;
+ drawable->depth_stencil_format = PIPE_FORMAT_NONE;
break;
case 16:
- debug_printf("Depth buffer 16.\n");
- drawable->depth_format = PIPE_FORMAT_Z16_UNORM;
+ drawable->depth_stencil_format = PIPE_FORMAT_Z16_UNORM;
break;
case 24:
if (visual->stencilBits == 0) {
- debug_printf("Depth buffer 24. Stencil 0.\n");
- drawable->depth_format = (screen->d_depth_bits_last) ?
+ drawable->depth_stencil_format = (screen->d_depth_bits_last) ?
PIPE_FORMAT_X8Z24_UNORM:
PIPE_FORMAT_Z24X8_UNORM;
} else {
- debug_printf("Combined depth stencil 24 / 8.\n");
- drawable->depth_format = (screen->sd_depth_bits_last) ?
+ drawable->depth_stencil_format = (screen->sd_depth_bits_last) ?
PIPE_FORMAT_S8Z24_UNORM:
PIPE_FORMAT_Z24S8_UNORM;
}
break;
- }
-
- switch(visual->stencilBits) {
- default:
- case 0:
- drawable->stencil_format = PIPE_FORMAT_NONE;
- break;
- case 8:
- drawable->stencil_format = (screen->sd_depth_bits_last) ?
- PIPE_FORMAT_S8Z24_UNORM:
- PIPE_FORMAT_Z24S8_UNORM;
+ case 32:
+ drawable->depth_stencil_format = PIPE_FORMAT_Z32_UNORM;
break;
}
drawable->stfb = st_create_framebuffer(visual,
drawable->color_format,
- drawable->depth_format,
- drawable->stencil_format,
+ drawable->depth_stencil_format,
+ drawable->depth_stencil_format,
dPriv->w,
dPriv->h, (void *)drawable);
if (drawable->stfb == NULL)
@@ -288,17 +354,19 @@ dri_create_buffer(__DRIscreenPrivate * sPriv,
dPriv->driverPrivate = (void *)drawable;
/* setup dri2 buffers information */
+ /* TODO incase of double buffer visual, delay fake creation */
i = 0;
drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT;
-#if 0
- /* TODO incase of double buffer visual, delay fake creation */
- drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
-#endif
+
if (visual->doubleBufferMode)
drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT;
- if (visual->depthBits)
+ else
+ drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT;
+ if (visual->depthBits && visual->stencilBits)
+ drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL;
+ else if (visual->depthBits)
drawable->attachments[i++] = __DRI_BUFFER_DEPTH;
- if (visual->stencilBits)
+ else if (visual->stencilBits)
drawable->attachments[i++] = __DRI_BUFFER_STENCIL;
drawable->num_attachments = i;
diff --git a/src/gallium/state_trackers/dri/dri_drawable.h b/src/gallium/state_trackers/dri/dri_drawable.h
index 2fbd5f1eb7..b910930db4 100644
--- a/src/gallium/state_trackers/dri/dri_drawable.h
+++ b/src/gallium/state_trackers/dri/dri_drawable.h
@@ -33,6 +33,7 @@
struct pipe_surface;
struct pipe_fence_handle;
struct st_framebuffer;
+struct dri_context;
#define DRI_SWAP_FENCES_MAX 8
#define DRI_SWAP_FENCES_MASK 7
@@ -46,6 +47,8 @@ struct dri_drawable
unsigned attachments[8];
unsigned num_attachments;
+ boolean is_pixmap;
+
__DRIbuffer old[8];
unsigned old_num;
unsigned old_w;
@@ -60,8 +63,7 @@ struct dri_drawable
unsigned int cur_fences;
enum pipe_format color_format;
- enum pipe_format depth_format;
- enum pipe_format stencil_format;
+ enum pipe_format depth_stencil_format;
};
static INLINE struct dri_drawable *
@@ -91,6 +93,12 @@ void dri_get_buffers(__DRIdrawablePrivate * dPriv);
void dri_destroy_buffer(__DRIdrawablePrivate * dPriv);
+void dri2_set_tex_buffer2(__DRIcontext *pDRICtx, GLint target,
+ GLint glx_texture_format, __DRIdrawable *dPriv);
+
+void dri2_set_tex_buffer(__DRIcontext *pDRICtx, GLint target,
+ __DRIdrawable *dPriv);
+
void
dri1_update_drawables(struct dri_context *ctx,
struct dri_drawable *draw, struct dri_drawable *read);
diff --git a/src/gallium/state_trackers/dri/dri_extensions.c b/src/gallium/state_trackers/dri/dri_extensions.c
index 7c04c2b970..4349a4d1d2 100644
--- a/src/gallium/state_trackers/dri/dri_extensions.c
+++ b/src/gallium/state_trackers/dri/dri_extensions.c
@@ -33,6 +33,7 @@
#include "dri_context.h"
#include "state_tracker/st_context.h"
+#define need_GL_ARB_map_buffer_range
#define need_GL_ARB_multisample
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
@@ -61,6 +62,7 @@
*/
const struct dri_extension card_extensions[] = {
{"GL_ARB_fragment_shader", NULL},
+ {"GL_ARB_map_buffer_range", GL_ARB_map_buffer_range_functions},
{"GL_ARB_multisample", GL_ARB_multisample_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c
index 5f78b7264a..884b6d5011 100644
--- a/src/gallium/state_trackers/dri/dri_screen.c
+++ b/src/gallium/state_trackers/dri/dri_screen.c
@@ -57,12 +57,19 @@ PUBLIC const char __driConfigOptions[] =
const uint __driNConfigOptions = 3;
+static const __DRItexBufferExtension dri2TexBufferExtension = {
+ { __DRI_TEX_BUFFER, __DRI_TEX_BUFFER_VERSION },
+ dri2_set_tex_buffer,
+ dri2_set_tex_buffer2,
+};
+
static const __DRIextension *dri_screen_extensions[] = {
&driReadDrawableExtension,
&driCopySubBufferExtension.base,
&driSwapControlExtension.base,
&driFrameTrackingExtension.base,
&driMediaStreamCounterExtension.base,
+ &dri2TexBufferExtension.base,
NULL
};
@@ -72,17 +79,17 @@ static const __DRIconfig **
dri_fill_in_modes(struct dri_screen *screen,
unsigned pixel_bits)
{
- __DRIconfig **configs;
+ __DRIconfig **configs = NULL;
unsigned num_modes;
- uint8_t depth_bits_array[4];
- uint8_t stencil_bits_array[4];
+ uint8_t depth_bits_array[5];
+ uint8_t stencil_bits_array[5];
uint8_t msaa_samples_array[1];
unsigned depth_buffer_factor;
unsigned back_buffer_factor;
unsigned msaa_samples_factor;
- GLenum fb_format;
- GLenum fb_type;
struct pipe_screen *p_screen = screen->pipe_screen;
+ boolean pf_r5g6b5, pf_a8r8g8b8, pf_x8r8g8b8;
+ boolean pf_z16, pf_x8z24, pf_z24x8, pf_s8z24, pf_z24s8, pf_z32;
static const GLenum back_buffer_modes[] = {
GLX_NONE, GLX_SWAP_UNDEFINED_OML, GLX_SWAP_COPY_OML
@@ -92,39 +99,51 @@ dri_fill_in_modes(struct dri_screen *screen,
stencil_bits_array[0] = 0;
depth_buffer_factor = 1;
- if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+ pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_z24x8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_s8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+ pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+ pf_x8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8R8G8B8_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_RENDER_TARGET, 0);
+
+ if (pf_z16) {
depth_bits_array[depth_buffer_factor] = 16;
stencil_bits_array[depth_buffer_factor++] = 0;
}
- if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
- depth_bits_array[depth_buffer_factor] = 24;
- stencil_bits_array[depth_buffer_factor++] = 0;
- screen->d_depth_bits_last = TRUE;
- } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24X8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
- 0)) {
+ if (pf_x8z24 || pf_z24x8) {
depth_bits_array[depth_buffer_factor] = 24;
stencil_bits_array[depth_buffer_factor++] = 0;
- screen->d_depth_bits_last = FALSE;
+ screen->d_depth_bits_last = pf_x8z24;
}
- if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_S8Z24_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0)) {
+ if (pf_s8z24 || pf_z24s8) {
depth_bits_array[depth_buffer_factor] = 24;
stencil_bits_array[depth_buffer_factor++] = 8;
- screen->sd_depth_bits_last = TRUE;
- } else if (p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_DEPTH_STENCIL,
- 0)) {
- depth_bits_array[depth_buffer_factor] = 24;
- stencil_bits_array[depth_buffer_factor++] = 8;
- screen->sd_depth_bits_last = FALSE;
+ screen->sd_depth_bits_last = pf_s8z24;
+ }
+ if (pf_z32) {
+ depth_bits_array[depth_buffer_factor] = 32;
+ stencil_bits_array[depth_buffer_factor++] = 0;
}
msaa_samples_array[0] = 0;
@@ -134,29 +153,43 @@ dri_fill_in_modes(struct dri_screen *screen,
num_modes =
depth_buffer_factor * back_buffer_factor * msaa_samples_factor * 4;
- if (pixel_bits == 16) {
- if (!p_screen->is_format_supported(p_screen,
- PIPE_FORMAT_R5G6B5_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
- return NULL;
- fb_format = GL_RGB;
- fb_type = GL_UNSIGNED_SHORT_5_6_5;
+ if (pixel_bits == 16 && pf_r5g6b5) {
+ configs = driCreateConfigs(GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
+ depth_bits_array, stencil_bits_array,
+ depth_buffer_factor, back_buffer_modes,
+ back_buffer_factor,
+ msaa_samples_array, 1);
} else {
- if (!p_screen->is_format_supported(p_screen,
- PIPE_FORMAT_A8R8G8B8_UNORM,
- PIPE_TEXTURE_2D,
- PIPE_TEXTURE_USAGE_RENDER_TARGET, 0))
- return NULL;
- fb_format = GL_BGRA;
- fb_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ __DRIconfig **configs_a8r8g8b8 = NULL;
+ __DRIconfig **configs_x8r8g8b8 = NULL;
+
+ if (pf_a8r8g8b8)
+ configs_a8r8g8b8 = driCreateConfigs(GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
+ depth_bits_array,
+ stencil_bits_array,
+ depth_buffer_factor,
+ back_buffer_modes,
+ back_buffer_factor,
+ msaa_samples_array, 1);
+ if (pf_x8r8g8b8)
+ configs_x8r8g8b8 = driCreateConfigs(GL_BGR, GL_UNSIGNED_INT_8_8_8_8_REV,
+ depth_bits_array,
+ stencil_bits_array,
+ depth_buffer_factor,
+ back_buffer_modes,
+ back_buffer_factor,
+ msaa_samples_array, 1);
+
+ if (configs_a8r8g8b8 && configs_x8r8g8b8)
+ configs = driConcatConfigs(configs_x8r8g8b8, configs_a8r8g8b8);
+ else if (configs_a8r8g8b8)
+ configs = configs_a8r8g8b8;
+ else if (configs_x8r8g8b8)
+ configs = configs_x8r8g8b8;
+ else
+ configs = NULL;
}
- configs = driCreateConfigs(fb_format, fb_type,
- depth_bits_array,
- stencil_bits_array, depth_buffer_factor,
- back_buffer_modes, back_buffer_factor,
- msaa_samples_array, msaa_samples_factor);
if (configs == NULL) {
debug_printf("%s: driCreateConfigs failed\n", __FUNCTION__);
return NULL;
diff --git a/src/gallium/state_trackers/dri/dri_screen.h b/src/gallium/state_trackers/dri/dri_screen.h
index f3335bb09f..f6c56d0f0c 100644
--- a/src/gallium/state_trackers/dri/dri_screen.h
+++ b/src/gallium/state_trackers/dri/dri_screen.h
@@ -49,12 +49,6 @@ struct dri_screen
*/
driOptionCache optionCache;
- /**
- * Temporary(?) context to use for SwapBuffers or other situations in
- * which we need a rendering context, but none is currently bound.
- */
- struct dri_context *dummyContext;
-
/* drm */
int fd;
drmLock *drmLock;
diff --git a/src/gallium/state_trackers/egl/egl_context.c b/src/gallium/state_trackers/egl/egl_context.c
index e2da2180f7..c4f7361ca0 100644
--- a/src/gallium/state_trackers/egl/egl_context.c
+++ b/src/gallium/state_trackers/egl/egl_context.c
@@ -83,23 +83,16 @@ const struct dri_extension card_extensions[] = {
{NULL, NULL}
};
-EGLContext
-drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list)
+_EGLContext *
+drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list)
{
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev = lookup_drm_device(dpy);
struct drm_context *ctx;
struct drm_context *share = NULL;
struct st_context *st_share = NULL;
- _EGLConfig *conf;
int i;
__GLcontextModes *visual;
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreateContext");
- return EGL_NO_CONTEXT;
- }
-
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
/* no attribs defined for now */
@@ -129,26 +122,21 @@ drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext
if (!ctx->st)
goto err_gl;
- /* link to display */
- _eglLinkContext(&ctx->base, _eglLookupDisplay(dpy));
- assert(_eglGetContextHandle(&ctx->base));
-
- return _eglGetContextHandle(&ctx->base);
+ return &ctx->base;
err_gl:
ctx->pipe->destroy(ctx->pipe);
err_pipe:
free(ctx);
err_c:
- return EGL_NO_CONTEXT;
+ return NULL;
}
EGLBoolean
-drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
+drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context)
{
struct drm_context *c = lookup_drm_context(context);
- _eglUnlinkContext(&c->base);
- if (!c->base.IsBound) {
+ if (!_eglIsContextBound(&c->base)) {
st_destroy_context(c->st);
c->pipe->destroy(c->pipe);
free(c);
@@ -157,7 +145,7 @@ drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
}
EGLBoolean
-drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context)
+drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context)
{
struct drm_surface *readSurf = lookup_drm_surface(read);
struct drm_surface *drawSurf = lookup_drm_surface(draw);
diff --git a/src/gallium/state_trackers/egl/egl_surface.c b/src/gallium/state_trackers/egl/egl_surface.c
index 86f2ea97e5..69e2d6b708 100644
--- a/src/gallium/state_trackers/egl/egl_surface.c
+++ b/src/gallium/state_trackers/egl/egl_surface.c
@@ -67,39 +67,21 @@ drm_create_framebuffer(const __GLcontextModes *visual,
}
static void
-drm_create_texture(_EGLDriver *drv,
+drm_create_texture(_EGLDisplay *dpy,
struct drm_screen *scrn,
unsigned w, unsigned h)
{
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev = lookup_drm_device(dpy);
struct pipe_screen *screen = dev->screen;
struct pipe_surface *surface;
struct pipe_texture *texture;
struct pipe_texture templat;
- struct pipe_buffer *buf;
- unsigned stride = 1024;
+ struct pipe_buffer *buf = NULL;
unsigned pitch = 0;
- unsigned size = 0;
-
- /* ugly */
- if (stride < w)
- stride = 2048;
-
- pitch = stride * 4;
- size = h * 2 * pitch;
-
- buf = pipe_buffer_create(screen,
- 0, /* alignment */
- PIPE_BUFFER_USAGE_GPU_READ_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ_WRITE,
- size);
-
- if (!buf)
- goto err_buf;
memset(&templat, 0, sizeof(templat));
- templat.tex_usage |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
- templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
templat.target = PIPE_TEXTURE_2D;
templat.last_level = 0;
templat.depth[0] = 1;
@@ -108,10 +90,9 @@ drm_create_texture(_EGLDriver *drv,
templat.height[0] = h;
pf_get_block(templat.format, &templat.block);
- texture = screen->texture_blanket(dev->screen,
- &templat,
- &pitch,
- buf);
+ texture = screen->texture_create(dev->screen,
+ &templat);
+
if (!texture)
goto err_tex;
@@ -125,14 +106,13 @@ drm_create_texture(_EGLDriver *drv,
if (!surface)
goto err_surf;
-
scrn->tex = texture;
scrn->surface = surface;
- scrn->buffer = buf;
scrn->front.width = w;
scrn->front.height = h;
scrn->front.pitch = pitch;
- dev->api->handle_from_buffer(dev->api, screen, scrn->buffer, &scrn->front.handle);
+ dev->api->local_handle_from_texture(dev->api, screen, texture,
+ &scrn->front.pitch, &scrn->front.handle);
if (0)
goto err_handle;
@@ -144,7 +124,6 @@ err_surf:
pipe_texture_reference(&texture, NULL);
err_tex:
pipe_buffer_reference(&buf, NULL);
-err_buf:
return;
}
@@ -153,9 +132,9 @@ err_buf:
*/
void
-drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
+drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen)
{
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev = lookup_drm_device(dpy);
screen->surf = NULL;
@@ -178,22 +157,22 @@ drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen)
screen->shown = 0;
}
-EGLSurface
-drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list)
+_EGLSurface *
+drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list)
{
- return EGL_NO_SURFACE;
+ return NULL;
}
-EGLSurface
-drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list)
+_EGLSurface *
+drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list)
{
- return EGL_NO_SURFACE;
+ return NULL;
}
-EGLSurface
-drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+_EGLSurface *
+drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
const EGLint *attrib_list)
{
int i;
@@ -201,13 +180,6 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
int height = -1;
struct drm_surface *surf = NULL;
__GLcontextModes *visual;
- _EGLConfig *conf;
-
- conf = _eglLookupConfig(drv, dpy, config);
- if (!conf) {
- _eglError(EGL_BAD_CONFIG, "eglCreatePbufferSurface");
- return EGL_NO_CONTEXT;
- }
for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i++) {
switch (attrib_list[i]) {
@@ -225,7 +197,7 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
if (width < 1 || height < 1) {
_eglError(EGL_BAD_ATTRIBUTE, "eglCreatePbufferSurface");
- return EGL_NO_SURFACE;
+ return NULL;
}
surf = (struct drm_surface *) calloc(1, sizeof(struct drm_surface));
@@ -245,17 +217,16 @@ drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
(void*)surf);
drm_visual_modes_destroy(visual);
- _eglLinkSurface(&surf->base, _eglLookupDisplay(dpy));
- return surf->base.Handle;
+ return &surf->base;
err_surf:
free(surf);
err:
- return EGL_NO_SURFACE;
+ return NULL;
}
-EGLSurface
-drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
+_EGLSurface *
+drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *cfg,
const EGLint *attrib_list)
{
EGLSurface surf = drm_create_pbuffer_surface(drv, dpy, cfg, attrib_list);
@@ -264,22 +235,21 @@ drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg,
}
EGLBoolean
-drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy,
- EGLScreenMESA screen,
- EGLSurface surface, EGLModeMESA m)
+drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLScreen *screen,
+ _EGLSurface *surface, _EGLMode *mode)
{
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev = lookup_drm_device(dpy);
struct drm_surface *surf = lookup_drm_surface(surface);
- struct drm_screen *scrn = lookup_drm_screen(dpy, screen);
- _EGLMode *mode = _eglLookupMode(dpy, m);
+ struct drm_screen *scrn = lookup_drm_screen(screen);
int ret;
unsigned int i, k;
if (scrn->shown)
- drm_takedown_shown_screen(drv, scrn);
+ drm_takedown_shown_screen(dpy, scrn);
- drm_create_texture(drv, scrn, mode->Width, mode->Height);
+ drm_create_texture(dpy, scrn, mode->Width, mode->Height);
if (!scrn->buffer)
return EGL_FALSE;
@@ -361,14 +331,12 @@ err_bo:
}
EGLBoolean
-drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
{
struct drm_surface *surf = lookup_drm_surface(surface);
- _eglUnlinkSurface(&surf->base);
-
- if (!surf->base.IsBound) {
+ if (!_eglIsSurfaceBound(&surf->base)) {
if (surf->screen)
- drm_takedown_shown_screen(drv, surf->screen);
+ drm_takedown_shown_screen(dpy, surf->screen);
st_unreference_framebuffer(surf->stfb);
free(surf);
}
@@ -376,8 +344,9 @@ drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
}
EGLBoolean
-drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
{
+ struct drm_device *dev = lookup_drm_device(dpy);
struct drm_surface *surf = lookup_drm_surface(draw);
struct pipe_surface *back_surf;
@@ -395,7 +364,6 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
st_notify_swapbuffers(surf->stfb);
if (surf->screen) {
- surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
surf->user->pipe->surface_copy(surf->user->pipe,
surf->screen->surface,
0, 0,
@@ -403,7 +371,15 @@ drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
0, 0,
surf->w, surf->h);
surf->user->pipe->flush(surf->user->pipe, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_TEXTURE_CACHE, NULL);
- /* TODO stuff here */
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ /* TODO query connector property to see if this is needed */
+ drmModeDirtyFB(dev->drmFD, surf->screen->fbID, NULL, 0);
+#else
+ (void)dev;
+#endif
+
+ /* TODO more stuff here */
}
}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.c b/src/gallium/state_trackers/egl/egl_tracker.c
index 521c91d895..5140755001 100644
--- a/src/gallium/state_trackers/egl/egl_tracker.c
+++ b/src/gallium/state_trackers/egl/egl_tracker.c
@@ -6,6 +6,8 @@
#include <string.h>
#include "egl_tracker.h"
+#include <fcntl.h>
+
#include "egllog.h"
#include "state_tracker/drm_api.h"
@@ -21,46 +23,46 @@ extern const struct dri_extension card_extensions[];
* Exported functions
*/
+static void
+drm_unload(_EGLDriver *drv)
+{
+ free(drv);
+}
+
/**
* The bootstrap function. Return a new drm_driver object and
* plug in API functions.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
- struct drm_device *drm;
+ _EGLDriver *drv;
- drm = (struct drm_device *) calloc(1, sizeof(struct drm_device));
- if (!drm) {
+ drv = (_EGLDriver *) calloc(1, sizeof(_EGLDriver));
+ if (!drv) {
return NULL;
}
- drm->api = drm_api_create();
-
/* First fill in the dispatch table with defaults */
- _eglInitDriverFallbacks(&drm->base);
+ _eglInitDriverFallbacks(drv);
/* then plug in our Drm-specific functions */
- drm->base.API.Initialize = drm_initialize;
- drm->base.API.Terminate = drm_terminate;
- drm->base.API.CreateContext = drm_create_context;
- drm->base.API.MakeCurrent = drm_make_current;
- drm->base.API.CreateWindowSurface = drm_create_window_surface;
- drm->base.API.CreatePixmapSurface = drm_create_pixmap_surface;
- drm->base.API.CreatePbufferSurface = drm_create_pbuffer_surface;
- drm->base.API.DestroySurface = drm_destroy_surface;
- drm->base.API.DestroyContext = drm_destroy_context;
- drm->base.API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
- drm->base.API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
- drm->base.API.SwapBuffers = drm_swap_buffers;
-
- drm->base.ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
- drm->base.Name = "DRM/Gallium/Win";
-
- /* enable supported extensions */
- drm->base.Extensions.MESA_screen_surface = EGL_TRUE;
- drm->base.Extensions.MESA_copy_context = EGL_TRUE;
-
- return &drm->base;
+ drv->API.Initialize = drm_initialize;
+ drv->API.Terminate = drm_terminate;
+ drv->API.CreateContext = drm_create_context;
+ drv->API.MakeCurrent = drm_make_current;
+ drv->API.CreateWindowSurface = drm_create_window_surface;
+ drv->API.CreatePixmapSurface = drm_create_pixmap_surface;
+ drv->API.CreatePbufferSurface = drm_create_pbuffer_surface;
+ drv->API.DestroySurface = drm_destroy_surface;
+ drv->API.DestroyContext = drm_destroy_context;
+ drv->API.CreateScreenSurfaceMESA = drm_create_screen_surface_mesa;
+ drv->API.ShowScreenSurfaceMESA = drm_show_screen_surface_mesa;
+ drv->API.SwapBuffers = drm_swap_buffers;
+
+ drv->Name = "DRM/Gallium/Win";
+ drv->Unload = drm_unload;
+
+ return drv;
}
static void
@@ -128,11 +130,18 @@ drm_find_dpms(struct drm_device *dev, struct drm_screen *screen)
screen->dpms = p;
}
+static int drm_open_minor(int minor)
+{
+ char buf[64];
+
+ sprintf(buf, DRM_DEV_NAME, DRM_DIR_NAME, minor);
+ return open(buf, O_RDWR, 0);
+}
+
EGLBoolean
-drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
+drm_initialize(_EGLDriver *drv, _EGLDisplay *disp, EGLint *major, EGLint *minor)
{
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev;
struct drm_screen *screen = NULL;
drmModeConnectorPtr connector = NULL;
drmModeResPtr res = NULL;
@@ -141,7 +150,13 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
EGLint i;
int fd;
- fd = drmOpen("i915", NULL);
+ dev = (struct drm_device *) calloc(1, sizeof(struct drm_device));
+ if (!dev)
+ return EGL_FALSE;
+ dev->api = drm_api_create();
+
+ /* try the first node */
+ fd = drm_open_minor(0);
if (fd < 0)
goto err_fd;
@@ -186,6 +201,8 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
}
dev->count_screens = num_screens;
+ disp->DriverData = dev;
+
/* for now we only have one config */
_EGLConfig *config = calloc(1, sizeof(*config));
memset(config, 1, sizeof(*config));
@@ -200,7 +217,10 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
_eglSetConfigAttrib(config, EGL_SURFACE_TYPE, EGL_PBUFFER_BIT);
_eglAddConfig(disp, config);
- drv->Initialized = EGL_TRUE;
+ disp->ClientAPIsMask = EGL_OPENGL_BIT /*| EGL_OPENGL_ES_BIT*/;
+ /* enable supported extensions */
+ disp->Extensions.MESA_screen_surface = EGL_TRUE;
+ disp->Extensions.MESA_copy_context = EGL_TRUE;
*major = 1;
*minor = 4;
@@ -210,23 +230,27 @@ drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor)
err_screen:
drmClose(fd);
err_fd:
+ free(dev);
return EGL_FALSE;
}
EGLBoolean
-drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
+drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
- struct drm_device *dev = (struct drm_device *)drv;
+ struct drm_device *dev = lookup_drm_device(dpy);
struct drm_screen *screen;
int i = 0;
+ _eglReleaseDisplayResources(drv, dpy);
+ _eglCleanupDisplay(dpy);
+
drmFreeVersion(dev->version);
for (i = 0; i < dev->count_screens; i++) {
screen = dev->screens[i];
if (screen->shown)
- drm_takedown_shown_screen(drv, screen);
+ drm_takedown_shown_screen(dpy, screen);
drmModeFreeProperty(screen->dpms);
drmModeFreeConnector(screen->connector);
@@ -236,12 +260,12 @@ drm_terminate(_EGLDriver *drv, EGLDisplay dpy)
dev->screen->destroy(dev->screen);
dev->winsys = NULL;
- dev->api->destroy(dev->api);
drmClose(dev->drmFD);
- _eglCleanupDisplay(_eglLookupDisplay(dpy));
+ dev->api->destroy(dev->api);
free(dev);
+ dpy->DriverData = NULL;
return EGL_TRUE;
}
diff --git a/src/gallium/state_trackers/egl/egl_tracker.h b/src/gallium/state_trackers/egl/egl_tracker.h
index 3b8836720d..dd4730f957 100644
--- a/src/gallium/state_trackers/egl/egl_tracker.h
+++ b/src/gallium/state_trackers/egl/egl_tracker.h
@@ -32,8 +32,6 @@ struct drm_context;
struct drm_device
{
- _EGLDriver base; /* base class/object */
-
/*
* pipe
*/
@@ -136,25 +134,29 @@ struct drm_screen
};
+static INLINE struct drm_device *
+lookup_drm_device(_EGLDisplay *d)
+{
+ return (struct drm_device *) d->DriverData;
+}
+
+
static INLINE struct drm_context *
-lookup_drm_context(EGLContext context)
+lookup_drm_context(_EGLContext *c)
{
- _EGLContext *c = _eglLookupContext(context);
return (struct drm_context *) c;
}
static INLINE struct drm_surface *
-lookup_drm_surface(EGLSurface surface)
+lookup_drm_surface(_EGLSurface *s)
{
- _EGLSurface *s = _eglLookupSurface(surface);
return (struct drm_surface *) s;
}
static INLINE struct drm_screen *
-lookup_drm_screen(EGLDisplay dpy, EGLScreenMESA screen)
+lookup_drm_screen(_EGLScreen *s)
{
- _EGLScreen *s = _eglLookupScreen(dpy, screen);
return (struct drm_screen *) s;
}
@@ -171,25 +173,25 @@ __GLcontextModes* drm_visual_from_config(_EGLConfig *conf);
* egl_surface.h
*/
/*@{*/
-void drm_takedown_shown_screen(_EGLDriver *drv, struct drm_screen *screen);
+void drm_takedown_shown_screen(_EGLDisplay *dpy, struct drm_screen *screen);
/*@}*/
/**
* All function exported to the egl side.
*/
/*@{*/
-EGLBoolean drm_initialize(_EGLDriver *drv, EGLDisplay dpy, EGLint *major, EGLint *minor);
-EGLBoolean drm_terminate(_EGLDriver *drv, EGLDisplay dpy);
-EGLContext drm_create_context(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list);
-EGLBoolean drm_destroy_context(_EGLDriver *drv, EGLDisplay dpy, EGLContext context);
-EGLSurface drm_create_window_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativeWindowType window, const EGLint *attrib_list);
-EGLSurface drm_create_pixmap_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, NativePixmapType pixmap, const EGLint *attrib_list);
-EGLSurface drm_create_pbuffer_surface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list);
-EGLSurface drm_create_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLConfig cfg, const EGLint *attrib_list);
-EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, EGLDisplay dpy, EGLScreenMESA screen, EGLSurface surface, EGLModeMESA m);
-EGLBoolean drm_destroy_surface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface);
-EGLBoolean drm_make_current(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext context);
-EGLBoolean drm_swap_buffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw);
+EGLBoolean drm_initialize(_EGLDriver *drv, _EGLDisplay *dpy, EGLint *major, EGLint *minor);
+EGLBoolean drm_terminate(_EGLDriver *drv, _EGLDisplay *dpy);
+_EGLContext *drm_create_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, _EGLContext *share_list, const EGLint *attrib_list);
+EGLBoolean drm_destroy_context(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *context);
+_EGLSurface *drm_create_window_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativeWindowType window, const EGLint *attrib_list);
+_EGLSurface *drm_create_pixmap_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, NativePixmapType pixmap, const EGLint *attrib_list);
+_EGLSurface *drm_create_pbuffer_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
+_EGLSurface *drm_create_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf, const EGLint *attrib_list);
+EGLBoolean drm_show_screen_surface_mesa(_EGLDriver *drv, _EGLDisplay *dpy, _EGLScreen *screen, _EGLSurface *surface, _EGLMode *mode);
+EGLBoolean drm_destroy_surface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface);
+EGLBoolean drm_make_current(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw, _EGLSurface *read, _EGLContext *context);
+EGLBoolean drm_swap_buffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw);
/*@}*/
#endif
diff --git a/src/gallium/state_trackers/g3dvl/vl_basic_csc.c b/src/gallium/state_trackers/g3dvl/vl_basic_csc.c
index 20d682de3f..b1683b891b 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 ef4a4b2add..34d93e1df0 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/glx/xlib/Makefile b/src/gallium/state_trackers/glx/xlib/Makefile
index 6d10b090aa..7b2adc62c3 100644
--- a/src/gallium/state_trackers/glx/xlib/Makefile
+++ b/src/gallium/state_trackers/glx/xlib/Makefile
@@ -5,13 +5,12 @@ LIBNAME = xlib
LIBRARY_INCLUDES = \
-I$(TOP)/include \
- -I$(TOP)/src/mesa \
- -I$(TOP)/src/mesa/main
+ -I$(TOP)/src/mesa
C_SOURCES = \
- glxapi.c \
- fakeglx.c \
- fakeglx_fonts.c \
+ glx_api.c \
+ glx_getproc.c \
+ glx_usefont.c \
xm_api.c
include ../../../Makefile.template
diff --git a/src/gallium/state_trackers/glx/xlib/SConscript b/src/gallium/state_trackers/glx/xlib/SConscript
index 0dbe341397..fa96df357d 100644
--- a/src/gallium/state_trackers/glx/xlib/SConscript
+++ b/src/gallium/state_trackers/glx/xlib/SConscript
@@ -4,8 +4,7 @@
Import('*')
if env['platform'] == 'linux' \
- and 'mesa' in env['statetrackers'] \
- and ('softpipe' or 'i915simple' or 'trace') in env['drivers']:
+ and 'mesa' in env['statetrackers']:
env = env.Clone()
@@ -18,9 +17,10 @@ if env['platform'] == 'linux' \
st_xlib = env.ConvenienceLibrary(
target = 'st_xlib',
- source = [ 'glxapi.c',
- 'fakeglx.c',
- 'fakeglx_fonts.c',
+ source = [
+ 'glx_api.c',
+ 'glx_getproc.c',
+ 'glx_usefont.c',
'xm_api.c',
]
)
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx.c b/src/gallium/state_trackers/glx/xlib/glx_api.c
index 23777c76f6..d1a98f8991 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_api.c
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 7.1
+ * Version: 7.6
*
* Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -23,31 +24,21 @@
*/
-/*
- * This is an emulation of the GLX API which allows Mesa/GLX-based programs
- * to run on X servers which do not have the real GLX extension.
- *
- * Thanks to the contributors:
- *
- * Initial version: Philip Brown (phil@bolthole.com)
- * Better glXGetConfig() support: Armin Liebchen (liebchen@asylum.cs.utah.edu)
- * Further visual-handling refinements: Wolfram Gloger
- * (wmglo@Dent.MED.Uni-Muenchen.DE).
- *
- * Notes:
- * Don't be fooled, stereo isn't supported yet.
+/**
+ * "Fake" GLX API implemented in terms of the XMesa*() functions.
*/
-#include "glxapi.h"
+#define GLX_GLXEXT_PROTOTYPES
+#include "GL/glx.h"
+
#include "xm_api.h"
-#include "context.h"
-#include "config.h"
-#include "macros.h"
-#include "imports.h"
-#include "version.h"
-#include "fakeglx.h"
+#include "main/context.h"
+#include "main/config.h"
+#include "main/macros.h"
+#include "main/imports.h"
+#include "main/version.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
@@ -80,24 +71,42 @@
"GLX_SGIX_fbconfig " \
"GLX_SGIX_pbuffer "
-/*
- * Our fake GLX context will contain a "real" GLX context and an XMesa context.
- *
- * Note that a pointer to a __GLXcontext is a pointer to a fake_glx_context,
- * and vice versa.
- *
- * We really just need this structure in order to make the libGL functions
- * glXGetCurrentContext(), glXGetCurrentDrawable() and glXGetCurrentDisplay()
- * work correctly.
+#define DEFAULT_DIRECT GL_TRUE
+
+
+
+/**
+ * The GLXContext typedef is defined as a pointer to this structure.
*/
-struct fake_glx_context {
- __GLXcontext glxContext; /* this MUST be first! */
+struct __GLXcontextRec
+{
+ Display *currentDpy;
+ GLboolean isDirect;
+ GLXDrawable currentDrawable;
+ GLXDrawable currentReadable;
+ XID xid;
+
XMesaContext xmesaContext;
};
-#define DEFAULT_DIRECT GL_TRUE
+static pipe_tsd ContextTSD;
+
+/** Set current context for calling thread */
+static void
+SetCurrentContext(GLXContext c)
+{
+ pipe_tsd_set(&ContextTSD, c);
+}
+
+/** Get current context for calling thread */
+static GLXContext
+GetCurrentContext(void)
+{
+ return pipe_tsd_get(&ContextTSD);
+}
+
/**********************************************************************/
@@ -366,10 +375,6 @@ find_glx_visual( Display *dpy, XVisualInfo *vinfo )
}
-
-
-
-
/**
* Try to get an X visual which matches the given arguments.
*/
@@ -418,7 +423,6 @@ get_visual( Display *dpy, int scr, unsigned int depth, int xclass )
}
-
/*
* Retrieve the value of the given environment variable and find
* the X visual which matches it.
@@ -1002,8 +1006,8 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig )
}
-static XVisualInfo *
-Fake_glXChooseVisual( Display *dpy, int screen, int *list )
+XVisualInfo *
+glXChooseVisual( Display *dpy, int screen, int *list )
{
XMesaVisual xmvis;
@@ -1024,18 +1028,18 @@ Fake_glXChooseVisual( Display *dpy, int screen, int *list )
}
-static GLXContext
-Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
- GLXContext share_list, Bool direct )
+GLXContext
+glXCreateContext( Display *dpy, XVisualInfo *visinfo,
+ GLXContext share_list, Bool direct )
{
XMesaVisual xmvis;
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
+ GLXContext glxCtx;
+ GLXContext shareCtx = share_list;
if (!dpy || !visinfo)
return 0;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -1062,13 +1066,11 @@ Fake_glXCreateContext( Display *dpy, XVisualInfo *visinfo,
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
-
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- return (GLXContext) glxCtx;
+ return glxCtx;
}
@@ -1081,11 +1083,11 @@ static XMesaBuffer MakeCurrent_PrevReadBuffer = 0;
/* GLX 1.3 and later */
-static Bool
-Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
- GLXDrawable read, GLXContext ctx )
+Bool
+glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
+ GLXDrawable read, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
static boolean firsttime = 1, no_rast = 0;
if (firsttime) {
@@ -1093,7 +1095,6 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
firsttime = 0;
}
-
if (ctx && draw && read) {
XMesaBuffer drawBuffer, readBuffer;
XMesaContext xmctx = glxCtx->xmesaContext;
@@ -1148,9 +1149,10 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
/* Now make current! */
if (XMesaMakeCurrent2(xmctx, drawBuffer, readBuffer)) {
- ((__GLXcontext *) ctx)->currentDpy = dpy;
- ((__GLXcontext *) ctx)->currentDrawable = draw;
- ((__GLXcontext *) ctx)->currentReadable = read;
+ ctx->currentDpy = dpy;
+ ctx->currentDrawable = draw;
+ ctx->currentReadable = read;
+ SetCurrentContext(ctx);
return True;
}
else {
@@ -1165,6 +1167,7 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
MakeCurrent_PrevReadable = 0;
MakeCurrent_PrevDrawBuffer = 0;
MakeCurrent_PrevReadBuffer = 0;
+ SetCurrentContext(NULL);
return True;
}
else {
@@ -1176,15 +1179,61 @@ Fake_glXMakeContextCurrent( Display *dpy, GLXDrawable draw,
}
-static Bool
-Fake_glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+Bool
+glXMakeCurrent( Display *dpy, GLXDrawable drawable, GLXContext ctx )
+{
+ return glXMakeContextCurrent( dpy, drawable, drawable, ctx );
+}
+
+
+GLXContext
+glXGetCurrentContext(void)
{
- return Fake_glXMakeContextCurrent( dpy, drawable, drawable, ctx );
+ return GetCurrentContext();
}
-static GLXPixmap
-Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
+Display *
+glXGetCurrentDisplay(void)
+{
+ GLXContext glxCtx = glXGetCurrentContext();
+
+ return glxCtx ? glxCtx->currentDpy : NULL;
+}
+
+
+Display *
+glXGetCurrentDisplayEXT(void)
+{
+ return glXGetCurrentDisplay();
+}
+
+
+GLXDrawable
+glXGetCurrentDrawable(void)
+{
+ GLXContext gc = glXGetCurrentContext();
+ return gc ? gc->currentDrawable : 0;
+}
+
+
+GLXDrawable
+glXGetCurrentReadDrawable(void)
+{
+ GLXContext gc = glXGetCurrentContext();
+ return gc ? gc->currentReadable : 0;
+}
+
+
+GLXDrawable
+glXGetCurrentReadDrawableSGI(void)
+{
+ return glXGetCurrentReadDrawable();
+}
+
+
+GLXPixmap
+glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
{
XMesaVisual v;
XMesaBuffer b;
@@ -1208,9 +1257,9 @@ Fake_glXCreateGLXPixmap( Display *dpy, XVisualInfo *visinfo, Pixmap pixmap )
/*** GLX_MESA_pixmap_colormap ***/
-static GLXPixmap
-Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
- Pixmap pixmap, Colormap cmap )
+GLXPixmap
+glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
+ Pixmap pixmap, Colormap cmap )
{
XMesaVisual v;
XMesaBuffer b;
@@ -1232,8 +1281,8 @@ Fake_glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visinfo,
}
-static void
-Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
+void
+glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
{
XMesaBuffer b = XMesaFindBuffer(dpy, pixmap);
if (b) {
@@ -1245,14 +1294,12 @@ Fake_glXDestroyGLXPixmap( Display *dpy, GLXPixmap pixmap )
}
-static void
-Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
- unsigned long mask )
+void
+glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
+ unsigned long mask )
{
- struct fake_glx_context *fakeSrc = (struct fake_glx_context *) src;
- struct fake_glx_context *fakeDst = (struct fake_glx_context *) dst;
- XMesaContext xm_src = fakeSrc->xmesaContext;
- XMesaContext xm_dst = fakeDst->xmesaContext;
+ XMesaContext xm_src = src->xmesaContext;
+ XMesaContext xm_dst = dst->xmesaContext;
(void) dpy;
if (MakeCurrent_PrevContext == src) {
_mesa_Flush();
@@ -1261,8 +1308,8 @@ Fake_glXCopyContext( Display *dpy, GLXContext src, GLXContext dst,
}
-static Bool
-Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
+Bool
+glXQueryExtension( Display *dpy, int *errorb, int *event )
{
/* Mesa's GLX isn't really an X extension but we try to act like one. */
(void) dpy;
@@ -1272,18 +1319,10 @@ Fake_glXQueryExtension( Display *dpy, int *errorb, int *event )
}
-extern void _kw_ungrab_all( Display *dpy );
-void _kw_ungrab_all( Display *dpy )
-{
- XUngrabPointer( dpy, CurrentTime );
- XUngrabKeyboard( dpy, CurrentTime );
-}
-
-
-static void
-Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
+void
+glXDestroyContext( Display *dpy, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
(void) dpy;
MakeCurrent_PrevContext = 0;
MakeCurrent_PrevDrawable = 0;
@@ -1296,18 +1335,18 @@ Fake_glXDestroyContext( Display *dpy, GLXContext ctx )
}
-static Bool
-Fake_glXIsDirect( Display *dpy, GLXContext ctx )
+Bool
+glXIsDirect( Display *dpy, GLXContext ctx )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
(void) ctx;
- return glxCtx->glxContext.isDirect;
+ return glxCtx->isDirect;
}
-static void
-Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
+void
+glXSwapBuffers( Display *dpy, GLXDrawable drawable )
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
static boolean firsttime = 1, no_rast = 0;
@@ -1333,8 +1372,8 @@ Fake_glXSwapBuffers( Display *dpy, GLXDrawable drawable )
/*** GLX_MESA_copy_sub_buffer ***/
-static void
-Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
+void
+glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
int x, int y, int width, int height )
{
XMesaBuffer buffer = XMesaFindBuffer( dpy, drawable );
@@ -1347,8 +1386,8 @@ Fake_glXCopySubBufferMESA( Display *dpy, GLXDrawable drawable,
}
-static Bool
-Fake_glXQueryVersion( Display *dpy, int *maj, int *min )
+Bool
+glXQueryVersion( Display *dpy, int *maj, int *min )
{
(void) dpy;
/* Return GLX version, not Mesa version */
@@ -1564,8 +1603,8 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig )
}
-static int
-Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
+int
+glXGetConfig( Display *dpy, XVisualInfo *visinfo,
int attrib, int *value )
{
XMesaVisual xmvis;
@@ -1594,8 +1633,8 @@ Fake_glXGetConfig( Display *dpy, XVisualInfo *visinfo,
}
-static void
-Fake_glXWaitGL( void )
+void
+glXWaitGL( void )
{
XMesaContext xmesa = XMesaGetCurrentContext();
XMesaFlush( xmesa );
@@ -1603,8 +1642,8 @@ Fake_glXWaitGL( void )
-static void
-Fake_glXWaitX( void )
+void
+glXWaitX( void )
{
XMesaContext xmesa = XMesaGetCurrentContext();
XMesaFlush( xmesa );
@@ -1620,8 +1659,8 @@ get_extensions( void )
/* GLX 1.1 and later */
-static const char *
-Fake_glXQueryExtensionsString( Display *dpy, int screen )
+const char *
+glXQueryExtensionsString( Display *dpy, int screen )
{
(void) dpy;
(void) screen;
@@ -1631,8 +1670,8 @@ Fake_glXQueryExtensionsString( Display *dpy, int screen )
/* GLX 1.1 and later */
-static const char *
-Fake_glXQueryServerString( Display *dpy, int screen, int name )
+const char *
+glXQueryServerString( Display *dpy, int screen, int name )
{
static char version[1000];
_mesa_sprintf(version, "%d.%d %s",
@@ -1656,8 +1695,8 @@ Fake_glXQueryServerString( Display *dpy, int screen, int name )
/* GLX 1.1 and later */
-static const char *
-Fake_glXGetClientString( Display *dpy, int name )
+const char *
+glXGetClientString( Display *dpy, int name )
{
static char version[1000];
_mesa_sprintf(version, "%d.%d %s", CLIENT_MAJOR_VERSION,
@@ -1684,8 +1723,8 @@ Fake_glXGetClientString( Display *dpy, int name )
*/
-static int
-Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
+int
+glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
int attribute, int *value )
{
XMesaVisual v = (XMesaVisual) config;
@@ -1699,8 +1738,8 @@ Fake_glXGetFBConfigAttrib( Display *dpy, GLXFBConfig config,
}
-static GLXFBConfig *
-Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
+GLXFBConfig *
+glXGetFBConfigs( Display *dpy, int screen, int *nelements )
{
XVisualInfo *visuals, visTemplate;
const long visMask = VisualScreenMask;
@@ -1725,15 +1764,15 @@ Fake_glXGetFBConfigs( Display *dpy, int screen, int *nelements )
}
-static GLXFBConfig *
-Fake_glXChooseFBConfig( Display *dpy, int screen,
+GLXFBConfig *
+glXChooseFBConfig( Display *dpy, int screen,
const int *attribList, int *nitems )
{
XMesaVisual xmvis;
if (!attribList || !attribList[0]) {
/* return list of all configs (per GLX_SGIX_fbconfig spec) */
- return Fake_glXGetFBConfigs(dpy, screen, nitems);
+ return glXGetFBConfigs(dpy, screen, nitems);
}
xmvis = choose_visual(dpy, screen, attribList, GL_TRUE);
@@ -1754,8 +1793,8 @@ Fake_glXChooseFBConfig( Display *dpy, int screen,
}
-static XVisualInfo *
-Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
+XVisualInfo *
+glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
{
if (dpy && config) {
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1776,8 +1815,8 @@ Fake_glXGetVisualFromFBConfig( Display *dpy, GLXFBConfig config )
}
-static GLXWindow
-Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
+GLXWindow
+glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
const int *attribList )
{
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1796,8 +1835,8 @@ Fake_glXCreateWindow( Display *dpy, GLXFBConfig config, Window win,
}
-static void
-Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
+void
+glXDestroyWindow( Display *dpy, GLXWindow window )
{
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable) window);
if (b)
@@ -1807,8 +1846,8 @@ Fake_glXDestroyWindow( Display *dpy, GLXWindow window )
/* XXX untested */
-static GLXPixmap
-Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
+GLXPixmap
+glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
const int *attribList )
{
XMesaVisual v = (XMesaVisual) config;
@@ -1917,8 +1956,8 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap,
}
-static void
-Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
+void
+glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
{
XMesaBuffer b = XMesaFindBuffer(dpy, (Drawable)pixmap);
if (b)
@@ -1927,8 +1966,8 @@ Fake_glXDestroyPixmap( Display *dpy, GLXPixmap pixmap )
}
-static GLXPbuffer
-Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
+GLXPbuffer
+glXCreatePbuffer( Display *dpy, GLXFBConfig config,
const int *attribList )
{
XMesaVisual xmvis = (XMesaVisual) config;
@@ -1980,8 +2019,8 @@ Fake_glXCreatePbuffer( Display *dpy, GLXFBConfig config,
}
-static void
-Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
+void
+glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
{
XMesaBuffer b = XMesaFindBuffer(dpy, pbuf);
if (b) {
@@ -1990,8 +2029,8 @@ Fake_glXDestroyPbuffer( Display *dpy, GLXPbuffer pbuf )
}
-static void
-Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
+void
+glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
unsigned int *value )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, draw);
@@ -2032,19 +2071,19 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute,
}
-static GLXContext
-Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
+GLXContext
+glXCreateNewContext( Display *dpy, GLXFBConfig config,
int renderType, GLXContext shareList, Bool direct )
{
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) shareList;
+ GLXContext glxCtx;
+ GLXContext shareCtx = shareList;
XMesaVisual xmvis = (XMesaVisual) config;
if (!dpy || !config ||
(renderType != GLX_RGBA_TYPE && renderType != GLX_COLOR_INDEX_TYPE))
return 0;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -2058,20 +2097,18 @@ Fake_glXCreateNewContext( Display *dpy, GLXFBConfig config,
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
-
- return (GLXContext) glxCtx;
+ return glxCtx;
}
-static int
-Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
+int
+glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
{
- struct fake_glx_context *glxCtx = (struct fake_glx_context *) ctx;
+ GLXContext glxCtx = ctx;
XMesaContext xmctx = glxCtx->xmesaContext;
(void) dpy;
@@ -2097,8 +2134,8 @@ Fake_glXQueryContext( Display *dpy, GLXContext ctx, int attribute, int *value )
}
-static void
-Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
+void
+glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf)
@@ -2106,8 +2143,8 @@ Fake_glXSelectEvent( Display *dpy, GLXDrawable drawable, unsigned long mask )
}
-static void
-Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
+void
+glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
unsigned long *mask )
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
@@ -2121,8 +2158,8 @@ Fake_glXGetSelectedEvent( Display *dpy, GLXDrawable drawable,
/*** GLX_SGI_swap_control ***/
-static int
-Fake_glXSwapIntervalSGI(int interval)
+int
+glXSwapIntervalSGI(int interval)
{
(void) interval;
return 0;
@@ -2134,16 +2171,16 @@ Fake_glXSwapIntervalSGI(int interval)
static unsigned int FrameCounter = 0;
-static int
-Fake_glXGetVideoSyncSGI(unsigned int *count)
+int
+glXGetVideoSyncSGI(unsigned int *count)
{
/* this is a bogus implementation */
*count = FrameCounter++;
return 0;
}
-static int
-Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
+int
+glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
if (divisor <= 0 || remainder < 0)
return GLX_BAD_VALUE;
@@ -2159,15 +2196,15 @@ Fake_glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
/*** GLX_SGI_make_current_read ***/
-static Bool
-Fake_glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
+Bool
+glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
{
- return Fake_glXMakeContextCurrent( dpy, draw, read, ctx );
+ return glXMakeContextCurrent( dpy, draw, read, ctx );
}
/* not used
static GLXDrawable
-Fake_glXGetCurrentReadDrawableSGI(void)
+glXGetCurrentReadDrawableSGI(void)
{
return 0;
}
@@ -2177,8 +2214,8 @@ Fake_glXGetCurrentReadDrawableSGI(void)
/*** GLX_SGIX_video_source ***/
#if defined(_VL_H)
-static GLXVideoSourceSGIX
-Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
+GLXVideoSourceSGIX
+glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
{
(void) dpy;
(void) screen;
@@ -2189,8 +2226,8 @@ Fake_glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPa
return 0;
}
-static void
-Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
+void
+glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
{
(void) dpy;
(void) src;
@@ -2201,30 +2238,30 @@ Fake_glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
/*** GLX_EXT_import_context ***/
-static void
-Fake_glXFreeContextEXT(Display *dpy, GLXContext context)
+void
+glXFreeContextEXT(Display *dpy, GLXContext context)
{
(void) dpy;
(void) context;
}
-static GLXContextID
-Fake_glXGetContextIDEXT(const GLXContext context)
+GLXContextID
+glXGetContextIDEXT(const GLXContext context)
{
(void) context;
return 0;
}
-static GLXContext
-Fake_glXImportContextEXT(Display *dpy, GLXContextID contextID)
+GLXContext
+glXImportContextEXT(Display *dpy, GLXContextID contextID)
{
(void) dpy;
(void) contextID;
return 0;
}
-static int
-Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
+int
+glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int *value)
{
(void) dpy;
(void) context;
@@ -2237,21 +2274,21 @@ Fake_glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute, int
/*** GLX_SGIX_fbconfig ***/
-static int
-Fake_glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
+int
+glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
{
- return Fake_glXGetFBConfigAttrib(dpy, config, attribute, value);
+ return glXGetFBConfigAttrib(dpy, config, attribute, value);
}
-static GLXFBConfigSGIX *
-Fake_glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
+GLXFBConfigSGIX *
+glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
{
- return (GLXFBConfig *) Fake_glXChooseFBConfig(dpy, screen, attrib_list, nelements);
+ return (GLXFBConfig *) glXChooseFBConfig(dpy, screen, attrib_list, nelements);
}
-static GLXPixmap
-Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
+GLXPixmap
+glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
{
XMesaVisual xmvis = (XMesaVisual) config;
XMesaBuffer xmbuf = XMesaCreatePixmapBuffer(xmvis, pixmap, 0);
@@ -2259,14 +2296,14 @@ Fake_glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixm
}
-static GLXContext
-Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
+GLXContext
+glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
{
XMesaVisual xmvis = (XMesaVisual) config;
- struct fake_glx_context *glxCtx;
- struct fake_glx_context *shareCtx = (struct fake_glx_context *) share_list;
+ GLXContext glxCtx;
+ GLXContext shareCtx = share_list;
- glxCtx = CALLOC_STRUCT(fake_glx_context);
+ glxCtx = CALLOC_STRUCT(__GLXcontextRec);
if (!glxCtx)
return 0;
@@ -2280,25 +2317,23 @@ Fake_glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int re
return NULL;
}
- glxCtx->glxContext.isDirect = DEFAULT_DIRECT;
- glxCtx->glxContext.currentDpy = dpy;
- glxCtx->glxContext.xid = (XID) glxCtx; /* self pointer */
-
- assert((void *) glxCtx == (void *) &(glxCtx->glxContext));
+ glxCtx->isDirect = DEFAULT_DIRECT;
+ glxCtx->currentDpy = dpy;
+ glxCtx->xid = (XID) glxCtx; /* self pointer */
- return (GLXContext) glxCtx;
+ return glxCtx;
}
-static XVisualInfo *
-Fake_glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
+XVisualInfo *
+glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
{
- return Fake_glXGetVisualFromFBConfig(dpy, config);
+ return glXGetVisualFromFBConfig(dpy, config);
}
-static GLXFBConfigSGIX
-Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
+GLXFBConfigSGIX
+glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
{
XMesaVisual xmvis = find_glx_visual(dpy, vis);
if (!xmvis) {
@@ -2313,8 +2348,8 @@ Fake_glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
/*** GLX_SGIX_pbuffer ***/
-static GLXPbufferSGIX
-Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
+GLXPbufferSGIX
+glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
unsigned int width, unsigned int height,
int *attribList)
{
@@ -2352,8 +2387,8 @@ Fake_glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config,
}
-static void
-Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
+void
+glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
if (xmbuf) {
@@ -2362,8 +2397,8 @@ Fake_glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
}
-static int
-Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
+int
+glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
{
const XMesaBuffer xmbuf = XMesaFindBuffer(dpy, pbuf);
@@ -2395,8 +2430,8 @@ Fake_glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, un
}
-static void
-Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
+void
+glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf) {
@@ -2406,8 +2441,8 @@ Fake_glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
}
-static void
-Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
+void
+glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
{
XMesaBuffer xmbuf = XMesaFindBuffer(dpy, drawable);
if (xmbuf) {
@@ -2422,8 +2457,8 @@ Fake_glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *
/*** GLX_SGI_cushion ***/
-static void
-Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
+void
+glXCushionSGI(Display *dpy, Window win, float cushion)
{
(void) dpy;
(void) win;
@@ -2434,8 +2469,8 @@ Fake_glXCushionSGI(Display *dpy, Window win, float cushion)
/*** GLX_SGIX_video_resize ***/
-static int
-Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
+int
+glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
{
(void) dpy;
(void) screen;
@@ -2444,8 +2479,8 @@ Fake_glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window w
return 0;
}
-static int
-Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
+int
+glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
{
(void) dpy;
(void) screen;
@@ -2457,8 +2492,8 @@ Fake_glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int
return 0;
}
-static int
-Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
+int
+glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
{
(void) dpy;
(void) screen;
@@ -2470,8 +2505,8 @@ Fake_glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int
return 0;
}
-static int
-Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
+int
+glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
{
(void) dpy;
(void) screen;
@@ -2483,8 +2518,8 @@ Fake_glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, i
return 0;
}
-static int
-Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
+int
+glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
{
(void) dpy;
(void) screen;
@@ -2498,8 +2533,8 @@ Fake_glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum syncty
/*** GLX_SGIX_dmbuffer **/
#if defined(_DM_BUFFER_H_)
-static Bool
-Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
+Bool
+glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
{
(void) dpy;
(void) pbuffer;
@@ -2512,8 +2547,8 @@ Fake_glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *p
/*** GLX_SGIX_swap_group ***/
-static void
-Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
+void
+glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
{
(void) dpy;
(void) drawable;
@@ -2524,16 +2559,16 @@ Fake_glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member
/*** GLX_SGIX_swap_barrier ***/
-static void
-Fake_glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
+void
+glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
{
(void) dpy;
(void) drawable;
(void) barrier;
}
-static Bool
-Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
+Bool
+glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
{
(void) dpy;
(void) screen;
@@ -2545,8 +2580,8 @@ Fake_glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
/*** GLX_SUN_get_transparent_index ***/
-static Status
-Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
+Status
+glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
{
(void) dpy;
(void) overlay;
@@ -2563,8 +2598,8 @@ Fake_glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, lo
* Release the depth, stencil, accum buffers attached to a GLXDrawable
* (a window or pixmap) prior to destroying the GLXDrawable.
*/
-static Bool
-Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+Bool
+glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
{
XMesaBuffer b = XMesaFindBuffer(dpy, d);
if (b) {
@@ -2576,8 +2611,8 @@ Fake_glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
/*** GLX_EXT_texture_from_pixmap ***/
-static void
-Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
+void
+glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
const int *attrib_list)
{
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
@@ -2585,162 +2620,10 @@ Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
XMesaBindTexImage(dpy, b, buffer, attrib_list);
}
-static void
-Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
+void
+glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
{
XMesaBuffer b = XMesaFindBuffer(dpy, drawable);
if (b)
XMesaReleaseTexImage(dpy, b, buffer);
}
-
-
-
-/**
- * Create a new GLX API dispatch table with its function pointers
- * initialized to point to Mesa's "fake" GLX API functions.
- *
- * Note: there used to be a similar function
- * (_real_GetGLXDispatchTable) that returns a new dispatch table with
- * all pointers initalized to point to "real" GLX functions (which
- * understand GLX wire protocol, etc).
- */
-struct _glxapi_table *
-_mesa_GetGLXDispatchTable(void)
-{
- static struct _glxapi_table glx;
-
- /* be sure our dispatch table size <= libGL's table */
- {
- GLuint size = sizeof(struct _glxapi_table) / sizeof(void *);
- (void) size;
- assert(_glxapi_get_dispatch_table_size() >= size);
- }
-
- /* initialize the whole table to no-ops */
- _glxapi_set_no_op_table(&glx);
-
- /* now initialize the table with the functions I implement */
- glx.ChooseVisual = Fake_glXChooseVisual;
- glx.CopyContext = Fake_glXCopyContext;
- glx.CreateContext = Fake_glXCreateContext;
- glx.CreateGLXPixmap = Fake_glXCreateGLXPixmap;
- glx.DestroyContext = Fake_glXDestroyContext;
- glx.DestroyGLXPixmap = Fake_glXDestroyGLXPixmap;
- glx.GetConfig = Fake_glXGetConfig;
- /*glx.GetCurrentContext = Fake_glXGetCurrentContext;*/
- /*glx.GetCurrentDrawable = Fake_glXGetCurrentDrawable;*/
- glx.IsDirect = Fake_glXIsDirect;
- glx.MakeCurrent = Fake_glXMakeCurrent;
- glx.QueryExtension = Fake_glXQueryExtension;
- glx.QueryVersion = Fake_glXQueryVersion;
- glx.SwapBuffers = Fake_glXSwapBuffers;
- glx.UseXFont = Fake_glXUseXFont;
- glx.WaitGL = Fake_glXWaitGL;
- glx.WaitX = Fake_glXWaitX;
-
- /*** GLX_VERSION_1_1 ***/
- glx.GetClientString = Fake_glXGetClientString;
- glx.QueryExtensionsString = Fake_glXQueryExtensionsString;
- glx.QueryServerString = Fake_glXQueryServerString;
-
- /*** GLX_VERSION_1_2 ***/
- /*glx.GetCurrentDisplay = Fake_glXGetCurrentDisplay;*/
-
- /*** GLX_VERSION_1_3 ***/
- glx.ChooseFBConfig = Fake_glXChooseFBConfig;
- glx.CreateNewContext = Fake_glXCreateNewContext;
- glx.CreatePbuffer = Fake_glXCreatePbuffer;
- glx.CreatePixmap = Fake_glXCreatePixmap;
- glx.CreateWindow = Fake_glXCreateWindow;
- glx.DestroyPbuffer = Fake_glXDestroyPbuffer;
- glx.DestroyPixmap = Fake_glXDestroyPixmap;
- glx.DestroyWindow = Fake_glXDestroyWindow;
- /*glx.GetCurrentReadDrawable = Fake_glXGetCurrentReadDrawable;*/
- glx.GetFBConfigAttrib = Fake_glXGetFBConfigAttrib;
- glx.GetFBConfigs = Fake_glXGetFBConfigs;
- glx.GetSelectedEvent = Fake_glXGetSelectedEvent;
- glx.GetVisualFromFBConfig = Fake_glXGetVisualFromFBConfig;
- glx.MakeContextCurrent = Fake_glXMakeContextCurrent;
- glx.QueryContext = Fake_glXQueryContext;
- glx.QueryDrawable = Fake_glXQueryDrawable;
- glx.SelectEvent = Fake_glXSelectEvent;
-
- /*** GLX_SGI_swap_control ***/
- glx.SwapIntervalSGI = Fake_glXSwapIntervalSGI;
-
- /*** GLX_SGI_video_sync ***/
- glx.GetVideoSyncSGI = Fake_glXGetVideoSyncSGI;
- glx.WaitVideoSyncSGI = Fake_glXWaitVideoSyncSGI;
-
- /*** GLX_SGI_make_current_read ***/
- glx.MakeCurrentReadSGI = Fake_glXMakeCurrentReadSGI;
- /*glx.GetCurrentReadDrawableSGI = Fake_glXGetCurrentReadDrawableSGI;*/
-
-/*** GLX_SGIX_video_source ***/
-#if defined(_VL_H)
- glx.CreateGLXVideoSourceSGIX = Fake_glXCreateGLXVideoSourceSGIX;
- glx.DestroyGLXVideoSourceSGIX = Fake_glXDestroyGLXVideoSourceSGIX;
-#endif
-
- /*** GLX_EXT_import_context ***/
- glx.FreeContextEXT = Fake_glXFreeContextEXT;
- glx.GetContextIDEXT = Fake_glXGetContextIDEXT;
- /*glx.GetCurrentDisplayEXT = Fake_glXGetCurrentDisplayEXT;*/
- glx.ImportContextEXT = Fake_glXImportContextEXT;
- glx.QueryContextInfoEXT = Fake_glXQueryContextInfoEXT;
-
- /*** GLX_SGIX_fbconfig ***/
- glx.GetFBConfigAttribSGIX = Fake_glXGetFBConfigAttribSGIX;
- glx.ChooseFBConfigSGIX = Fake_glXChooseFBConfigSGIX;
- glx.CreateGLXPixmapWithConfigSGIX = Fake_glXCreateGLXPixmapWithConfigSGIX;
- glx.CreateContextWithConfigSGIX = Fake_glXCreateContextWithConfigSGIX;
- glx.GetVisualFromFBConfigSGIX = Fake_glXGetVisualFromFBConfigSGIX;
- glx.GetFBConfigFromVisualSGIX = Fake_glXGetFBConfigFromVisualSGIX;
-
- /*** GLX_SGIX_pbuffer ***/
- glx.CreateGLXPbufferSGIX = Fake_glXCreateGLXPbufferSGIX;
- glx.DestroyGLXPbufferSGIX = Fake_glXDestroyGLXPbufferSGIX;
- glx.QueryGLXPbufferSGIX = Fake_glXQueryGLXPbufferSGIX;
- glx.SelectEventSGIX = Fake_glXSelectEventSGIX;
- glx.GetSelectedEventSGIX = Fake_glXGetSelectedEventSGIX;
-
- /*** GLX_SGI_cushion ***/
- glx.CushionSGI = Fake_glXCushionSGI;
-
- /*** GLX_SGIX_video_resize ***/
- glx.BindChannelToWindowSGIX = Fake_glXBindChannelToWindowSGIX;
- glx.ChannelRectSGIX = Fake_glXChannelRectSGIX;
- glx.QueryChannelRectSGIX = Fake_glXQueryChannelRectSGIX;
- glx.QueryChannelDeltasSGIX = Fake_glXQueryChannelDeltasSGIX;
- glx.ChannelRectSyncSGIX = Fake_glXChannelRectSyncSGIX;
-
- /*** GLX_SGIX_dmbuffer **/
-#if defined(_DM_BUFFER_H_)
- glx.AssociateDMPbufferSGIX = NULL;
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- glx.JoinSwapGroupSGIX = Fake_glXJoinSwapGroupSGIX;
-
- /*** GLX_SGIX_swap_barrier ***/
- glx.BindSwapBarrierSGIX = Fake_glXBindSwapBarrierSGIX;
- glx.QueryMaxSwapBarriersSGIX = Fake_glXQueryMaxSwapBarriersSGIX;
-
- /*** GLX_SUN_get_transparent_index ***/
- glx.GetTransparentIndexSUN = Fake_glXGetTransparentIndexSUN;
-
- /*** GLX_MESA_copy_sub_buffer ***/
- glx.CopySubBufferMESA = Fake_glXCopySubBufferMESA;
-
- /*** GLX_MESA_release_buffers ***/
- glx.ReleaseBuffersMESA = Fake_glXReleaseBuffersMESA;
-
- /*** GLX_MESA_pixmap_colormap ***/
- glx.CreateGLXPixmapMESA = Fake_glXCreateGLXPixmapMESA;
-
- /*** GLX_EXT_texture_from_pixmap ***/
- glx.BindTexImageEXT = Fake_glXBindTexImageEXT;
- glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT;
-
- return &glx;
-}
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
new file mode 100644
index 0000000000..ca7d88c922
--- /dev/null
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -0,0 +1,214 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/**
+ * glXGetProcAddress()
+ */
+
+
+#define GLX_GLXEXT_PROTOTYPES
+
+#include <string.h>
+#include "GL/glx.h"
+#include "glapi/glapi.h"
+
+
+struct name_address_pair {
+ const char *Name;
+ __GLXextFuncPtr Address;
+};
+
+
+static struct name_address_pair GLX_functions[] = {
+ /*** GLX_VERSION_1_0 ***/
+ { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
+ { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
+ { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
+ { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
+ { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
+ { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
+ { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
+ { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
+ { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
+ { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
+ { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
+ { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
+ { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
+ { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
+ { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
+ { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
+ { "glXWaitX", (__GLXextFuncPtr) glXWaitX },
+
+ /*** GLX_VERSION_1_1 ***/
+ { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
+ { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
+ { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
+
+ /*** GLX_VERSION_1_2 ***/
+ { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
+
+ /*** GLX_VERSION_1_3 ***/
+ { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
+ { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
+ { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
+ { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
+ { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
+ { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
+ { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
+ { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
+ { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
+ { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
+ { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
+ { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
+ { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
+ { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
+ { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
+ { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
+ { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
+
+ /*** GLX_VERSION_1_4 ***/
+ { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
+
+ /*** GLX_SGI_swap_control ***/
+ { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
+
+ /*** GLX_SGI_video_sync ***/
+ { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
+ { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
+
+ /*** GLX_SGI_make_current_read ***/
+ { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
+ { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
+
+ /*** GLX_SGIX_video_source ***/
+#if defined(_VL_H)
+ { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
+ { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
+#endif
+
+ /*** GLX_EXT_import_context ***/
+ { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
+ { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
+ { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
+ { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
+ { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
+
+ /*** GLX_SGIX_fbconfig ***/
+ { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
+ { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
+ { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
+ { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
+ { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
+ { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
+
+ /*** GLX_SGIX_pbuffer ***/
+ { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
+ { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
+ { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
+ { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
+ { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
+
+ /*** GLX_SGI_cushion ***/
+ { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
+
+ /*** GLX_SGIX_video_resize ***/
+ { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
+ { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
+ { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
+ { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
+ { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
+
+ /*** GLX_SGIX_dmbuffer **/
+#if defined(_DM_BUFFER_H_)
+ { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
+#endif
+
+ /*** GLX_SGIX_swap_group ***/
+ { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX },
+
+ /*** GLX_SGIX_swap_barrier ***/
+ { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX },
+ { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX },
+
+ /*** GLX_SUN_get_transparent_index ***/
+ { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
+
+ /*** GLX_MESA_copy_sub_buffer ***/
+ { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
+
+ /*** GLX_MESA_pixmap_colormap ***/
+ { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
+
+ /*** GLX_MESA_release_buffers ***/
+ { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
+
+ /*** GLX_ARB_get_proc_address ***/
+ { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
+
+ /*** GLX_EXT_texture_from_pixmap ***/
+ { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
+ { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
+
+ { NULL, NULL } /* end of list */
+};
+
+
+
+/**
+ * Return address of named glX function, or NULL if not found.
+ */
+static __GLXextFuncPtr
+_glxapi_get_proc_address(const char *funcName)
+{
+ GLuint i;
+ for (i = 0; GLX_functions[i].Name; i++) {
+ if (strcmp(GLX_functions[i].Name, funcName) == 0)
+ return GLX_functions[i].Address;
+ }
+ return NULL;
+}
+
+
+__GLXextFuncPtr
+glXGetProcAddressARB(const GLubyte *procName)
+{
+ __GLXextFuncPtr f;
+
+ f = _glxapi_get_proc_address((const char *) procName);
+ if (f) {
+ return f;
+ }
+
+ f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName);
+ return f;
+}
+
+
+/* GLX 1.4 */
+void (*glXGetProcAddress(const GLubyte *procName))()
+{
+ return glXGetProcAddressARB(procName);
+}
diff --git a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
index e359046756..acc64df62b 100644
--- a/src/gallium/state_trackers/glx/xlib/fakeglx_fonts.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c
@@ -1,9 +1,10 @@
-
/*
* Mesa 3-D graphics library
- * Version: 3.5
+ * Version: 7.6
*
- * Copyright (C) 1999-2000 Brian Paul All Rights Reserved.
+ * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+ * Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -24,13 +25,13 @@
*/
-/* xfonts.c -- glXUseXFont() for Mesa written by
- * Copyright (C) 1995 Thorsten.Ohl @ Physik.TH-Darmstadt.de
+/**
+ * Fake implementation of glXUseXFont().
*/
-#include "context.h"
-#include "imports.h"
-#include "fakeglx.h"
+
+#include "main/context.h"
+#include "main/imports.h"
#include <GL/glx.h>
@@ -210,7 +211,7 @@ isvalid(XFontStruct * fs, unsigned int which)
void
-Fake_glXUseXFont(Font font, int first, int count, int listbase)
+glXUseXFont(Font font, int first, int count, int listbase)
{
Display *dpy;
Window win;
@@ -228,7 +229,8 @@ Fake_glXUseXFont(Font font, int first, int count, int listbase)
dpy = glXGetCurrentDisplay();
if (!dpy)
return; /* I guess glXMakeCurrent wasn't called */
- win = RootWindow(dpy, DefaultScreen(dpy));
+ i = DefaultScreen(dpy);
+ win = RootWindow(dpy, i);
fs = XQueryFont(dpy, font);
if (!fs) {
diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.c b/src/gallium/state_trackers/glx/xlib/glxapi.c
deleted file mode 100644
index c2cb34d7cf..0000000000
--- a/src/gallium/state_trackers/glx/xlib/glxapi.c
+++ /dev/null
@@ -1,1254 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2007 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * This is the GLX API dispatcher. Calls to the glX* functions are
- * either routed to the real GLX encoders or to Mesa's pseudo-GLX functions.
- * See the glxapi.h file for more details.
- */
-
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "glapi/glapi.h"
-#include "glxapi.h"
-#include "fakeglx.h"
-#include "pipe/p_thread.h"
-
-
-#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
-# define PUBLIC __attribute__((visibility("default")))
-# define USED __attribute__((used))
-#else
-# define PUBLIC
-# define USED
-#endif
-
-
-struct display_dispatch {
- Display *Dpy;
- struct _glxapi_table *Table;
- struct display_dispatch *Next;
-};
-
-static struct display_dispatch *DispatchList = NULL;
-
-
-/* Display -> Dispatch caching */
-static Display *prevDisplay = NULL;
-static struct _glxapi_table *prevTable = NULL;
-
-
-static struct _glxapi_table *
-get_dispatch(Display *dpy)
-{
- if (!dpy)
- return NULL;
-
- /* search list of display/dispatch pairs for this display */
- {
- const struct display_dispatch *d = DispatchList;
- while (d) {
- if (d->Dpy == dpy) {
- prevDisplay = dpy;
- prevTable = d->Table;
- return d->Table; /* done! */
- }
- d = d->Next;
- }
- }
-
- /* A new display, determine if we should use real GLX
- * or Mesa's pseudo-GLX.
- */
- {
- struct _glxapi_table *t = _mesa_GetGLXDispatchTable();
-
- if (t) {
- struct display_dispatch *d;
- d = (struct display_dispatch *) malloc(sizeof(struct display_dispatch));
- if (d) {
- d->Dpy = dpy;
- d->Table = t;
- /* insert at head of list */
- d->Next = DispatchList;
- DispatchList = d;
- /* update cache */
- prevDisplay = dpy;
- prevTable = t;
- return t;
- }
- }
- }
-
- /* If we get here that means we can't use real GLX on this display
- * and the Mesa pseudo-GLX software renderer wasn't compiled in.
- * Or, we ran out of memory!
- */
- return NULL;
-}
-
-
-/* Don't use the GET_DISPATCH defined in glthread.h */
-#undef GET_DISPATCH
-
-#define GET_DISPATCH(DPY, TABLE) \
- if (DPY == prevDisplay) { \
- TABLE = prevTable; \
- } \
- else if (!DPY) { \
- TABLE = NULL; \
- } \
- else { \
- TABLE = get_dispatch(DPY); \
- }
-
-
-
-
-/**
- * GLX API current context.
- */
-pipe_tsd ContextTSD;
-
-
-static void
-SetCurrentContext(GLXContext c)
-{
- pipe_tsd_set(&ContextTSD, c);
-}
-
-
-/*
- * GLX API entrypoints
- */
-
-/*** GLX_VERSION_1_0 ***/
-
-XVisualInfo PUBLIC *
-glXChooseVisual(Display *dpy, int screen, int *list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->ChooseVisual)(dpy, screen, list);
-}
-
-
-void PUBLIC
-glXCopyContext(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CopyContext)(dpy, src, dst, mask);
-}
-
-
-GLXContext PUBLIC
-glXCreateContext(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateContext)(dpy, visinfo, shareList, direct);
-}
-
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmap(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmap)(dpy, visinfo, pixmap);
-}
-
-
-void PUBLIC
-glXDestroyContext(Display *dpy, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- if (glXGetCurrentContext() == ctx)
- SetCurrentContext(NULL);
- (t->DestroyContext)(dpy, ctx);
-}
-
-
-void PUBLIC
-glXDestroyGLXPixmap(Display *dpy, GLXPixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyGLXPixmap)(dpy, pixmap);
-}
-
-
-int PUBLIC
-glXGetConfig(Display *dpy, XVisualInfo *visinfo, int attrib, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return GLX_NO_EXTENSION;
- return (t->GetConfig)(dpy, visinfo, attrib, value);
-}
-
-
-GLXContext PUBLIC
-glXGetCurrentContext(void)
-{
- return (GLXContext) pipe_tsd_get(&ContextTSD);
-}
-
-
-GLXDrawable PUBLIC
-glXGetCurrentDrawable(void)
-{
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- return gc ? gc->currentDrawable : 0;
-}
-
-
-Bool PUBLIC
-glXIsDirect(Display *dpy, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->IsDirect)(dpy, ctx);
-}
-
-
-Bool PUBLIC
-glXMakeCurrent(Display *dpy, GLXDrawable drawable, GLXContext ctx)
-{
- Bool b;
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t) {
- return False;
- }
- b = (*t->MakeCurrent)(dpy, drawable, ctx);
- if (b) {
- SetCurrentContext(ctx);
- }
- return b;
-}
-
-
-Bool PUBLIC
-glXQueryExtension(Display *dpy, int *errorb, int *event)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->QueryExtension)(dpy, errorb, event);
-}
-
-
-Bool PUBLIC
-glXQueryVersion(Display *dpy, int *maj, int *min)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->QueryVersion)(dpy, maj, min);
-}
-
-
-void PUBLIC
-glXSwapBuffers(Display *dpy, GLXDrawable drawable)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SwapBuffers)(dpy, drawable);
-}
-
-
-void PUBLIC
-glXUseXFont(Font font, int first, int count, int listBase)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->UseXFont)(font, first, count, listBase);
-}
-
-
-void PUBLIC
-glXWaitGL(void)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->WaitGL)();
-}
-
-
-void PUBLIC
-glXWaitX(void)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->WaitX)();
-}
-
-
-
-/*** GLX_VERSION_1_1 ***/
-
-const char PUBLIC *
-glXGetClientString(Display *dpy, int name)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->GetClientString)(dpy, name);
-}
-
-
-const char PUBLIC *
-glXQueryExtensionsString(Display *dpy, int screen)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->QueryExtensionsString)(dpy, screen);
-}
-
-
-const char PUBLIC *
-glXQueryServerString(Display *dpy, int screen, int name)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->QueryServerString)(dpy, screen, name);
-}
-
-
-/*** GLX_VERSION_1_2 ***/
-
-Display PUBLIC *
-glXGetCurrentDisplay(void)
-{
- /* Same code as in libGL's glxext.c */
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- if (NULL == gc) return NULL;
- return gc->currentDpy;
-}
-
-
-
-/*** GLX_VERSION_1_3 ***/
-
-GLXFBConfig PUBLIC *
-glXChooseFBConfig(Display *dpy, int screen, const int *attribList, int *nitems)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChooseFBConfig)(dpy, screen, attribList, nitems);
-}
-
-
-GLXContext PUBLIC
-glXCreateNewContext(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateNewContext)(dpy, config, renderType, shareList, direct);
-}
-
-
-GLXPbuffer PUBLIC
-glXCreatePbuffer(Display *dpy, GLXFBConfig config, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreatePbuffer)(dpy, config, attribList);
-}
-
-
-GLXPixmap PUBLIC
-glXCreatePixmap(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreatePixmap)(dpy, config, pixmap, attribList);
-}
-
-
-GLXWindow PUBLIC
-glXCreateWindow(Display *dpy, GLXFBConfig config, Window win, const int *attribList)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateWindow)(dpy, config, win, attribList);
-}
-
-
-void PUBLIC
-glXDestroyPbuffer(Display *dpy, GLXPbuffer pbuf)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyPbuffer)(dpy, pbuf);
-}
-
-
-void PUBLIC
-glXDestroyPixmap(Display *dpy, GLXPixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyPixmap)(dpy, pixmap);
-}
-
-
-void PUBLIC
-glXDestroyWindow(Display *dpy, GLXWindow window)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyWindow)(dpy, window);
-}
-
-
-GLXDrawable PUBLIC
-glXGetCurrentReadDrawable(void)
-{
- __GLXcontext *gc = (__GLXcontext *) glXGetCurrentContext();
- return gc ? gc->currentReadable : 0;
-}
-
-
-int PUBLIC
-glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return GLX_NO_EXTENSION;
- return (t->GetFBConfigAttrib)(dpy, config, attribute, value);
-}
-
-
-GLXFBConfig PUBLIC *
-glXGetFBConfigs(Display *dpy, int screen, int *nelements)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigs)(dpy, screen, nelements);
-}
-
-void PUBLIC
-glXGetSelectedEvent(Display *dpy, GLXDrawable drawable, unsigned long *mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->GetSelectedEvent)(dpy, drawable, mask);
-}
-
-
-XVisualInfo PUBLIC *
-glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return NULL;
- return (t->GetVisualFromFBConfig)(dpy, config);
-}
-
-
-Bool PUBLIC
-glXMakeContextCurrent(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
- Bool b;
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- b = (t->MakeContextCurrent)(dpy, draw, read, ctx);
- if (b) {
- SetCurrentContext(ctx);
- }
- return b;
-}
-
-
-int PUBLIC
-glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- assert(t);
- if (!t)
- return 0; /* XXX correct? */
- return (t->QueryContext)(dpy, ctx, attribute, value);
-}
-
-
-void PUBLIC
-glXQueryDrawable(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->QueryDrawable)(dpy, draw, attribute, value);
-}
-
-
-void PUBLIC
-glXSelectEvent(Display *dpy, GLXDrawable drawable, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SelectEvent)(dpy, drawable, mask);
-}
-
-
-
-/*** GLX_SGI_swap_control ***/
-
-int PUBLIC
-glXSwapIntervalSGI(int interval)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->SwapIntervalSGI)(interval);
-}
-
-
-
-/*** GLX_SGI_video_sync ***/
-
-int PUBLIC
-glXGetVideoSyncSGI(unsigned int *count)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t || !glXGetCurrentContext())
- return GLX_BAD_CONTEXT;
- return (t->GetVideoSyncSGI)(count);
-}
-
-int PUBLIC
-glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
-{
- struct _glxapi_table *t;
- Display *dpy = glXGetCurrentDisplay();
- GET_DISPATCH(dpy, t);
- if (!t || !glXGetCurrentContext())
- return GLX_BAD_CONTEXT;
- return (t->WaitVideoSyncSGI)(divisor, remainder, count);
-}
-
-
-
-/*** GLX_SGI_make_current_read ***/
-
-Bool PUBLIC
-glXMakeCurrentReadSGI(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->MakeCurrentReadSGI)(dpy, draw, read, ctx);
-}
-
-GLXDrawable PUBLIC
-glXGetCurrentReadDrawableSGI(void)
-{
- return glXGetCurrentReadDrawable();
-}
-
-
-#if defined(_VL_H)
-
-GLXVideoSourceSGIX PUBLIC
-glXCreateGLXVideoSourceSGIX(Display *dpy, int screen, VLServer server, VLPath path, int nodeClass, VLNode drainNode)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXVideoSourceSGIX)(dpy, screen, server, path, nodeClass, drainNode);
-}
-
-void PUBLIC
-glXDestroyGLXVideoSourceSGIX(Display *dpy, GLXVideoSourceSGIX src)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->DestroyGLXVideoSourceSGIX)(dpy, src);
-}
-
-#endif
-
-
-/*** GLX_EXT_import_context ***/
-
-void PUBLIC
-glXFreeContextEXT(Display *dpy, GLXContext context)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->FreeContextEXT)(dpy, context);
-}
-
-GLXContextID PUBLIC
-glXGetContextIDEXT(const GLXContext context)
-{
- return ((__GLXcontext *) context)->xid;
-}
-
-Display PUBLIC *
-glXGetCurrentDisplayEXT(void)
-{
- return glXGetCurrentDisplay();
-}
-
-GLXContext PUBLIC
-glXImportContextEXT(Display *dpy, GLXContextID contextID)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ImportContextEXT)(dpy, contextID);
-}
-
-int PUBLIC
-glXQueryContextInfoEXT(Display *dpy, GLXContext context, int attribute,int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0; /* XXX ok? */
- return (t->QueryContextInfoEXT)(dpy, context, attribute, value);
-}
-
-
-
-/*** GLX_SGIX_fbconfig ***/
-
-int PUBLIC
-glXGetFBConfigAttribSGIX(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigAttribSGIX)(dpy, config, attribute, value);
-}
-
-GLXFBConfigSGIX PUBLIC *
-glXChooseFBConfigSGIX(Display *dpy, int screen, int *attrib_list, int *nelements)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChooseFBConfigSGIX)(dpy, screen, attrib_list, nelements);
-}
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmapWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmapWithConfigSGIX)(dpy, config, pixmap);
-}
-
-GLXContext PUBLIC
-glXCreateContextWithConfigSGIX(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateContextWithConfigSGIX)(dpy, config, render_type, share_list, direct);
-}
-
-XVisualInfo PUBLIC *
-glXGetVisualFromFBConfigSGIX(Display *dpy, GLXFBConfigSGIX config)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetVisualFromFBConfigSGIX)(dpy, config);
-}
-
-GLXFBConfigSGIX PUBLIC
-glXGetFBConfigFromVisualSGIX(Display *dpy, XVisualInfo *vis)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->GetFBConfigFromVisualSGIX)(dpy, vis);
-}
-
-
-
-/*** GLX_SGIX_pbuffer ***/
-
-GLXPbufferSGIX PUBLIC
-glXCreateGLXPbufferSGIX(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPbufferSGIX)(dpy, config, width, height, attrib_list);
-}
-
-void PUBLIC
-glXDestroyGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->DestroyGLXPbufferSGIX)(dpy, pbuf);
-}
-
-int PUBLIC
-glXQueryGLXPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryGLXPbufferSGIX)(dpy, pbuf, attribute, value);
-}
-
-void PUBLIC
-glXSelectEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->SelectEventSGIX)(dpy, drawable, mask);
-}
-
-void PUBLIC
-glXGetSelectedEventSGIX(Display *dpy, GLXDrawable drawable, unsigned long *mask)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->GetSelectedEventSGIX)(dpy, drawable, mask);
-}
-
-
-
-/*** GLX_SGI_cushion ***/
-
-void PUBLIC
-glXCushionSGI(Display *dpy, Window win, float cushion)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CushionSGI)(dpy, win, cushion);
-}
-
-
-
-/*** GLX_SGIX_video_resize ***/
-
-int PUBLIC
-glXBindChannelToWindowSGIX(Display *dpy, int screen, int channel , Window window)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->BindChannelToWindowSGIX)(dpy, screen, channel, window);
-}
-
-int PUBLIC
-glXChannelRectSGIX(Display *dpy, int screen, int channel, int x, int y, int w, int h)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
-}
-
-int PUBLIC
-glXQueryChannelRectSGIX(Display *dpy, int screen, int channel, int *x, int *y, int *w, int *h)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryChannelRectSGIX)(dpy, screen, channel, x, y, w, h);
-}
-
-int PUBLIC
-glXQueryChannelDeltasSGIX(Display *dpy, int screen, int channel, int *dx, int *dy, int *dw, int *dh)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->QueryChannelDeltasSGIX)(dpy, screen, channel, dx, dy, dw, dh);
-}
-
-int PUBLIC
-glXChannelRectSyncSGIX(Display *dpy, int screen, int channel, GLenum synctype)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->ChannelRectSyncSGIX)(dpy, screen, channel, synctype);
-}
-
-
-
-#if defined(_DM_BUFFER_H_)
-
-Bool PUBLIC
-glXAssociateDMPbufferSGIX(Display *dpy, GLXPbufferSGIX pbuffer, DMparams *params, DMbuffer dmbuffer)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->AssociateDMPbufferSGIX)(dpy, pbuffer, params, dmbuffer);
-}
-
-#endif
-
-
-/*** GLX_SGIX_swap_group ***/
-
-void PUBLIC
-glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable, GLXDrawable member)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (*t->JoinSwapGroupSGIX)(dpy, drawable, member);
-}
-
-
-/*** GLX_SGIX_swap_barrier ***/
-
-void PUBLIC
-glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable, int barrier)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (*t->BindSwapBarrierSGIX)(dpy, drawable, barrier);
-}
-
-Bool PUBLIC
-glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (*t->QueryMaxSwapBarriersSGIX)(dpy, screen, max);
-}
-
-
-
-/*** GLX_SUN_get_transparent_index ***/
-
-Status PUBLIC
-glXGetTransparentIndexSUN(Display *dpy, Window overlay, Window underlay, long *pTransparent)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (*t->GetTransparentIndexSUN)(dpy, overlay, underlay, pTransparent);
-}
-
-
-
-/*** GLX_MESA_copy_sub_buffer ***/
-
-void PUBLIC
-glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return;
- (t->CopySubBufferMESA)(dpy, drawable, x, y, width, height);
-}
-
-
-
-/*** GLX_MESA_release_buffers ***/
-
-Bool PUBLIC
-glXReleaseBuffersMESA(Display *dpy, Window w)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return False;
- return (t->ReleaseBuffersMESA)(dpy, w);
-}
-
-
-
-/*** GLX_MESA_pixmap_colormap ***/
-
-GLXPixmap PUBLIC
-glXCreateGLXPixmapMESA(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (!t)
- return 0;
- return (t->CreateGLXPixmapMESA)(dpy, visinfo, pixmap, cmap);
-}
-
-/*** GLX_EXT_texture_from_pixmap */
-
-void
-glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer,
- const int *attrib_list)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (t)
- t->BindTexImageEXT(dpy, drawable, buffer, attrib_list);
-}
-
-void
-glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer)
-{
- struct _glxapi_table *t;
- GET_DISPATCH(dpy, t);
- if (t)
- t->ReleaseTexImageEXT(dpy, drawable, buffer);
-}
-
-
-/**********************************************************************/
-/* GLX API management functions */
-/**********************************************************************/
-
-
-const char *
-_glxapi_get_version(void)
-{
- return "1.3";
-}
-
-
-
-/*
- * Return size of the GLX dispatch table, in entries, not bytes.
- */
-GLuint
-_glxapi_get_dispatch_table_size(void)
-{
- return sizeof(struct _glxapi_table) / sizeof(void *);
-}
-
-
-static int
-generic_no_op_func(void)
-{
- return 0;
-}
-
-
-/*
- * Initialize all functions in given dispatch table to be no-ops
- */
-void
-_glxapi_set_no_op_table(struct _glxapi_table *t)
-{
- typedef int (*nop_func)(void);
- nop_func *dispatch = (nop_func *) t;
- GLuint n = _glxapi_get_dispatch_table_size();
- GLuint i;
- for (i = 0; i < n; i++) {
- dispatch[i] = generic_no_op_func;
- }
-}
-
-
-struct name_address_pair {
- const char *Name;
- __GLXextFuncPtr Address;
-};
-
-static struct name_address_pair GLX_functions[] = {
- /*** GLX_VERSION_1_0 ***/
- { "glXChooseVisual", (__GLXextFuncPtr) glXChooseVisual },
- { "glXCopyContext", (__GLXextFuncPtr) glXCopyContext },
- { "glXCreateContext", (__GLXextFuncPtr) glXCreateContext },
- { "glXCreateGLXPixmap", (__GLXextFuncPtr) glXCreateGLXPixmap },
- { "glXDestroyContext", (__GLXextFuncPtr) glXDestroyContext },
- { "glXDestroyGLXPixmap", (__GLXextFuncPtr) glXDestroyGLXPixmap },
- { "glXGetConfig", (__GLXextFuncPtr) glXGetConfig },
- { "glXGetCurrentContext", (__GLXextFuncPtr) glXGetCurrentContext },
- { "glXGetCurrentDrawable", (__GLXextFuncPtr) glXGetCurrentDrawable },
- { "glXIsDirect", (__GLXextFuncPtr) glXIsDirect },
- { "glXMakeCurrent", (__GLXextFuncPtr) glXMakeCurrent },
- { "glXQueryExtension", (__GLXextFuncPtr) glXQueryExtension },
- { "glXQueryVersion", (__GLXextFuncPtr) glXQueryVersion },
- { "glXSwapBuffers", (__GLXextFuncPtr) glXSwapBuffers },
- { "glXUseXFont", (__GLXextFuncPtr) glXUseXFont },
- { "glXWaitGL", (__GLXextFuncPtr) glXWaitGL },
- { "glXWaitX", (__GLXextFuncPtr) glXWaitX },
-
- /*** GLX_VERSION_1_1 ***/
- { "glXGetClientString", (__GLXextFuncPtr) glXGetClientString },
- { "glXQueryExtensionsString", (__GLXextFuncPtr) glXQueryExtensionsString },
- { "glXQueryServerString", (__GLXextFuncPtr) glXQueryServerString },
-
- /*** GLX_VERSION_1_2 ***/
- { "glXGetCurrentDisplay", (__GLXextFuncPtr) glXGetCurrentDisplay },
-
- /*** GLX_VERSION_1_3 ***/
- { "glXChooseFBConfig", (__GLXextFuncPtr) glXChooseFBConfig },
- { "glXCreateNewContext", (__GLXextFuncPtr) glXCreateNewContext },
- { "glXCreatePbuffer", (__GLXextFuncPtr) glXCreatePbuffer },
- { "glXCreatePixmap", (__GLXextFuncPtr) glXCreatePixmap },
- { "glXCreateWindow", (__GLXextFuncPtr) glXCreateWindow },
- { "glXDestroyPbuffer", (__GLXextFuncPtr) glXDestroyPbuffer },
- { "glXDestroyPixmap", (__GLXextFuncPtr) glXDestroyPixmap },
- { "glXDestroyWindow", (__GLXextFuncPtr) glXDestroyWindow },
- { "glXGetCurrentReadDrawable", (__GLXextFuncPtr) glXGetCurrentReadDrawable },
- { "glXGetFBConfigAttrib", (__GLXextFuncPtr) glXGetFBConfigAttrib },
- { "glXGetFBConfigs", (__GLXextFuncPtr) glXGetFBConfigs },
- { "glXGetSelectedEvent", (__GLXextFuncPtr) glXGetSelectedEvent },
- { "glXGetVisualFromFBConfig", (__GLXextFuncPtr) glXGetVisualFromFBConfig },
- { "glXMakeContextCurrent", (__GLXextFuncPtr) glXMakeContextCurrent },
- { "glXQueryContext", (__GLXextFuncPtr) glXQueryContext },
- { "glXQueryDrawable", (__GLXextFuncPtr) glXQueryDrawable },
- { "glXSelectEvent", (__GLXextFuncPtr) glXSelectEvent },
-
- /*** GLX_VERSION_1_4 ***/
- { "glXGetProcAddress", (__GLXextFuncPtr) glXGetProcAddress },
-
- /*** GLX_SGI_swap_control ***/
- { "glXSwapIntervalSGI", (__GLXextFuncPtr) glXSwapIntervalSGI },
-
- /*** GLX_SGI_video_sync ***/
- { "glXGetVideoSyncSGI", (__GLXextFuncPtr) glXGetVideoSyncSGI },
- { "glXWaitVideoSyncSGI", (__GLXextFuncPtr) glXWaitVideoSyncSGI },
-
- /*** GLX_SGI_make_current_read ***/
- { "glXMakeCurrentReadSGI", (__GLXextFuncPtr) glXMakeCurrentReadSGI },
- { "glXGetCurrentReadDrawableSGI", (__GLXextFuncPtr) glXGetCurrentReadDrawableSGI },
-
- /*** GLX_SGIX_video_source ***/
-#if defined(_VL_H)
- { "glXCreateGLXVideoSourceSGIX", (__GLXextFuncPtr) glXCreateGLXVideoSourceSGIX },
- { "glXDestroyGLXVideoSourceSGIX", (__GLXextFuncPtr) glXDestroyGLXVideoSourceSGIX },
-#endif
-
- /*** GLX_EXT_import_context ***/
- { "glXFreeContextEXT", (__GLXextFuncPtr) glXFreeContextEXT },
- { "glXGetContextIDEXT", (__GLXextFuncPtr) glXGetContextIDEXT },
- { "glXGetCurrentDisplayEXT", (__GLXextFuncPtr) glXGetCurrentDisplayEXT },
- { "glXImportContextEXT", (__GLXextFuncPtr) glXImportContextEXT },
- { "glXQueryContextInfoEXT", (__GLXextFuncPtr) glXQueryContextInfoEXT },
-
- /*** GLX_SGIX_fbconfig ***/
- { "glXGetFBConfigAttribSGIX", (__GLXextFuncPtr) glXGetFBConfigAttribSGIX },
- { "glXChooseFBConfigSGIX", (__GLXextFuncPtr) glXChooseFBConfigSGIX },
- { "glXCreateGLXPixmapWithConfigSGIX", (__GLXextFuncPtr) glXCreateGLXPixmapWithConfigSGIX },
- { "glXCreateContextWithConfigSGIX", (__GLXextFuncPtr) glXCreateContextWithConfigSGIX },
- { "glXGetVisualFromFBConfigSGIX", (__GLXextFuncPtr) glXGetVisualFromFBConfigSGIX },
- { "glXGetFBConfigFromVisualSGIX", (__GLXextFuncPtr) glXGetFBConfigFromVisualSGIX },
-
- /*** GLX_SGIX_pbuffer ***/
- { "glXCreateGLXPbufferSGIX", (__GLXextFuncPtr) glXCreateGLXPbufferSGIX },
- { "glXDestroyGLXPbufferSGIX", (__GLXextFuncPtr) glXDestroyGLXPbufferSGIX },
- { "glXQueryGLXPbufferSGIX", (__GLXextFuncPtr) glXQueryGLXPbufferSGIX },
- { "glXSelectEventSGIX", (__GLXextFuncPtr) glXSelectEventSGIX },
- { "glXGetSelectedEventSGIX", (__GLXextFuncPtr) glXGetSelectedEventSGIX },
-
- /*** GLX_SGI_cushion ***/
- { "glXCushionSGI", (__GLXextFuncPtr) glXCushionSGI },
-
- /*** GLX_SGIX_video_resize ***/
- { "glXBindChannelToWindowSGIX", (__GLXextFuncPtr) glXBindChannelToWindowSGIX },
- { "glXChannelRectSGIX", (__GLXextFuncPtr) glXChannelRectSGIX },
- { "glXQueryChannelRectSGIX", (__GLXextFuncPtr) glXQueryChannelRectSGIX },
- { "glXQueryChannelDeltasSGIX", (__GLXextFuncPtr) glXQueryChannelDeltasSGIX },
- { "glXChannelRectSyncSGIX", (__GLXextFuncPtr) glXChannelRectSyncSGIX },
-
- /*** GLX_SGIX_dmbuffer **/
-#if defined(_DM_BUFFER_H_)
- { "glXAssociateDMPbufferSGIX", (__GLXextFuncPtr) glXAssociateDMPbufferSGIX },
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- { "glXJoinSwapGroupSGIX", (__GLXextFuncPtr) glXJoinSwapGroupSGIX },
-
- /*** GLX_SGIX_swap_barrier ***/
- { "glXBindSwapBarrierSGIX", (__GLXextFuncPtr) glXBindSwapBarrierSGIX },
- { "glXQueryMaxSwapBarriersSGIX", (__GLXextFuncPtr) glXQueryMaxSwapBarriersSGIX },
-
- /*** GLX_SUN_get_transparent_index ***/
- { "glXGetTransparentIndexSUN", (__GLXextFuncPtr) glXGetTransparentIndexSUN },
-
- /*** GLX_MESA_copy_sub_buffer ***/
- { "glXCopySubBufferMESA", (__GLXextFuncPtr) glXCopySubBufferMESA },
-
- /*** GLX_MESA_pixmap_colormap ***/
- { "glXCreateGLXPixmapMESA", (__GLXextFuncPtr) glXCreateGLXPixmapMESA },
-
- /*** GLX_MESA_release_buffers ***/
- { "glXReleaseBuffersMESA", (__GLXextFuncPtr) glXReleaseBuffersMESA },
-
- /*** GLX_ARB_get_proc_address ***/
- { "glXGetProcAddressARB", (__GLXextFuncPtr) glXGetProcAddressARB },
-
- /*** GLX_EXT_texture_from_pixmap ***/
- { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT },
- { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT },
-
- { NULL, NULL } /* end of list */
-};
-
-
-
-/*
- * Return address of named glX function, or NULL if not found.
- */
-__GLXextFuncPtr
-_glxapi_get_proc_address(const char *funcName)
-{
- GLuint i;
- for (i = 0; GLX_functions[i].Name; i++) {
- if (strcmp(GLX_functions[i].Name, funcName) == 0)
- return GLX_functions[i].Address;
- }
- return NULL;
-}
-
-
-
-/*
- * This function does not get dispatched through the dispatch table
- * since it's really a "meta" function.
- */
-__GLXextFuncPtr
-glXGetProcAddressARB(const GLubyte *procName)
-{
- __GLXextFuncPtr f;
-
- f = _glxapi_get_proc_address((const char *) procName);
- if (f) {
- return f;
- }
-
- f = (__GLXextFuncPtr) _glapi_get_proc_address((const char *) procName);
- return f;
-}
-
-
-/* GLX 1.4 */
-void (*glXGetProcAddress(const GLubyte *procName))()
-{
- return glXGetProcAddressARB(procName);
-}
diff --git a/src/gallium/state_trackers/glx/xlib/glxapi.h b/src/gallium/state_trackers/glx/xlib/glxapi.h
deleted file mode 100644
index b4e12b4162..0000000000
--- a/src/gallium/state_trackers/glx/xlib/glxapi.h
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.3
- *
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef _glxapi_h_
-#define _glxapi_h_
-
-
-#define GLX_GLXEXT_PROTOTYPES
-#include "GL/glx.h"
-
-
-/* The GLX API dispatcher (i.e. this code) is being built into stand-alone
- * Mesa. We don't know anything about XFree86 or real GLX so we define a
- * minimal __GLXContextRec here so some of the functions in this file can
- * work properly.
- */
-typedef struct __GLXcontextRec {
- Display *currentDpy;
- GLboolean isDirect;
- GLXDrawable currentDrawable;
- GLXDrawable currentReadable;
- XID xid;
-} __GLXcontext;
-
-
-/*
- * Almost all the GLX API functions get routed through this dispatch table.
- * The exceptions are the glXGetCurrentXXX() functions.
- *
- * This dispatch table allows multiple GLX client-side modules to coexist.
- * Specifically, a real GLX library (like SGI's or the Utah GLX) and Mesa's
- * pseudo-GLX can be present at the same time. The former being used on
- * GLX-enabled X servers and the later on non-GLX X servers.
- *
- * Red Hat has been using this since Red Hat Linux 7.0 (I think).
- * This'll be a standard feature in XFree86 4.3. It basically allows one
- * libGL to do both DRI-rendering and "fake GLX" rendering to X displays
- * that lack the GLX extension.
- */
-struct _glxapi_table {
- /*** GLX_VERSION_1_0 ***/
- XVisualInfo *(*ChooseVisual)(Display *dpy, int screen, int *list);
- void (*CopyContext)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask);
- GLXContext (*CreateContext)(Display *dpy, XVisualInfo *visinfo, GLXContext shareList, Bool direct);
- GLXPixmap (*CreateGLXPixmap)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap);
- void (*DestroyContext)(Display *dpy, GLXContext ctx);
- void (*DestroyGLXPixmap)(Display *dpy, GLXPixmap pixmap);
- int (*GetConfig)(Display *dpy, XVisualInfo *visinfo, int attrib, int *value);
- /*GLXContext (*GetCurrentContext)(void);*/
- /*GLXDrawable (*GetCurrentDrawable)(void);*/
- Bool (*IsDirect)(Display *dpy, GLXContext ctx);
- Bool (*MakeCurrent)(Display *dpy, GLXDrawable drawable, GLXContext ctx);
- Bool (*QueryExtension)(Display *dpy, int *errorb, int *event);
- Bool (*QueryVersion)(Display *dpy, int *maj, int *min);
- void (*SwapBuffers)(Display *dpy, GLXDrawable drawable);
- void (*UseXFont)(Font font, int first, int count, int listBase);
- void (*WaitGL)(void);
- void (*WaitX)(void);
-
- /*** GLX_VERSION_1_1 ***/
- const char *(*GetClientString)(Display *dpy, int name);
- const char *(*QueryExtensionsString)(Display *dpy, int screen);
- const char *(*QueryServerString)(Display *dpy, int screen, int name);
-
- /*** GLX_VERSION_1_2 ***/
- /*Display *(*GetCurrentDisplay)(void);*/
-
- /*** GLX_VERSION_1_3 ***/
- GLXFBConfig *(*ChooseFBConfig)(Display *dpy, int screen, const int *attribList, int *nitems);
- GLXContext (*CreateNewContext)(Display *dpy, GLXFBConfig config, int renderType, GLXContext shareList, Bool direct);
- GLXPbuffer (*CreatePbuffer)(Display *dpy, GLXFBConfig config, const int *attribList);
- GLXPixmap (*CreatePixmap)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attribList);
- GLXWindow (*CreateWindow)(Display *dpy, GLXFBConfig config, Window win, const int *attribList);
- void (*DestroyPbuffer)(Display *dpy, GLXPbuffer pbuf);
- void (*DestroyPixmap)(Display *dpy, GLXPixmap pixmap);
- void (*DestroyWindow)(Display *dpy, GLXWindow window);
- /*GLXDrawable (*GetCurrentReadDrawable)(void);*/
- int (*GetFBConfigAttrib)(Display *dpy, GLXFBConfig config, int attribute, int *value);
- GLXFBConfig *(*GetFBConfigs)(Display *dpy, int screen, int *nelements);
- void (*GetSelectedEvent)(Display *dpy, GLXDrawable drawable, unsigned long *mask);
- XVisualInfo *(*GetVisualFromFBConfig)(Display *dpy, GLXFBConfig config);
- Bool (*MakeContextCurrent)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx);
- int (*QueryContext)(Display *dpy, GLXContext ctx, int attribute, int *value);
- void (*QueryDrawable)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value);
- void (*SelectEvent)(Display *dpy, GLXDrawable drawable, unsigned long mask);
-
- /*** GLX_SGI_swap_control ***/
- int (*SwapIntervalSGI)(int);
-
- /*** GLX_SGI_video_sync ***/
- int (*GetVideoSyncSGI)(unsigned int *count);
- int (*WaitVideoSyncSGI)(int divisor, int remainder, unsigned int *count);
-
- /*** GLX_SGI_make_current_read ***/
- Bool (*MakeCurrentReadSGI)(Display *, GLXDrawable, GLXDrawable, GLXContext);
- /*GLXDrawable (*GetCurrentReadDrawableSGI)(void);*/
-
- /*** GLX_SGIX_video_source (needs video library) ***/
-#if defined(_VL_H_)
- GLXVideoSourceSGIX (*CreateGLXVideoSourceSGIX)(Display *, int, VLServer, VLPath, int, VLNode);
- void (*DestroyGLXVideoSourceSGIX)(Display *, GLXVideoSourceSGIX);
-#else
- void *CreateGLXVideoSourceSGIX;
- void *DestroyGLXVideoSourceSGIX;
-#endif
-
- /*** GLX_EXT_import_context ***/
- void (*FreeContextEXT)(Display *dpy, GLXContext context);
- GLXContextID (*GetContextIDEXT)(const GLXContext context);
- /*Display *(*GetCurrentDisplayEXT)(void);*/
- GLXContext (*ImportContextEXT)(Display *dpy, GLXContextID contextID);
- int (*QueryContextInfoEXT)(Display *dpy, GLXContext context, int attribute,int *value);
-
- /*** GLX_SGIX_fbconfig ***/
- int (*GetFBConfigAttribSGIX)(Display *, GLXFBConfigSGIX, int, int *);
- GLXFBConfigSGIX * (*ChooseFBConfigSGIX)(Display *, int, int *, int *);
- GLXPixmap (*CreateGLXPixmapWithConfigSGIX)(Display *, GLXFBConfigSGIX, Pixmap);
- GLXContext (*CreateContextWithConfigSGIX)(Display *, GLXFBConfigSGIX, int, GLXContext, Bool);
- XVisualInfo * (*GetVisualFromFBConfigSGIX)(Display *, GLXFBConfigSGIX);
- GLXFBConfigSGIX (*GetFBConfigFromVisualSGIX)(Display *, XVisualInfo *);
-
- /*** GLX_SGIX_pbuffer ***/
- GLXPbufferSGIX (*CreateGLXPbufferSGIX)(Display *, GLXFBConfigSGIX, unsigned int, unsigned int, int *);
- void (*DestroyGLXPbufferSGIX)(Display *, GLXPbufferSGIX);
- int (*QueryGLXPbufferSGIX)(Display *, GLXPbufferSGIX, int, unsigned int *);
- void (*SelectEventSGIX)(Display *, GLXDrawable, unsigned long);
- void (*GetSelectedEventSGIX)(Display *, GLXDrawable, unsigned long *);
-
- /*** GLX_SGI_cushion ***/
- void (*CushionSGI)(Display *, Window, float);
-
- /*** GLX_SGIX_video_resize ***/
- int (*BindChannelToWindowSGIX)(Display *, int, int, Window);
- int (*ChannelRectSGIX)(Display *, int, int, int, int, int, int);
- int (*QueryChannelRectSGIX)(Display *, int, int, int *, int *, int *, int *);
- int (*QueryChannelDeltasSGIX)(Display *, int, int, int *, int *, int *, int *);
- int (*ChannelRectSyncSGIX)(Display *, int, int, GLenum);
-
- /*** GLX_SGIX_dmbuffer (needs dmedia library) ***/
-#if defined (_DM_BUFFER_H_)
- Bool (*AssociateDMPbufferSGIX)(Display *, GLXPbufferSGIX, DMparams *, DMbuffer);
-#else
- void *AssociciateDMPbufferSGIX;
-#endif
-
- /*** GLX_SGIX_swap_group ***/
- void (*JoinSwapGroupSGIX)(Display *, GLXDrawable, GLXDrawable);
-
- /*** GLX_SGIX_swap_barrier ***/
- void (*BindSwapBarrierSGIX)(Display *, GLXDrawable, int);
- Bool (*QueryMaxSwapBarriersSGIX)(Display *, int, int *);
-
- /*** GLX_SUN_get_transparent_index ***/
- Status (*GetTransparentIndexSUN)(Display *, Window, Window, long *);
-
- /*** GLX_MESA_copy_sub_buffer ***/
- void (*CopySubBufferMESA)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height);
-
- /*** GLX_MESA_release_buffers ***/
- Bool (*ReleaseBuffersMESA)(Display *dpy, Window w);
-
- /*** GLX_MESA_pixmap_colormap ***/
- GLXPixmap (*CreateGLXPixmapMESA)(Display *dpy, XVisualInfo *visinfo, Pixmap pixmap, Colormap cmap);
-
- /*** GLX_EXT_texture_from_pixmap ***/
- void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer,
- const int *attrib_list);
- void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer);
-};
-
-
-
-extern const char *
-_glxapi_get_version(void);
-
-
-
-
-extern GLuint
-_glxapi_get_dispatch_table_size(void);
-
-
-extern void
-_glxapi_set_no_op_table(struct _glxapi_table *t);
-
-
-extern __GLXextFuncPtr
-_glxapi_get_proc_address(const char *funcName);
-
-
-#endif
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.c b/src/gallium/state_trackers/glx/xlib/xm_api.c
index 79c2230588..957002ddd5 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.c
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.c
@@ -286,6 +286,18 @@ choose_pixel_format(XMesaVisual v)
return PIPE_FORMAT_B8G8R8A8_UNORM;
}
}
+ else if ( GET_REDMASK(v) == 0x0000ff00
+ && GET_GREENMASK(v) == 0x00ff0000
+ && GET_BLUEMASK(v) == 0xff000000
+ && v->BitsPerPixel == 32) {
+ if (native_byte_order) {
+ /* no byteswapping needed */
+ return PIPE_FORMAT_B8G8R8A8_UNORM;
+ }
+ else {
+ return PIPE_FORMAT_A8R8G8B8_UNORM;
+ }
+ }
else if ( GET_REDMASK(v) == 0xf800
&& GET_GREENMASK(v) == 0x07e0
&& GET_BLUEMASK(v) == 0x001f
@@ -656,7 +668,7 @@ XMesaVisual XMesaCreateVisual( Display *display,
* at a later time.
*/
v->visinfo = (XVisualInfo *) MALLOC(sizeof(*visinfo));
- if(!v->visinfo) {
+ if (!v->visinfo) {
_mesa_free(v);
return NULL;
}
@@ -742,14 +754,15 @@ PUBLIC
XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
{
static GLboolean firstTime = GL_TRUE;
- struct pipe_screen *screen;
- struct pipe_context *pipe;
+ static struct pipe_screen *screen = NULL;
+ struct pipe_context *pipe = NULL;
XMesaContext c;
GLcontext *mesaCtx;
uint pf;
if (firstTime) {
pipe_mutex_init(_xmesa_lock);
+ screen = driver.create_pipe_screen();
firstTime = GL_FALSE;
}
@@ -765,14 +778,10 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
c->xm_buffer = NULL; /* set later by XMesaMakeCurrent */
c->xm_read_buffer = NULL;
- /* XXX: create once per Xlib Display.
- */
- screen = driver.create_pipe_screen();
if (screen == NULL)
goto fail;
- pipe = driver.create_pipe_context( screen,
- (void *)c );
+ pipe = driver.create_pipe_context(screen, (void *) c);
if (pipe == NULL)
goto fail;
@@ -785,26 +794,15 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
mesaCtx = c->st->ctx;
c->st->ctx->DriverCtx = c;
-#if 00
- _mesa_enable_sw_extensions(mesaCtx);
- _mesa_enable_1_3_extensions(mesaCtx);
- _mesa_enable_1_4_extensions(mesaCtx);
- _mesa_enable_1_5_extensions(mesaCtx);
- _mesa_enable_2_0_extensions(mesaCtx);
-#endif
-
return c;
- fail:
+fail:
if (c->st)
st_destroy_context(c->st);
else if (pipe)
pipe->destroy(pipe);
- if (screen)
- screen->destroy( screen );
-
- FREE(c);
+ _mesa_free(c);
return NULL;
}
@@ -1158,7 +1156,7 @@ void XMesaFlush( XMesaContext c )
XMesaBuffer XMesaFindBuffer( Display *dpy, Drawable d )
{
XMesaBuffer b;
- for (b=XMesaBufferList; b; b=b->Next) {
+ for (b = XMesaBufferList; b; b = b->Next) {
if (b->drawable == d && b->xm_visual->display == dpy) {
return b;
}
diff --git a/src/gallium/state_trackers/glx/xlib/xm_api.h b/src/gallium/state_trackers/glx/xlib/xm_api.h
index bdd434cd36..ce97a3ec76 100644
--- a/src/gallium/state_trackers/glx/xlib/xm_api.h
+++ b/src/gallium/state_trackers/glx/xlib/xm_api.h
@@ -57,7 +57,7 @@ and create a window, you must do the following to use the X/Mesa interface:
#define XMESA_H
-#include "mtypes.h"
+#include "main/mtypes.h"
#include "state_tracker/st_context.h"
#include "state_tracker/st_public.h"
#include "pipe/p_thread.h"
diff --git a/src/gallium/state_trackers/python/retrace/parse.py b/src/gallium/state_trackers/python/retrace/parse.py
index b0f3e8a432..b08d368671 100755
--- a/src/gallium/state_trackers/python/retrace/parse.py
+++ b/src/gallium/state_trackers/python/retrace/parse.py
@@ -371,7 +371,7 @@ class Main:
stream = GzipFile(arg, 'rt')
elif arg.endswith('.bz2'):
from bz2 import BZ2File
- stream = BZ2File(arg, 'rt')
+ stream = BZ2File(arg, 'rU')
else:
stream = open(arg, 'rt')
self.process_arg(stream, options)
diff --git a/src/gallium/state_trackers/vega/asm_filters.h b/src/gallium/state_trackers/vega/asm_filters.h
index 49807b9ab4..9a49f2e12d 100644
--- a/src/gallium/state_trackers/vega/asm_filters.h
+++ b/src/gallium/state_trackers/vega/asm_filters.h
@@ -60,7 +60,7 @@ static const char convolution_asm[] =
"DCL SAMP[0], CONSTANT\n"
"0: MOV TEMP[0], CONST[0].xxxx\n"
"1: MOV TEMP[1], CONST[0].xxxx\n"
- "2: BGNLOOP2 :14\n"
+ "2: BGNLOOP :14\n"
"3: SGE TEMP[0].z, TEMP[0].yyyy, CONST[1].xxxx\n"
"4: IF TEMP[0].zzzz :7\n"
"5: BRK\n"
@@ -72,7 +72,7 @@ static const char convolution_asm[] =
"11: MOV TEMP[3], CONST[ADDR[0]+%d]\n"
"12: MAD TEMP[1], TEMP[2], TEMP[3], TEMP[1]\n"
"13: ADD TEMP[0].y, TEMP[0].yyyy, CONST[0].yyyy\n"
- "14: ENDLOOP2 :2\n"
+ "14: ENDLOOP :2\n"
"15: MAD OUT[0], TEMP[1], CONST[1].yyyy, CONST[1].zzzz\n"
"16: END\n";
diff --git a/src/gallium/state_trackers/vega/path.c b/src/gallium/state_trackers/vega/path.c
index d04f9d9ae6..4fc23a7a27 100644
--- a/src/gallium/state_trackers/vega/path.c
+++ b/src/gallium/state_trackers/vega/path.c
@@ -868,7 +868,7 @@ static VGboolean transform_cb(struct path *p,
vg_float_to_datatype(td->datatype, common_data, data, num_coords);
- array_append_data(td->segments, &segment, 1);
+ array_append_data(td->segments, &pd->segment, 1);
array_append_data(td->coords, common_data, num_coords);
return VG_TRUE;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.c b/src/gallium/state_trackers/vega/vg_tracker.c
index c262ce08fa..56cc60aebe 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.c
+++ b/src/gallium/state_trackers/vega/vg_tracker.c
@@ -367,6 +367,11 @@ void st_make_current(struct vg_context *st,
}
}
+struct vg_context *st_get_current(void)
+{
+ return vg_current_context();
+}
+
void st_flush(struct vg_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence)
{
@@ -399,8 +404,13 @@ void st_notify_swapbuffers_complete(struct st_framebuffer *stfb)
{
}
-int
-st_set_teximage(struct pipe_texture *pt, int target)
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format)
+{
+ return 0;
+}
+
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
{
return 0;
}
diff --git a/src/gallium/state_trackers/vega/vg_tracker.h b/src/gallium/state_trackers/vega/vg_tracker.h
index 805c58ccc7..5457631106 100644
--- a/src/gallium/state_trackers/vega/vg_tracker.h
+++ b/src/gallium/state_trackers/vega/vg_tracker.h
@@ -70,7 +70,10 @@ void st_set_framebuffer_surface(struct st_framebuffer *stfb,
void st_get_framebuffer_dimensions( struct st_framebuffer *stfb,
uint *width, uint *height);
-int st_set_teximage(struct pipe_texture *pt, int target);
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format);
+
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
int st_get_framebuffer_surface(struct st_framebuffer *stfb,
uint surfIndex, struct pipe_surface **surf);
@@ -86,6 +89,8 @@ void st_make_current(struct vg_context *st,
struct st_framebuffer *draw,
struct st_framebuffer *read);
+struct vg_context *st_get_current(void);
+
void st_flush(struct vg_context *st, uint pipeFlushFlags,
struct pipe_fence_handle **fence);
void st_finish(struct vg_context *st);
diff --git a/src/gallium/state_trackers/wgl/SConscript b/src/gallium/state_trackers/wgl/SConscript
index 69b88618ec..b05944a33b 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/shared/stw_context.c b/src/gallium/state_trackers/wgl/shared/stw_context.c
deleted file mode 100644
index 4968ecc692..0000000000
--- 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/icd/stw_icd.c b/src/gallium/state_trackers/wgl/stw_context.c
index 347f40aa06..f2f0264844 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 166471de5e..256c27e21e 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 0b6954915a..a1a5b892ef 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_device.c
+++ b/src/gallium/state_trackers/wgl/stw_device.c
@@ -37,12 +37,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;
@@ -182,7 +182,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 +212,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 +223,20 @@ 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 )
+{
+ 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 e1bb9518dd..5e4e3d6180 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"
@@ -69,7 +68,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 62c859e1f9..62c859e1f9 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 fc22737d7e..fb30ec5dba 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 cc35f2bb7f..cc35f2bb7f 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 0e2d407699..8a9995aba8 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 9eac6a1d09..9eac6a1d09 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 b8956bb550..123b841c8f 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.c
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c
@@ -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"
@@ -379,10 +379,10 @@ stw_framebuffer_from_hwnd(
}
-BOOL
-stw_pixelformat_set(
+BOOL APIENTRY
+DrvSetPixelFormat(
HDC hdc,
- int iPixelFormat )
+ LONG iPixelFormat )
{
uint count;
uint index;
@@ -435,8 +435,8 @@ stw_pixelformat_get(
}
-BOOL
-stw_swap_buffers(
+BOOL APIENTRY
+DrvSwapBuffers(
HDC hdc )
{
struct stw_framebuffer *fb;
@@ -481,13 +481,13 @@ stw_swap_buffers(
}
-BOOL
-stw_swap_layer_buffers(
+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 13d29f37e4..13d29f37e4 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_framebuffer.h
+++ b/src/gallium/state_trackers/wgl/stw_framebuffer.h
diff --git a/src/gallium/state_trackers/wgl/shared/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c
index 879ced925a..8875dc22f3 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 cbc1a66548..cbc1a66548 100644
--- a/src/gallium/state_trackers/wgl/icd/stw_icd.h
+++ b/src/gallium/state_trackers/wgl/stw_icd.h
diff --git a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c
index c296744838..9b591d5751 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"
@@ -288,12 +288,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 +306,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 +316,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 bec429231b..2fa7e22c43 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_pixelformat.h
+++ b/src/gallium/state_trackers/wgl/stw_pixelformat.h
@@ -62,4 +62,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 4bd6a9289c..4bd6a9289c 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 fbf8b1cbee..fbf8b1cbee 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 a131292f7a..bb199fdd25 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 a98179944a..a98179944a 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 c0bf82c9ed..c0bf82c9ed 100644
--- a/src/gallium/state_trackers/wgl/shared/stw_winsys.h
+++ b/src/gallium/state_trackers/wgl/stw_winsys.h
diff --git a/src/gallium/state_trackers/xorg/SConscript b/src/gallium/state_trackers/xorg/SConscript
new file mode 100644
index 0000000000..65f55ea378
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/SConscript
@@ -0,0 +1,27 @@
+#######################################################################
+# SConscript for xorg state_tracker
+
+Import('*')
+
+if 'xorg' in env['statetrackers']:
+
+ env = env.Clone()
+
+ env.Append(CPPPATH = [
+ '#/src/mesa',
+ ])
+
+ env.ParseConfig('pkg-config --cflags --libs xorg-server')
+
+ st_xorg = env.ConvenienceLibrary(
+ target = 'st_xorg',
+ source = [ 'xorg_composite.c',
+ 'xorg_crtc.c',
+ 'xorg_dri2.c',
+ 'xorg_driver.c',
+ 'xorg_exa.c',
+ 'xorg_exa_tgsi.c',
+ 'xorg_output.c',
+ ]
+ )
+ Export('st_xorg')
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.c b/src/gallium/state_trackers/xorg/xorg_composite.c
index 255ae91f09..a870ad1049 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.c
+++ b/src/gallium/state_trackers/xorg/xorg_composite.c
@@ -1,20 +1,596 @@
#include "xorg_composite.h"
+#include "xorg_exa_tgsi.h"
+
+#include "cso_cache/cso_context.h"
+#include "util/u_draw_quad.h"
+#include "util/u_math.h"
+
+#include "pipe/p_inlines.h"
+
+struct xorg_composite_blend {
+ int op:8;
+
+ unsigned rgb_src_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 */
+};
+
+#define BLEND_OP_OVER 3
+static const struct xorg_composite_blend xorg_blends[] = {
+ { PictOpClear,
+ PIPE_BLENDFACTOR_CONST_COLOR, PIPE_BLENDFACTOR_CONST_ALPHA,
+ PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO },
+
+ { PictOpSrc,
+ PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE,
+ PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO },
+
+ { PictOpDst,
+ PIPE_BLENDFACTOR_ZERO, PIPE_BLENDFACTOR_ZERO,
+ PIPE_BLENDFACTOR_ONE, PIPE_BLENDFACTOR_ONE },
+
+ { PictOpOver,
+ PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
+ PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
+
+ { PictOpOverReverse,
+ PIPE_BLENDFACTOR_SRC_ALPHA, PIPE_BLENDFACTOR_ONE,
+ PIPE_BLENDFACTOR_INV_SRC_ALPHA, PIPE_BLENDFACTOR_INV_SRC_ALPHA },
+};
+
+
+static INLINE void
+pixel_to_float4(Pixel pixel, float *color)
+{
+ CARD32 r, g, b, a;
+
+ a = (pixel >> 24) & 0xff;
+ r = (pixel >> 16) & 0xff;
+ g = (pixel >> 8) & 0xff;
+ b = (pixel >> 0) & 0xff;
+ color[0] = ((float)r) / 255.;
+ color[1] = ((float)g) / 255.;
+ color[2] = ((float)b) / 255.;
+ 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;
+ int component_alpha : 1;
+};
+static const struct acceleration_info accelerated_ops[] = {
+ {PictOpClear, 1, 0},
+ {PictOpSrc, 1, 0},
+ {PictOpDst, 1, 0},
+ {PictOpOver, 1, 0},
+ {PictOpOverReverse, 1, 0},
+ {PictOpIn, 1, 0},
+ {PictOpInReverse, 1, 0},
+ {PictOpOut, 1, 0},
+ {PictOpOutReverse, 1, 0},
+ {PictOpAtop, 1, 0},
+ {PictOpAtopReverse, 1, 0},
+ {PictOpXor, 1, 0},
+ {PictOpAdd, 1, 0},
+ {PictOpSaturate, 1, 0},
+};
+
+static struct xorg_composite_blend
+blend_for_op(int op)
+{
+ const int num_blends =
+ sizeof(xorg_blends)/sizeof(struct xorg_composite_blend);
+ int i;
+
+ for (i = 0; i < num_blends; ++i) {
+ if (xorg_blends[i].op == op)
+ return xorg_blends[i];
+ }
+ return xorg_blends[BLEND_OP_OVER];
+}
+
+static INLINE int
+render_repeat_to_gallium(int mode)
+{
+ switch(mode) {
+ case RepeatNone:
+ return PIPE_TEX_WRAP_CLAMP;
+ case RepeatNormal:
+ return PIPE_TEX_WRAP_REPEAT;
+ case RepeatReflect:
+ return PIPE_TEX_WRAP_MIRROR_REPEAT;
+ case RepeatPad:
+ return PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ default:
+ debug_printf("Unsupported repeat mode\n");
+ }
+ return PIPE_TEX_WRAP_REPEAT;
+}
+
+
+static INLINE void
+setup_vertex0(float vertex[2][4], float x, float y,
+ float color[4])
+{
+ vertex[0][0] = x;
+ vertex[0][1] = y;
+ vertex[0][2] = 0.f; /*z*/
+ vertex[0][3] = 1.f; /*w*/
+
+ vertex[1][0] = color[0]; /*r*/
+ vertex[1][1] = color[1]; /*g*/
+ vertex[1][2] = color[2]; /*b*/
+ vertex[1][3] = color[3]; /*a*/
+}
+
+static struct pipe_buffer *
+setup_vertex_data0(struct exa_context *ctx,
+ int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int width, int height)
+{
+ /* 1st vertex */
+ setup_vertex0(ctx->vertices2[0], dstX, dstY,
+ ctx->solid_color);
+ /* 2nd vertex */
+ setup_vertex0(ctx->vertices2[1], dstX + width, dstY,
+ ctx->solid_color);
+ /* 3rd vertex */
+ setup_vertex0(ctx->vertices2[2], dstX + width, dstY + height,
+ ctx->solid_color);
+ /* 4th vertex */
+ setup_vertex0(ctx->vertices2[3], dstX, dstY + height,
+ ctx->solid_color);
+
+ return pipe_user_buffer_create(ctx->pipe->screen,
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
+}
+
+static INLINE void
+setup_vertex1(float vertex[2][4], float x, float y, float s, float t)
+{
+ vertex[0][0] = x;
+ vertex[0][1] = y;
+ vertex[0][2] = 0.f; /*z*/
+ vertex[0][3] = 1.f; /*w*/
+
+ vertex[1][0] = s; /*s*/
+ vertex[1][1] = t; /*t*/
+ vertex[1][2] = 0.f; /*r*/
+ vertex[1][3] = 1.f; /*q*/
+}
+
+static struct pipe_buffer *
+setup_vertex_data1(struct exa_context *ctx,
+ int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int width, int height)
+{
+ float s0, t0, s1, t1;
+ struct pipe_texture *src = ctx->bound_textures[0];
+
+ s0 = srcX / src->width[0];
+ s1 = srcX + width / src->width[0];
+ t0 = srcY / src->height[0];
+ t1 = srcY + height / src->height[0];
+
+ /* 1st vertex */
+ setup_vertex1(ctx->vertices2[0], dstX, dstY,
+ s0, t0);
+ /* 2nd vertex */
+ setup_vertex1(ctx->vertices2[1], dstX + width, dstY,
+ s1, t0);
+ /* 3rd vertex */
+ setup_vertex1(ctx->vertices2[2], dstX + width, dstY + height,
+ s1, t1);
+ /* 4th vertex */
+ setup_vertex1(ctx->vertices2[3], dstX, dstY + height,
+ s0, t1);
+
+ return pipe_user_buffer_create(ctx->pipe->screen,
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
+}
+
+static struct pipe_buffer *
+setup_vertex_data_tex(struct exa_context *ctx,
+ float x0, float y0, float x1, float y1,
+ float s0, float t0, float s1, float t1,
+ float z)
+{
+ /* 1st vertex */
+ setup_vertex1(ctx->vertices2[0], x0, y0,
+ s0, t0);
+ /* 2nd vertex */
+ setup_vertex1(ctx->vertices2[1], x1, y0,
+ s1, t0);
+ /* 3rd vertex */
+ setup_vertex1(ctx->vertices2[2], x1, y1,
+ s1, t1);
+ /* 4th vertex */
+ setup_vertex1(ctx->vertices2[3], x0, y1,
+ s0, t1);
+
+ return pipe_user_buffer_create(ctx->pipe->screen,
+ ctx->vertices2,
+ sizeof(ctx->vertices2));
+}
+
+
+
+static INLINE void
+setup_vertex2(float vertex[3][4], float x, float y,
+ float s0, float t0, float s1, float t1)
+{
+ vertex[0][0] = x;
+ vertex[0][1] = y;
+ vertex[0][2] = 0.f; /*z*/
+ vertex[0][3] = 1.f; /*w*/
+
+ vertex[1][0] = s0; /*s*/
+ vertex[1][1] = t0; /*t*/
+ vertex[1][2] = 0.f; /*r*/
+ vertex[1][3] = 1.f; /*q*/
+
+ vertex[2][0] = s1; /*s*/
+ vertex[2][1] = t1; /*t*/
+ vertex[2][2] = 0.f; /*r*/
+ vertex[2][3] = 1.f; /*q*/
+}
+
+static struct pipe_buffer *
+setup_vertex_data2(struct exa_context *ctx,
+ int srcX, int srcY, int maskX, int maskY,
+ int dstX, int dstY, int width, int height)
+{
+ float st0[4], st1[4];
+ struct pipe_texture *src = ctx->bound_textures[0];
+ struct pipe_texture *mask = ctx->bound_textures[0];
+
+ st0[0] = srcX / src->width[0];
+ st0[1] = srcY / src->height[0];
+ st0[2] = srcX + width / src->width[0];
+ st0[3] = srcY + height / src->height[0];
+
+ st1[0] = maskX / mask->width[0];
+ st1[1] = maskY / mask->height[0];
+ st1[2] = maskX + width / mask->width[0];
+ st1[3] = maskY + height / mask->height[0];
+
+ /* 1st vertex */
+ setup_vertex2(ctx->vertices3[0], dstX, dstY,
+ st0[0], st0[1], st1[0], st1[1]);
+ /* 2nd vertex */
+ setup_vertex2(ctx->vertices3[1], dstX + width, dstY,
+ st0[2], st0[1], st1[2], st1[1]);
+ /* 3rd vertex */
+ setup_vertex2(ctx->vertices3[2], dstX + width, dstY + height,
+ st0[2], st0[3], st1[2], st1[3]);
+ /* 4th vertex */
+ setup_vertex2(ctx->vertices3[3], dstX, dstY + height,
+ st0[0], st0[3], st1[0], st1[3]);
+
+ return pipe_user_buffer_create(ctx->pipe->screen,
+ ctx->vertices3,
+ sizeof(ctx->vertices3));
+}
boolean xorg_composite_accelerated(int op,
PicturePtr pSrcPicture,
PicturePtr pMaskPicture,
PicturePtr pDstPicture)
{
+ unsigned i;
+ 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)
+ return FALSE;
+ /* fills not supported */
+ if (pSrcPicture->pSourcePict)
+ return FALSE;
+ }
+
+ for (i = 0; i < accel_ops_count; ++i) {
+ if (op == accelerated_ops[i].op) {
+ if (pMaskPicture && !accelerated_ops[i].with_mask)
+ return FALSE;
+ return TRUE;
+ }
+ }
return FALSE;
}
+static void
+bind_clip_state(struct exa_context *exa)
+{
+}
+
+static void
+bind_framebuffer_state(struct exa_context *exa, struct exa_pixmap_priv *pDst)
+{
+ unsigned i;
+ struct pipe_framebuffer_state state;
+ struct pipe_surface *surface = exa_gpu_surface(exa, pDst);
+ memset(&state, 0, sizeof(struct pipe_framebuffer_state));
+
+ state.width = pDst->tex->width[0];
+ state.height = pDst->tex->height[0];
+
+ state.nr_cbufs = 1;
+ state.cbufs[0] = surface;
+ for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
+ state.cbufs[i] = 0;
+
+ /* currently we don't use depth/stencil */
+ 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 {
+ Y0_BOTTOM,
+ Y0_TOP
+};
+
+static void
+set_viewport(struct exa_context *exa, int width, int height,
+ enum AxisOrientation orientation)
+{
+ struct pipe_viewport_state viewport;
+ float y_scale = (orientation == Y0_BOTTOM) ? -2.f : 2.f;
+
+ viewport.scale[0] = width / 2.f;
+ viewport.scale[1] = height / y_scale;
+ viewport.scale[2] = 1.0;
+ viewport.scale[3] = 1.0;
+ viewport.translate[0] = width / 2.f;
+ viewport.translate[1] = height / 2.f;
+ viewport.translate[2] = 0.0;
+ viewport.translate[3] = 0.0;
+
+ cso_set_viewport(exa->cso, &viewport);
+}
+
+static void
+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);
+
+ set_viewport(exa, width, height, Y0_TOP);
+}
+
+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));
+ blend.blend_enable = 1;
+ blend.colormask |= PIPE_MASK_R;
+ blend.colormask |= PIPE_MASK_G;
+ blend.colormask |= PIPE_MASK_B;
+ blend.colormask |= PIPE_MASK_A;
+
+ blend.rgb_src_factor = blend_opt.rgb_src_factor;
+ blend.alpha_src_factor = blend_opt.alpha_src_factor;
+ blend.rgb_dst_factor = blend_opt.rgb_dst_factor;
+ blend.alpha_dst_factor = blend_opt.alpha_dst_factor;
+
+ cso_set_blend(exa->cso, &blend);
+}
+
+static void
+bind_rasterizer_state(struct exa_context *exa)
+{
+ struct pipe_rasterizer_state raster;
+ memset(&raster, 0, sizeof(struct pipe_rasterizer_state));
+ raster.gl_rasterization_rules = 1;
+ cso_set_rasterizer(exa->cso, &raster);
+}
+
+static void
+bind_shaders(struct exa_context *exa, int op,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture)
+{
+ unsigned vs_traits = 0, fs_traits = 0;
+ struct xorg_shader shader;
+
+ exa->has_solid_color = FALSE;
+
+ if (pSrcPicture) {
+ if (pSrcPicture->pSourcePict) {
+ 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);
+ exa->has_solid_color = TRUE;
+ } else {
+ debug_assert("!gradients not supported");
+ }
+ } else {
+ fs_traits |= FS_COMPOSITE;
+ vs_traits |= VS_COMPOSITE;
+ }
+ }
+
+ if (pMaskPicture) {
+ vs_traits |= VS_MASK;
+ fs_traits |= FS_MASK;
+ }
+
+ shader = xorg_shaders_get(exa->shaders, vs_traits, fs_traits);
+ cso_set_vertex_shader_handle(exa->cso, shader.vs);
+ cso_set_fragment_shader_handle(exa->cso, shader.fs);
+}
+
+
+static void
+bind_samplers(struct exa_context *exa, int op,
+ PicturePtr pSrcPicture, PicturePtr pMaskPicture,
+ PicturePtr pDstPicture,
+ struct exa_pixmap_priv *pSrc,
+ struct exa_pixmap_priv *pMask,
+ struct exa_pixmap_priv *pDst)
+{
+ struct pipe_sampler_state *samplers[PIPE_MAX_SAMPLERS];
+ struct pipe_sampler_state src_sampler, mask_sampler;
+
+ exa->num_bound_samplers = 0;
+
+ memset(&src_sampler, 0, sizeof(struct pipe_sampler_state));
+ memset(&mask_sampler, 0, sizeof(struct pipe_sampler_state));
+
+ if (pSrcPicture && pSrc) {
+ unsigned src_wrap = render_repeat_to_gallium(
+ pSrcPicture->repeatType);
+ src_sampler.wrap_s = src_wrap;
+ src_sampler.wrap_t = src_wrap;
+ src_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ src_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ src_sampler.normalized_coords = 1;
+ samplers[0] = &src_sampler;
+ exa->bound_textures[0] = pSrc->tex;
+ ++exa->num_bound_samplers;
+ }
+
+ if (pMaskPicture && pMask) {
+ unsigned mask_wrap = render_repeat_to_gallium(
+ pMaskPicture->repeatType);
+ mask_sampler.wrap_s = mask_wrap;
+ mask_sampler.wrap_t = mask_wrap;
+ mask_sampler.min_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ mask_sampler.mag_img_filter = PIPE_TEX_MIPFILTER_NEAREST;
+ mask_sampler.normalized_coords = 1;
+ samplers[1] = &mask_sampler;
+ exa->bound_textures[1] = pMask->tex;
+ ++exa->num_bound_samplers;
+ }
+
+ cso_set_samplers(exa->cso, exa->num_bound_samplers,
+ (const struct pipe_sampler_state **)samplers);
+ cso_set_sampler_textures(exa->cso, exa->num_bound_samplers,
+ exa->bound_textures);
+}
+
+static void
+setup_vs_constant_buffer(struct exa_context *exa,
+ int width, int height)
+{
+ const int param_bytes = 8 * sizeof(float);
+ float vs_consts[8] = {
+ 2.f/width, 2.f/height, 1, 1,
+ -1, -1, 0, 0
+ };
+ struct pipe_constant_buffer *cbuf = &exa->vs_const_buffer;
+
+ pipe_buffer_reference(&cbuf->buffer, NULL);
+ cbuf->buffer = pipe_buffer_create(exa->pipe->screen, 16,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
+
+ if (cbuf->buffer) {
+ pipe_buffer_write(exa->pipe->screen, cbuf->buffer,
+ 0, param_bytes, vs_consts);
+ }
+ exa->pipe->set_constant_buffer(exa->pipe, PIPE_SHADER_VERTEX, 0, cbuf);
+}
+
+
+static void
+setup_fs_constant_buffer(struct exa_context *exa)
+{
+ const int param_bytes = 4 * sizeof(float);
+ float fs_consts[8] = {
+ 0, 0, 0, 1,
+ };
+ struct pipe_constant_buffer *cbuf = &exa->fs_const_buffer;
+
+ pipe_buffer_reference(&cbuf->buffer, NULL);
+ cbuf->buffer = pipe_buffer_create(exa->pipe->screen, 16,
+ PIPE_BUFFER_USAGE_CONSTANT,
+ param_bytes);
+
+ if (cbuf->buffer) {
+ pipe_buffer_write(exa->pipe->screen, cbuf->buffer,
+ 0, param_bytes, fs_consts);
+ }
+ exa->pipe->set_constant_buffer(exa->pipe, PIPE_SHADER_FRAGMENT, 0, cbuf);
+}
+
+static void
+setup_constant_buffers(struct exa_context *exa, struct exa_pixmap_priv *pDst)
+{
+ int width = pDst->tex->width[0];
+ int height = pDst->tex->height[0];
+
+ setup_vs_constant_buffer(exa, width, height);
+ setup_fs_constant_buffer(exa);
+}
+
boolean xorg_composite_bind_state(struct exa_context *exa,
int op,
PicturePtr pSrcPicture,
PicturePtr pMaskPicture,
- PicturePtr pDstPicture)
+ PicturePtr pDstPicture,
+ struct exa_pixmap_priv *pSrc,
+ struct exa_pixmap_priv *pMask,
+ struct exa_pixmap_priv *pDst)
{
+ bind_framebuffer_state(exa, pDst);
+ bind_viewport_state(exa, pDst);
+ bind_blend_state(exa, op, pSrcPicture, pMaskPicture);
+ bind_rasterizer_state(exa);
+ bind_shaders(exa, op, pSrcPicture, pMaskPicture);
+ bind_samplers(exa, op, pSrcPicture, pMaskPicture,
+ pDstPicture, pSrc, pMask, pDst);
+ bind_clip_state(exa);
+ setup_constant_buffers(exa, pDst);
+
return FALSE;
}
@@ -23,5 +599,479 @@ void xorg_composite(struct exa_context *exa,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height)
{
+ struct pipe_context *pipe = exa->pipe;
+ struct pipe_buffer *buf = 0;
+
+ if (exa->num_bound_samplers == 0 ) { /* solid fill */
+ buf = setup_vertex_data0(exa,
+ srcX, srcY, maskX, maskY,
+ dstX, dstY, width, height);
+ } else if (exa->num_bound_samplers == 1 ) /* src */
+ buf = setup_vertex_data1(exa,
+ srcX, srcY, maskX, maskY,
+ dstX, dstY, width, height);
+ else if (exa->num_bound_samplers == 2) /* src + mask */
+ buf = setup_vertex_data2(exa,
+ srcX, srcY, maskX, maskY,
+ dstX, dstY, width, height);
+ else if (exa->num_bound_samplers == 3) { /* src + mask + dst */
+ debug_assert(!"src/mask/dst not handled right now");
+#if 0
+ buf = setup_vertex_data2(exa,
+ srcX, srcY, maskX, maskY,
+ dstX, dstY, width, height);
+#endif
+ }
+
+ if (buf) {
+ int num_attribs = 1; /*pos*/
+ num_attribs += exa->num_bound_samplers;
+ if (exa->has_solid_color)
+ ++num_attribs;
+
+ util_draw_vertex_buffer(pipe, buf, 0,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ num_attribs); /* attribs/vert */
+
+ pipe_buffer_reference(&buf, NULL);
+ }
+}
+
+boolean xorg_solid_bind_state(struct exa_context *exa,
+ struct exa_pixmap_priv *pixmap,
+ Pixel fg)
+{
+ unsigned vs_traits, fs_traits;
+ struct xorg_shader shader;
+
+ pixel_to_float4(fg, exa->solid_color);
+ exa->has_solid_color = TRUE;
+
+ 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]);
+#endif
+
+ vs_traits = VS_SOLID_FILL;
+ fs_traits = FS_SOLID_FILL;
+
+ bind_framebuffer_state(exa, pixmap);
+ bind_viewport_state(exa, pixmap);
+ bind_rasterizer_state(exa);
+ bind_blend_state(exa, PictOpSrc, NULL, NULL);
+ setup_constant_buffers(exa, pixmap);
+ bind_clip_state(exa);
+
+ shader = xorg_shaders_get(exa->shaders, vs_traits, fs_traits);
+ cso_set_vertex_shader_handle(exa->cso, shader.vs);
+ cso_set_fragment_shader_handle(exa->cso, shader.fs);
+
+ return FALSE;
+}
+
+void xorg_solid(struct exa_context *exa,
+ struct exa_pixmap_priv *pixmap,
+ int x0, int y0, int x1, int y1)
+{
+ struct pipe_context *pipe = exa->pipe;
+ struct pipe_buffer *buf = 0;
+
+ /* 1st vertex */
+ setup_vertex0(exa->vertices2[0], x0, y0,
+ exa->solid_color);
+ /* 2nd vertex */
+ setup_vertex0(exa->vertices2[1], x1, y0,
+ exa->solid_color);
+ /* 3rd vertex */
+ setup_vertex0(exa->vertices2[2], x1, y1,
+ exa->solid_color);
+ /* 4th vertex */
+ setup_vertex0(exa->vertices2[3], x0, y1,
+ exa->solid_color);
+
+ buf = pipe_user_buffer_create(exa->pipe->screen,
+ 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 */
+ 2); /* attribs/vert */
+
+ pipe_buffer_reference(&buf, NULL);
+ }
+}
+
+
+static INLINE void shift_rectx(float coords[4],
+ const float *bounds,
+ const float shift)
+{
+ coords[0] += shift;
+ coords[2] -= shift;
+ if (bounds) {
+ coords[2] = MIN2(coords[2], bounds[2]);
+ /* bound x/y + width/height */
+ if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
+ coords[2] = (bounds[0] + bounds[2]) - coords[0];
+ }
+ }
+}
+
+static INLINE void shift_recty(float coords[4],
+ const float *bounds,
+ const float shift)
+{
+ coords[1] += shift;
+ coords[3] -= shift;
+ if (bounds) {
+ coords[3] = MIN2(coords[3], bounds[3]);
+ if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
+ coords[3] = (bounds[1] + bounds[3]) - coords[1];
+ }
+ }
+}
+
+static INLINE void bound_rect(float coords[4],
+ const float bounds[4],
+ float shift[4])
+{
+ /* if outside the bounds */
+ if (coords[0] > (bounds[0] + bounds[2]) ||
+ coords[1] > (bounds[1] + bounds[3]) ||
+ (coords[0] + coords[2]) < bounds[0] ||
+ (coords[1] + coords[3]) < bounds[1]) {
+ coords[0] = 0.f;
+ coords[1] = 0.f;
+ coords[2] = 0.f;
+ coords[3] = 0.f;
+ shift[0] = 0.f;
+ shift[1] = 0.f;
+ return;
+ }
+
+ /* bound x */
+ if (coords[0] < bounds[0]) {
+ shift[0] = bounds[0] - coords[0];
+ coords[2] -= shift[0];
+ coords[0] = bounds[0];
+ } else
+ shift[0] = 0.f;
+
+ /* bound y */
+ if (coords[1] < bounds[1]) {
+ shift[1] = bounds[1] - coords[1];
+ coords[3] -= shift[1];
+ coords[1] = bounds[1];
+ } else
+ shift[1] = 0.f;
+
+ shift[2] = bounds[2] - coords[2];
+ shift[3] = bounds[3] - coords[3];
+ /* bound width/height */
+ coords[2] = MIN2(coords[2], bounds[2]);
+ coords[3] = MIN2(coords[3], bounds[3]);
+
+ /* bound x/y + width/height */
+ if ((coords[0] + coords[2]) > (bounds[0] + bounds[2])) {
+ coords[2] = (bounds[0] + bounds[2]) - coords[0];
+ }
+ if ((coords[1] + coords[3]) > (bounds[1] + bounds[3])) {
+ coords[3] = (bounds[1] + bounds[3]) - coords[1];
+ }
+
+ /* if outside the bounds */
+ if ((coords[0] + coords[2]) < bounds[0] ||
+ (coords[1] + coords[3]) < bounds[1]) {
+ coords[0] = 0.f;
+ coords[1] = 0.f;
+ coords[2] = 0.f;
+ coords[3] = 0.f;
+ return;
+ }
+}
+
+static INLINE void sync_size(float *src_loc, float *dst_loc)
+{
+ src_loc[2] = MIN2(src_loc[2], dst_loc[2]);
+ src_loc[3] = MIN2(src_loc[3], dst_loc[3]);
+ dst_loc[2] = src_loc[2];
+ dst_loc[3] = src_loc[3];
+}
+
+
+static void renderer_copy_texture(struct exa_context *exa,
+ struct pipe_texture *src,
+ float sx1, float sy1,
+ float sx2, float sy2,
+ struct pipe_texture *dst,
+ float dx1, float dy1,
+ float dx2, float dy2)
+{
+ struct pipe_context *pipe = exa->pipe;
+ struct pipe_screen *screen = pipe->screen;
+ struct pipe_buffer *buf;
+ struct pipe_surface *dst_surf = screen->get_tex_surface(
+ screen, dst, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+ struct pipe_framebuffer_state fb;
+ float s0, t0, s1, t1;
+ struct xorg_shader shader;
+
+ assert(src->width[0] != 0);
+ assert(src->height[0] != 0);
+ assert(dst->width[0] != 0);
+ assert(dst->height[0] != 0);
+
+#if 1
+ s0 = sx1 / src->width[0];
+ s1 = sx2 / src->width[0];
+ t0 = sy1 / src->height[0];
+ t1 = sy2 / src->height[0];
+#else
+ s0 = 0;
+ s1 = 1;
+ t0 = 0;
+ t1 = 1;
+#endif
+
+#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);
+ cso_save_samplers(exa->cso);
+ cso_save_sampler_textures(exa->cso);
+ cso_save_framebuffer(exa->cso);
+ cso_save_fragment_shader(exa->cso);
+ cso_save_vertex_shader(exa->cso);
+
+ cso_save_viewport(exa->cso);
+
+
+ /* set misc state we care about */
+ {
+ struct pipe_blend_state blend;
+ memset(&blend, 0, sizeof(blend));
+ blend.rgb_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.alpha_src_factor = PIPE_BLENDFACTOR_ONE;
+ blend.rgb_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.alpha_dst_factor = PIPE_BLENDFACTOR_ZERO;
+ blend.colormask = PIPE_MASK_RGBA;
+ cso_set_blend(exa->cso, &blend);
+ }
+
+ /* sampler */
+ {
+ struct pipe_sampler_state sampler;
+ memset(&sampler, 0, sizeof(sampler));
+ sampler.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE;
+ sampler.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+ sampler.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+ sampler.normalized_coords = 1;
+ cso_single_sampler(exa->cso, 0, &sampler);
+ cso_single_sampler_done(exa->cso);
+ }
+
+ set_viewport(exa, dst_surf->width, dst_surf->height, Y0_TOP);
+
+ /* texture */
+ cso_set_sampler_textures(exa->cso, 1, &src);
+
+ /* shaders */
+ shader = xorg_shaders_get(exa->shaders,
+ VS_COMPOSITE,
+ FS_COMPOSITE);
+ cso_set_vertex_shader_handle(exa->cso, shader.vs);
+ cso_set_fragment_shader_handle(exa->cso, shader.fs);
+
+ /* drawing dest */
+ memset(&fb, 0, sizeof(fb));
+ fb.width = dst_surf->width;
+ fb.height = dst_surf->height;
+ fb.nr_cbufs = 1;
+ fb.cbufs[0] = dst_surf;
+ {
+ int i;
+ for (i = 1; i < PIPE_MAX_COLOR_BUFS; ++i)
+ 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,
+ dx1, dy1,
+ dx2, dy2,
+ s0, t0, s1, t1,
+ 0.0f);
+
+ if (buf) {
+ util_draw_vertex_buffer(exa->pipe, buf, 0,
+ PIPE_PRIM_TRIANGLE_FAN,
+ 4, /* verts */
+ 2); /* attribs/vert */
+
+ pipe_buffer_reference(&buf, NULL);
+ }
+
+ /* restore state we changed */
+ cso_restore_blend(exa->cso);
+ cso_restore_samplers(exa->cso);
+ cso_restore_sampler_textures(exa->cso);
+ cso_restore_framebuffer(exa->cso);
+ cso_restore_vertex_shader(exa->cso);
+ cso_restore_fragment_shader(exa->cso);
+ cso_restore_viewport(exa->cso);
+
+ 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,
+ int width, int height)
+{
+ float dst_loc[4], src_loc[4];
+ float dst_bounds[4], src_bounds[4];
+ float src_shift[4], dst_shift[4], shift[4];
+ struct pipe_texture *dst = dst_priv->tex;
+ struct pipe_texture *src = src_priv->tex;
+
+ xorg_exa_finish(ctx);
+
+ dst_loc[0] = dx;
+ dst_loc[1] = dy;
+ dst_loc[2] = width;
+ dst_loc[3] = height;
+ dst_bounds[0] = 0.f;
+ dst_bounds[1] = 0.f;
+ dst_bounds[2] = dst->width[0];
+ dst_bounds[3] = dst->height[0];
+
+ src_loc[0] = sx;
+ src_loc[1] = sy;
+ src_loc[2] = width;
+ src_loc[3] = height;
+ src_bounds[0] = 0.f;
+ src_bounds[1] = 0.f;
+ src_bounds[2] = src->width[0];
+ src_bounds[3] = src->height[0];
+
+ bound_rect(src_loc, src_bounds, src_shift);
+ bound_rect(dst_loc, dst_bounds, dst_shift);
+ shift[0] = src_shift[0] - dst_shift[0];
+ shift[1] = src_shift[1] - dst_shift[1];
+
+ if (shift[0] < 0)
+ shift_rectx(src_loc, src_bounds, -shift[0]);
+ else
+ shift_rectx(dst_loc, dst_bounds, shift[0]);
+
+ if (shift[1] < 0)
+ shift_recty(src_loc, src_bounds, -shift[1]);
+ else
+ shift_recty(dst_loc, dst_bounds, shift[1]);
+
+ sync_size(src_loc, dst_loc);
+
+ 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,
+ temp_src,
+ src_loc[0],
+ src_loc[1],
+ src_loc[0] + src_loc[2],
+ src_loc[1] + src_loc[3],
+ dst,
+ dst_loc[0],
+ dst_loc[1],
+ dst_loc[0] + dst_loc[2],
+ dst_loc[1] + dst_loc[3]);
+
+ if (src == dst)
+ pipe_texture_reference(&temp_src, NULL);
+ }
}
diff --git a/src/gallium/state_trackers/xorg/xorg_composite.h b/src/gallium/state_trackers/xorg/xorg_composite.h
index a52e0e6dff..e73f1c704a 100644
--- a/src/gallium/state_trackers/xorg/xorg_composite.h
+++ b/src/gallium/state_trackers/xorg/xorg_composite.h
@@ -12,11 +12,26 @@ boolean xorg_composite_bind_state(struct exa_context *exa,
int op,
PicturePtr pSrcPicture,
PicturePtr pMaskPicture,
- PicturePtr pDstPicture);
+ PicturePtr pDstPicture,
+ struct exa_pixmap_priv *pSrc,
+ struct exa_pixmap_priv *pMask,
+ struct exa_pixmap_priv *pDst);
void xorg_composite(struct exa_context *exa,
struct exa_pixmap_priv *dst,
int srcX, int srcY, int maskX, int maskY,
int dstX, int dstY, int width, int height);
+boolean xorg_solid_bind_state(struct exa_context *exa,
+ struct exa_pixmap_priv *pixmap,
+ Pixel fg);
+void xorg_solid(struct exa_context *exa,
+ struct exa_pixmap_priv *pixmap,
+ int x0, int y0, int x1, int y1);
+
+void xorg_copy_pixmap(struct exa_context *ctx,
+ struct exa_pixmap_priv *dst, int dx, int dy,
+ struct exa_pixmap_priv *src, int sx, int sy,
+ int width, int height);
+
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 2235961b03..67fe29a69d 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -42,17 +42,22 @@
#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"
struct crtc_private
{
drmModeCrtcPtr drm_crtc;
/* hwcursor */
- struct pipe_buffer *cursor_buf;
+ struct pipe_texture *cursor_tex;
unsigned cursor_handle;
};
@@ -173,8 +178,8 @@ crtc_destroy(xf86CrtcPtr crtc)
{
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_buf)
- pipe_buffer_reference(&crtcp->cursor_buf, NULL);
+ if (crtcp->cursor_tex)
+ pipe_texture_reference(&crtcp->cursor_tex, NULL);
drmModeFreeCrtc(crtcp->drm_crtc);
xfree(crtcp);
@@ -186,25 +191,42 @@ crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 * image)
unsigned char *ptr;
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
-
- if (!crtcp->cursor_buf) {
- crtcp->cursor_buf = pipe_buffer_create(ms->screen,
- 0,
- PIPE_BUFFER_USAGE_CPU_WRITE |
- PIPE_BUFFER_USAGE_GPU_READ,
- 64*64*4);
- ms->api->handle_from_buffer(ms->api,
- ms->screen,
- crtcp->cursor_buf,
- &crtcp->cursor_handle);
+ struct pipe_transfer *transfer;
+
+ if (!crtcp->cursor_tex) {
+ struct pipe_texture templat;
+ unsigned pitch;
+
+ memset(&templat, 0, sizeof(templat));
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ templat.tex_usage |= PIPE_TEXTURE_USAGE_PRIMARY;
+ templat.target = PIPE_TEXTURE_2D;
+ templat.last_level = 0;
+ templat.depth[0] = 1;
+ templat.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ templat.width[0] = 64;
+ templat.height[0] = 64;
+ pf_get_block(templat.format, &templat.block);
+
+ crtcp->cursor_tex = ms->screen->texture_create(ms->screen,
+ &templat);
+ ms->api->local_handle_from_texture(ms->api,
+ ms->screen,
+ crtcp->cursor_tex,
+ &pitch,
+ &crtcp->cursor_handle);
}
- ptr = pipe_buffer_map(ms->screen, crtcp->cursor_buf, PIPE_BUFFER_USAGE_CPU_WRITE);
-
- if (ptr)
- memcpy(ptr, image, 64 * 64 * 4);
-
- pipe_buffer_unmap(ms->screen, crtcp->cursor_buf);
+ transfer = ms->screen->get_tex_transfer(ms->screen, crtcp->cursor_tex,
+ 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, 64, 64);
+ ptr = ms->screen->transfer_map(ms->screen, transfer);
+ util_copy_rect(ptr, &crtcp->cursor_tex->block,
+ transfer->stride, 0, 0,
+ 64, 64, (void*)image, 64 * 4, 0, 0);
+ ms->screen->transfer_unmap(ms->screen, transfer);
+ ms->screen->tex_transfer_destroy(transfer);
}
static void
@@ -222,7 +244,7 @@ crtc_show_cursor(xf86CrtcPtr crtc)
modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_buf)
+ if (crtcp->cursor_tex)
drmModeSetCursor(ms->fd, crtcp->drm_crtc->crtc_id,
crtcp->cursor_handle, 64, 64);
}
@@ -260,13 +282,12 @@ static const xf86CrtcFuncsRec crtc_funcs = {
};
void
-cursor_destroy(xf86CrtcPtr crtc)
+crtc_cursor_destroy(xf86CrtcPtr crtc)
{
- modesettingPtr ms = modesettingPTR(crtc->scrn);
struct crtc_private *crtcp = crtc->driver_private;
- if (crtcp->cursor_buf) {
- pipe_buffer_reference(&crtcp->cursor_buf, NULL);
+ if (crtcp->cursor_tex) {
+ pipe_texture_reference(&crtcp->cursor_tex, NULL);
}
}
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index ae3338ffef..8a362596c7 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -33,97 +33,194 @@
#include "xf86_OSproc.h"
#include "xorg_tracker.h"
+#include "xorg_exa.h"
#include "dri2.h"
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "util/u_rect.h"
+
typedef struct {
PixmapPtr pPixmap;
struct pipe_texture *tex;
- struct pipe_buffer *buf;
+ struct pipe_fence_handle *fence;
} *BufferPrivatePtr;
-static DRI2BufferPtr
-driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
+static Bool
+driDoCreateBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int format)
{
- struct pipe_texture *depth, *tex;
- struct pipe_buffer *buf;
+ struct pipe_texture *tex = NULL;
ScreenPtr pScreen = pDraw->pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
- BufferPrivatePtr privates;
- DRI2BufferPtr buffers;
+ struct exa_pixmap_priv *exa_priv;
+ BufferPrivatePtr private = buffer->driverPrivate;
PixmapPtr pPixmap;
unsigned stride, handle;
- int i;
-
- buffers = xcalloc(count, sizeof *buffers);
- if (!buffers)
- goto fail_buffers;
- privates = xcalloc(count, sizeof *privates);
- if (!privates)
- goto fail_privates;
+ if (pDraw->type == DRAWABLE_PIXMAP)
+ pPixmap = (PixmapPtr) pDraw;
+ else
+ pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
+ exa_priv = exaGetPixmapDriverPrivate(pPixmap);
- depth = NULL;
- for (i = 0; i < count; i++) {
- pPixmap = NULL;
- tex = NULL;
- buf = NULL;
- if (attachments[i] == DRI2BufferFrontLeft) {
- if (pDraw->type == DRAWABLE_PIXMAP)
- pPixmap = (PixmapPtr) pDraw;
- else
- pPixmap = (*pScreen->GetWindowPixmap)((WindowPtr) pDraw);
- pPixmap->refcnt++;
- tex = xorg_exa_get_texture(pPixmap);
- } else if (attachments[i] == DRI2BufferStencil) {
- pipe_texture_reference(&tex, depth);
- } else if (attachments[i] == DRI2BufferDepth) {
- struct pipe_texture template;
-
- memset(&template, 0, sizeof(template));
- template.target = PIPE_TEXTURE_2D;
- template.format = PIPE_FORMAT_S8Z24_UNORM;
- pf_get_block(template.format, &template.block);
- template.width[0] = pDraw->width;
- template.height[0] = pDraw->height;
- template.depth[0] = 1;
- template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- tex = ms->screen->texture_create(ms->screen, &template);
- } else {
+ switch (buffer->attachment) {
+ default:
+ if (buffer->attachment != DRI2BufferFakeFrontLeft ||
+ pDraw->type != DRAWABLE_PIXMAP) {
+ private->pPixmap = (*pScreen->CreatePixmap)(pScreen, pDraw->width,
+ pDraw->height,
+ pDraw->depth,
+ 0);
+ }
+ break;
+ case DRI2BufferFrontLeft:
+ break;
+ case DRI2BufferStencil:
+#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+ case DRI2BufferDepthStencil:
+ if (exa_priv->depth_stencil_tex &&
+ !pf_is_depth_stencil(exa_priv->depth_stencil_tex->format))
+ exa_priv->depth_stencil_tex = NULL;
+ /* Fall through */
+#endif
+ case DRI2BufferDepth:
+ if (exa_priv->depth_stencil_tex)
+ pipe_texture_reference(&tex, exa_priv->depth_stencil_tex);
+ else {
struct pipe_texture template;
memset(&template, 0, sizeof(template));
template.target = PIPE_TEXTURE_2D;
- template.format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ if (buffer->attachment == DRI2BufferDepth)
+ template.format = ms->ds_depth_bits_last ?
+ PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM;
+ else
+ template.format = ms->ds_depth_bits_last ?
+ PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM;
pf_get_block(template.format, &template.block);
template.width[0] = pDraw->width;
template.height[0] = pDraw->height;
template.depth[0] = 1;
template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
+ template.tex_usage = PIPE_TEXTURE_USAGE_DEPTH_STENCIL |
+ PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
tex = ms->screen->texture_create(ms->screen, &template);
+ pipe_texture_reference(&exa_priv->depth_stencil_tex, tex);
}
+ break;
+ }
+
+ if (!private->pPixmap) {
+ private->pPixmap = pPixmap;
+ pPixmap->refcnt++;
+ }
+
+ if (!tex) {
+ exaMoveInPixmap(private->pPixmap);
+ xorg_exa_set_shared_usage(private->pPixmap);
+ pScreen->ModifyPixmapHeader(private->pPixmap, 0, 0, 0, 0, 0, NULL);
+ tex = xorg_exa_get_texture(private->pPixmap);
+ }
+
+ if (!tex)
+ FatalError("NO TEXTURE IN DRI2\n");
+
+ ms->api->shared_handle_from_texture(ms->api, ms->screen, tex, &stride, &handle);
+
+ buffer->name = handle;
+ buffer->pitch = stride;
+ buffer->cpp = 4;
+ buffer->driverPrivate = private;
+ buffer->flags = 0; /* not tiled */
+ private->tex = tex;
+
+ return TRUE;
+}
+
+static void
+driDoDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ BufferPrivatePtr private = buffer->driverPrivate;
+ struct exa_pixmap_priv *exa_priv = exaGetPixmapDriverPrivate(private->pPixmap);
+
+ pipe_texture_reference(&private->tex, NULL);
+ ms->screen->fence_reference(ms->screen, &private->fence, NULL);
+ pipe_texture_reference(&exa_priv->depth_stencil_tex, NULL);
+ (*pScreen->DestroyPixmap)(private->pPixmap);
+}
+
+#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+
+static DRI2BufferPtr
+driCreateBuffer(DrawablePtr pDraw, unsigned int attachment, unsigned int format)
+{
+ DRI2BufferPtr buffer;
+ BufferPrivatePtr private;
+
+ buffer = xcalloc(1, sizeof *buffer);
+ if (!buffer)
+ return NULL;
+
+ private = xcalloc(1, sizeof *private);
+ if (!private) {
+ goto fail;
+ }
+
+ buffer->attachment = attachment;
+ buffer->driverPrivate = private;
+
+ if (driDoCreateBuffer(pDraw, buffer, format))
+ return buffer;
+
+ xfree(private);
+fail:
+ xfree(buffer);
+ return NULL;
+}
+
+static void
+driDestroyBuffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
+{
+ driDoDestroyBuffer(pDraw, buffer);
+
+ xfree(buffer->driverPrivate);
+ xfree(buffer);
+}
- ms->api->buffer_from_texture(ms->api, tex, &buf, &stride);
- ms->api->global_handle_from_buffer(ms->api, ms->screen, buf, &handle);
+#else /* DRI2INFOREC_VERSION <= 2 */
- buffers[i].name = handle;
+static DRI2BufferPtr
+driCreateBuffers(DrawablePtr pDraw, unsigned int *attachments, int count)
+{
+ BufferPrivatePtr privates;
+ DRI2BufferPtr buffers;
+ int i;
+
+ buffers = xcalloc(count, sizeof *buffers);
+ if (!buffers)
+ goto fail_buffers;
+
+ privates = xcalloc(count, sizeof *privates);
+ if (!privates)
+ goto fail_privates;
+
+ for (i = 0; i < count; i++) {
buffers[i].attachment = attachments[i];
- buffers[i].pitch = stride;
- buffers[i].cpp = 4;
buffers[i].driverPrivate = &privates[i];
- buffers[i].flags = 0; /* not tiled */
- privates[i].pPixmap = pPixmap;
- privates[i].buf = buf;
- privates[i].tex = tex;
+
+ if (!driDoCreateBuffer(pDraw, &buffers[i], 0))
+ goto fail;
}
return buffers;
+fail:
+ xfree(privates);
fail_privates:
xfree(buffers);
fail_buffers:
@@ -133,20 +230,10 @@ fail_buffers:
static void
driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
{
- ScreenPtr pScreen = pDraw->pScreen;
- ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- BufferPrivatePtr private;
int i;
for (i = 0; i < count; i++) {
- private = buffers[i].driverPrivate;
-
- if (private->pPixmap)
- (*pScreen->DestroyPixmap)(private->pPixmap);
-
- pipe_texture_reference(&private->tex, NULL);
- pipe_buffer_reference(&private->buf, NULL);
+ driDoDestroyBuffer(pDraw, &buffers[i]);
}
if (buffers) {
@@ -155,6 +242,8 @@ driDestroyBuffers(DrawablePtr pDraw, DRI2BufferPtr buffers, int count)
}
}
+#endif /* DRI2INFOREC_VERSION */
+
static void
driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
DRI2BufferPtr pDestBuffer, DRI2BufferPtr pSrcBuffer)
@@ -164,19 +253,83 @@ driCopyRegion(DrawablePtr pDraw, RegionPtr pRegion,
modesettingPtr ms = modesettingPTR(pScrn);
BufferPrivatePtr dst_priv = pDestBuffer->driverPrivate;
BufferPrivatePtr src_priv = pSrcBuffer->driverPrivate;
+ PixmapPtr src_pixmap;
+ PixmapPtr dst_pixmap;
+ GCPtr gc;
+ RegionPtr copy_clip;
+
+ /*
+ * In driCreateBuffers we dewrap windows into the
+ * backing pixmaps in order to get to the texture.
+ * We need to use the real drawable in CopyArea
+ * so that cliprects and offsets are correct.
+ */
+ src_pixmap = src_priv->pPixmap;
+ dst_pixmap = dst_priv->pPixmap;
+ if (pSrcBuffer->attachment == DRI2BufferFrontLeft)
+ src_pixmap = (PixmapPtr)pDraw;
+ if (pDestBuffer->attachment == DRI2BufferFrontLeft)
+ dst_pixmap = (PixmapPtr)pDraw;
+
+ /*
+ * The clients implements glXWaitX with a copy front to fake and then
+ * waiting on the server to signal its completion of it. While
+ * glXWaitGL is a client side flush and a copy from fake to front.
+ * This is how it is done in the DRI2 protocol, how ever depending
+ * which type of drawables the server does things a bit differently
+ * then what the protocol says as the fake and front are the same.
+ *
+ * for pixmaps glXWaitX is a server flush.
+ * for pixmaps glXWaitGL is a client flush.
+ * for windows glXWaitX is a copy from front to fake then a server flush.
+ * for windows glXWaitGL is a client flush then a copy from fake to front.
+ *
+ * XXX in the windows case this code always flushes but that isn't a
+ * must in the glXWaitGL case but we don't know if this is a glXWaitGL
+ * or a glFlush/glFinish call.
+ */
+ if (dst_pixmap == src_pixmap) {
+ /* pixmap glXWaitX */
+ if (pSrcBuffer->attachment == DRI2BufferFrontLeft &&
+ pDestBuffer->attachment == DRI2BufferFakeFrontLeft) {
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS, NULL);
+ return;
+ }
+ /* pixmap glXWaitGL */
+ if (pDestBuffer->attachment == DRI2BufferFrontLeft &&
+ pSrcBuffer->attachment == DRI2BufferFakeFrontLeft) {
+ return;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "copying between the same pixmap\n");
+ }
+ }
- struct pipe_surface *dst_surf =
- ms->screen->get_tex_surface(ms->screen, dst_priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_WRITE);
- struct pipe_surface *src_surf =
- ms->screen->get_tex_surface(ms->screen, src_priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ);
+ gc = GetScratchGC(pDraw->depth, pScreen);
+ copy_clip = REGION_CREATE(pScreen, NULL, 0);
+ REGION_COPY(pScreen, copy_clip, pRegion);
+ (*gc->funcs->ChangeClip) (gc, CT_REGION, copy_clip, 0);
+ ValidateGC(&dst_pixmap->drawable, gc);
- ms->ctx->surface_copy(ms->ctx, dst_surf, 0, 0, src_surf,
- 0, 0, pDraw->width, pDraw->height);
+ /* If this is a full buffer swap, throttle on the previous one */
+ if (dst_priv->fence && REGION_NUM_RECTS(pRegion) == 1) {
+ BoxPtr extents = REGION_EXTENTS(pScreen, pRegion);
- pipe_surface_reference(&dst_surf, NULL);
- pipe_surface_reference(&src_surf, NULL);
+ if (extents->x1 == 0 && extents->y1 == 0 &&
+ extents->x2 == pDraw->width && extents->y2 == pDraw->height) {
+ ms->screen->fence_finish(ms->screen, dst_priv->fence, 0);
+ ms->screen->fence_reference(ms->screen, &dst_priv->fence, NULL);
+ }
+ }
+
+ (*gc->ops->CopyArea)(&src_pixmap->drawable, &dst_pixmap->drawable, gc,
+ 0, 0, pDraw->width, pDraw->height, 0, 0);
+
+ FreeScratchGC(gc);
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_SWAPBUFFERS,
+ pDestBuffer->attachment == DRI2BufferFrontLeft ?
+ &dst_priv->fence : NULL);
}
Bool
@@ -186,18 +339,34 @@ driScreenInit(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
DRI2InfoRec dri2info;
- dri2info.version = 1;
- dri2info.fd = ms->fd;
-#if 0
- dri2info.driverName = pScrn->name;
+#if defined(DRI2INFOREC_VERSION)
+ dri2info.version = DRI2INFOREC_VERSION;
#else
- dri2info.driverName = "i915"; /* FIXME */
+ dri2info.version = 1;
#endif
+ dri2info.fd = ms->fd;
+
+ dri2info.driverName = pScrn->driverName;
dri2info.deviceName = "/dev/dri/card0"; /* FIXME */
+#if defined(DRI2INFOREC_VERSION) && DRI2INFOREC_VERSION > 2
+ dri2info.CreateBuffer = driCreateBuffer;
+ dri2info.DestroyBuffer = driDestroyBuffer;
+#else
dri2info.CreateBuffers = driCreateBuffers;
dri2info.DestroyBuffers = driDestroyBuffers;
+#endif
dri2info.CopyRegion = driCopyRegion;
+ dri2info.Wait = NULL;
+
+ ms->d_depth_bits_last =
+ ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_X8Z24_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
+ ms->ds_depth_bits_last =
+ ms->screen->is_format_supported(ms->screen, PIPE_FORMAT_S8Z24_UNORM,
+ PIPE_TEXTURE_2D,
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0);
return DRI2ScreenInit(pScreen, &dri2info);
}
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index e01e5294b1..643b6b3b9e 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -33,10 +33,8 @@
#include "xf86.h"
#include "xf86_OSproc.h"
#include "compiler.h"
-#include "xf86RAC.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
-#include "xf86Resources.h"
#include "mipointer.h"
#include "micmap.h"
#include <X11/extensions/randr.h>
@@ -54,6 +52,7 @@
#include <pciaccess.h>
+#include "pipe/p_context.h"
#include "xorg_tracker.h"
#include "xorg_winsys.h"
@@ -84,41 +83,9 @@ static const OptionInfoRec Options[] = {
};
/*
- * Functions that might be needed
- */
-
-static const char *exaSymbols[] = {
- "exaGetVersion",
- "exaDriverInit",
- "exaDriverFini",
- "exaOffscreenAlloc",
- "exaOffscreenFree",
- "exaWaitSync",
- NULL
-};
-
-static const char *fbSymbols[] = {
- "fbPictureInit",
- "fbScreenInit",
- NULL
-};
-
-static const char *ddcSymbols[] = {
- "xf86PrintEDID",
- "xf86SetDDCproperties",
- NULL
-};
-
-/*
* Exported Xorg driver functions to winsys
*/
-void
-xorg_tracker_loader_ref_sym_lists()
-{
- LoaderRefSymLists(exaSymbols, fbSymbols, ddcSymbols, NULL);
-}
-
const OptionInfoRec *
xorg_tracker_available_options(int chipid, int busid)
{
@@ -179,8 +146,10 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
modesettingPtr ms = modesettingPTR(pScrn);
ScreenPtr pScreen = pScrn->pScreen;
PixmapPtr rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ unsigned handle, stride;
ms->noEvict = TRUE;
+ xorg_exa_set_displayed_usage(rootPixmap);
pScreen->ModifyPixmapHeader(rootPixmap,
pScrn->virtualX, pScrn->virtualY,
pScrn->depth, pScrn->bitsPerPixel,
@@ -188,13 +157,16 @@ CreateFrontBuffer(ScrnInfoPtr pScrn)
NULL);
ms->noEvict = FALSE;
+ handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
+
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
+ stride,
+ handle,
+ &ms->fb_id);
pScrn->frameX0 = 0;
pScrn->frameY0 = 0;
@@ -282,10 +254,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
} else
ms->entityPrivate = NULL;
- if (xf86RegisterResources(ms->pEnt->index, NULL, ResNone)) {
- return FALSE;
- }
-
if (xf86IsEntityShared(pScrn->entityList[0])) {
if (xf86IsPrimInitDone(pScrn->entityList[0])) {
/* do something */
@@ -306,7 +274,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
if (ms->fd < 0)
return FALSE;
- pScrn->racMemFlags = RAC_FB | RAC_COLORMAP;
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE;
pScrn->rgbBits = 8;
@@ -392,8 +359,6 @@ PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
- xf86LoaderReqSymLists(fbSymbols, NULL);
-
xf86LoadSubModule(pScrn, "exa");
#ifdef DRI2
@@ -419,6 +384,44 @@ RestoreHWState(ScrnInfoPtr pScrn)
return TRUE;
}
+static void xorgBlockHandler(int i, pointer blockData, pointer pTimeout,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[i];
+ modesettingPtr ms = modesettingPTR(xf86Screens[pScreen->myNum]);
+
+ pScreen->BlockHandler = ms->blockHandler;
+ pScreen->BlockHandler(i, blockData, pTimeout, pReadmask);
+ pScreen->BlockHandler = xorgBlockHandler;
+
+ ms->ctx->flush(ms->ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ {
+ RegionPtr dirty = DamageRegion(ms->damage);
+ unsigned num_cliprects = REGION_NUM_RECTS(dirty);
+
+ if (num_cliprects) {
+ drmModeClip *clip = alloca(num_cliprects * sizeof(drmModeClip));
+ BoxPtr rect = REGION_RECTS(dirty);
+ int i;
+
+ for (i = 0; i < num_cliprects; i++, rect++) {
+ clip[i].x = rect->x1;
+ clip[i].y = rect->y1;
+ clip[i].width = rect->x2 - rect->x1;
+ clip[i].height = rect->y2 - rect->y1;
+ }
+
+ /* TODO query connector property to see if this is needed */
+ drmModeDirtyFB(ms->fd, ms->fb_id, clip, num_cliprects);
+
+ DamageEmpty(ms->damage);
+ }
+ }
+#endif
+}
+
static Bool
CreateScreenResources(ScreenPtr pScreen)
{
@@ -426,6 +429,7 @@ CreateScreenResources(ScreenPtr pScreen)
modesettingPtr ms = modesettingPTR(pScrn);
PixmapPtr rootPixmap;
Bool ret;
+ unsigned handle, stride;
ms->noEvict = TRUE;
@@ -435,21 +439,41 @@ CreateScreenResources(ScreenPtr pScreen)
rootPixmap = pScreen->GetScreenPixmap(pScreen);
+ xorg_exa_set_displayed_usage(rootPixmap);
+ xorg_exa_set_shared_usage(rootPixmap);
if (!pScreen->ModifyPixmapHeader(rootPixmap, -1, -1, -1, -1, -1, NULL))
FatalError("Couldn't adjust screen pixmap\n");
ms->noEvict = FALSE;
+ handle = xorg_exa_get_pixmap_handle(rootPixmap, &stride);
+
drmModeAddFB(ms->fd,
pScrn->virtualX,
pScrn->virtualY,
pScrn->depth,
pScrn->bitsPerPixel,
- pScrn->displayWidth * pScrn->bitsPerPixel / 8,
- xorg_exa_get_pixmap_handle(rootPixmap), &ms->fb_id);
+ stride,
+ handle,
+ &ms->fb_id);
AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ ms->damage = DamageCreate(NULL, NULL, DamageReportNone, TRUE,
+ pScreen, rootPixmap);
+
+ if (ms->damage) {
+ DamageRegister(&rootPixmap->drawable, ms->damage);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Damage tracking initialized\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to create screen damage record\n");
+ return FALSE;
+ }
+#endif
+
return ret;
}
@@ -526,6 +550,8 @@ ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
fbPictureInit(pScreen, NULL, 0);
+ ms->blockHandler = pScreen->BlockHandler;
+ pScreen->BlockHandler = xorgBlockHandler;
ms->createScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = CreateScreenResources;
@@ -594,10 +620,6 @@ FreeScreen(int scrnIndex, int flags)
FreeRec(xf86Screens[scrnIndex]);
}
-/* HACK */
-void
-cursor_destroy(xf86CrtcPtr crtc);
-
static void
LeaveVT(int scrnIndex, int flags)
{
@@ -609,7 +631,7 @@ LeaveVT(int scrnIndex, int flags)
for (o = 0; o < config->num_crtc; o++) {
xf86CrtcPtr crtc = config->crtc[o];
- cursor_destroy(crtc);
+ crtc_cursor_destroy(crtc);
if (crtc->rotatedPixmap || crtc->rotatedData) {
crtc->funcs->shadow_destroy(crtc, crtc->rotatedPixmap,
@@ -623,6 +645,10 @@ LeaveVT(int scrnIndex, int flags)
RestoreHWState(pScrn);
+ if (drmDropMaster(ms->fd))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmDropMaster failed: %s\n", strerror(errno));
+
pScrn->vtSema = FALSE;
}
@@ -635,6 +661,17 @@ EnterVT(int scrnIndex, int flags)
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
modesettingPtr ms = modesettingPTR(pScrn);
+ if (drmSetMaster(ms->fd)) {
+ if (errno == EINVAL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: 2.6.29 or newer kernel required for "
+ "multi-server DRI\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "drmSetMaster failed: %s\n", strerror(errno));
+ }
+ }
+
/*
* Only save state once per server generation since that's what most
* drivers do. Could change this to save state at each VT enter.
@@ -674,8 +711,17 @@ CloseScreen(int scrnIndex, ScreenPtr pScreen)
driCloseScreen(pScreen);
#endif
+ pScreen->BlockHandler = ms->blockHandler;
pScreen->CreateScreenResources = ms->createScreenResources;
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ if (ms->damage) {
+ DamageUnregister(&pScreen->GetScreenPixmap(pScreen)->drawable, ms->damage);
+ DamageDestroy(ms->damage);
+ ms->damage = NULL;
+ }
+#endif
+
if (ms->exa)
xorg_exa_close(pScrn);
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 2c4291aa4e..6507b2950e 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -31,6 +31,7 @@
#include "xorg_exa.h"
#include "xorg_tracker.h"
#include "xorg_composite.h"
+#include "xorg_exa_tgsi.h"
#include <xorg-server.h>
#include <xf86.h>
@@ -42,8 +43,12 @@
#include "pipe/p_state.h"
#include "pipe/p_inlines.h"
+#include "cso_cache/cso_context.h"
+
#include "util/u_rect.h"
+#define DEBUG_SOLID 0
+
/*
* Helper functions
*/
@@ -69,6 +74,9 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
assert(*bbp == 16);
break;
case 8:
+ *format = PIPE_FORMAT_A8_UNORM;
+ assert(*bbp == 8);
+ break;
case 4:
case 1:
*format = PIPE_FORMAT_A8R8G8B8_UNORM; /* bad bad bad */
@@ -79,6 +87,25 @@ exa_get_pipe_format(int depth, enum pipe_format *format, int *bbp)
}
}
+static void
+xorg_exa_init_state(struct exa_context *exa)
+{
+ struct pipe_depth_stencil_alpha_state dsa;
+
+ /* set common initial clip state */
+ memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state));
+ cso_set_depth_stencil_alpha(exa->cso, &dsa);
+}
+
+static void
+xorg_exa_common_done(struct exa_context *exa)
+{
+ exa->copy.src = NULL;
+ exa->copy.dst = NULL;
+ exa->has_solid_color = FALSE;
+ exa->num_bound_samplers = 0;
+}
+
/*
* Static exported EXA functions
*/
@@ -95,6 +122,68 @@ ExaMarkSync(ScreenPtr pScreen)
}
static Bool
+ExaDownloadFromScreen(PixmapPtr pPix, int x, int y, int w, int h, char *dst,
+ int dst_pitch)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
+ struct pipe_transfer *transfer;
+
+ if (!priv || !priv->tex)
+ return FALSE;
+
+ if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)
+ exa->pipe->flush(exa->pipe, 0, NULL);
+
+ transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ PIPE_TRANSFER_READ, x, y, w, h);
+ if (!transfer)
+ return FALSE;
+
+ util_copy_rect((unsigned char*)dst, &priv->tex->block, dst_pitch, 0, 0,
+ w, h, exa->scrn->transfer_map(exa->scrn, transfer),
+ transfer->stride, 0, 0);
+
+ exa->scrn->transfer_unmap(exa->scrn, transfer);
+ exa->scrn->tex_transfer_destroy(transfer);
+
+ return TRUE;
+}
+
+static Bool
+ExaUploadToScreen(PixmapPtr pPix, int x, int y, int w, int h, char *src,
+ int src_pitch)
+{
+ ScreenPtr pScreen = pPix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPix);
+ struct pipe_transfer *transfer;
+
+ if (!priv || !priv->tex)
+ return FALSE;
+
+ transfer = exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
+ PIPE_TRANSFER_WRITE, x, y, w, h);
+ if (!transfer)
+ return FALSE;
+
+ util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+ &priv->tex->block, transfer->stride, 0, 0, w, h,
+ (unsigned char*)src, src_pitch, 0, 0);
+
+ exa->scrn->transfer_unmap(exa->scrn, transfer);
+ exa->scrn->tex_transfer_destroy(transfer);
+
+ return TRUE;
+}
+
+static Bool
ExaPrepareAccess(PixmapPtr pPix, int index)
{
ScreenPtr pScreen = pPix->drawable.pScreen;
@@ -113,6 +202,10 @@ ExaPrepareAccess(PixmapPtr pPix, int index)
if (priv->map_count++ == 0)
{
+ if (exa->pipe->is_texture_referenced(exa->pipe, priv->tex, 0, 0) &
+ PIPE_REFERENCED_FOR_WRITE)
+ exa->pipe->flush(exa->pipe, 0, NULL);
+
priv->map_transfer =
exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
PIPE_TRANSFER_READ_WRITE,
@@ -147,6 +240,7 @@ ExaFinishAccess(PixmapPtr pPix, int index)
exa->scrn->transfer_unmap(exa->scrn, priv->map_transfer);
exa->scrn->tex_transfer_destroy(priv->map_transfer);
priv->map_transfer = NULL;
+ pPix->devPrivate.ptr = NULL;
}
}
@@ -161,15 +255,22 @@ ExaDone(PixmapPtr pPixmap)
if (!priv)
return;
- if (priv->src_surf)
- exa->scrn->tex_surface_destroy(priv->src_surf);
- priv->src_surf = NULL;
+#if 1
+ xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, NULL);
+#else
+ xorg_exa_finish(exa);
+#endif
+ xorg_exa_common_done(exa);
}
static void
ExaDoneComposite(PixmapPtr pPixmap)
{
+ ScrnInfoPtr pScrn = xf86Screens[pPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ xorg_exa_common_done(exa);
}
static Bool
@@ -180,27 +281,36 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg)
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
struct exa_context *exa = ms->exa;
- if (1)
- return FALSE;
-
- if (pPixmap->drawable.depth < 15)
- return FALSE;
-
+#if 0
+ debug_printf("ExaPrepareSolid - test\n");
+#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->ctx || !exa->ctx->surface_fill)
+ if (!exa->pipe)
return FALSE;
- priv->color = fg;
- return TRUE;
+#if DEBUG_SOLID
+ fg = 0xffff0000;
+#endif
+
+#if 1
+ debug_printf(" ExaPrepareSolid(0x%x)\n", fg);
+#endif
+
+ return xorg_solid_bind_state(exa, priv, fg);
}
static void
@@ -210,15 +320,49 @@ ExaSolid(PixmapPtr pPixmap, int x0, int y0, int x1, int y1)
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- struct pipe_surface *surf =
- exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
- exa->ctx->surface_fill(exa->ctx, surf, x0, y0, x1 - x0, y1 - y0,
- priv->color);
-
- exa->scrn->tex_surface_destroy(surf);
+ debug_printf("\tExaSolid(%d, %d, %d, %d)\n", x0, y0, x1, y1);
+
+#if 0
+ if (x0 == 0 && y0 == 0 &&
+ x1 == priv->tex->width[0] &&
+ y1 == priv->tex->height[0]) {
+ exa->ctx->clear(exa->pipe, PIPE_CLEAR_COLOR,
+ exa->solid_color, 1., 0);
+ } else
+#endif
+
+#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
@@ -231,51 +375,55 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir,
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
struct exa_pixmap_priv *src_priv = exaGetPixmapDriverPrivate(pSrcPixmap);
- if (1)
- return FALSE;
+ debug_printf("ExaPrepareCopy\n");
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;
- if (!exa->ctx || !exa->ctx->surface_copy)
+ if (!exa->pipe)
return FALSE;
- priv->src_surf =
- exa->scrn->get_tex_surface(exa->scrn, src_priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
+ exa->copy.src = src_priv;
+ exa->copy.dst = priv;
- return TRUE;
+ /*XXX disabled until some issues with syncing are fixed */
+ return FALSE;
}
static void
ExaCopy(PixmapPtr pDstPixmap, int srcX, int srcY, int dstX, int dstY,
int width, int height)
{
- ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
- struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
- struct pipe_surface *surf =
- exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- exa->ctx->surface_copy(exa->ctx, surf, dstX, dstY, priv->src_surf,
- srcX, srcY, width, height);
- exa->scrn->tex_surface_destroy(surf);
+ ScrnInfoPtr pScrn = xf86Screens[pDstPixmap->drawable.pScreen->myNum];
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDstPixmap);
+
+ debug_printf("\tExaCopy(srcx=%d, srcy=%d, dstX=%d, dstY=%d, w=%d, h=%d)\n",
+ srcX, srcY, dstX, dstY, width, height);
+
+ debug_assert(priv == exa->copy.dst);
+
+ xorg_copy_pixmap(exa, exa->copy.dst, dstX, dstY,
+ exa->copy.src, srcX, srcY,
+ width, height);
}
static Bool
@@ -287,8 +435,13 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture,
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
+ debug_printf("ExaPrepareComposite\n");
+
return xorg_composite_bind_state(exa, op, pSrcPicture, pMaskPicture,
- pDstPicture);
+ pDstPicture,
+ exaGetPixmapDriverPrivate(pSrc),
+ exaGetPixmapDriverPrivate(pMask),
+ exaGetPixmapDriverPrivate(pDst));
}
static void
@@ -300,6 +453,8 @@ ExaComposite(PixmapPtr pDst, int srcX, int srcY, int maskX, int maskY,
struct exa_context *exa = ms->exa;
struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pDst);
+ debug_printf("\tExaComposite\n");
+
xorg_composite(exa, priv, srcX, srcY, maskX, maskY,
dstX, dstY, width, height);
}
@@ -331,14 +486,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);
}
@@ -359,14 +511,45 @@ ExaPixmapIsOffscreen(PixmapPtr pPixmap)
return FALSE;
}
+int
+xorg_exa_set_displayed_usage(PixmapPtr pPixmap)
+{
+ struct exa_pixmap_priv *priv;
+ priv = exaGetPixmapDriverPrivate(pPixmap);
+
+ if (!priv) {
+ FatalError("NO PIXMAP PRIVATE\n");
+ return 0;
+ }
+
+ priv->flags |= PIPE_TEXTURE_USAGE_PRIMARY;
+
+ return 0;
+}
+
+int
+xorg_exa_set_shared_usage(PixmapPtr pPixmap)
+{
+ struct exa_pixmap_priv *priv;
+ priv = exaGetPixmapDriverPrivate(pPixmap);
+
+ if (!priv) {
+ FatalError("NO PIXMAP PRIVATE\n");
+ return 0;
+ }
+
+ priv->flags |= PIPE_TEXTURE_USAGE_DISPLAY_TARGET;
+
+ return 0;
+}
+
unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
+xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride_out)
{
ScreenPtr pScreen = pPixmap->drawable.pScreen;
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_pixmap_priv *priv;
- struct pipe_buffer *buffer = NULL;
unsigned handle;
unsigned stride;
@@ -382,9 +565,10 @@ xorg_exa_get_pixmap_handle(PixmapPtr pPixmap)
return 0;
}
- ms->api->buffer_from_texture(ms->api, priv->tex, &buffer, &stride);
- ms->api->handle_from_buffer(ms->api, ms->screen, buffer, &handle);
- pipe_buffer_reference(&buffer, NULL);
+ ms->api->local_handle_from_texture(ms->api, ms->screen, priv->tex, &stride, &handle);
+ if (stride_out)
+ *stride_out = stride;
+
return handle;
}
@@ -399,7 +583,7 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
modesettingPtr ms = modesettingPTR(pScrn);
struct exa_context *exa = ms->exa;
- if (!priv)
+ if (!priv || pPixData)
return FALSE;
if (depth <= 0)
@@ -421,35 +605,74 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
bitsPerPixel, devKind, NULL);
/* Deal with screen resize */
- if (priv->tex && (priv->tex->width[0] != width || priv->tex->height[0] != height)) {
- pipe_texture_reference(&priv->tex, NULL);
- }
-
- if (!priv->tex) {
- struct pipe_texture template;
-
- memset(&template, 0, sizeof(template));
- template.target = PIPE_TEXTURE_2D;
- exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
- pf_get_block(template.format, &template.block);
- template.width[0] = width;
- template.height[0] = height;
- template.depth[0] = 1;
- template.last_level = 0;
- template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET;
- priv->tex = exa->scrn->texture_create(exa->scrn, &template);
- }
-
- if (pPixData) {
- struct pipe_transfer *transfer =
- exa->scrn->get_tex_transfer(exa->scrn, priv->tex, 0, 0, 0,
- PIPE_TRANSFER_WRITE,
- 0, 0, width, height);
- pipe_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
- &priv->tex->block, transfer->stride, 0, 0,
- width, height, pPixData, pPixmap->devKind, 0, 0);
- exa->scrn->transfer_unmap(exa->scrn, transfer);
- exa->scrn->tex_transfer_destroy(transfer);
+ if (!priv->tex ||
+ (priv->tex->width[0] != width ||
+ priv->tex->height[0] != height ||
+ priv->tex_flags != priv->flags)) {
+ struct pipe_texture *texture = NULL;
+
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ if (priv->flags)
+#endif
+ {
+ struct pipe_texture template;
+
+ memset(&template, 0, sizeof(template));
+ template.target = PIPE_TEXTURE_2D;
+ exa_get_pipe_format(depth, &template.format, &bitsPerPixel);
+ pf_get_block(template.format, &template.block);
+ template.width[0] = width;
+ template.height[0] = height;
+ template.depth[0] = 1;
+ template.last_level = 0;
+ template.tex_usage = PIPE_TEXTURE_USAGE_RENDER_TARGET | priv->flags;
+ priv->tex_flags = priv->flags;
+ texture = exa->scrn->texture_create(exa->scrn, &template);
+
+ if (priv->tex) {
+ 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);
+ 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]),
+ min(height, texture->height[0]));
+ exa->scrn->tex_surface_destroy(dst_surf);
+ exa->scrn->tex_surface_destroy(src_surf);
+ } else if (pPixmap->devPrivate.ptr) {
+ struct pipe_transfer *transfer;
+
+ if (priv->map_count != 0)
+ FatalError("doing ExaModifyPixmapHeader on mapped buffer\n");
+
+ transfer =
+ exa->scrn->get_tex_transfer(exa->scrn, texture, 0, 0, 0,
+ PIPE_TRANSFER_WRITE,
+ 0, 0, width, height);
+ util_copy_rect(exa->scrn->transfer_map(exa->scrn, transfer),
+ &texture->block, transfer->stride, 0, 0,
+ width, height, pPixmap->devPrivate.ptr,
+ pPixmap->devKind, 0, 0);
+ exa->scrn->transfer_unmap(exa->scrn, transfer);
+ exa->scrn->tex_transfer_destroy(transfer);
+
+ xfree(pPixmap->devPrivate.ptr);
+ pPixmap->devPrivate.ptr = NULL;
+ }
+ }
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ else {
+ xfree(pPixmap->devPrivate.ptr);
+ pPixmap->devPrivate.ptr = xalloc(pPixmap->drawable.height *
+ pPixmap->devKind);
+ }
+#endif
+
+ pipe_texture_reference(&priv->tex, texture);
+ /* the texture we create has one reference */
+ pipe_texture_reference(&texture, NULL);
}
return TRUE;
@@ -458,87 +681,143 @@ ExaModifyPixmapHeader(PixmapPtr pPixmap, int width, int height,
struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap)
{
- struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
- struct pipe_texture *tex = NULL;
- pipe_texture_reference(&tex, priv->tex);
- return tex;
+ struct exa_pixmap_priv *priv = exaGetPixmapDriverPrivate(pPixmap);
+ struct pipe_texture *tex = NULL;
+ pipe_texture_reference(&tex, priv->tex);
+ return tex;
}
void
xorg_exa_close(ScrnInfoPtr pScrn)
{
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa = ms->exa;
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa = ms->exa;
+ struct pipe_constant_buffer *vsbuf = &exa->vs_const_buffer;
+ struct pipe_constant_buffer *fsbuf = &exa->fs_const_buffer;
- if (exa->ctx)
- exa->ctx->destroy(exa->ctx);
+ if (exa->shaders) {
+ xorg_shaders_destroy(exa->shaders);
+ }
- exaDriverFini(pScrn->pScreen);
- xfree(exa);
- ms->exa = NULL;
+ if (vsbuf && vsbuf->buffer)
+ pipe_buffer_reference(&vsbuf->buffer, NULL);
+
+ if (fsbuf && fsbuf->buffer)
+ pipe_buffer_reference(&fsbuf->buffer, NULL);
+
+ if (exa->cso) {
+ cso_release_all(exa->cso);
+ cso_destroy_context(exa->cso);
+ }
+
+ if (exa->pipe)
+ exa->pipe->destroy(exa->pipe);
+
+ exaDriverFini(pScrn->pScreen);
+ xfree(exa);
+ ms->exa = NULL;
}
void *
xorg_exa_init(ScrnInfoPtr pScrn)
{
- modesettingPtr ms = modesettingPTR(pScrn);
- struct exa_context *exa;
- ExaDriverPtr pExa;
-
- exa = xcalloc(1, sizeof(struct exa_context));
- if (!exa)
- return NULL;
+ modesettingPtr ms = modesettingPTR(pScrn);
+ struct exa_context *exa;
+ ExaDriverPtr pExa;
+
+ exa = xcalloc(1, sizeof(struct exa_context));
+ if (!exa)
+ return NULL;
+
+ pExa = exaDriverAlloc();
+ if (!pExa) {
+ goto out_err;
+ }
+
+ memset(pExa, 0, sizeof(*pExa));
+
+ pExa->exa_major = 2;
+ pExa->exa_minor = 2;
+ pExa->memoryBase = 0;
+ pExa->memorySize = 0;
+ pExa->offScreenBase = 0;
+ pExa->pixmapOffsetAlign = 0;
+ pExa->pixmapPitchAlign = 1;
+ pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
+#ifdef EXA_SUPPORTS_PREPARE_AUX
+ pExa->flags |= EXA_SUPPORTS_PREPARE_AUX;
+#endif
+#ifdef EXA_MIXED_PIXMAPS
+ pExa->flags |= EXA_MIXED_PIXMAPS;
+#endif
+ pExa->maxX = 8191; /* FIXME */
+ pExa->maxY = 8191; /* FIXME */
+
+ pExa->WaitMarker = ExaWaitMarker;
+ pExa->MarkSync = ExaMarkSync;
+ pExa->PrepareSolid = ExaPrepareSolid;
+ pExa->Solid = ExaSolid;
+ pExa->DoneSolid = ExaDone;
+ pExa->PrepareCopy = ExaPrepareCopy;
+ pExa->Copy = ExaCopy;
+ pExa->DoneCopy = ExaDone;
+ pExa->CheckComposite = ExaCheckComposite;
+ pExa->PrepareComposite = ExaPrepareComposite;
+ pExa->Composite = ExaComposite;
+ pExa->DoneComposite = ExaDoneComposite;
+ pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
+ pExa->DownloadFromScreen = ExaDownloadFromScreen;
+ pExa->UploadToScreen = ExaUploadToScreen;
+ pExa->PrepareAccess = ExaPrepareAccess;
+ pExa->FinishAccess = ExaFinishAccess;
+ pExa->CreatePixmap = ExaCreatePixmap;
+ pExa->DestroyPixmap = ExaDestroyPixmap;
+ pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
+
+ if (!exaDriverInit(pScrn->pScreen, pExa)) {
+ goto out_err;
+ }
+
+ exa->scrn = ms->screen;
+ exa->pipe = ms->api->create_context(ms->api, exa->scrn);
+ /* Share context with DRI */
+ ms->ctx = exa->pipe;
+
+ exa->cso = cso_create_context(exa->pipe);
+ exa->shaders = xorg_shaders_create(exa);
+
+ xorg_exa_init_state(exa);
+
+ return (void *)exa;
+
+out_err:
+ xorg_exa_close(pScrn);
+
+ return NULL;
+}
- pExa = exaDriverAlloc();
- if (!pExa) {
- goto out_err;
- }
+struct pipe_surface *
+exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv)
+{
+ return exa->scrn->get_tex_surface(exa->scrn, priv->tex, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
- memset(pExa, 0, sizeof(*pExa));
- pExa->exa_major = 2;
- pExa->exa_minor = 2;
- pExa->memoryBase = 0;
- pExa->memorySize = 0;
- pExa->offScreenBase = 0;
- pExa->pixmapOffsetAlign = 0;
- pExa->pixmapPitchAlign = 1;
- pExa->flags = EXA_OFFSCREEN_PIXMAPS | EXA_HANDLES_PIXMAPS;
- pExa->maxX = 8191; /* FIXME */
- pExa->maxY = 8191; /* FIXME */
- pExa->WaitMarker = ExaWaitMarker;
- pExa->MarkSync = ExaMarkSync;
- pExa->PrepareSolid = ExaPrepareSolid;
- pExa->Solid = ExaSolid;
- pExa->DoneSolid = ExaDone;
- pExa->PrepareCopy = ExaPrepareCopy;
- pExa->Copy = ExaCopy;
- pExa->DoneCopy = ExaDone;
- pExa->CheckComposite = ExaCheckComposite;
- pExa->PrepareComposite = ExaPrepareComposite;
- pExa->Composite = ExaComposite;
- pExa->DoneComposite = ExaDoneComposite;
- pExa->PixmapIsOffscreen = ExaPixmapIsOffscreen;
- pExa->PrepareAccess = ExaPrepareAccess;
- pExa->FinishAccess = ExaFinishAccess;
- pExa->CreatePixmap = ExaCreatePixmap;
- pExa->DestroyPixmap = ExaDestroyPixmap;
- pExa->ModifyPixmapHeader = ExaModifyPixmapHeader;
-
- if (!exaDriverInit(pScrn->pScreen, pExa)) {
- goto out_err;
- }
+}
- exa->scrn = ms->screen;
- exa->ctx = ms->api->create_context(ms->api, exa->scrn);
- /* Share context with DRI */
- ms->ctx = exa->ctx;
+void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
+ struct pipe_fence_handle **fence)
+{
+ exa->pipe->flush(exa->pipe, pipeFlushFlags, fence);
+}
- return (void *)exa;
+void xorg_exa_finish(struct exa_context *exa)
+{
+ struct pipe_fence_handle *fence = NULL;
- out_err:
- xorg_exa_close(pScrn);
+ xorg_exa_flush(exa, PIPE_FLUSH_RENDER_CACHE, &fence);
- return NULL;
+ exa->pipe->screen->fence_finish(exa->pipe->screen, fence, 0);
+ exa->pipe->screen->fence_reference(exa->pipe->screen, &fence, NULL);
}
-/* vim: set sw=4 ts=8 sts=4: */
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.h b/src/gallium/state_trackers/xorg/xorg_exa.h
index 650997aec6..fe1f1cd103 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.h
+++ b/src/gallium/state_trackers/xorg/xorg_exa.h
@@ -3,25 +3,58 @@
#include "xorg_tracker.h"
+#include <pipe/p_state.h>
+
+struct cso_context;
+struct xorg_shaders;
+
+/* src + mask + dst */
+#define MAX_EXA_SAMPLERS 3
+
struct exa_context
{
- ExaDriverPtr pExa;
- struct pipe_context *ctx;
- struct pipe_screen *scrn;
-};
+ ExaDriverPtr pExa;
+ struct pipe_context *pipe;
+ struct pipe_screen *scrn;
+ struct cso_context *cso;
+ struct xorg_shaders *shaders;
+
+ struct pipe_constant_buffer vs_const_buffer;
+ struct pipe_constant_buffer fs_const_buffer;
+ struct pipe_texture *bound_textures[MAX_EXA_SAMPLERS];
+ int num_bound_samplers;
+
+ float solid_color[4];
+ boolean has_solid_color;
+
+ struct {
+ 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
{
- int flags;
- struct pipe_texture *tex;
- unsigned int color;
- struct pipe_surface *src_surf; /* for copies */
+ int flags;
+ int tex_flags;
+
+ struct pipe_texture *tex;
+ struct pipe_texture *depth_stencil_tex;
- struct pipe_transfer *map_transfer;
- unsigned map_count;
+ struct pipe_transfer *map_transfer;
+ unsigned map_count;
};
+struct pipe_surface *
+exa_gpu_surface(struct exa_context *exa, struct exa_pixmap_priv *priv);
+void xorg_exa_flush(struct exa_context *exa, uint pipeFlushFlags,
+ struct pipe_fence_handle **fence);
+void xorg_exa_finish(struct exa_context *exa);
#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
new file mode 100644
index 0000000000..2daa5b5628
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.c
@@ -0,0 +1,484 @@
+#include "xorg_exa_tgsi.h"
+
+/*### stupidity defined in X11/extensions/XI.h */
+#undef Absolute
+
+#include "pipe/p_format.h"
+#include "pipe/p_context.h"
+#include "pipe/p_state.h"
+#include "pipe/p_inlines.h"
+#include "pipe/p_shader_tokens.h"
+
+#include "util/u_memory.h"
+#include "util/u_simple_shaders.h"
+
+#include "tgsi/tgsi_ureg.h"
+
+#include "cso_cache/cso_context.h"
+#include "cso_cache/cso_hash.h"
+
+/* Vertex shader:
+ * IN[0] = vertex pos
+ * IN[1] = src tex coord | solid fill color
+ * IN[2] = mask tex coord
+ * IN[3] = dst tex coord
+ * CONST[0] = (2/dst_width, 2/dst_height, 1, 1)
+ * CONST[1] = (-1, -1, 0, 0)
+ *
+ * OUT[0] = vertex pos
+ * OUT[1] = src tex coord | solid fill color
+ * OUT[2] = mask tex coord
+ * OUT[3] = dst tex coord
+ */
+
+/* Fragment shader:
+ * SAMP[0] = src
+ * SAMP[1] = mask
+ * SAMP[2] = dst
+ * IN[0] = pos src | solid fill color
+ * IN[1] = pos mask
+ * IN[2] = pos dst
+ * CONST[0] = (0, 0, 0, 1)
+ *
+ * OUT[0] = color
+ */
+
+struct xorg_shaders {
+ struct exa_context *exa;
+
+ struct cso_hash *vs_hash;
+ struct cso_hash *fs_hash;
+};
+
+static const char over_op[] =
+ "SUB TEMP[3], CONST[0].wwww, TEMP[1].wwww\n"
+ "MAD TEMP[3], TEMP[0], TEMP[3], TEMP[0]\n";
+
+
+static INLINE void
+create_preamble(struct ureg_program *ureg)
+{
+}
+
+
+static INLINE void
+src_in_mask(struct ureg_program *ureg,
+ struct ureg_dst dst,
+ struct ureg_src src,
+ struct ureg_src mask)
+{
+ /* MUL dst, src, mask.wwww */
+ ureg_MUL(ureg, dst, src,
+ ureg_scalar(mask, TGSI_SWIZZLE_W));
+}
+
+static struct ureg_src
+vs_normalize_coords(struct ureg_program *ureg, struct ureg_src coords,
+ struct ureg_src const0, struct ureg_src const1)
+{
+ struct ureg_dst tmp = ureg_DECL_temporary(ureg);
+ struct ureg_src ret;
+ ureg_MAD(ureg, tmp, coords, const0, const1);
+ ret = ureg_src(tmp);
+ ureg_release_temporary(ureg, tmp);
+ return ret;
+}
+
+static void
+linear_gradient(struct ureg_program *ureg,
+ struct ureg_dst out,
+ struct ureg_src pos,
+ struct ureg_src sampler,
+ struct ureg_src coords,
+ struct ureg_src const0124,
+ struct ureg_src matrow0,
+ struct ureg_src matrow1,
+ struct ureg_src matrow2)
+{
+ struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
+
+ ureg_MOV(ureg,
+ ureg_writemask(temp0, TGSI_WRITEMASK_XY), pos);
+ ureg_MOV(ureg,
+ ureg_writemask(temp0, TGSI_WRITEMASK_Z),
+ ureg_scalar(const0124, TGSI_SWIZZLE_Y));
+
+ ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
+ ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
+ ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
+ ureg_RCP(ureg, temp3, ureg_src(temp3));
+ ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
+ ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
+
+ ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_X),
+ ureg_src(temp1));
+ ureg_MOV(ureg, ureg_writemask(temp4, TGSI_WRITEMASK_Y),
+ ureg_src(temp2));
+
+ ureg_MUL(ureg, temp0,
+ ureg_scalar(coords, TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp1,
+ ureg_scalar(coords, TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp4), TGSI_SWIZZLE_X),
+ ureg_src(temp0));
+
+ ureg_MUL(ureg, temp2,
+ ureg_src(temp1),
+ ureg_scalar(coords, TGSI_SWIZZLE_Z));
+
+ ureg_TEX(ureg, out,
+ TGSI_TEXTURE_1D, ureg_src(temp2), sampler);
+
+ ureg_release_temporary(ureg, temp0);
+ ureg_release_temporary(ureg, temp1);
+ ureg_release_temporary(ureg, temp2);
+ ureg_release_temporary(ureg, temp3);
+ ureg_release_temporary(ureg, temp4);
+ ureg_release_temporary(ureg, temp5);
+}
+
+
+static void
+radial_gradient(struct ureg_program *ureg,
+ struct ureg_dst out,
+ struct ureg_src pos,
+ struct ureg_src sampler,
+ struct ureg_src coords,
+ struct ureg_src const0124,
+ struct ureg_src matrow0,
+ struct ureg_src matrow1,
+ struct ureg_src matrow2)
+{
+ struct ureg_dst temp0 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp1 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp2 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp3 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp4 = ureg_DECL_temporary(ureg);
+ struct ureg_dst temp5 = ureg_DECL_temporary(ureg);
+
+ ureg_MOV(ureg,
+ ureg_writemask(temp0, TGSI_WRITEMASK_XY),
+ pos);
+ ureg_MOV(ureg,
+ ureg_writemask(temp0, TGSI_WRITEMASK_Z),
+ ureg_scalar(const0124, TGSI_SWIZZLE_Y));
+
+ ureg_DP3(ureg, temp1, matrow0, ureg_src(temp0));
+ ureg_DP3(ureg, temp2, matrow1, ureg_src(temp0));
+ ureg_DP3(ureg, temp3, matrow2, ureg_src(temp0));
+ ureg_RCP(ureg, temp3, ureg_src(temp3));
+ ureg_MUL(ureg, temp1, ureg_src(temp1), ureg_src(temp3));
+ ureg_MUL(ureg, temp2, ureg_src(temp2), ureg_src(temp3));
+
+ ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_X),
+ ureg_src(temp1));
+ ureg_MOV(ureg, ureg_writemask(temp5, TGSI_WRITEMASK_Y),
+ ureg_src(temp2));
+
+ ureg_MUL(ureg, temp0, ureg_scalar(coords, TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp1,
+ ureg_scalar(coords, TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
+ ureg_src(temp0));
+ ureg_ADD(ureg, temp1,
+ ureg_src(temp1), ureg_src(temp1));
+ ureg_MUL(ureg, temp3,
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y),
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_Y));
+ ureg_MAD(ureg, temp4,
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
+ ureg_scalar(ureg_src(temp5), TGSI_SWIZZLE_X),
+ ureg_src(temp3));
+ ureg_MOV(ureg, temp4, ureg_negate(ureg_src(temp4)));
+ ureg_MUL(ureg, temp2,
+ ureg_scalar(coords, TGSI_SWIZZLE_Z),
+ ureg_src(temp4));
+ ureg_MUL(ureg, temp0,
+ ureg_scalar(const0124, TGSI_SWIZZLE_W),
+ ureg_src(temp2));
+ ureg_MUL(ureg, temp3,
+ ureg_src(temp1), ureg_src(temp1));
+ ureg_SUB(ureg, temp2,
+ ureg_src(temp3), ureg_src(temp0));
+ ureg_RSQ(ureg, temp2, ureg_abs(ureg_src(temp2)));
+ ureg_RCP(ureg, temp2, ureg_src(temp2));
+ ureg_SUB(ureg, temp1,
+ ureg_src(temp2), ureg_src(temp1));
+ ureg_ADD(ureg, temp0,
+ ureg_scalar(coords, TGSI_SWIZZLE_Z),
+ ureg_scalar(coords, TGSI_SWIZZLE_Z));
+ ureg_RCP(ureg, temp0, ureg_src(temp0));
+ ureg_MUL(ureg, temp2,
+ ureg_src(temp1), ureg_src(temp0));
+ ureg_TEX(ureg, out, TGSI_TEXTURE_1D,
+ ureg_src(temp2), sampler);
+
+ ureg_release_temporary(ureg, temp0);
+ ureg_release_temporary(ureg, temp1);
+ ureg_release_temporary(ureg, temp2);
+ ureg_release_temporary(ureg, temp3);
+ ureg_release_temporary(ureg, temp4);
+ ureg_release_temporary(ureg, temp5);
+}
+
+static void *
+create_vs(struct pipe_context *pipe,
+ unsigned vs_traits)
+{
+ struct ureg_program *ureg;
+ struct ureg_src src;
+ struct ureg_dst dst;
+ struct ureg_src const0, const1;
+ 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, 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, 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, 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, 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, input_slot++);
+ dst = ureg_DECL_output(ureg, TGSI_SEMANTIC_POSITION, 2);
+ ureg_MOV(ureg, dst, src);
+ }
+
+ ureg_END(ureg);
+
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+static void *
+create_fs(struct pipe_context *pipe,
+ unsigned fs_traits)
+{
+ struct ureg_program *ureg;
+ struct ureg_src /*dst_sampler,*/ src_sampler, mask_sampler;
+ struct ureg_src /*dst_pos,*/ src_input, mask_pos;
+ struct ureg_dst src, mask;
+ struct ureg_dst out;
+ boolean has_mask = fs_traits & FS_MASK;
+ boolean is_fill = fs_traits & FS_FILL;
+ boolean is_composite = fs_traits & FS_COMPOSITE;
+ boolean is_solid = fs_traits & FS_SOLID_FILL;
+ boolean is_lingrad = fs_traits & FS_LINGRAD_FILL;
+ boolean is_radgrad = fs_traits & FS_RADGRAD_FILL;
+
+ ureg = ureg_create(TGSI_PROCESSOR_FRAGMENT);
+ if (ureg == NULL)
+ return 0;
+
+ /* it has to be either a fill or a composite op */
+ debug_assert(is_fill ^ is_composite);
+
+ out = ureg_DECL_output(ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0);
+
+ if (is_composite) {
+ src_sampler = ureg_DECL_sampler(ureg, 0);
+ src_input = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_GENERIC,
+ 0,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ } else {
+ debug_assert(is_fill);
+ if (is_solid)
+ src_input = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ else
+ src_input = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_POSITION,
+ 0,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ }
+
+ if (has_mask) {
+ mask_sampler = ureg_DECL_sampler(ureg, 1);
+ mask_pos = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_POSITION,
+ 1,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+ }
+
+#if 0 /* unused right now */
+ dst_sampler = ureg_DECL_sampler(ureg, 2);
+ dst_pos = ureg_DECL_fs_input(ureg,
+ TGSI_SEMANTIC_POSITION,
+ 2,
+ TGSI_INTERPOLATE_PERSPECTIVE);
+#endif
+
+ if (is_composite) {
+ if (has_mask)
+ src = ureg_DECL_temporary(ureg);
+ else
+ src = out;
+ ureg_TEX(ureg, src,
+ TGSI_TEXTURE_2D, src_input, src_sampler);
+ } else if (is_fill) {
+ if (is_solid) {
+ if (has_mask)
+ src = ureg_dst(src_input);
+ else
+ ureg_MOV(ureg, out, src_input);
+ } else if (is_lingrad || is_radgrad) {
+ struct ureg_src coords, const0124,
+ matrow0, matrow1, matrow2;
+
+ if (has_mask)
+ src = ureg_DECL_temporary(ureg);
+ else
+ src = out;
+
+ 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,
+ src_input, src_sampler,
+ coords, const0124,
+ matrow0, matrow1, matrow2);
+ } else if (is_radgrad) {
+ radial_gradient(ureg, src,
+ src_input, src_sampler,
+ coords, const0124,
+ matrow0, matrow1, matrow2);
+ }
+ } else
+ debug_assert(!"Unknown fill type!");
+ }
+
+ if (has_mask) {
+ mask = ureg_DECL_temporary(ureg);
+ ureg_TEX(ureg, mask,
+ TGSI_TEXTURE_2D, mask_pos, mask_sampler);
+ /* src IN mask */
+ src_in_mask(ureg, out, ureg_src(src), ureg_src(mask));
+ ureg_release_temporary(ureg, mask);
+ }
+
+ ureg_END(ureg);
+
+ return ureg_create_shader_and_destroy(ureg, pipe);
+}
+
+struct xorg_shaders * xorg_shaders_create(struct exa_context *exa)
+{
+ struct xorg_shaders *sc = CALLOC_STRUCT(xorg_shaders);
+
+ sc->exa = exa;
+ sc->vs_hash = cso_hash_create();
+ sc->fs_hash = cso_hash_create();
+
+ return sc;
+}
+
+static void
+cache_destroy(struct cso_context *cso,
+ struct cso_hash *hash,
+ unsigned processor)
+{
+ struct cso_hash_iter iter = cso_hash_first_node(hash);
+ while (!cso_hash_iter_is_null(iter)) {
+ void *shader = (void *)cso_hash_iter_data(iter);
+ if (processor == PIPE_SHADER_FRAGMENT) {
+ cso_delete_fragment_shader(cso, shader);
+ } else if (processor == PIPE_SHADER_VERTEX) {
+ cso_delete_vertex_shader(cso, shader);
+ }
+ iter = cso_hash_erase(hash, iter);
+ }
+ cso_hash_delete(hash);
+}
+
+void xorg_shaders_destroy(struct xorg_shaders *sc)
+{
+ cache_destroy(sc->exa->cso, sc->vs_hash,
+ PIPE_SHADER_VERTEX);
+ cache_destroy(sc->exa->cso, sc->fs_hash,
+ PIPE_SHADER_FRAGMENT);
+
+ free(sc);
+}
+
+static INLINE void *
+shader_from_cache(struct pipe_context *pipe,
+ unsigned type,
+ struct cso_hash *hash,
+ unsigned key)
+{
+ void *shader = 0;
+
+ struct cso_hash_iter iter = cso_hash_find(hash, key);
+
+ if (cso_hash_iter_is_null(iter)) {
+ if (type == PIPE_SHADER_VERTEX)
+ shader = create_vs(pipe, key);
+ else
+ shader = create_fs(pipe, key);
+ cso_hash_insert(hash, key, shader);
+ } else
+ shader = (void *)cso_hash_iter_data(iter);
+
+ return shader;
+}
+
+struct xorg_shader xorg_shaders_get(struct xorg_shaders *sc,
+ unsigned vs_traits,
+ unsigned fs_traits)
+{
+ struct xorg_shader shader = {0};
+ void *vs, *fs;
+
+ vs = shader_from_cache(sc->exa->pipe, PIPE_SHADER_VERTEX,
+ sc->vs_hash, vs_traits);
+ fs = shader_from_cache(sc->exa->pipe, PIPE_SHADER_FRAGMENT,
+ sc->fs_hash, fs_traits);
+
+ debug_assert(vs && fs);
+ if (!vs || !fs)
+ return shader;
+
+ shader.vs = vs;
+ shader.fs = fs;
+
+ return shader;
+}
diff --git a/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
new file mode 100644
index 0000000000..1535a0c8c3
--- /dev/null
+++ b/src/gallium/state_trackers/xorg/xorg_exa_tgsi.h
@@ -0,0 +1,43 @@
+#ifndef XORG_EXA_TGSI_H
+#define XORG_EXA_TGSI_H
+
+#include "xorg_exa.h"
+
+enum xorg_vs_traits {
+ VS_COMPOSITE = 1 << 0,
+ VS_MASK = 1 << 1,
+ VS_SOLID_FILL = 1 << 2,
+ VS_LINGRAD_FILL = 1 << 3,
+ VS_RADGRAD_FILL = 1 << 4,
+ VS_FILL = (VS_SOLID_FILL |
+ VS_LINGRAD_FILL |
+ VS_RADGRAD_FILL)
+ /*VS_TRANSFORM = 1 << 5*/
+};
+
+enum xorg_fs_traits {
+ FS_COMPOSITE = 1 << 0,
+ FS_MASK = 1 << 1,
+ FS_SOLID_FILL = 1 << 2,
+ FS_LINGRAD_FILL = 1 << 3,
+ FS_RADGRAD_FILL = 1 << 4,
+ FS_FILL = (FS_SOLID_FILL |
+ FS_LINGRAD_FILL |
+ FS_RADGRAD_FILL)
+};
+
+struct xorg_shader {
+ void *fs;
+ void *vs;
+};
+
+struct xorg_shaders;
+
+struct xorg_shaders *xorg_shaders_create(struct exa_context *exa);
+void xorg_shaders_destroy(struct xorg_shaders *shaders);
+
+struct xorg_shader xorg_shaders_get(struct xorg_shaders *shaders,
+ unsigned vs_traits,
+ unsigned fs_traits);
+
+#endif
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 950af942f5..26f45f8d64 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 b4742bdbf5..b1ab783a15 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -31,6 +31,7 @@
#ifndef _XORG_TRACKER_H_
#define _XORG_TRACKER_H_
+#include <stddef.h>
#include <stdint.h>
#include <errno.h>
#include <drm.h>
@@ -38,8 +39,13 @@
#include <xf86drmMode.h>
#include <xorg-server.h>
#include <xf86.h>
+#include "xf86Crtc.h"
#include <exa.h>
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+#include <damage.h>
+#endif
+
#include "pipe/p_screen.h"
#include "state_tracker/drm_api.h"
@@ -75,17 +81,23 @@ typedef struct _modesettingRec
unsigned int SaveGeneration;
+ void (*blockHandler)(int, pointer, pointer, pointer);
CreateScreenResourcesProcPtr createScreenResources;
/* gallium */
struct drm_api *api;
struct pipe_screen *screen;
struct pipe_context *ctx;
+ boolean d_depth_bits_last;
+ boolean ds_depth_bits_last;
/* exa */
void *exa;
Bool noEvict;
+#ifdef DRM_MODE_FEATURE_DIRTYFB
+ DamagePtr damage;
+#endif
} modesettingRec, *modesettingPtr;
#define modesettingPTR(p) ((modesettingPtr)((p)->driverPrivate))
@@ -98,7 +110,13 @@ struct pipe_texture *
xorg_exa_get_texture(PixmapPtr pPixmap);
unsigned
-xorg_exa_get_pixmap_handle(PixmapPtr pPixmap);
+xorg_exa_get_pixmap_handle(PixmapPtr pPixmap, unsigned *stride);
+
+int
+xorg_exa_set_displayed_usage(PixmapPtr pPixmap);
+
+int
+xorg_exa_set_shared_usage(PixmapPtr pPixmap);
void *
xorg_exa_init(ScrnInfoPtr pScrn);
@@ -123,6 +141,9 @@ driCloseScreen(ScreenPtr pScreen);
void
crtc_init(ScrnInfoPtr pScrn);
+void
+crtc_cursor_destroy(xf86CrtcPtr crtc);
+
/***********************************************************************
* xorg_output.c
diff --git a/src/gallium/state_trackers/xorg/xorg_winsys.h b/src/gallium/state_trackers/xorg/xorg_winsys.h
index d523080e90..47ee4b9ffd 100644
--- a/src/gallium/state_trackers/xorg/xorg_winsys.h
+++ b/src/gallium/state_trackers/xorg/xorg_winsys.h
@@ -37,7 +37,6 @@
#include "xorg-server.h"
#include "xf86.h"
-#include "xf86Resources.h"
#include "pciaccess.h"
#ifndef XSERVER_LIBPCIACCESS
@@ -46,6 +45,5 @@
void xorg_tracker_set_functions(ScrnInfoPtr scrn);
const OptionInfoRec * xorg_tracker_available_options(int chipid, int busid);
-void xorg_tracker_loader_ref_sym_lists(void);
#endif
diff --git a/src/gallium/winsys/drm/Makefile.template b/src/gallium/winsys/drm/Makefile.template
index 985e5a861f..9635c3c50e 100644
--- a/src/gallium/winsys/drm/Makefile.template
+++ b/src/gallium/winsys/drm/Makefile.template
@@ -83,7 +83,9 @@ default: depend symlinks $(TOP)/$(LIB_DIR)/gallium/$(LIBNAME)
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(PIPE_DRIVERS) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(MKLIB) -noprefix -o $@ \
- $(OBJECTS) $(PIPE_DRIVERS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
+ $(OBJECTS) $(PIPE_DRIVERS) \
+ -Wl,--start-group $(MESA_MODULES) -Wl,--end-group \
+ $(WINOBJ) $(DRI_LIB_DEPS) $(DRIVER_EXTRAS)
$(LIBNAME_EGL): $(WINSYS_OBJECTS) $(LIBS)
$(MKLIB) -o $(LIBNAME_EGL) \
diff --git a/src/gallium/winsys/drm/intel/dri/SConscript b/src/gallium/winsys/drm/intel/dri/SConscript
index e14e96e32f..f973811072 100644
--- a/src/gallium/winsys/drm/intel/dri/SConscript
+++ b/src/gallium/winsys/drm/intel/dri/SConscript
@@ -2,15 +2,19 @@ Import('*')
env = drienv.Clone()
+env.ParseConfig('pkg-config --cflags --libs libdrm_intel')
+
drivers = [
+ st_dri,
+ inteldrm,
softpipe,
i915simple,
trace,
- inteldrm
]
-env.SharedLibrary(
+env.LoadableModule(
target ='i915_dri.so',
source = COMMON_GALLIUM_SOURCES,
LIBS = drivers + mesa + auxiliaries + env['LIBS'],
+ SHLIBPREFIX = '',
)
diff --git a/src/gallium/winsys/drm/intel/egl/Makefile b/src/gallium/winsys/drm/intel/egl/Makefile
index c5217ad2d6..490baded66 100644
--- a/src/gallium/winsys/drm/intel/egl/Makefile
+++ b/src/gallium/winsys/drm/intel/egl/Makefile
@@ -8,6 +8,7 @@ PIPE_DRIVERS = \
$(TOP)/src/gallium/state_trackers/egl/libegldrm.a \
$(GALLIUMDIR)/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a
DRIVER_SOURCES =
diff --git a/src/gallium/winsys/drm/intel/gem/Makefile b/src/gallium/winsys/drm/intel/gem/Makefile
index 7ab1a2a771..0d6d4e37db 100644
--- a/src/gallium/winsys/drm/intel/gem/Makefile
+++ b/src/gallium/winsys/drm/intel/gem/Makefile
@@ -4,10 +4,10 @@ include $(TOP)/configs/current
LIBNAME = inteldrm
C_SOURCES = \
- intel_be_batchbuffer.c \
- intel_be_context.c \
- intel_be_device.c \
- intel_be_api.c
+ intel_drm_batchbuffer.c \
+ intel_drm_buffer.c \
+ intel_drm_fence.c \
+ intel_drm_api.c
LIBRARY_INCLUDES = $(shell pkg-config libdrm --cflags-only-I)
diff --git a/src/gallium/winsys/drm/intel/gem/SConscript b/src/gallium/winsys/drm/intel/gem/SConscript
index ea8a2e55f6..26717f391f 100644
--- a/src/gallium/winsys/drm/intel/gem/SConscript
+++ b/src/gallium/winsys/drm/intel/gem/SConscript
@@ -3,10 +3,10 @@ Import('*')
env = drienv.Clone()
inteldrm_sources = [
- 'intel_be_api.c',
- 'intel_be_batchbuffer.c',
- 'intel_be_context.c',
- 'intel_be_device.c',
+ 'intel_drm_api.c',
+ 'intel_drm_batchbuffer.c',
+ 'intel_drm_buffer.c',
+ 'intel_drm_fence.c',
]
inteldrm = env.ConvenienceLibrary(
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.c b/src/gallium/winsys/drm/intel/gem/intel_be_api.c
deleted file mode 100644
index dd5f814da3..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.c
+++ /dev/null
@@ -1,37 +0,0 @@
-
-#include "intel_be_api.h"
-#include "i915simple/i915_winsys.h"
-#include "identity/id_drm.h"
-#include "trace/tr_drm.h"
-
-static void destroy(struct drm_api *api)
-{
-
-}
-
-struct drm_api intel_be_drm_api =
-{
- /* intel_be_context.c */
- .create_context = intel_be_create_context,
- /* intel_be_device.c */
- .create_screen = intel_be_create_screen,
- .buffer_from_texture = intel_be_get_texture_buffer,
- .buffer_from_handle = intel_be_buffer_from_handle,
- .handle_from_buffer = intel_be_handle_from_buffer,
- .global_handle_from_buffer = intel_be_global_handle_from_buffer,
- .destroy = destroy,
-};
-
-struct drm_api *
-drm_api_create()
-{
-#ifdef DEBUG
-#if 0
- return identity_drm_create(&intel_be_drm_api);
-#else
- return trace_drm_create(&intel_be_drm_api);
-#endif
-#else
- return &intel_be_drm_api;
-#endif
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_api.h b/src/gallium/winsys/drm/intel/gem/intel_be_api.h
deleted file mode 100644
index f286b62eb8..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_api.h
+++ /dev/null
@@ -1,18 +0,0 @@
-
-#ifndef _INTEL_BE_API_H_
-#define _INTEL_BE_API_H_
-
-#include "pipe/p_compiler.h"
-
-#include "state_tracker/drm_api.h"
-
-#include "intel_be_device.h"
-
-extern struct drm_api intel_be_drm_api;
-
-struct pipe_screen *intel_be_create_screen(struct drm_api *api, int drmFD,
- struct drm_create_screen_arg *arg);
-struct pipe_context *intel_be_create_context(struct drm_api *api,
- struct pipe_screen *screen);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
deleted file mode 100644
index d5e63c3bae..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c
+++ /dev/null
@@ -1,139 +0,0 @@
-
-#include "i915simple/i915_debug.h"
-#include "intel_be_batchbuffer.h"
-#include "intel_be_context.h"
-#include "intel_be_device.h"
-#include "intel_be_fence.h"
-#include <errno.h>
-
-#include "util/u_memory.h"
-
-struct intel_be_batchbuffer *
-intel_be_batchbuffer_alloc(struct intel_be_context *intel)
-{
- struct intel_be_batchbuffer *batch = CALLOC_STRUCT(intel_be_batchbuffer);
-
-
- batch->base.buffer = NULL;
- batch->base.winsys = &intel->base;
- batch->base.map = NULL;
- batch->base.ptr = NULL;
- batch->base.size = 0;
- batch->base.actual_size = intel->device->max_batch_size;
- batch->base.relocs = 0;
- batch->base.max_relocs = 500;/*INTEL_DEFAULT_RELOCS;*/
-
- batch->base.map = malloc(batch->base.actual_size);
- memset(batch->base.map, 0, batch->base.actual_size);
-
- batch->base.ptr = batch->base.map;
-
- intel_be_batchbuffer_reset(batch);
-
- return batch;
-}
-
-void
-intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch)
-{
- struct intel_be_context *intel = intel_be_context(batch->base.winsys);
- struct intel_be_device *dev = intel->device;
-
- if (batch->bo)
- drm_intel_bo_unreference(batch->bo);
-
- memset(batch->base.map, 0, batch->base.actual_size);
- batch->base.ptr = batch->base.map;
- batch->base.size = batch->base.actual_size - BATCH_RESERVED;
-
- batch->base.relocs = 0;
-
- batch->bo = drm_intel_bo_alloc(dev->pools.gem,
- "gallium3d_batch_buffer",
- batch->base.actual_size, 0);
-}
-
-int
-intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
- unsigned pre_add,
- drm_intel_bo *bo,
- uint32_t read_domains,
- uint32_t write_domain)
-{
- unsigned offset;
- int ret = 0;
-
- assert(batch->base.relocs < batch->base.max_relocs);
-
- offset = (unsigned)(batch->base.ptr - batch->base.map);
-
- ret = drm_intel_bo_emit_reloc(batch->bo, offset,
- bo, pre_add,
- read_domains,
- write_domain);
-
- ((uint32_t*)batch->base.ptr)[0] = bo->offset + pre_add;
- batch->base.ptr += 4;
-
- if (!ret)
- batch->base.relocs++;
-
- return ret;
-}
-
-void
-intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
- struct intel_be_fence **fence)
-{
- struct i915_batchbuffer *i915 = &batch->base;
- unsigned used = 0;
- int ret = 0;
-
- assert(i915_batchbuffer_space(i915) >= 0);
-
- used = batch->base.ptr - batch->base.map;
- assert((used & 3) == 0);
-
- if (used & 4) {
- i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); // MI_FLUSH | FLUSH_MAP_CACHE;
- i915_batchbuffer_dword(i915, (0x0<<29)|(0x0<<23)); // MI_NOOP
- i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
- } else {
- i915_batchbuffer_dword(i915, (0x0<<29)|(0x4<<23)|(1<<0)); //MI_FLUSH | FLUSH_MAP_CACHE;
- i915_batchbuffer_dword(i915, (0x0<<29)|(0xA<<23)); // MI_BATCH_BUFFER_END;
- }
-
- used = batch->base.ptr - batch->base.map;
-
- drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
- ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
-
- assert(ret == 0);
-
- intel_be_batchbuffer_reset(batch);
-
- if (fence) {
- if (*fence)
- intel_be_fence_reference(fence, NULL);
-
- (*fence) = CALLOC_STRUCT(intel_be_fence);
- pipe_reference_init(&(*fence)->reference, 1);
- (*fence)->bo = NULL;
- }
-}
-
-void
-intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch)
-{
-
-}
-
-void
-intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch)
-{
- if (batch->bo)
- drm_intel_bo_unreference(batch->bo);
-
- free(batch->base.map);
- free(batch);
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h b/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
deleted file mode 100644
index 195bf8dee7..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.h
+++ /dev/null
@@ -1,55 +0,0 @@
-
-#ifndef INTEL_BE_BATCHBUFFER_H
-#define INTEL_BE_BATCHBUFFER_H
-
-#include "i915simple/i915_batch.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-#define BATCH_RESERVED 16
-
-#define INTEL_DEFAULT_RELOCS 100
-#define INTEL_MAX_RELOCS 400
-
-#define INTEL_BATCH_NO_CLIPRECTS 0x1
-#define INTEL_BATCH_CLIPRECTS 0x2
-
-struct intel_be_context;
-struct intel_be_device;
-struct intel_be_fence;
-
-struct intel_be_batchbuffer
-{
- struct i915_batchbuffer base;
-
- struct intel_be_context *intel;
- struct intel_be_device *device;
-
- drm_intel_bo *bo;
-};
-
-struct intel_be_batchbuffer *
-intel_be_batchbuffer_alloc(struct intel_be_context *intel);
-
-void
-intel_be_batchbuffer_free(struct intel_be_batchbuffer *batch);
-
-void
-intel_be_batchbuffer_finish(struct intel_be_batchbuffer *batch);
-
-void
-intel_be_batchbuffer_flush(struct intel_be_batchbuffer *batch,
- struct intel_be_fence **fence);
-
-void
-intel_be_batchbuffer_reset(struct intel_be_batchbuffer *batch);
-
-int
-intel_be_offset_relocation(struct intel_be_batchbuffer *batch,
- unsigned pre_add,
- drm_intel_bo *bo,
- uint32_t read_domains,
- uint32_t write_doman);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.c b/src/gallium/winsys/drm/intel/gem/intel_be_context.c
deleted file mode 100644
index db84f9af51..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.c
+++ /dev/null
@@ -1,120 +0,0 @@
-
-#include "pipe/p_screen.h"
-
-#include "softpipe/sp_winsys.h"
-
-#include "intel_be_device.h"
-#include "intel_be_context.h"
-#include "intel_be_batchbuffer.h"
-
-#include "i915_drm.h"
-
-#include "intel_be_api.h"
-
-static struct i915_batchbuffer *
-intel_be_batch_get(struct i915_winsys *sws)
-{
- struct intel_be_context *intel = intel_be_context(sws);
- return &intel->batch->base;
-}
-
-static void
-intel_be_batch_reloc(struct i915_winsys *sws,
- struct pipe_buffer *buf,
- unsigned access_flags,
- unsigned delta)
-{
- struct intel_be_context *intel = intel_be_context(sws);
- drm_intel_bo *bo = intel_bo(buf);
- int ret;
- uint32_t read = 0;
- uint32_t write = 0;
-
- if (access_flags & I915_BUFFER_ACCESS_WRITE) {
- write = I915_GEM_DOMAIN_RENDER;
- read = I915_GEM_DOMAIN_RENDER;
- }
-
- if (access_flags & I915_BUFFER_ACCESS_READ) {
- read |= I915_GEM_DOMAIN_VERTEX;
- }
-
- ret = intel_be_offset_relocation(intel->batch,
- delta,
- bo,
- read,
- write);
- assert(ret == 0);
-
- /* TODO change return type */
- /* return ret; */
-}
-
-static void
-intel_be_batch_flush(struct i915_winsys *sws,
- struct pipe_fence_handle **fence)
-{
- struct intel_be_context *intel = intel_be_context(sws);
- struct intel_be_fence **f = (struct intel_be_fence **)fence;
-
- if (fence && *fence)
- assert(0);
-
- intel_be_batchbuffer_flush(intel->batch, f);
-}
-
-
-/*
- * Misc functions.
- */
-
-static void
-intel_be_destroy_context(struct i915_winsys *winsys)
-{
- struct intel_be_context *intel = intel_be_context(winsys);
-
- intel_be_batchbuffer_free(intel->batch);
-
- free(intel);
-}
-
-boolean
-intel_be_init_context(struct intel_be_context *intel, struct intel_be_device *device)
-{
- assert(intel);
- assert(device);
- intel->device = device;
-
- intel->base.batch_get = intel_be_batch_get;
- intel->base.batch_reloc = intel_be_batch_reloc;
- intel->base.batch_flush = intel_be_batch_flush;
-
- intel->base.destroy = intel_be_destroy_context;
-
- intel->batch = intel_be_batchbuffer_alloc(intel);
-
- return true;
-}
-
-struct pipe_context *
-intel_be_create_context(struct drm_api *api, struct pipe_screen *screen)
-{
- struct intel_be_context *intel;
- struct pipe_context *pipe;
- struct intel_be_device *device = intel_be_device(screen->winsys);
-
- intel = (struct intel_be_context *)malloc(sizeof(*intel));
- memset(intel, 0, sizeof(*intel));
-
- intel_be_init_context(intel, device);
-
- if (device->softpipe)
- pipe = softpipe_create(screen);
- else
- pipe = i915_create_context(screen, &device->base, &intel->base);
-
- if (pipe)
- pipe->priv = intel;
-
- return pipe;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_context.h b/src/gallium/winsys/drm/intel/gem/intel_be_context.h
deleted file mode 100644
index 5a369669c0..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_context.h
+++ /dev/null
@@ -1,31 +0,0 @@
-
-#ifndef INTEL_BE_CONTEXT_H
-#define INTEL_BE_CONTEXT_H
-
-#include "i915simple/i915_winsys.h"
-
-struct intel_be_context
-{
- /** Interface to i915simple driver */
- struct i915_winsys base;
-
- struct intel_be_device *device;
- struct intel_be_batchbuffer *batch;
-};
-
-static INLINE struct intel_be_context *
-intel_be_context(struct i915_winsys *sws)
-{
- return (struct intel_be_context *)sws;
-}
-
-/**
- * Intialize a allocated intel_be_context struct.
- *
- * Remember to set the hardware_* functions.
- */
-boolean
-intel_be_init_context(struct intel_be_context *intel,
- struct intel_be_device *device);
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.c b/src/gallium/winsys/drm/intel/gem/intel_be_device.c
deleted file mode 100644
index e3630f5d12..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.c
+++ /dev/null
@@ -1,369 +0,0 @@
-
-#include "intel_be_device.h"
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_defines.h"
-#include "pipe/p_state.h"
-#include "pipe/p_inlines.h"
-#include "util/u_memory.h"
-#include "util/u_debug.h"
-
-#include "intel_be_fence.h"
-
-#include "i915simple/i915_winsys.h"
-#include "softpipe/sp_winsys.h"
-
-#include "intel_be_api.h"
-#include <stdio.h>
-
-/*
- * Buffer
- */
-
-static void *
-intel_be_buffer_map(struct pipe_winsys *winsys,
- struct pipe_buffer *buf,
- unsigned flags)
-{
- drm_intel_bo *bo = intel_bo(buf);
- int write = 0;
- int ret;
-
- if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- /* Remove this when drm_intel_bo_map supports DONTBLOCK
- */
- return NULL;
- }
-
- if (flags & PIPE_BUFFER_USAGE_CPU_WRITE)
- write = 1;
-
- ret = drm_intel_bo_map(bo, write);
-
- if (ret)
- return NULL;
-
- return bo->virtual;
-}
-
-static void
-intel_be_buffer_unmap(struct pipe_winsys *winsys,
- struct pipe_buffer *buf)
-{
- drm_intel_bo_unmap(intel_bo(buf));
-}
-
-static void
-intel_be_buffer_destroy(struct pipe_buffer *buf)
-{
- drm_intel_bo_unreference(intel_bo(buf));
- free(buf);
-}
-
-static struct pipe_buffer *
-intel_be_buffer_create(struct pipe_winsys *winsys,
- unsigned alignment,
- unsigned usage,
- unsigned size)
-{
- struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
- struct intel_be_device *dev = intel_be_device(winsys);
- drm_intel_bufmgr *pool;
- char *name;
-
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = alignment;
- buffer->base.usage = usage;
- buffer->base.size = size;
- buffer->flinked = FALSE;
- buffer->flink = 0;
-
- if (usage & (PIPE_BUFFER_USAGE_VERTEX | PIPE_BUFFER_USAGE_CONSTANT)) {
- /* Local buffer */
- name = "gallium3d_local";
- pool = dev->pools.gem;
- } else if (usage & PIPE_BUFFER_USAGE_CUSTOM) {
- /* For vertex buffers */
- name = "gallium3d_internal_vertex";
- pool = dev->pools.gem;
- } else {
- /* Regular buffers */
- name = "gallium3d_regular";
- pool = dev->pools.gem;
- }
-
- buffer->bo = drm_intel_bo_alloc(pool, name, size, alignment);
-
- if (!buffer->bo)
- goto err;
-
- return &buffer->base;
-
-err:
- free(buffer);
- return NULL;
-}
-
-static struct pipe_buffer *
-intel_be_user_buffer_create(struct pipe_winsys *winsys, void *ptr, unsigned bytes)
-{
- struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
- struct intel_be_device *dev = intel_be_device(winsys);
- int ret;
-
- if (!buffer)
- return NULL;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.alignment = 0;
- buffer->base.usage = 0;
- buffer->base.size = bytes;
-
- buffer->bo = drm_intel_bo_alloc(dev->pools.gem,
- "gallium3d_user_buffer",
- bytes, 0);
-
- if (!buffer->bo)
- goto err;
-
- ret = drm_intel_bo_subdata(buffer->bo,
- 0, bytes, ptr);
-
- if (ret)
- goto err;
-
- return &buffer->base;
-
-err:
- free(buffer);
- return NULL;
-}
-
-boolean
-intel_be_get_texture_buffer(struct drm_api *api,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride)
-{
- struct intel_be_device *dev;
-
- if (!texture)
- return FALSE;
-
- dev = intel_be_device(texture->screen->winsys);
- if (dev->softpipe)
- return softpipe_get_texture_buffer(texture, buffer, stride);
- else
- return i915_get_texture_buffer(texture, buffer, stride);
-}
-
-struct pipe_buffer *
-intel_be_buffer_from_handle(struct drm_api *api,
- struct pipe_screen *screen,
- const char* name, unsigned handle)
-{
- struct intel_be_device *dev = intel_be_device(screen->winsys);
- struct intel_be_buffer *buffer = CALLOC_STRUCT(intel_be_buffer);
-
- if (!buffer)
- return NULL;
-
- buffer->bo = drm_intel_bo_gem_create_from_name(dev->pools.gem, name, handle);
-
- if (!buffer->bo)
- goto err;
-
- pipe_reference_init(&buffer->base.reference, 1);
- buffer->base.screen = screen;
- buffer->base.alignment = buffer->bo->align;
- buffer->base.usage = PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE |
- PIPE_BUFFER_USAGE_CPU_READ |
- PIPE_BUFFER_USAGE_CPU_WRITE;
- buffer->base.size = buffer->bo->size;
-
- return &buffer->base;
-
-err:
- free(buffer);
- return NULL;
-}
-
-boolean
-intel_be_handle_from_buffer(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle)
-{
- if (!buffer)
- return FALSE;
-
- *handle = intel_bo(buffer)->handle;
- return TRUE;
-}
-
-boolean
-intel_be_global_handle_from_buffer(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle)
-{
- struct intel_be_buffer *buf = intel_be_buffer(buffer);
-
- if (!buffer)
- return FALSE;
-
- if (!buf->flinked) {
- if (drm_intel_bo_flink(intel_bo(buffer), &buf->flink))
- return FALSE;
- buf->flinked = TRUE;
- }
-
- *handle = buf->flink;
- return TRUE;
-}
-/*
- * Fence
- */
-
-static void
-intel_be_fence_refunref(struct pipe_winsys *sws,
- struct pipe_fence_handle **ptr,
- struct pipe_fence_handle *fence)
-{
- struct intel_be_fence **p = (struct intel_be_fence **)ptr;
- struct intel_be_fence *f = (struct intel_be_fence *)fence;
-
- intel_be_fence_reference(p, f);
-}
-
-static int
-intel_be_fence_signalled(struct pipe_winsys *sws,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- assert(0);
-
- return 0;
-}
-
-static int
-intel_be_fence_finish(struct pipe_winsys *sws,
- struct pipe_fence_handle *fence,
- unsigned flag)
-{
- struct intel_be_fence *f = (struct intel_be_fence *)fence;
-
- /* fence already expired */
- if (!f->bo)
- return 0;
-
- drm_intel_bo_wait_rendering(f->bo);
- drm_intel_bo_unreference(f->bo);
- f->bo = NULL;
-
- return 0;
-}
-
-/*
- * Misc functions
- */
-
-static void
-intel_be_destroy_winsys(struct pipe_winsys *winsys)
-{
- struct intel_be_device *dev = intel_be_device(winsys);
-
- drm_intel_bufmgr_destroy(dev->pools.gem);
-
- free(dev);
-}
-
-boolean
-intel_be_init_device(struct intel_be_device *dev, int fd, unsigned id)
-{
- dev->fd = fd;
- dev->id = id;
- dev->max_batch_size = 16 * 4096;
- dev->max_vertex_size = 128 * 4096;
-
- dev->base.buffer_create = intel_be_buffer_create;
- dev->base.user_buffer_create = intel_be_user_buffer_create;
- dev->base.buffer_map = intel_be_buffer_map;
- dev->base.buffer_unmap = intel_be_buffer_unmap;
- dev->base.buffer_destroy = intel_be_buffer_destroy;
-
- /* Not used anymore */
- dev->base.surface_buffer_create = NULL;
-
- dev->base.fence_reference = intel_be_fence_refunref;
- dev->base.fence_signalled = intel_be_fence_signalled;
- dev->base.fence_finish = intel_be_fence_finish;
-
- dev->base.destroy = intel_be_destroy_winsys;
-
- dev->pools.gem = drm_intel_bufmgr_gem_init(dev->fd, dev->max_batch_size);
-
- dev->softpipe = debug_get_bool_option("INTEL_SOFTPIPE", FALSE);
-
- return true;
-}
-
-static void
-intel_be_get_device_id(unsigned int *device_id)
-{
- char path[512];
- FILE *file;
- void *shutup_gcc;
-
- /*
- * FIXME: Fix this up to use a drm ioctl or whatever.
- */
-
- snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
- file = fopen(path, "r");
- if (!file) {
- return;
- }
-
- shutup_gcc = fgets(path, sizeof(path), file);
- sscanf(path, "%x", device_id);
- fclose(file);
-}
-
-struct pipe_screen *
-intel_be_create_screen(struct drm_api *api, int drmFD,
- struct drm_create_screen_arg *arg)
-{
- struct intel_be_device *dev;
- struct pipe_screen *screen;
- unsigned int deviceID;
-
- if (arg != NULL) {
- switch(arg->mode) {
- case DRM_CREATE_NORMAL:
- break;
- default:
- return NULL;
- }
- }
-
- /* Allocate the private area */
- dev = malloc(sizeof(*dev));
- if (!dev)
- return NULL;
- memset(dev, 0, sizeof(*dev));
-
- intel_be_get_device_id(&deviceID);
- intel_be_init_device(dev, drmFD, deviceID);
-
- if (dev->softpipe) {
- screen = softpipe_create_screen(&dev->base);
- } else
- screen = i915_create_screen(&dev->base, deviceID);
-
- return screen;
-}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_device.h b/src/gallium/winsys/drm/intel/gem/intel_be_device.h
deleted file mode 100644
index 56d95bd7fe..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_device.h
+++ /dev/null
@@ -1,108 +0,0 @@
-
-#ifndef INTEL_DRM_DEVICE_H
-#define INTEL_DRM_DEVICE_H
-
-#include "pipe/internal/p_winsys_screen.h"
-#include "pipe/p_context.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-struct drm_api;
-
-/*
- * Device
- */
-
-struct intel_be_device
-{
- struct pipe_winsys base;
-
- boolean softpipe;
-
- int fd; /**< Drm file discriptor */
-
- unsigned id;
-
- size_t max_batch_size;
- size_t max_vertex_size;
-
- struct {
- drm_intel_bufmgr *gem;
- } pools;
-};
-
-static INLINE struct intel_be_device *
-intel_be_device(struct pipe_winsys *winsys)
-{
- return (struct intel_be_device *)winsys;
-}
-
-boolean
-intel_be_init_device(struct intel_be_device *device, int fd, unsigned id);
-
-/*
- * Buffer
- */
-
-struct intel_be_buffer {
- struct pipe_buffer base;
- drm_intel_bo *bo;
- boolean flinked;
- unsigned flink;
-};
-
-/*
- * Wrapper for driver get_texture_buffer functions.
- */
-boolean
-intel_be_get_texture_buffer(struct drm_api *api,
- struct pipe_texture *texture,
- struct pipe_buffer **buffer,
- unsigned *stride);
-
-/**
- * Create a be buffer from a drm bo handle.
- *
- * Takes a reference.
- */
-struct pipe_buffer *
-intel_be_buffer_from_handle(struct drm_api *api,
- struct pipe_screen *screen,
- const char* name, unsigned handle);
-
-/**
- * Gets a handle from a buffer.
- *
- * If buffer is destroyed handle may become invalid.
- */
-boolean
-intel_be_handle_from_buffer(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle);
-
-/**
- * Gets the global handle from a buffer.
- *
- * If buffer is destroyed handle may become invalid.
- */
-boolean
-intel_be_global_handle_from_buffer(struct drm_api *api,
- struct pipe_screen *screen,
- struct pipe_buffer *buffer,
- unsigned *handle);
-
-static INLINE struct intel_be_buffer *
-intel_be_buffer(struct pipe_buffer *buf)
-{
- return (struct intel_be_buffer *)buf;
-}
-
-static INLINE drm_intel_bo *
-intel_bo(struct pipe_buffer *buf)
-{
- return intel_be_buffer(buf)->bo;
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h b/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
deleted file mode 100644
index a8abb01a9e..0000000000
--- a/src/gallium/winsys/drm/intel/gem/intel_be_fence.h
+++ /dev/null
@@ -1,34 +0,0 @@
-
-#ifndef INTEL_BE_FENCE_H
-#define INTEL_BE_FENCE_H
-
-#include "pipe/p_defines.h"
-
-#include "drm.h"
-#include "intel_bufmgr.h"
-
-/**
- * Because gem does not have fence's we have to create our own fences.
- *
- * They work by keeping the batchbuffer around and checking if that has
- * been idled. If bo is NULL fence has expired.
- */
-struct intel_be_fence
-{
- struct pipe_reference reference;
- drm_intel_bo *bo;
-};
-
-static INLINE void
-intel_be_fence_reference(struct intel_be_fence **ptr, struct intel_be_fence *f)
-{
- struct intel_be_fence *old_fence = *ptr;
-
- if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
- if (old_fence->bo)
- drm_intel_bo_unreference(old_fence->bo);
- free(old_fence);
- }
-}
-
-#endif
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_api.c b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
new file mode 100644
index 0000000000..0fd5cdd969
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_api.c
@@ -0,0 +1,203 @@
+
+#include "state_tracker/drm_api.h"
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915simple/i915_context.h"
+#include "i915simple/i915_screen.h"
+
+#include "trace/tr_drm.h"
+
+/*
+ * Helper functions
+ */
+
+
+static void
+intel_drm_get_device_id(unsigned int *device_id)
+{
+ char path[512];
+ FILE *file;
+ void *shutup_gcc;
+
+ /*
+ * FIXME: Fix this up to use a drm ioctl or whatever.
+ */
+
+ snprintf(path, sizeof(path), "/sys/class/drm/card0/device/device");
+ file = fopen(path, "r");
+ if (!file) {
+ return;
+ }
+
+ shutup_gcc = fgets(path, sizeof(path), file);
+ sscanf(path, "%x", device_id);
+ fclose(file);
+}
+
+static struct intel_buffer *
+intel_drm_buffer_from_handle(struct intel_drm_winsys *idws,
+ const char* name, unsigned handle)
+{
+ struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->bo = drm_intel_bo_gem_create_from_name(idws->pools.gem, name, handle);
+ buf->flinked = TRUE;
+ buf->flink = handle;
+
+ if (!buf->bo)
+ goto err;
+
+ return (struct intel_buffer *)buf;
+
+err:
+ FREE(buf);
+ return NULL;
+}
+
+
+/*
+ * Exported functions
+ */
+
+
+static struct pipe_texture *
+intel_drm_texture_from_shared_handle(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *templ,
+ const char* name,
+ unsigned pitch,
+ unsigned handle)
+{
+ struct intel_drm_winsys *idws = intel_drm_winsys(i915_screen(screen)->iws);
+ struct intel_buffer *buffer;
+
+ buffer = intel_drm_buffer_from_handle(idws, name, handle);
+ if (!buffer)
+ return NULL;
+
+ return i915_texture_blanket_intel(screen, templ, pitch, buffer);
+}
+
+static boolean
+intel_drm_shared_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *pitch,
+ unsigned *handle)
+{
+ struct intel_drm_buffer *buf = NULL;
+ struct intel_buffer *buffer = NULL;
+ if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
+ return FALSE;
+
+ buf = intel_drm_buffer(buffer);
+ if (!buf->flinked) {
+ if (drm_intel_bo_flink(buf->bo, &buf->flink))
+ return FALSE;
+ buf->flinked = TRUE;
+ }
+
+ *handle = buf->flink;
+
+ return TRUE;
+}
+
+static boolean
+intel_drm_local_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *pitch,
+ unsigned *handle)
+{
+ struct intel_buffer *buffer = NULL;
+ if (!i915_get_texture_buffer_intel(texture, &buffer, pitch))
+ return FALSE;
+
+ *handle = intel_drm_buffer(buffer)->bo->handle;
+
+ return TRUE;
+}
+
+static void
+intel_drm_winsys_destroy(struct intel_winsys *iws)
+{
+ struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+
+ drm_intel_bufmgr_destroy(idws->pools.gem);
+
+ FREE(idws);
+}
+
+static struct pipe_screen *
+intel_drm_create_screen(struct drm_api *api, int drmFD,
+ struct drm_create_screen_arg *arg)
+{
+ struct intel_drm_winsys *idws;
+ unsigned int deviceID;
+
+ if (arg != NULL) {
+ switch(arg->mode) {
+ case DRM_CREATE_NORMAL:
+ break;
+ default:
+ return NULL;
+ }
+ }
+
+ idws = CALLOC_STRUCT(intel_drm_winsys);
+ if (!idws)
+ return NULL;
+
+ intel_drm_get_device_id(&deviceID);
+
+ intel_drm_winsys_init_batchbuffer_functions(idws);
+ intel_drm_winsys_init_buffer_functions(idws);
+ intel_drm_winsys_init_fence_functions(idws);
+
+ idws->fd = drmFD;
+ idws->id = deviceID;
+ idws->max_batch_size = 16 * 4096;
+
+ idws->base.destroy = intel_drm_winsys_destroy;
+
+ idws->pools.gem = drm_intel_bufmgr_gem_init(idws->fd, idws->max_batch_size);
+
+ idws->softpipe = FALSE;
+ idws->dump_cmd = debug_get_bool_option("INTEL_DUMP_CMD", FALSE);
+
+ return i915_create_screen(&idws->base, deviceID);
+}
+
+static struct pipe_context *
+intel_drm_create_context(struct drm_api *api, struct pipe_screen *screen)
+{
+ return i915_create_context(screen);
+}
+
+static void
+destroy(struct drm_api *api)
+{
+
+}
+
+struct drm_api intel_drm_api =
+{
+ .create_context = intel_drm_create_context,
+ .create_screen = intel_drm_create_screen,
+ .texture_from_shared_handle = intel_drm_texture_from_shared_handle,
+ .shared_handle_from_texture = intel_drm_shared_handle_from_texture,
+ .local_handle_from_texture = intel_drm_local_handle_from_texture,
+ .destroy = destroy,
+};
+
+struct drm_api *
+drm_api_create()
+{
+ return trace_drm_create(&intel_drm_api);
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
new file mode 100644
index 0000000000..ebd1b607b7
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_batchbuffer.c
@@ -0,0 +1,229 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+#define BATCH_RESERVED 16
+
+#define INTEL_DEFAULT_RELOCS 100
+#define INTEL_MAX_RELOCS 400
+
+#define INTEL_BATCH_NO_CLIPRECTS 0x1
+#define INTEL_BATCH_CLIPRECTS 0x2
+
+#undef INTEL_RUN_SYNC
+#undef INTEL_MAP_BATCHBUFFER
+
+struct intel_drm_batchbuffer
+{
+ struct intel_batchbuffer base;
+
+ size_t actual_size;
+
+ drm_intel_bo *bo;
+};
+
+static INLINE struct intel_drm_batchbuffer *
+intel_drm_batchbuffer(struct intel_batchbuffer *batch)
+{
+ return (struct intel_drm_batchbuffer *)batch;
+}
+
+static void
+intel_drm_batchbuffer_reset(struct intel_drm_batchbuffer *batch)
+{
+ struct intel_drm_winsys *idws = intel_drm_winsys(batch->base.iws);
+
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+ batch->bo = drm_intel_bo_alloc(idws->pools.gem,
+ "gallium3d_batchbuffer",
+ batch->actual_size,
+ 4096);
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ drm_intel_bo_map(batch->bo, TRUE);
+ batch->base.map = batch->bo->virtual;
+#endif
+
+ memset(batch->base.map, 0, batch->actual_size);
+ batch->base.ptr = batch->base.map;
+ batch->base.size = batch->actual_size - BATCH_RESERVED;
+ batch->base.relocs = 0;
+}
+
+static struct intel_batchbuffer *
+intel_drm_batchbuffer_create(struct intel_winsys *iws)
+{
+ struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+ struct intel_drm_batchbuffer *batch = CALLOC_STRUCT(intel_drm_batchbuffer);
+
+ batch->actual_size = idws->max_batch_size;
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ batch->base.map = NULL;
+#else
+ batch->base.map = MALLOC(batch->actual_size);
+#endif
+ batch->base.ptr = NULL;
+ batch->base.size = 0;
+
+ batch->base.relocs = 0;
+ batch->base.max_relocs = 300;/*INTEL_DEFAULT_RELOCS;*/
+
+ batch->base.iws = iws;
+
+ intel_drm_batchbuffer_reset(batch);
+
+ return &batch->base;
+}
+
+static int
+intel_drm_batchbuffer_reloc(struct intel_batchbuffer *ibatch,
+ struct intel_buffer *buffer,
+ enum intel_buffer_usage usage,
+ unsigned pre_add)
+{
+ struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ unsigned write_domain = 0;
+ unsigned read_domain = 0;
+ unsigned offset;
+ int ret = 0;
+
+ assert(batch->base.relocs < batch->base.max_relocs);
+
+ if (usage == INTEL_USAGE_SAMPLER) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_SAMPLER;
+
+ } else if (usage == INTEL_USAGE_RENDER) {
+ write_domain = I915_GEM_DOMAIN_RENDER;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == INTEL_USAGE_2D_TARGET) {
+ write_domain = I915_GEM_DOMAIN_RENDER;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == INTEL_USAGE_2D_SOURCE) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_RENDER;
+
+ } else if (usage == INTEL_USAGE_VERTEX) {
+ write_domain = 0;
+ read_domain = I915_GEM_DOMAIN_VERTEX;
+
+ } else {
+ assert(0);
+ return -1;
+ }
+
+ offset = (unsigned)(batch->base.ptr - batch->base.map);
+
+ ret = drm_intel_bo_emit_reloc(batch->bo, offset,
+ intel_bo(buffer), pre_add,
+ read_domain,
+ write_domain);
+
+ ((uint32_t*)batch->base.ptr)[0] = intel_bo(buffer)->offset + pre_add;
+ batch->base.ptr += 4;
+
+ if (!ret)
+ batch->base.relocs++;
+
+ return ret;
+}
+
+static void
+intel_drm_batchbuffer_flush(struct intel_batchbuffer *ibatch,
+ struct pipe_fence_handle **fence)
+{
+ struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+ unsigned used = 0;
+ int ret = 0;
+ int i;
+
+ assert(intel_batchbuffer_space(ibatch) >= 0);
+
+ used = batch->base.ptr - batch->base.map;
+ assert((used & 3) == 0);
+
+ if (used & 4) {
+ // MI_FLUSH | FLUSH_MAP_CACHE;
+ intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0));
+ // MI_NOOP
+ intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x0<<23));
+ // MI_BATCH_BUFFER_END;
+ intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23));
+ } else {
+ //MI_FLUSH | FLUSH_MAP_CACHE;
+ intel_batchbuffer_dword(ibatch, (0x0<<29)|(0x4<<23)|(1<<0));
+ // MI_BATCH_BUFFER_END;
+ intel_batchbuffer_dword(ibatch, (0x0<<29)|(0xA<<23));
+ }
+
+ used = batch->base.ptr - batch->base.map;
+
+#ifdef INTEL_MAP_BATCHBUFFER
+ drm_intel_bo_unmap(batch->bo);
+#else
+ drm_intel_bo_subdata(batch->bo, 0, used, batch->base.map);
+#endif
+
+ /* Do the sending to HW */
+ ret = drm_intel_bo_exec(batch->bo, used, NULL, 0, 0);
+ assert(ret == 0);
+
+ if (intel_drm_winsys(ibatch->iws)->dump_cmd) {
+ unsigned *ptr;
+ drm_intel_bo_map(batch->bo, FALSE);
+ ptr = (unsigned*)batch->bo->virtual;
+
+ debug_printf("%s:\n", __func__);
+ for (i = 0; i < used / 4; i++, ptr++) {
+ debug_printf("\t%08x: %08x\n", i*4, *ptr);
+ }
+
+ drm_intel_bo_unmap(batch->bo);
+ } else {
+#ifdef INTEL_RUN_SYNC
+ drm_intel_bo_map(batch->bo, FALSE);
+ drm_intel_bo_unmap(batch->bo);
+#endif
+ }
+
+ if (fence) {
+ ibatch->iws->fence_reference(ibatch->iws, fence, NULL);
+
+#ifdef INTEL_RUN_SYNC
+ /* we run synced to GPU so just pass null */
+ (*fence) = intel_drm_fence_create(NULL);
+#else
+ (*fence) = intel_drm_fence_create(batch->bo);
+#endif
+ }
+
+ intel_drm_batchbuffer_reset(batch);
+}
+
+static void
+intel_drm_batchbuffer_destroy(struct intel_batchbuffer *ibatch)
+{
+ struct intel_drm_batchbuffer *batch = intel_drm_batchbuffer(ibatch);
+
+ if (batch->bo)
+ drm_intel_bo_unreference(batch->bo);
+
+#ifndef INTEL_MAP_BATCHBUFFER
+ FREE(batch->base.map);
+#endif
+ FREE(batch);
+}
+
+void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws)
+{
+ idws->base.batchbuffer_create = intel_drm_batchbuffer_create;
+ idws->base.batchbuffer_reloc = intel_drm_batchbuffer_reloc;
+ idws->base.batchbuffer_flush = intel_drm_batchbuffer_flush;
+ idws->base.batchbuffer_destroy = intel_drm_batchbuffer_destroy;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
new file mode 100644
index 0000000000..0030f915a3
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_buffer.c
@@ -0,0 +1,148 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+
+#include "i915_drm.h"
+
+static struct intel_buffer *
+intel_drm_buffer_create(struct intel_winsys *iws,
+ unsigned size, unsigned alignment,
+ enum intel_buffer_type type)
+{
+ struct intel_drm_buffer *buf = CALLOC_STRUCT(intel_drm_buffer);
+ struct intel_drm_winsys *idws = intel_drm_winsys(iws);
+ drm_intel_bufmgr *pool;
+ char *name;
+
+ if (!buf)
+ return NULL;
+
+ buf->magic = 0xDEAD1337;
+ buf->flinked = FALSE;
+ buf->flink = 0;
+ buf->map_gtt = FALSE;
+
+ if (type == INTEL_NEW_TEXTURE) {
+ name = "gallium3d_texture";
+ pool = idws->pools.gem;
+ } else if (type == INTEL_NEW_VERTEX) {
+ name = "gallium3d_vertex";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else if (type == INTEL_NEW_SCANOUT) {
+ name = "gallium3d_scanout";
+ pool = idws->pools.gem;
+ buf->map_gtt = TRUE;
+ } else {
+ assert(0);
+ name = "gallium3d_unknown";
+ pool = idws->pools.gem;
+ }
+
+ buf->bo = drm_intel_bo_alloc(pool, name, size, alignment);
+
+ if (!buf->bo)
+ goto err;
+
+ return (struct intel_buffer *)buf;
+
+err:
+ assert(0);
+ FREE(buf);
+ return NULL;
+}
+
+static int
+intel_drm_buffer_set_fence_reg(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ unsigned stride,
+ enum intel_buffer_tile tile)
+{
+ assert(I915_TILING_NONE == INTEL_TILE_NONE);
+ assert(I915_TILING_X == INTEL_TILE_X);
+ assert(I915_TILING_Y == INTEL_TILE_Y);
+
+ return drm_intel_bo_set_tiling(intel_bo(buffer), &tile, stride);
+}
+
+static void *
+intel_drm_buffer_map(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ boolean write)
+{
+ struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+ drm_intel_bo *bo = intel_bo(buffer);
+ int ret = 0;
+
+ assert(bo);
+
+ if (buf->map_count)
+ goto out;
+
+ if (buf->map_gtt)
+ ret = drm_intel_gem_bo_map_gtt(bo);
+ else
+ ret = drm_intel_bo_map(bo, write);
+
+ buf->ptr = bo->virtual;
+
+ assert(ret == 0);
+out:
+ if (ret)
+ return NULL;
+
+ buf->map_count++;
+ return buf->ptr;
+}
+
+static void
+intel_drm_buffer_unmap(struct intel_winsys *iws,
+ struct intel_buffer *buffer)
+{
+ struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+
+ if (--buf->map_count)
+ return;
+
+ if (buf->map_gtt)
+ drm_intel_gem_bo_unmap_gtt(intel_bo(buffer));
+ else
+ drm_intel_bo_unmap(intel_bo(buffer));
+}
+
+static int
+intel_drm_buffer_write(struct intel_winsys *iws,
+ struct intel_buffer *buffer,
+ const void *data,
+ size_t size,
+ size_t offset)
+{
+ struct intel_drm_buffer *buf = intel_drm_buffer(buffer);
+
+ return drm_intel_bo_subdata(buf->bo, offset, size, (void*)data);
+}
+
+static void
+intel_drm_buffer_destroy(struct intel_winsys *iws,
+ struct intel_buffer *buffer)
+{
+ drm_intel_bo_unreference(intel_bo(buffer));
+
+#ifdef DEBUG
+ intel_drm_buffer(buffer)->magic = 0;
+ intel_drm_buffer(buffer)->bo = NULL;
+#endif
+
+ FREE(buffer);
+}
+
+void
+intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws)
+{
+ idws->base.buffer_create = intel_drm_buffer_create;
+ idws->base.buffer_set_fence_reg = intel_drm_buffer_set_fence_reg;
+ idws->base.buffer_map = intel_drm_buffer_map;
+ idws->base.buffer_unmap = intel_drm_buffer_unmap;
+ idws->base.buffer_write = intel_drm_buffer_write;
+ idws->base.buffer_destroy = intel_drm_buffer_destroy;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
new file mode 100644
index 0000000000..e70bfe7b44
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_fence.c
@@ -0,0 +1,81 @@
+
+#include "intel_drm_winsys.h"
+#include "util/u_memory.h"
+#include "pipe/p_refcnt.h"
+
+/**
+ * Because gem does not have fence's we have to create our own fences.
+ *
+ * They work by keeping the batchbuffer around and checking if that has
+ * been idled. If bo is NULL fence has expired.
+ */
+struct intel_drm_fence
+{
+ struct pipe_reference reference;
+ drm_intel_bo *bo;
+};
+
+
+struct pipe_fence_handle *
+intel_drm_fence_create(drm_intel_bo *bo)
+{
+ struct intel_drm_fence *fence = CALLOC_STRUCT(intel_drm_fence);
+
+ pipe_reference_init(&fence->reference, 1);
+ /* bo is null if fence already expired */
+ if (bo) {
+ drm_intel_bo_reference(bo);
+ fence->bo = bo;
+ }
+
+ return (struct pipe_fence_handle *)fence;
+}
+
+static void
+intel_drm_fence_reference(struct intel_winsys *iws,
+ struct pipe_fence_handle **ptr,
+ struct pipe_fence_handle *fence)
+{
+ struct intel_drm_fence *old = (struct intel_drm_fence *)*ptr;
+ struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+
+ if (pipe_reference((struct pipe_reference**)ptr, &f->reference)) {
+ if (old->bo)
+ drm_intel_bo_unreference(old->bo);
+ FREE(old);
+ }
+}
+
+static int
+intel_drm_fence_signalled(struct intel_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ assert(0);
+
+ return 0;
+}
+
+static int
+intel_drm_fence_finish(struct intel_winsys *iws,
+ struct pipe_fence_handle *fence)
+{
+ struct intel_drm_fence *f = (struct intel_drm_fence *)fence;
+
+ /* fence already expired */
+ if (!f->bo)
+ return 0;
+
+ drm_intel_bo_wait_rendering(f->bo);
+ drm_intel_bo_unreference(f->bo);
+ f->bo = NULL;
+
+ return 0;
+}
+
+void
+intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws)
+{
+ idws->base.fence_reference = intel_drm_fence_reference;
+ idws->base.fence_signalled = intel_drm_fence_signalled;
+ idws->base.fence_finish = intel_drm_fence_finish;
+}
diff --git a/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
new file mode 100644
index 0000000000..415c45feea
--- /dev/null
+++ b/src/gallium/winsys/drm/intel/gem/intel_drm_winsys.h
@@ -0,0 +1,78 @@
+
+#ifndef INTEL_DRM_WINSYS_H
+#define INTEL_DRM_WINSYS_H
+
+#include "i915simple/intel_batchbuffer.h"
+
+#include "drm.h"
+#include "intel_bufmgr.h"
+
+
+/*
+ * Winsys
+ */
+
+
+struct intel_drm_winsys
+{
+ struct intel_winsys base;
+
+ boolean softpipe;
+ boolean dump_cmd;
+
+ int fd; /**< Drm file discriptor */
+
+ unsigned id;
+
+ size_t max_batch_size;
+
+ struct {
+ drm_intel_bufmgr *gem;
+ } pools;
+};
+
+static INLINE struct intel_drm_winsys *
+intel_drm_winsys(struct intel_winsys *iws)
+{
+ return (struct intel_drm_winsys *)iws;
+}
+
+struct intel_drm_winsys * intel_drm_winsys_create(int fd, unsigned pci_id);
+struct pipe_fence_handle * intel_drm_fence_create(drm_intel_bo *bo);
+
+void intel_drm_winsys_init_batchbuffer_functions(struct intel_drm_winsys *idws);
+void intel_drm_winsys_init_buffer_functions(struct intel_drm_winsys *idws);
+void intel_drm_winsys_init_fence_functions(struct intel_drm_winsys *idws);
+
+
+/*
+ * Buffer
+ */
+
+
+struct intel_drm_buffer {
+ unsigned magic;
+
+ drm_intel_bo *bo;
+
+ void *ptr;
+ unsigned map_count;
+ boolean map_gtt;
+
+ boolean flinked;
+ unsigned flink;
+};
+
+static INLINE struct intel_drm_buffer *
+intel_drm_buffer(struct intel_buffer *buffer)
+{
+ return (struct intel_drm_buffer *)buffer;
+}
+
+static INLINE drm_intel_bo *
+intel_bo(struct intel_buffer *buffer)
+{
+ return intel_drm_buffer(buffer)->bo;
+}
+
+#endif
diff --git a/src/gallium/winsys/drm/intel/xorg/Makefile b/src/gallium/winsys/drm/intel/xorg/Makefile
index d51cca8d21..9e56853b02 100644
--- a/src/gallium/winsys/drm/intel/xorg/Makefile
+++ b/src/gallium/winsys/drm/intel/xorg/Makefile
@@ -19,6 +19,7 @@ LIBS = \
$(TOP)/src/gallium/state_trackers/xorg/libxorgtracker.a \
$(TOP)/src/gallium/winsys/drm/intel/gem/libinteldrm.a \
$(TOP)/src/gallium/drivers/i915simple/libi915simple.a \
+ $(TOP)/src/gallium/drivers/trace/libtrace.a \
$(TOP)/src/gallium/drivers/softpipe/libsoftpipe.a \
$(GALLIUM_AUXILIARIES)
diff --git a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
index 46a7971f60..369dc356cf 100644
--- a/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
+++ b/src/gallium/winsys/drm/intel/xorg/intel_xorg.c
@@ -47,8 +47,8 @@ static SymTabRec intel_xorg_chipsets[] = {
};
static PciChipsets intel_xorg_pci_devices[] = {
- {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
- {-1, -1, RES_UNDEFINED}
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
};
static XF86ModuleVersionInfo intel_xorg_version = {
@@ -105,12 +105,6 @@ intel_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
/*
- * Tell the loader about symbols from other modules that this module
- * might refer to.
- */
- xorg_tracker_loader_ref_sym_lists();
-
- /*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
@@ -140,7 +134,7 @@ intel_xorg_pci_probe(DriverPtr driver,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
- scrn->driverName = "modesetting";
+ scrn->driverName = "i915";
scrn->name = "modesetting";
scrn->Probe = NULL;
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 3167ccfdc1..117ca6059b 100644
--- a/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
+++ b/src/gallium/winsys/drm/nouveau/drm/nouveau_drm_api.c
@@ -12,51 +12,37 @@
#include "nouveau/nouveau_screen.h"
static struct pipe_surface *
-dri_surface_from_handle(struct drm_api *api, struct pipe_screen *screen,
- unsigned handle,
- enum pipe_format format,
- unsigned width,
- unsigned height,
- unsigned pitch)
+dri_surface_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
+ unsigned handle, enum pipe_format format,
+ unsigned width, unsigned height, unsigned pitch)
{
- struct pipe_surface *surface = NULL;
- struct pipe_texture *texture = NULL;
- struct pipe_texture templat;
- struct pipe_buffer *buf = NULL;
-
- buf = api->buffer_from_handle(api, screen, "front buffer", handle);
- if (!buf)
- return NULL;
-
- memset(&templat, 0, sizeof(templat));
- templat.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
- NOUVEAU_TEXTURE_USAGE_LINEAR;
- templat.target = PIPE_TEXTURE_2D;
- templat.last_level = 0;
- templat.depth[0] = 1;
- templat.format = format;
- templat.width[0] = width;
- templat.height[0] = height;
- pf_get_block(templat.format, &templat.block);
-
- texture = screen->texture_blanket(screen,
- &templat,
- &pitch,
- buf);
-
- /* we don't need the buffer from this point on */
- pipe_buffer_reference(&buf, NULL);
-
- if (!texture)
- return NULL;
-
- surface = screen->get_tex_surface(screen, texture, 0, 0, 0,
- PIPE_BUFFER_USAGE_GPU_READ |
- PIPE_BUFFER_USAGE_GPU_WRITE);
-
- /* we don't need the texture from this point on */
- pipe_texture_reference(&texture, NULL);
- return surface;
+ struct pipe_surface *ps = NULL;
+ struct pipe_texture *pt = NULL;
+ struct pipe_texture tmpl;
+
+ memset(&tmpl, 0, sizeof(tmpl));
+ tmpl.tex_usage = PIPE_TEXTURE_USAGE_PRIMARY |
+ NOUVEAU_TEXTURE_USAGE_LINEAR;
+ tmpl.target = PIPE_TEXTURE_2D;
+ tmpl.last_level = 0;
+ tmpl.depth[0] = 1;
+ tmpl.format = format;
+ tmpl.width[0] = width;
+ tmpl.height[0] = height;
+ pf_get_block(tmpl.format, &tmpl.block);
+
+ pt = api->texture_from_shared_handle(api, pscreen, &tmpl,
+ "front buffer", pitch, handle);
+ if (!pt)
+ return NULL;
+
+ ps = pscreen->get_tex_surface(pscreen, pt, 0, 0, 0,
+ PIPE_BUFFER_USAGE_GPU_READ |
+ PIPE_BUFFER_USAGE_GPU_WRITE);
+
+ /* we don't need the texture from this point on */
+ pipe_texture_reference(&pt, NULL);
+ return ps;
}
static struct pipe_surface *
@@ -126,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;
@@ -205,16 +191,10 @@ nouveau_drm_create_context(struct drm_api *api, struct pipe_screen *pscreen)
return nvws->pctx[i];
}
-static boolean
-nouveau_drm_pb_from_pt(struct drm_api *api, struct pipe_texture *pt,
- struct pipe_buffer **ppb, unsigned *stride)
-{
- return false;
-}
-
-static struct pipe_buffer *
-nouveau_drm_pb_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
- const char *name, unsigned handle)
+static struct pipe_texture *
+nouveau_drm_pt_from_name(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *templ, const char *name,
+ unsigned stride, unsigned handle)
{
struct nouveau_device *dev = nouveau_screen(pscreen)->device;
struct pipe_buffer *pb;
@@ -238,41 +218,42 @@ nouveau_drm_pb_from_handle(struct drm_api *api, struct pipe_screen *pscreen,
pb->usage = PIPE_BUFFER_USAGE_GPU_READ_WRITE |
PIPE_BUFFER_USAGE_CPU_READ_WRITE;
pb->size = nouveau_bo(pb)->size;
- return pb;
+ return pscreen->texture_blanket(pscreen, templ, &stride, pb);
}
static boolean
-nouveau_drm_handle_from_pb(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_buffer *pb, unsigned *handle)
+nouveau_drm_name_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *pt, unsigned *stride,
+ unsigned *handle)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
- if (!bo)
- return FALSE;
+ if (!mt || !mt->bo)
+ return false;
- *handle = bo->handle;
- return TRUE;
+ return nouveau_bo_handle_get(mt->bo, handle) == 0;
}
static boolean
-nouveau_drm_name_from_pb(struct drm_api *api, struct pipe_screen *pscreen,
- struct pipe_buffer *pb, unsigned *handle)
+nouveau_drm_handle_from_pt(struct drm_api *api, struct pipe_screen *pscreen,
+ struct pipe_texture *pt, unsigned *stride,
+ unsigned *handle)
{
- struct nouveau_bo *bo = nouveau_bo(pb);
+ struct nouveau_miptree *mt = nouveau_miptree(pt);
- if (!bo)
- return FALSE;
+ if (!mt || !mt->bo)
+ return false;
- return nouveau_bo_handle_get(bo, handle) == 0;
+ *handle = mt->bo->handle;
+ return true;
}
struct drm_api drm_api_hooks = {
.create_screen = nouveau_drm_create_screen,
.create_context = nouveau_drm_create_context,
- .buffer_from_texture = nouveau_drm_pb_from_pt,
- .buffer_from_handle = nouveau_drm_pb_from_handle,
- .handle_from_buffer = nouveau_drm_handle_from_pb,
- .global_handle_from_buffer = nouveau_drm_name_from_pb,
+ .texture_from_shared_handle = nouveau_drm_pt_from_name,
+ .shared_handle_from_texture = nouveau_drm_name_from_pt,
+ .local_handle_from_texture = nouveau_drm_handle_from_pt,
};
struct drm_api *
diff --git a/src/gallium/winsys/drm/nouveau/xorg/Makefile b/src/gallium/winsys/drm/nouveau/xorg/Makefile
new file mode 100644
index 0000000000..f0d3b337e8
--- /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 0000000000..a669b3080a
--- /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 <alanh@tungstengraphics.com>
+ * Author: Jakob Bornecrantz <wallbraker@gmail.com>
+ *
+ */
+
+#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/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
index 684a487f24..7bf23cba23 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c
@@ -32,6 +32,8 @@
#include "radeon_buffer.h"
+#include "radeon_bo_gem.h"
+
static const char *radeon_get_name(struct pipe_winsys *ws)
{
return "Radeon/GEM+KMS";
@@ -72,6 +74,7 @@ static struct pipe_buffer *radeon_buffer_create(struct pipe_winsys *ws,
alignment, domain, 0);
if (radeon_buffer->bo == NULL) {
FREE(radeon_buffer);
+ return NULL;
}
return &radeon_buffer->base;
}
@@ -98,6 +101,7 @@ static struct pipe_buffer *radeon_surface_buffer_create(struct pipe_winsys *ws,
unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
struct pipe_format_block block;
@@ -134,17 +138,19 @@ static void *radeon_buffer_map(struct pipe_winsys *ws,
int write = 0;
if (flags & PIPE_BUFFER_USAGE_DONTBLOCK) {
- /* XXX Remove this when radeon_bo_map supports DONTBLOCK */
- return NULL;
+ uint32_t domain;
+
+ if (radeon_bo_is_busy(radeon_buffer->bo, &domain))
+ return NULL;
}
if (flags & PIPE_BUFFER_USAGE_CPU_WRITE) {
write = 1;
}
- radeon_bo_wait(radeon_buffer->bo);
-
- if (radeon_bo_map(radeon_buffer->bo, write))
+ if (radeon_bo_map(radeon_buffer->bo, write)) {
return NULL;
+ }
+
return radeon_buffer->bo->ptr;
}
@@ -187,7 +193,6 @@ static void radeon_flush_frontbuffer(struct pipe_winsys *pipe_winsys,
struct radeon_winsys* radeon_pipe_winsys(int fd)
{
struct radeon_winsys* radeon_ws;
- struct radeon_bo_manager* bom;
radeon_ws = CALLOC_STRUCT(radeon_winsys);
if (radeon_ws == NULL) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
index 8c8b61fa10..f5153b06af 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.h
@@ -61,11 +61,6 @@ struct radeon_winsys_priv {
/* Radeon BO manager. */
struct radeon_bo_manager* bom;
- /* Radeon BO space checker. */
- struct radeon_cs_space_check sc[RADEON_MAX_BOS];
- /* Current BO count. */
- unsigned bo_count;
-
/* Radeon CS manager. */
struct radeon_cs_manager* csm;
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.c b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
index da2010184a..a4011db0b8 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.c
@@ -26,15 +26,15 @@
/*
* Authors:
* Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Joakim Sindholt <opensource@zhasha.com>
*/
#include "radeon_drm.h"
-#include "trace/tr_drm.h"
/* Create a pipe_screen. */
struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
- struct drm_create_screen_arg *arg)
+ struct drm_create_screen_arg *arg)
{
struct radeon_winsys* winsys = radeon_pipe_winsys(drmFB);
@@ -54,7 +54,8 @@ struct pipe_context* radeon_create_context(struct drm_api* api,
if (getenv("RADEON_SOFTPIPE")) {
return radeon_create_softpipe(screen->winsys);
} else {
- return r300_create_context(screen, screen->winsys);
+ return r300_create_context(screen,
+ (struct r300_winsys*)screen->winsys);
}
}
@@ -97,27 +98,40 @@ struct pipe_buffer* radeon_buffer_from_handle(struct drm_api* api,
return &radeon_buffer->base;
}
-boolean radeon_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle)
+static struct pipe_texture*
+radeon_texture_from_shared_handle(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *templ,
+ const char *name,
+ unsigned stride,
+ unsigned handle)
{
- struct radeon_pipe_buffer* radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
- *handle = radeon_buffer->bo->handle;
- return TRUE;
+ struct pipe_buffer *buffer;
+
+ buffer = radeon_buffer_from_handle(api, screen, name, handle);
+ if (!buffer) {
+ return NULL;
+ }
+
+ return screen->texture_blanket(screen, templ, &stride, buffer);
}
-boolean radeon_global_handle_from_buffer(struct drm_api* api,
- struct pipe_screen* screen,
- struct pipe_buffer* buffer,
- unsigned* handle)
+static boolean radeon_shared_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle)
{
int retval, fd;
struct drm_gem_flink flink;
- struct radeon_pipe_buffer* radeon_buffer =
- (struct radeon_pipe_buffer*)buffer;
+ struct radeon_pipe_buffer* radeon_buffer;
+ struct pipe_buffer *buffer;
+
+ if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ return FALSE;
+ }
+ radeon_buffer = (struct radeon_pipe_buffer*)buffer;
if (!radeon_buffer->flinked) {
fd = ((struct radeon_winsys*)screen->winsys)->priv->fd;
@@ -138,13 +152,30 @@ boolean radeon_global_handle_from_buffer(struct drm_api* api,
return TRUE;
}
+static boolean radeon_local_handle_from_texture(struct drm_api *api,
+ struct pipe_screen *screen,
+ struct pipe_texture *texture,
+ unsigned *stride,
+ unsigned *handle)
+{
+ struct pipe_buffer *buffer;
+ if (!radeon_buffer_from_texture(api, texture, &buffer, stride)) {
+ return FALSE;
+ }
+
+ *handle = ((struct radeon_pipe_buffer*)buffer)->bo->handle;
+
+ pipe_buffer_reference(&buffer, NULL);
+
+ return TRUE;
+}
+
struct drm_api drm_api_hooks = {
.create_screen = radeon_create_screen,
.create_context = radeon_create_context,
- .buffer_from_texture = radeon_buffer_from_texture,
- .buffer_from_handle = radeon_buffer_from_handle,
- .handle_from_buffer = radeon_handle_from_buffer,
- .global_handle_from_buffer = radeon_global_handle_from_buffer,
+ .texture_from_shared_handle = radeon_texture_from_shared_handle,
+ .shared_handle_from_texture = radeon_shared_handle_from_texture,
+ .local_handle_from_texture = radeon_local_handle_from_texture,
};
struct drm_api* drm_api_create()
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_drm.h b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
index 8560f71db6..88a5c82b28 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_drm.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_drm.h
@@ -30,8 +30,13 @@
#ifndef RADEON_DRM_H
#define RADEON_DRM_H
+#include <sys/ioctl.h>
+
+#include "xf86drm.h"
+
#include "pipe/p_screen.h"
+#include "trace/tr_drm.h"
#include "util/u_memory.h"
#include "state_tracker/drm_api.h"
@@ -40,6 +45,9 @@
#include "radeon_r300.h"
#include "radeon_winsys_softpipe.h"
+/* XXX */
+#include "r300_screen.h"
+
struct pipe_screen* radeon_create_screen(struct drm_api* api,
int drmFB,
struct drm_create_screen_arg *arg);
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.c b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
index 8c5f756ddf..d2d84f1a8f 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.c
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.c
@@ -27,66 +27,25 @@ static boolean radeon_r300_add_buffer(struct r300_winsys* winsys,
uint32_t rd,
uint32_t wd)
{
- int i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
struct radeon_bo* bo = ((struct radeon_pipe_buffer*)pbuffer)->bo;
- /* Check to see if this BO is already in line for validation;
- * find a slot for it otherwise. */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].bo == bo) {
- sc[i].read_domains |= rd;
- sc[i].write_domain |= wd;
- return TRUE;
- }
- }
-
- if (priv->bo_count >= RADEON_MAX_BOS) {
- /* Dohoho. Not falling for that one again. Request a flush. */
- return FALSE;
- }
-
- sc[priv->bo_count].bo = bo;
- sc[priv->bo_count].read_domains = rd;
- sc[priv->bo_count].write_domain = wd;
- priv->bo_count++;
-
+ radeon_cs_space_add_persistent_bo(priv->cs, bo, rd, wd);
return TRUE;
}
static boolean radeon_r300_validate(struct r300_winsys* winsys)
{
- int retval, i;
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
-
- retval = radeon_cs_space_check(priv->cs, sc, priv->bo_count);
-
- if (retval == RADEON_CS_SPACE_OP_TO_BIG) {
- /* We might as well HCF, since this is not going to fit in the card,
- * period. */
- /* XXX just drop it on the floor instead */
- exit(1);
- } else if (retval == RADEON_CS_SPACE_FLUSH) {
- /* We must flush before more rendering can commence. */
- return TRUE;
- }
- /* XXX should probably be its own function */
- for (i = 0; i < priv->bo_count; i++) {
- if (sc[i].read_domains && sc[i].write_domain) {
- /* Cute, cute. We need to flush first. */
- debug_printf("radeon: BO %p can't be read and written; "
- "requesting flush.\n", sc[i].bo);
- return TRUE;
- }
+ if (radeon_cs_space_check(priv->cs) < 0) {
+ return FALSE;
}
/* Things are fine, we can proceed as normal. */
- return FALSE;
+ return TRUE;
}
static boolean radeon_r300_check_cs(struct r300_winsys* winsys, int size)
@@ -151,8 +110,7 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
{
struct radeon_winsys_priv* priv =
(struct radeon_winsys_priv*)winsys->radeon_winsys;
- struct radeon_cs_space_check* sc = priv->sc;
- int retval = 1;
+ int retval;
/* Emit the CS. */
retval = radeon_cs_emit(priv->cs);
@@ -160,44 +118,48 @@ static void radeon_r300_flush_cs(struct r300_winsys* winsys)
debug_printf("radeon: Bad CS, dumping...\n");
radeon_cs_print(priv->cs, stderr);
}
- radeon_cs_erase(priv->cs);
/* Clean out BOs. */
- memset(sc, 0, sizeof(struct radeon_cs_space_check) * RADEON_MAX_BOS);
- priv->bo_count = 0;
+ radeon_cs_space_reset_bos(priv->cs);
+
+ /* Reset CS.
+ * Someday, when we care about performance, we should really find a way
+ * to rotate between two or three CS objects so that the GPU can be
+ * spinning through one CS while another one is being filled. */
+ radeon_cs_erase(priv->cs);
}
/* Helper function to do the ioctls needed for setup and init. */
static void do_ioctls(struct r300_winsys* winsys, int fd)
{
struct drm_radeon_gem_info gem_info = {0};
- drm_radeon_getparam_t gp = {0};
struct drm_radeon_info info = {0};
int target = 0;
int retval;
- info.value = &target;
- gp.value = &target;
+ info.value = (unsigned long)&target;
+
+ /* First, get the number of pixel pipes */
+ info.request = RADEON_INFO_NUM_GB_PIPES;
+ retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
+ if (retval) {
+ fprintf(stderr, "%s: Failed to get GB pipe count, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
+ }
+ winsys->gb_pipes = target;
- /* First, get PCI ID */
+ /* Then, get PCI ID */
info.request = RADEON_INFO_DEVICE_ID;
retval = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info, sizeof(info));
if (retval) {
- fprintf(stderr, "%s: New ioctl for PCI ID failed "
- "(error number %d), trying classic ioctl...\n",
- __FUNCTION__, retval);
- gp.param = RADEON_PARAM_DEVICE_ID;
- retval = drmCommandWriteRead(fd, DRM_RADEON_GETPARAM, &gp,
- sizeof(gp));
- if (retval) {
- fprintf(stderr, "%s: Failed to get PCI ID, "
- "error number %d\n", __FUNCTION__, retval);
- exit(1);
- }
+ fprintf(stderr, "%s: Failed to get PCI ID, "
+ "error number %d\n", __FUNCTION__, retval);
+ exit(1);
}
winsys->pci_id = target;
- /* Then, retrieve MM info */
+ /* Finally, retrieve MM info */
retval = drmCommandWriteRead(fd, DRM_RADEON_GEM_INFO,
&gem_info, sizeof(gem_info));
if (retval) {
diff --git a/src/gallium/winsys/drm/radeon/core/radeon_r300.h b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
index a2e0e58248..775d7937fd 100644
--- a/src/gallium/winsys/drm/radeon/core/radeon_r300.h
+++ b/src/gallium/winsys/drm/radeon/core/radeon_r300.h
@@ -20,29 +20,23 @@
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
* USE OR OTHER DEALINGS IN THE SOFTWARE. */
+#ifndef RADEON_R300_H
+#define RADEON_R300_H
+
/* XXX WTF is this! I shouldn't have to include those first three! FUCK! */
#include <stdint.h>
#include <stdlib.h>
#include "drm.h"
#include "radeon_drm.h"
-#include "radeon_cs.h"
+#include "radeon_cs_gem.h"
#include "r300_winsys.h"
#include "radeon_buffer.h"
-/* protect us from bonghits */
-#ifndef RADEON_INFO_DEVICE_ID
-#define RADEON_INFO_DEVICE_ID 0
-#endif
-#ifndef DRM_RADEON_INFO
-#define DRM_RADEON_INFO 0x1
-struct drm_radeon_info {
- uint32_t request;
- uint32_t pad;
- uint64_t value;
-};
-#endif
+struct radeon_winsys;
struct r300_winsys*
radeon_create_r300_winsys(int fd, struct radeon_winsys* old_winsys);
+
+#endif /* RADEON_R300_H */
diff --git a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
index 36824251f0..837f2aa8fe 100644
--- a/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
+++ b/src/gallium/winsys/drm/radeon/xorg/radeon_xorg.c
@@ -48,8 +48,8 @@ static SymTabRec radeon_xorg_chipsets[] = {
};
static PciChipsets radeon_xorg_pci_devices[] = {
- {PCI_MATCH_ANY, PCI_MATCH_ANY, RES_SHARED_VGA},
- {-1, -1, RES_UNDEFINED}
+ {PCI_MATCH_ANY, PCI_MATCH_ANY, NULL},
+ {-1, -1, NULL}
};
static XF86ModuleVersionInfo radeon_xorg_version = {
@@ -106,12 +106,6 @@ radeon_xorg_setup(pointer module, pointer opts, int *errmaj, int *errmin)
xf86AddDriver(&modesetting, module, HaveDriverFuncs);
/*
- * Tell the loader about symbols from other modules that this module
- * might refer to.
- */
- xorg_tracker_loader_ref_sym_lists();
-
- /*
* The return value must be non-NULL on success even though there
* is no TearDownProc.
*/
@@ -141,7 +135,7 @@ radeon_xorg_pci_probe(DriverPtr driver,
NULL, NULL, NULL, NULL, NULL);
if (scrn != NULL) {
scrn->driverVersion = 1;
- scrn->driverName = "modesetting";
+ scrn->driverName = "radeon";
scrn->name = "modesetting";
scrn->Probe = NULL;
diff --git a/src/gallium/winsys/egl_xlib/Makefile b/src/gallium/winsys/egl_xlib/Makefile
index a33a50ec22..3efb7ed4af 100644
--- a/src/gallium/winsys/egl_xlib/Makefile
+++ b/src/gallium/winsys/egl_xlib/Makefile
@@ -37,7 +37,7 @@ UNUSED_LIBS = \
$(TOP)/src/mesa/libmesagallium.a \
-LOCAL_CFLAGS = -D_EGL_PLATFORM_X=1
+LOCAL_CFLAGS =
.c.o:
diff --git a/src/gallium/winsys/egl_xlib/egl_xlib.c b/src/gallium/winsys/egl_xlib/egl_xlib.c
index e1ddcae97b..d02f825047 100644
--- a/src/gallium/winsys/egl_xlib/egl_xlib.c
+++ b/src/gallium/winsys/egl_xlib/egl_xlib.c
@@ -33,6 +33,7 @@
#include <dlfcn.h>
+#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include "pipe/p_compiler.h"
@@ -61,6 +62,14 @@
struct xlib_egl_driver
{
_EGLDriver Base; /**< base class */
+ EGLint apis;
+};
+
+
+/** driver data of _EGLDisplay */
+struct xlib_egl_display
+{
+ Display *Dpy;
struct pipe_winsys *winsys;
struct pipe_screen *screen;
@@ -82,6 +91,7 @@ struct xlib_egl_surface
{
_EGLSurface Base; /**< base class */
+ /* These are set for window surface */
Display *Dpy; /**< The X Display of the window */
Window Win; /**< The user-created window ID */
GC Gc;
@@ -93,6 +103,12 @@ struct xlib_egl_surface
};
+static void
+flush_frontbuffer(struct pipe_winsys *pws,
+ struct pipe_surface *psurf,
+ void *context_private);
+
+
/** cast wrapper */
static INLINE struct xlib_egl_driver *
xlib_egl_driver(_EGLDriver *drv)
@@ -101,19 +117,24 @@ xlib_egl_driver(_EGLDriver *drv)
}
-static struct xlib_egl_surface *
-lookup_surface(EGLSurface surf)
+static INLINE struct xlib_egl_display *
+xlib_egl_display(_EGLDisplay *dpy)
{
- _EGLSurface *surface = _eglLookupSurface(surf);
- return (struct xlib_egl_surface *) surface;
+ return (struct xlib_egl_display *) dpy->DriverData;
}
-static struct xlib_egl_context *
-lookup_context(EGLContext surf)
+static INLINE struct xlib_egl_surface *
+lookup_surface(_EGLSurface *surf)
{
- _EGLContext *context = _eglLookupContext(surf);
- return (struct xlib_egl_context *) context;
+ return (struct xlib_egl_surface *) surf;
+}
+
+
+static INLINE struct xlib_egl_context *
+lookup_context(_EGLContext *ctx)
+{
+ return (struct xlib_egl_context *) ctx;
}
@@ -132,19 +153,18 @@ bitcount(unsigned int n)
* Create the EGLConfigs. (one per X visual)
*/
static void
-create_configs(_EGLDriver *drv, EGLDisplay dpy)
+create_configs(struct xlib_egl_display *xdpy, _EGLDisplay *disp)
{
static const EGLint all_apis = (EGL_OPENGL_ES_BIT |
EGL_OPENGL_ES2_BIT |
EGL_OPENVG_BIT |
EGL_OPENGL_BIT);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
XVisualInfo *visInfo, visTemplate;
int num_visuals, i;
/* get list of all X visuals, create an EGL config for each */
- visTemplate.screen = DefaultScreen(disp->Xdpy);
- visInfo = XGetVisualInfo(disp->Xdpy, VisualScreenMask,
+ visTemplate.screen = DefaultScreen(xdpy->Dpy);
+ visInfo = XGetVisualInfo(xdpy->Dpy, VisualScreenMask,
&visTemplate, &num_visuals);
if (!visInfo) {
printf("egl_xlib.c: couldn't get any X visuals\n");
@@ -180,10 +200,14 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
SET_CONFIG_ATTRIB(config, EGL_NATIVE_RENDERABLE, EGL_FALSE);
SET_CONFIG_ATTRIB(config, EGL_CONFORMANT, all_apis);
SET_CONFIG_ATTRIB(config, EGL_RENDERABLE_TYPE, all_apis);
- SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_SURFACE_TYPE, EGL_WINDOW_BIT | EGL_PBUFFER_BIT);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGBA, EGL_TRUE);
+ SET_CONFIG_ATTRIB(config, EGL_BIND_TO_TEXTURE_RGB, EGL_TRUE);
_eglAddConfig(disp, config);
}
+
+ XFree(visInfo);
}
@@ -191,16 +215,47 @@ create_configs(_EGLDriver *drv, EGLDisplay dpy)
* Called via eglInitialize(), drv->API.Initialize().
*/
static EGLBoolean
-xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
- EGLint *minor, EGLint *major)
+xlib_eglInitialize(_EGLDriver *drv, _EGLDisplay *dpy,
+ EGLint *major, EGLint *minor)
{
- create_configs(drv, dpy);
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ struct xlib_egl_display *xdpy;
+
+ xdpy = CALLOC_STRUCT(xlib_egl_display);
+ if (!xdpy)
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+
+ xdpy->Dpy = (Display *) dpy->NativeDisplay;
+ if (!xdpy->Dpy) {
+ xdpy->Dpy = XOpenDisplay(NULL);
+ if (!xdpy->Dpy) {
+ free(xdpy);
+ return EGL_FALSE;
+ }
+ }
- drv->Initialized = EGL_TRUE;
+ /* create winsys and pipe screen */
+ xdpy->winsys = create_sw_winsys();
+ if (!xdpy->winsys) {
+ free(xdpy);
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+ }
+ xdpy->winsys->flush_frontbuffer = flush_frontbuffer;
+ xdpy->screen = softpipe_create_screen(xdpy->winsys);
+ if (!xdpy->screen) {
+ free(xdpy->winsys);
+ free(xdpy);
+ return _eglError(EGL_BAD_ALLOC, "eglInitialize");
+ }
+
+ dpy->DriverData = (void *) xdpy;
+ dpy->ClientAPIsMask = xdrv->apis;
+
+ create_configs(xdpy, dpy);
/* we're supporting EGL 1.4 */
- *minor = 1;
- *major = 4;
+ *major = 1;
+ *minor = 4;
return EGL_TRUE;
}
@@ -210,8 +265,20 @@ xlib_eglInitialize(_EGLDriver *drv, EGLDisplay dpy,
* Called via eglTerminate(), drv->API.Terminate().
*/
static EGLBoolean
-xlib_eglTerminate(_EGLDriver *drv, EGLDisplay dpy)
+xlib_eglTerminate(_EGLDriver *drv, _EGLDisplay *dpy)
{
+ struct xlib_egl_display *xdpy = xlib_egl_display(dpy);
+
+ _eglReleaseDisplayResources(drv, dpy);
+ _eglCleanupDisplay(dpy);
+
+ xdpy->screen->destroy(xdpy->screen);
+ free(xdpy->winsys);
+
+ if (!dpy->NativeDisplay)
+ XCloseDisplay(xdpy->Dpy);
+ free(xdpy);
+
return EGL_TRUE;
}
@@ -264,7 +331,13 @@ static void
check_and_update_buffer_size(struct xlib_egl_surface *surface)
{
uint width, height;
- get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ if (surface->Base.Type == EGL_PBUFFER_BIT) {
+ width = surface->Base.Width;
+ height = surface->Base.Height;
+ }
+ else {
+ get_drawable_size(surface->Dpy, surface->Win, &width, &height);
+ }
st_resize_framebuffer(surface->Framebuffer, width, height);
surface->Base.Width = width;
surface->Base.Height = height;
@@ -281,6 +354,9 @@ display_surface(struct pipe_winsys *pws,
XImage *ximage;
void *data;
+ if (xsurf->Base.Type == EGL_PBUFFER_BIT)
+ return;
+
ximage = XCreateImage(xsurf->Dpy,
xsurf->VisInfo.visual,
xsurf->VisInfo.depth,
@@ -330,24 +406,23 @@ flush_frontbuffer(struct pipe_winsys *pws,
/**
* Called via eglCreateContext(), drv->API.CreateContext().
*/
-static EGLContext
-xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
- EGLContext share_list, const EGLint *attrib_list)
+static _EGLContext *
+xlib_eglCreateContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLConfig *conf,
+ _EGLContext *share_list, const EGLint *attrib_list)
{
- struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
- _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
+ struct xlib_egl_display *xdpy = xlib_egl_display(dpy);
struct xlib_egl_context *ctx;
struct st_context *share_ctx = NULL; /* XXX fix */
__GLcontextModes visual;
ctx = CALLOC_STRUCT(xlib_egl_context);
if (!ctx)
- return EGL_NO_CONTEXT;
+ return NULL;
/* let EGL lib init the common stuff */
if (!_eglInitContext(drv, &ctx->Base, conf, attrib_list)) {
free(ctx);
- return EGL_NO_CONTEXT;
+ return NULL;
}
/* API-dependent context creation */
@@ -359,7 +434,7 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
/* fall-through */
case EGL_OPENGL_API:
/* create a softpipe context */
- ctx->pipe = softpipe_create(xdrv->screen);
+ ctx->pipe = softpipe_create(xdpy->screen);
/* Now do xlib / state tracker inits here */
_eglConfigToContextModesRec(conf, &visual);
ctx->Context = st_create_context(ctx->pipe, &visual, share_ctx);
@@ -367,41 +442,33 @@ xlib_eglCreateContext(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
default:
_eglError(EGL_BAD_MATCH, "eglCreateContext(unsupported API)");
free(ctx);
- return EGL_NO_CONTEXT;
+ return NULL;
}
- _eglLinkContext(&ctx->Base, _eglLookupDisplay(dpy));
-
- return _eglGetContextHandle(&ctx->Base);
+ return &ctx->Base;
}
static EGLBoolean
-xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
+xlib_eglDestroyContext(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx)
{
struct xlib_egl_context *context = lookup_context(ctx);
- if (context) {
- _eglUnlinkContext(&context->Base);
- if (!context->Base.IsBound) {
- /* API-dependent clean-up */
- switch (context->Base.ClientAPI) {
- case EGL_OPENGL_ES_API:
- case EGL_OPENVG_API:
- /* fall-through */
- case EGL_OPENGL_API:
- st_destroy_context(context->Context);
- break;
- default:
- assert(0);
- }
- free(context);
+
+ if (!_eglIsContextBound(&context->Base)) {
+ /* API-dependent clean-up */
+ switch (context->Base.ClientAPI) {
+ case EGL_OPENGL_ES_API:
+ case EGL_OPENVG_API:
+ /* fall-through */
+ case EGL_OPENGL_API:
+ st_destroy_context(context->Context);
+ break;
+ default:
+ assert(0);
}
- return EGL_TRUE;
- }
- else {
- _eglError(EGL_BAD_CONTEXT, "eglDestroyContext");
- return EGL_TRUE;
+ free(context);
}
+ return EGL_TRUE;
}
@@ -409,16 +476,25 @@ xlib_eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
* Called via eglMakeCurrent(), drv->API.MakeCurrent().
*/
static EGLBoolean
-xlib_eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy,
- EGLSurface draw, EGLSurface read, EGLContext ctx)
+xlib_eglMakeCurrent(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *draw, _EGLSurface *read, _EGLContext *ctx)
{
struct xlib_egl_context *context = lookup_context(ctx);
struct xlib_egl_surface *draw_surf = lookup_surface(draw);
struct xlib_egl_surface *read_surf = lookup_surface(read);
+ struct st_context *oldcontext = NULL;
+ _EGLContext *oldctx;
+
+ oldctx = _eglGetCurrentContext();
+ if (oldctx && _eglIsContextLinked(oldctx))
+ oldcontext = st_get_current();
- if (!_eglMakeCurrent(drv, dpy, draw, read, context))
+ if (!_eglMakeCurrent(drv, dpy, draw, read, ctx))
return EGL_FALSE;
+ /* Flush before switching context. Check client API? */
+ if (oldcontext)
+ st_flush(oldcontext, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME, NULL);
st_make_current((context ? context->Context : NULL),
(draw_surf ? draw_surf->Framebuffer : NULL),
(read_surf ? read_surf->Framebuffer : NULL));
@@ -472,39 +548,34 @@ choose_stencil_format(const __GLcontextModes *visual)
/**
* Called via eglCreateWindowSurface(), drv->API.CreateWindowSurface().
*/
-static EGLSurface
-xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
+static _EGLSurface *
+xlib_eglCreateWindowSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
NativeWindowType window, const EGLint *attrib_list)
{
- struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
- _EGLDisplay *disp = _eglLookupDisplay(dpy);
- _EGLConfig *conf = _eglLookupConfig(drv, dpy, config);
-
+ struct xlib_egl_display *xdpy = xlib_egl_display(disp);
struct xlib_egl_surface *surf;
__GLcontextModes visual;
uint width, height;
surf = CALLOC_STRUCT(xlib_egl_surface);
if (!surf)
- return EGL_NO_SURFACE;
+ return NULL;
/* Let EGL lib init the common stuff */
if (!_eglInitSurface(drv, &surf->Base, EGL_WINDOW_BIT,
conf, attrib_list)) {
free(surf);
- return EGL_NO_SURFACE;
+ return NULL;
}
- _eglLinkSurface(&surf->Base, disp);
-
/*
* Now init the Xlib and gallium stuff
*/
surf->Win = (Window) window; /* The X window ID */
- surf->Dpy = disp->Xdpy; /* The X display */
+ surf->Dpy = xdpy->Dpy; /* The X display */
surf->Gc = XCreateGC(surf->Dpy, surf->Win, 0, NULL);
- surf->winsys = xdrv->winsys;
+ surf->winsys = xdpy->winsys;
_eglConfigToContextModesRec(conf, &visual);
get_drawable_size(surf->Dpy, surf->Win, &width, &height);
@@ -523,32 +594,172 @@ xlib_eglCreateWindowSurface(_EGLDriver *drv, EGLDisplay dpy, EGLConfig config,
st_resize_framebuffer(surf->Framebuffer, width, height);
- return _eglGetSurfaceHandle(&surf->Base);
+ return &surf->Base;
+}
+
+
+static _EGLSurface *
+xlib_eglCreatePbufferSurface(_EGLDriver *drv, _EGLDisplay *disp, _EGLConfig *conf,
+ const EGLint *attrib_list)
+{
+ struct xlib_egl_display *xdpy = xlib_egl_display(disp);
+ struct xlib_egl_surface *surf;
+ __GLcontextModes visual;
+ uint width, height;
+ EGLBoolean bind_texture;
+
+ surf = CALLOC_STRUCT(xlib_egl_surface);
+ if (!surf) {
+ _eglError(EGL_BAD_ALLOC, "eglCreatePbufferSurface");
+ return NULL;
+ }
+
+ if (!_eglInitSurface(drv, &surf->Base, EGL_PBUFFER_BIT,
+ conf, attrib_list)) {
+ free(surf);
+ return NULL;
+ }
+ if (surf->Base.Width < 0 || surf->Base.Height < 0) {
+ _eglError(EGL_BAD_PARAMETER, "eglCreatePbufferSurface");
+ free(surf);
+ return NULL;
+ }
+
+ bind_texture = (surf->Base.TextureFormat != EGL_NO_TEXTURE);
+ width = (uint) surf->Base.Width;
+ height = (uint) surf->Base.Height;
+ if ((surf->Base.TextureTarget == EGL_NO_TEXTURE && bind_texture) ||
+ (surf->Base.TextureTarget != EGL_NO_TEXTURE && !bind_texture)) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return NULL;
+ }
+ /* a framebuffer of zero width or height confuses st */
+ if (width == 0 || height == 0) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return NULL;
+ }
+ /* no mipmap generation */
+ if (surf->Base.MipmapTexture) {
+ _eglError(EGL_BAD_MATCH, "eglCreatePbufferSurface");
+ free(surf);
+ return NULL;
+ }
+
+ surf->winsys = xdpy->winsys;
+
+ _eglConfigToContextModesRec(conf, &visual);
+
+ /* Create GL statetracker framebuffer */
+ surf->Framebuffer = st_create_framebuffer(&visual,
+ choose_color_format(&visual),
+ choose_depth_format(&visual),
+ choose_stencil_format(&visual),
+ width, height,
+ (void *) surf);
+ st_resize_framebuffer(surf->Framebuffer, width, height);
+
+ return &surf->Base;
}
static EGLBoolean
-xlib_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
+xlib_eglDestroySurface(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface)
{
struct xlib_egl_surface *surf = lookup_surface(surface);
- if (surf) {
- _eglUnlinkSurface(&surf->Base);
- if (!surf->Base.IsBound) {
+ if (!_eglIsSurfaceBound(&surf->Base)) {
+ if (surf->Base.Type != EGL_PBUFFER_BIT)
XFreeGC(surf->Dpy, surf->Gc);
- st_unreference_framebuffer(surf->Framebuffer);
- free(surf);
- }
- return EGL_TRUE;
+ st_unreference_framebuffer(surf->Framebuffer);
+ free(surf);
}
- else {
- _eglError(EGL_BAD_SURFACE, "eglDestroySurface");
- return EGL_FALSE;
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
+xlib_eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy,
+ _EGLSurface *surface, EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct xlib_egl_context *xctx;
+ struct pipe_surface *psurf;
+ enum pipe_format format;
+ int target;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT)
+ return _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+ if (xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_ACCESS, "eglBindTexImage");
+
+ /* this should be updated when choose_color_format is */
+ switch (xsurf->Base.TextureFormat) {
+ case EGL_TEXTURE_RGB:
+ format = PIPE_FORMAT_R8G8B8_UNORM;
+ break;
+ case EGL_TEXTURE_RGBA:
+ format = PIPE_FORMAT_A8R8G8B8_UNORM;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ switch (xsurf->Base.TextureTarget) {
+ case EGL_TEXTURE_2D:
+ target = ST_TEXTURE_2D;
+ break;
+ default:
+ return _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+ }
+
+ /* flush properly */
+ if (eglGetCurrentSurface(EGL_DRAW) == surface) {
+ xctx = lookup_context(_eglGetCurrentContext());
+ st_flush(xctx->Context, PIPE_FLUSH_RENDER_CACHE | PIPE_FLUSH_FRAME,
+ NULL);
+ }
+ else if (_eglIsSurfaceBound(&xsurf->Base)) {
+ xctx = lookup_context(xsurf->Base.Binding);
+ if (xctx)
+ st_finish(xctx->Context);
}
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_bind_texture_surface(psurf, target, xsurf->Base.MipmapLevel, format);
+ xsurf->Base.BoundToTexture = EGL_TRUE;
+
+ return EGL_TRUE;
+}
+
+
+static EGLBoolean
+xlib_eglReleaseTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
+ EGLint buffer)
+{
+ struct xlib_egl_surface *xsurf = lookup_surface(surface);
+ struct pipe_surface *psurf;
+
+ if (!xsurf || xsurf->Base.Type != EGL_PBUFFER_BIT ||
+ !xsurf->Base.BoundToTexture)
+ return _eglError(EGL_BAD_SURFACE, "eglReleaseTexImage");
+ if (buffer != EGL_BACK_BUFFER)
+ return _eglError(EGL_BAD_PARAMETER, "eglReleaseTexImage");
+
+ st_get_framebuffer_surface(xsurf->Framebuffer, ST_SURFACE_BACK_LEFT,
+ &psurf);
+ st_unbind_texture_surface(psurf, ST_TEXTURE_2D, xsurf->Base.MipmapLevel);
+ xsurf->Base.BoundToTexture = EGL_FALSE;
+
+ return EGL_TRUE;
}
static EGLBoolean
-xlib_eglSwapBuffers(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw)
+xlib_eglSwapBuffers(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *draw)
{
/* error checking step: */
if (!_eglSwapBuffers(drv, dpy, draw))
@@ -605,12 +816,20 @@ find_supported_apis(void)
}
+static void
+xlib_Unload(_EGLDriver *drv)
+{
+ struct xlib_egl_driver *xdrv = xlib_egl_driver(drv);
+ free(xdrv);
+}
+
+
/**
* This is the main entrypoint into the driver.
* Called by libEGL to instantiate an _EGLDriver object.
*/
_EGLDriver *
-_eglMain(_EGLDisplay *dpy, const char *args)
+_eglMain(const char *args)
{
struct xlib_egl_driver *xdrv;
@@ -620,10 +839,6 @@ _eglMain(_EGLDisplay *dpy, const char *args)
if (!xdrv)
return NULL;
- if (!dpy->Xdpy) {
- dpy->Xdpy = XOpenDisplay(NULL);
- }
-
_eglInitDriverFallbacks(&xdrv->Base);
xdrv->Base.API.Initialize = xlib_eglInitialize;
xdrv->Base.API.Terminate = xlib_eglTerminate;
@@ -631,27 +846,24 @@ _eglMain(_EGLDisplay *dpy, const char *args)
xdrv->Base.API.CreateContext = xlib_eglCreateContext;
xdrv->Base.API.DestroyContext = xlib_eglDestroyContext;
xdrv->Base.API.CreateWindowSurface = xlib_eglCreateWindowSurface;
+ xdrv->Base.API.CreatePbufferSurface = xlib_eglCreatePbufferSurface;
xdrv->Base.API.DestroySurface = xlib_eglDestroySurface;
+ xdrv->Base.API.BindTexImage = xlib_eglBindTexImage;
+ xdrv->Base.API.ReleaseTexImage = xlib_eglReleaseTexImage;
xdrv->Base.API.MakeCurrent = xlib_eglMakeCurrent;
xdrv->Base.API.SwapBuffers = xlib_eglSwapBuffers;
- xdrv->Base.ClientAPIsMask = find_supported_apis();
- if (xdrv->Base.ClientAPIsMask == 0x0) {
+ xdrv->apis = find_supported_apis();
+ if (xdrv->apis == 0x0) {
/* the app isn't directly linked with any EGL-supprted APIs
* (such as libGLESv2.so) so use an EGL utility to see what
* APIs might be loaded dynamically on this system.
*/
- xdrv->Base.ClientAPIsMask = _eglFindAPIs();
- }
+ xdrv->apis = _eglFindAPIs();
+ }
xdrv->Base.Name = "Xlib/softpipe";
-
- /* create one winsys and use it for all contexts/surfaces */
- xdrv->winsys = create_sw_winsys();
- xdrv->winsys->flush_frontbuffer = flush_frontbuffer;
-
- xdrv->screen = softpipe_create_screen(xdrv->winsys);
+ xdrv->Base.Unload = xlib_Unload;
return &xdrv->Base;
}
-
diff --git a/src/gallium/winsys/egl_xlib/sw_winsys.c b/src/gallium/winsys/egl_xlib/sw_winsys.c
index aa1bfa8e88..79ff2cc985 100644
--- a/src/gallium/winsys/egl_xlib/sw_winsys.c
+++ b/src/gallium/winsys/egl_xlib/sw_winsys.c
@@ -166,6 +166,7 @@ surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/g3dvl/xsp_winsys.c b/src/gallium/winsys/g3dvl/xsp_winsys.c
index 698c2856a4..37d60ce540 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 86eb9ef55e..f5e6d36d89 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 0000000000..9d0daf77e9
--- /dev/null
+++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c
@@ -0,0 +1,284 @@
+/**************************************************************************
+ *
+ * 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 <jfonseca@vmware.com>
+ */
+
+
+#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_flush_frontbuffer(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_flush_frontbuffer
+};
+
+
+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 33826524d7..d82c8d6773 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
@@ -166,6 +166,7 @@ gdi_softpipe_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/gallium/winsys/xlib/Makefile b/src/gallium/winsys/xlib/Makefile
index 522f6dc5ae..3a1945d92c 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/SConscript b/src/gallium/winsys/xlib/SConscript
index 0fb4b50f63..467d595d33 100644
--- a/src/gallium/winsys/xlib/SConscript
+++ b/src/gallium/winsys/xlib/SConscript
@@ -5,7 +5,7 @@ Import('*')
if env['platform'] == 'linux' \
and 'mesa' in env['statetrackers'] \
- and ('softpipe' or 'i915simple' or 'trace') in env['drivers'] \
+ and set(('softpipe', 'llvmpipe', 'i915simple', 'trace')).intersection(env['drivers']) \
and not env['dri']:
env = env.Clone()
@@ -29,6 +29,14 @@ if env['platform'] == 'linux' \
sources += ['xlib_softpipe.c']
drivers += [softpipe]
+ if 'llvmpipe' in env['drivers']:
+ env.Tool('llvm')
+ if 'LLVM_VERSION' in env:
+ env.Append(CPPDEFINES = 'GALLIUM_LLVMPIPE')
+ env.Tool('udis86')
+ sources += ['xlib_llvmpipe.c']
+ drivers += [llvmpipe]
+
if 'i965simple' in env['drivers']:
env.Append(CPPDEFINES = 'GALLIUM_I965SIMPLE')
sources += [
diff --git a/src/gallium/winsys/xlib/xlib.c b/src/gallium/winsys/xlib/xlib.c
index da72228215..4b71cf7ec3 100644
--- a/src/gallium/winsys/xlib/xlib.c
+++ b/src/gallium/winsys/xlib/xlib.c
@@ -45,6 +45,7 @@ enum mode {
MODE_TRACE,
MODE_BRW,
MODE_CELL,
+ MODE_LLVMPIPE,
MODE_SOFTPIPE
};
@@ -62,7 +63,11 @@ static enum mode get_mode()
return MODE_CELL;
#endif
+#if defined(GALLIUM_LLVMPIPE)
+ return MODE_LLVMPIPE;
+#else
return MODE_SOFTPIPE;
+#endif
}
static void _init( void ) __attribute__((constructor));
@@ -87,6 +92,11 @@ static void _init( void )
xmesa_set_driver( &xlib_cell_driver );
#endif
break;
+ case MODE_LLVMPIPE:
+#if defined(GALLIUM_LLVMPIPE)
+ xmesa_set_driver( &xlib_llvmpipe_driver );
+#endif
+ break;
case MODE_SOFTPIPE:
#if defined(GALLIUM_SOFTPIPE)
xmesa_set_driver( &xlib_softpipe_driver );
diff --git a/src/gallium/winsys/xlib/xlib.h b/src/gallium/winsys/xlib/xlib.h
index d602ab0b13..347d45f4d6 100644
--- a/src/gallium/winsys/xlib/xlib.h
+++ b/src/gallium/winsys/xlib/xlib.h
@@ -7,6 +7,7 @@
extern struct xm_driver xlib_trace_driver;
extern struct xm_driver xlib_softpipe_driver;
+extern struct xm_driver xlib_llvmpipe_driver;
extern struct xm_driver xlib_cell_driver;
extern struct xm_driver xlib_brw_driver;
diff --git a/src/gallium/winsys/xlib/xlib_brw_screen.c b/src/gallium/winsys/xlib/xlib_brw_screen.c
index fe8dfff767..ef545796f3 100644
--- a/src/gallium/winsys/xlib/xlib_brw_screen.c
+++ b/src/gallium/winsys/xlib/xlib_brw_screen.c
@@ -249,6 +249,7 @@ aub_i915_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
@@ -364,7 +365,7 @@ void xlib_brw_buffer_subdata_typed( struct pipe_winsys *pws,
unsigned data_type )
{
unsigned aub_type = DW_GENERAL_STATE;
- unsigned aub_sub_type;
+ unsigned aub_sub_type = 0;
switch (data_type) {
case BRW_CC_VP:
diff --git a/src/gallium/winsys/xlib/xlib_llvmpipe.c b/src/gallium/winsys/xlib/xlib_llvmpipe.c
new file mode 100644
index 0000000000..3dd15e099b
--- /dev/null
+++ b/src/gallium/winsys/xlib/xlib_llvmpipe.c
@@ -0,0 +1,464 @@
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Bismarck, ND., USA
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ *
+ *
+ **************************************************************************/
+
+/*
+ * Authors:
+ * Keith Whitwell
+ * Brian Paul
+ */
+
+
+#if defined(GALLIUM_LLVMPIPE)
+
+#include "xm_api.h"
+
+#undef ASSERT
+#undef Elements
+
+#include "pipe/internal/p_winsys_screen.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 "xlib.h"
+
+/**
+ * Subclass of pipe_buffer for Xlib winsys.
+ * Low-level OS/window system memory buffer
+ */
+struct xm_displaytarget
+{
+ enum pipe_format format;
+ struct pipe_format_block block;
+ unsigned width;
+ unsigned height;
+ unsigned stride;
+
+ void *data;
+ void *mapped;
+
+ XImage *tempImage;
+#ifdef USE_XSHM
+ int shm;
+ XShmSegmentInfo shminfo;
+#endif
+};
+
+
+/**
+ * Subclass of llvmpipe_winsys for Xlib winsys
+ */
+struct xmesa_llvmpipe_winsys
+{
+ struct llvmpipe_winsys base;
+/* struct xmesa_visual *xm_visual; */
+};
+
+
+
+/** Cast wrapper */
+static INLINE struct xm_displaytarget *
+xm_displaytarget( struct llvmpipe_displaytarget *dt )
+{
+ return (struct xm_displaytarget *)dt;
+}
+
+
+/**
+ * X Shared Memory Image extension code
+ */
+
+#ifdef USE_XSHM
+
+static volatile int mesaXErrorFlag = 0;
+
+/**
+ * Catches potential Xlib errors.
+ */
+static int
+mesaHandleXError(Display *dpy, XErrorEvent *event)
+{
+ (void) dpy;
+ (void) event;
+ mesaXErrorFlag = 1;
+ return 0;
+}
+
+
+static char *alloc_shm(struct xm_displaytarget *buf, unsigned size)
+{
+ XShmSegmentInfo *const shminfo = & buf->shminfo;
+
+ shminfo->shmid = shmget(IPC_PRIVATE, size, IPC_CREAT|0777);
+ if (shminfo->shmid < 0) {
+ return NULL;
+ }
+
+ shminfo->shmaddr = (char *) shmat(shminfo->shmid, 0, 0);
+ if (shminfo->shmaddr == (char *) -1) {
+ shmctl(shminfo->shmid, IPC_RMID, 0);
+ return NULL;
+ }
+
+ shminfo->readOnly = False;
+ return shminfo->shmaddr;
+}
+
+
+/**
+ * Allocate a shared memory XImage back buffer for the given XMesaBuffer.
+ */
+static void
+alloc_shm_ximage(struct xm_displaytarget *xm_buffer,
+ struct xmesa_buffer *xmb,
+ unsigned width, unsigned height)
+{
+ /*
+ * We have to do a _lot_ of error checking here to be sure we can
+ * really use the XSHM extension. It seems different servers trigger
+ * errors at different points if the extension won't work. Therefore
+ * we have to be very careful...
+ */
+ int (*old_handler)(Display *, XErrorEvent *);
+
+ xm_buffer->tempImage = XShmCreateImage(xmb->xm_visual->display,
+ xmb->xm_visual->visinfo->visual,
+ xmb->xm_visual->visinfo->depth,
+ ZPixmap,
+ NULL,
+ &xm_buffer->shminfo,
+ width, height);
+ if (xm_buffer->tempImage == NULL) {
+ xm_buffer->shm = 0;
+ return;
+ }
+
+
+ mesaXErrorFlag = 0;
+ old_handler = XSetErrorHandler(mesaHandleXError);
+ /* This may trigger the X protocol error we're ready to catch: */
+ XShmAttach(xmb->xm_visual->display, &xm_buffer->shminfo);
+ XSync(xmb->xm_visual->display, False);
+
+ if (mesaXErrorFlag) {
+ /* we are on a remote display, this error is normal, don't print it */
+ XFlush(xmb->xm_visual->display);
+ mesaXErrorFlag = 0;
+ XDestroyImage(xm_buffer->tempImage);
+ xm_buffer->tempImage = NULL;
+ xm_buffer->shm = 0;
+ (void) XSetErrorHandler(old_handler);
+ return;
+ }
+
+ xm_buffer->shm = 1;
+}
+
+#endif /* USE_XSHM */
+
+static boolean
+xm_is_displaytarget_format_supported( struct llvmpipe_winsys *ws,
+ enum pipe_format format )
+{
+ /* TODO: check visuals or other sensible thing here */
+ return TRUE;
+}
+
+
+static void *
+xm_displaytarget_map(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt,
+ unsigned flags)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = xm_dt->data;
+ return xm_dt->mapped;
+}
+
+static void
+xm_displaytarget_unmap(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ xm_dt->mapped = NULL;
+}
+
+static void
+xm_displaytarget_destroy(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt)
+{
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+
+ if (xm_dt->data) {
+#ifdef USE_XSHM
+ if (xm_dt->shminfo.shmid >= 0) {
+ shmdt(xm_dt->shminfo.shmaddr);
+ shmctl(xm_dt->shminfo.shmid, IPC_RMID, 0);
+
+ xm_dt->shminfo.shmid = -1;
+ xm_dt->shminfo.shmaddr = (char *) -1;
+ }
+ else
+#endif
+ FREE(xm_dt->data);
+ }
+
+ FREE(xm_dt);
+}
+
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xm_llvmpipe_display(struct xmesa_buffer *xm_buffer,
+ struct llvmpipe_displaytarget *dt)
+{
+ XImage *ximage;
+ struct xm_displaytarget *xm_dt = xm_displaytarget(dt);
+ static boolean no_swap = 0;
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ no_swap = getenv("SP_NO_RAST") != NULL;
+ firsttime = 0;
+ }
+
+ if (no_swap)
+ return;
+
+#ifdef USE_XSHM
+ if (xm_dt->shm)
+ {
+ if (xm_dt->tempImage == NULL)
+ {
+ assert(xm_dt->block.width == 1);
+ assert(xm_dt->block.height == 1);
+ alloc_shm_ximage(xm_dt, xm_buffer,
+ xm_dt->stride / xm_dt->block.size,
+ xm_dt->height);
+ }
+
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* _debug_printf("XSHM\n"); */
+ XShmPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height, False);
+ }
+ else
+#endif
+ {
+ /* display image in Window */
+ ximage = xm_dt->tempImage;
+ ximage->data = xm_dt->data;
+
+ /* check that the XImage has been previously initialized */
+ assert(ximage->format);
+ assert(ximage->bitmap_unit);
+
+ /* update XImage's fields */
+ ximage->width = xm_dt->width;
+ ximage->height = xm_dt->height;
+ ximage->bytes_per_line = xm_dt->stride;
+
+ /* _debug_printf("XPUT\n"); */
+ XPutImage(xm_buffer->xm_visual->display, xm_buffer->drawable, xm_buffer->gc,
+ ximage, 0, 0, 0, 0, xm_dt->width, xm_dt->height);
+ }
+}
+
+/**
+ * Display/copy the image in the surface into the X window specified
+ * by the XMesaBuffer.
+ */
+static void
+xm_displaytarget_display(struct llvmpipe_winsys *ws,
+ struct llvmpipe_displaytarget *dt,
+ void *context_private)
+{
+ XMesaContext xmctx = (XMesaContext) context_private;
+ struct xmesa_buffer *xm_buffer = xmctx->xm_buffer;
+ xm_llvmpipe_display(xm_buffer, dt);
+}
+
+
+static struct llvmpipe_displaytarget *
+xm_displaytarget_create(struct llvmpipe_winsys *winsys,
+ enum pipe_format format,
+ unsigned width, unsigned height,
+ unsigned alignment,
+ unsigned *stride)
+{
+ struct xm_displaytarget *xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ unsigned nblocksx, nblocksy, size;
+
+ xm_dt = CALLOC_STRUCT(xm_displaytarget);
+ if(!xm_dt)
+ goto no_xm_dt;
+
+ xm_dt->format = format;
+ xm_dt->width = width;
+ xm_dt->height = height;
+
+ pf_get_block(format, &xm_dt->block);
+ nblocksx = pf_get_nblocksx(&xm_dt->block, width);
+ nblocksy = pf_get_nblocksy(&xm_dt->block, height);
+ xm_dt->stride = align(nblocksx * xm_dt->block.size, alignment);
+ size = xm_dt->stride * nblocksy;
+
+#ifdef USE_XSHM
+ if (!debug_get_bool_option("XLIB_NO_SHM", FALSE))
+ {
+ xm_dt->shminfo.shmid = -1;
+ xm_dt->shminfo.shmaddr = (char *) -1;
+ xm_dt->shm = TRUE;
+
+ xm_dt->data = alloc_shm(xm_dt, size);
+ if(!xm_dt->data)
+ goto no_data;
+ }
+#endif
+
+ if(!xm_dt->data) {
+ xm_dt->data = align_malloc(size, alignment);
+ if(!xm_dt->data)
+ goto no_data;
+ }
+
+ *stride = xm_dt->stride;
+ return (struct llvmpipe_displaytarget *)xm_dt;
+
+no_data:
+ FREE(xm_dt);
+no_xm_dt:
+ return NULL;
+}
+
+
+static void
+xm_destroy( struct llvmpipe_winsys *ws )
+{
+ FREE(ws);
+}
+
+
+static struct llvmpipe_winsys *
+xlib_create_llvmpipe_winsys( void )
+{
+ struct xmesa_llvmpipe_winsys *ws;
+
+ ws = CALLOC_STRUCT(xmesa_llvmpipe_winsys);
+ if (!ws)
+ return NULL;
+
+ ws->base.destroy = xm_destroy;
+
+ ws->base.is_displaytarget_format_supported = xm_is_displaytarget_format_supported;
+
+ ws->base.displaytarget_create = xm_displaytarget_create;
+ ws->base.displaytarget_map = xm_displaytarget_map;
+ ws->base.displaytarget_unmap = xm_displaytarget_unmap;
+ ws->base.displaytarget_destroy = xm_displaytarget_destroy;
+
+ ws->base.displaytarget_display = xm_displaytarget_display;
+
+ return &ws->base;
+}
+
+
+static struct pipe_screen *
+xlib_create_llvmpipe_screen( void )
+{
+ struct llvmpipe_winsys *winsys;
+ struct pipe_screen *screen;
+
+ winsys = xlib_create_llvmpipe_winsys();
+ if (winsys == NULL)
+ return NULL;
+
+ screen = llvmpipe_create_screen(winsys);
+ if (screen == NULL)
+ goto fail;
+
+ return screen;
+
+fail:
+ if (winsys)
+ winsys->destroy( winsys );
+
+ return NULL;
+}
+
+
+static struct pipe_context *
+xlib_create_llvmpipe_context( struct pipe_screen *screen,
+ void *context_private )
+{
+ struct pipe_context *pipe;
+
+ pipe = llvmpipe_create(screen);
+ if (pipe == NULL)
+ goto fail;
+
+ pipe->priv = context_private;
+ return pipe;
+
+fail:
+ /* Free stuff here */
+ return NULL;
+}
+
+
+static void
+xlib_llvmpipe_display_surface(struct xmesa_buffer *xm_buffer,
+ struct pipe_surface *surf)
+{
+ struct llvmpipe_texture *texture = llvmpipe_texture(surf->texture);
+
+ assert(texture->dt);
+ if (texture->dt)
+ xm_llvmpipe_display(xm_buffer, texture->dt);
+}
+
+
+struct xm_driver xlib_llvmpipe_driver =
+{
+ .create_pipe_screen = xlib_create_llvmpipe_screen,
+ .create_pipe_context = xlib_create_llvmpipe_context,
+ .display_surface = xlib_llvmpipe_display_surface
+};
+
+
+
+#endif /* GALLIUM_LLVMPIPE */
diff --git a/src/gallium/winsys/xlib/xlib_softpipe.c b/src/gallium/winsys/xlib/xlib_softpipe.c
index 1de93c4e8c..260b39e2a0 100644
--- a/src/gallium/winsys/xlib/xlib_softpipe.c
+++ b/src/gallium/winsys/xlib/xlib_softpipe.c
@@ -301,6 +301,7 @@ xm_flush_frontbuffer(struct pipe_winsys *pws,
*/
XMesaContext xmctx = (XMesaContext) context_private;
xlib_softpipe_display_surface(xmctx->xm_buffer, surf);
+ xmesa_check_and_update_buffer_size(xmctx, xmctx->xm_buffer);
}
@@ -355,6 +356,7 @@ xm_surface_buffer_create(struct pipe_winsys *winsys,
unsigned width, unsigned height,
enum pipe_format format,
unsigned usage,
+ unsigned tex_usage,
unsigned *stride)
{
const unsigned alignment = 64;
diff --git a/src/glut/glx/win32_winproc.c b/src/glut/glx/win32_winproc.c
index 4a9dc3781c..1b3a297828 100644
--- a/src/glut/glx/win32_winproc.c
+++ b/src/glut/glx/win32_winproc.c
@@ -548,8 +548,13 @@ __glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
window to be bigger than the screen, and smaller than 100x100
(although it doesn't seem to help the y minimum). */
minmax = (LPMINMAXINFO)lParam;
+#if 0
+ /* These two lines are disabled to fix incorrect handling of
+ * window maximization on Vista. See bug 23182.
+ */
minmax->ptMaxSize.x = __glutScreenWidth;
minmax->ptMaxSize.y = __glutScreenHeight;
+#endif
minmax->ptMinTrackSize.x = 0;
minmax->ptMinTrackSize.y = 0;
minmax->ptMaxTrackSize.x = __glutScreenWidth +
diff --git a/src/glx/x11/dri2.c b/src/glx/x11/dri2.c
index ebb2985924..e144ed3e1f 100644
--- a/src/glx/x11/dri2.c
+++ b/src/glx/x11/dri2.c
@@ -52,320 +52,328 @@
static char dri2ExtensionName[] = DRI2_NAME;
static XExtensionInfo *dri2Info;
static XEXT_GENERATE_CLOSE_DISPLAY (DRI2CloseDisplay, dri2Info)
+
static /* const */ XExtensionHooks dri2ExtensionHooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- DRI2CloseDisplay, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- NULL, /* error_string */
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ DRI2CloseDisplay, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ NULL, /* error_string */
};
-static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info,
- dri2ExtensionName,
- &dri2ExtensionHooks,
- 0, NULL)
+static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay,
+ dri2Info,
+ dri2ExtensionName,
+ &dri2ExtensionHooks,
+ 0, NULL)
-Bool DRI2QueryExtension(Display *dpy, int *eventBase, int *errorBase)
+Bool
+DRI2QueryExtension(Display * dpy, int *eventBase, int *errorBase)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- if (XextHasExtension(info)) {
- *eventBase = info->codes->first_event;
- *errorBase = info->codes->first_error;
- return True;
- }
+ if (XextHasExtension(info)) {
+ *eventBase = info->codes->first_event;
+ *errorBase = info->codes->first_error;
+ return True;
+ }
- return False;
+ return False;
}
-Bool DRI2QueryVersion(Display *dpy, int *major, int *minor)
+Bool
+DRI2QueryVersion(Display * dpy, int *major, int *minor)
{
- XExtDisplayInfo *info = DRI2FindDisplay (dpy);
- xDRI2QueryVersionReply rep;
- xDRI2QueryVersionReq *req;
-
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
-
- LockDisplay(dpy);
- GetReq(DRI2QueryVersion, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2QueryVersion;
- req->majorVersion = DRI2_MAJOR;
- req->minorVersion = DRI2_MINOR;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- *major = rep.majorVersion;
- *minor = rep.minorVersion;
- UnlockDisplay(dpy);
- SyncHandle();
-
- return True;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2QueryVersionReply rep;
+ xDRI2QueryVersionReq *req;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2QueryVersion, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2QueryVersion;
+ req->majorVersion = DRI2_MAJOR;
+ req->minorVersion = DRI2_MINOR;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ *major = rep.majorVersion;
+ *minor = rep.minorVersion;
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
}
-Bool DRI2Connect(Display *dpy, XID window,
- char **driverName, char **deviceName)
+Bool
+DRI2Connect(Display * dpy, XID window, char **driverName, char **deviceName)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2ConnectReply rep;
- xDRI2ConnectReq *req;
-
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
-
- LockDisplay(dpy);
- GetReq(DRI2Connect, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2Connect;
- req->window = window;
- req->driverType = DRI2DriverDRI;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
-
- if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
-
- *driverName = Xmalloc(rep.driverNameLength + 1);
- if (*driverName == NULL) {
- _XEatData(dpy,
- ((rep.driverNameLength + 3) & ~3) +
- ((rep.deviceNameLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- _XReadPad(dpy, *driverName, rep.driverNameLength);
- (*driverName)[rep.driverNameLength] = '\0';
-
- *deviceName = Xmalloc(rep.deviceNameLength + 1);
- if (*deviceName == NULL) {
- Xfree(*driverName);
- _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
- _XReadPad(dpy, *deviceName, rep.deviceNameLength);
- (*deviceName)[rep.deviceNameLength] = '\0';
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return True;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2ConnectReply rep;
+ xDRI2ConnectReq *req;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReq(DRI2Connect, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2Connect;
+ req->window = window;
+ req->driverType = DRI2DriverDRI;
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ if (rep.driverNameLength == 0 && rep.deviceNameLength == 0) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+
+ *driverName = Xmalloc(rep.driverNameLength + 1);
+ if (*driverName == NULL) {
+ _XEatData(dpy,
+ ((rep.driverNameLength + 3) & ~3) +
+ ((rep.deviceNameLength + 3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ _XReadPad(dpy, *driverName, rep.driverNameLength);
+ (*driverName)[rep.driverNameLength] = '\0';
+
+ *deviceName = Xmalloc(rep.deviceNameLength + 1);
+ if (*deviceName == NULL) {
+ Xfree(*driverName);
+ _XEatData(dpy, ((rep.deviceNameLength + 3) & ~3));
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
+ _XReadPad(dpy, *deviceName, rep.deviceNameLength);
+ (*deviceName)[rep.deviceNameLength] = '\0';
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return True;
}
-Bool DRI2Authenticate(Display *dpy, XID window, drm_magic_t magic)
+Bool
+DRI2Authenticate(Display * dpy, XID window, drm_magic_t magic)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2AuthenticateReq *req;
- xDRI2AuthenticateReply rep;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2AuthenticateReq *req;
+ xDRI2AuthenticateReply rep;
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
- LockDisplay(dpy);
- GetReq(DRI2Authenticate, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2Authenticate;
- req->window = window;
- req->magic = magic;
+ LockDisplay(dpy);
+ GetReq(DRI2Authenticate, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2Authenticate;
+ req->window = window;
+ req->magic = magic;
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return False;
- }
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return False;
+ }
- UnlockDisplay(dpy);
- SyncHandle();
+ UnlockDisplay(dpy);
+ SyncHandle();
- return rep.authenticated;
+ return rep.authenticated;
}
-void DRI2CreateDrawable(Display *dpy, XID drawable)
+void
+DRI2CreateDrawable(Display * dpy, XID drawable)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2CreateDrawableReq *req;
-
- XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
-
- LockDisplay(dpy);
- GetReq(DRI2CreateDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2CreateDrawable;
- req->drawable = drawable;
- UnlockDisplay(dpy);
- SyncHandle();
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2CreateDrawableReq *req;
+
+ XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
+
+ LockDisplay(dpy);
+ GetReq(DRI2CreateDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2CreateDrawable;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
-void DRI2DestroyDrawable(Display *dpy, XID drawable)
+void
+DRI2DestroyDrawable(Display * dpy, XID drawable)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2DestroyDrawableReq *req;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2DestroyDrawableReq *req;
- XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+ XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
- XSync(dpy, False);
+ XSync(dpy, False);
- LockDisplay(dpy);
- GetReq(DRI2DestroyDrawable, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2DestroyDrawable;
- req->drawable = drawable;
- UnlockDisplay(dpy);
- SyncHandle();
+ LockDisplay(dpy);
+ GetReq(DRI2DestroyDrawable, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2DestroyDrawable;
+ req->drawable = drawable;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
-DRI2Buffer *DRI2GetBuffers(Display *dpy, XID drawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *outCount)
+DRI2Buffer *
+DRI2GetBuffers(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count, int *outCount)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2GetBuffersReply rep;
- xDRI2GetBuffersReq *req;
- DRI2Buffer *buffers;
- xDRI2Buffer repBuffer;
- CARD32 *p;
- int i;
-
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
-
- LockDisplay(dpy);
- GetReqExtra(DRI2GetBuffers, count * 4, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2GetBuffers;
- req->drawable = drawable;
- req->count = count;
- p = (CARD32 *) &req[1];
- for (i = 0; i < count; i++)
- p[i] = attachments[i];
-
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- *width = rep.width;
- *height = rep.height;
- *outCount = rep.count;
-
- buffers = Xmalloc(rep.count * sizeof buffers[0]);
- if (buffers == NULL) {
- _XEatData(dpy, rep.count * sizeof repBuffer);
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- for (i = 0; i < rep.count; i++) {
- _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
- buffers[i].attachment = repBuffer.attachment;
- buffers[i].name = repBuffer.name;
- buffers[i].pitch = repBuffer.pitch;
- buffers[i].cpp = repBuffer.cpp;
- buffers[i].flags = repBuffer.flags;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return buffers;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * 4, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffers;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) & req[1];
+ for (i = 0; i < count; i++)
+ p[i] = attachments[i];
+
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+ *outCount = rep.count;
+
+ buffers = Xmalloc(rep.count * sizeof buffers[0]);
+ if (buffers == NULL) {
+ _XEatData(dpy, rep.count * sizeof repBuffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ for (i = 0; i < rep.count; i++) {
+ _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
+ buffers[i].attachment = repBuffer.attachment;
+ buffers[i].name = repBuffer.name;
+ buffers[i].pitch = repBuffer.pitch;
+ buffers[i].cpp = repBuffer.cpp;
+ buffers[i].flags = repBuffer.flags;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buffers;
}
-DRI2Buffer *DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *outCount)
+DRI2Buffer *
+DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count, int *outCount)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2GetBuffersReply rep;
- xDRI2GetBuffersReq *req;
- DRI2Buffer *buffers;
- xDRI2Buffer repBuffer;
- CARD32 *p;
- int i;
-
- XextCheckExtension (dpy, info, dri2ExtensionName, False);
-
- LockDisplay(dpy);
- GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2GetBuffersWithFormat;
- req->drawable = drawable;
- req->count = count;
- p = (CARD32 *) &req[1];
- for (i = 0; i < (count * 2); i++)
- p[i] = attachments[i];
-
- if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- *width = rep.width;
- *height = rep.height;
- *outCount = rep.count;
-
- buffers = Xmalloc(rep.count * sizeof buffers[0]);
- if (buffers == NULL) {
- _XEatData(dpy, rep.count * sizeof repBuffer);
- UnlockDisplay(dpy);
- SyncHandle();
- return NULL;
- }
-
- for (i = 0; i < rep.count; i++) {
- _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
- buffers[i].attachment = repBuffer.attachment;
- buffers[i].name = repBuffer.name;
- buffers[i].pitch = repBuffer.pitch;
- buffers[i].cpp = repBuffer.cpp;
- buffers[i].flags = repBuffer.flags;
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-
- return buffers;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2GetBuffersReply rep;
+ xDRI2GetBuffersReq *req;
+ DRI2Buffer *buffers;
+ xDRI2Buffer repBuffer;
+ CARD32 *p;
+ int i;
+
+ XextCheckExtension(dpy, info, dri2ExtensionName, False);
+
+ LockDisplay(dpy);
+ GetReqExtra(DRI2GetBuffers, count * (4 * 2), req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2GetBuffersWithFormat;
+ req->drawable = drawable;
+ req->count = count;
+ p = (CARD32 *) & req[1];
+ for (i = 0; i < (count * 2); i++)
+ p[i] = attachments[i];
+
+ if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ *width = rep.width;
+ *height = rep.height;
+ *outCount = rep.count;
+
+ buffers = Xmalloc(rep.count * sizeof buffers[0]);
+ if (buffers == NULL) {
+ _XEatData(dpy, rep.count * sizeof repBuffer);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return NULL;
+ }
+
+ for (i = 0; i < rep.count; i++) {
+ _XReadPad(dpy, (char *) &repBuffer, sizeof repBuffer);
+ buffers[i].attachment = repBuffer.attachment;
+ buffers[i].name = repBuffer.name;
+ buffers[i].pitch = repBuffer.pitch;
+ buffers[i].cpp = repBuffer.cpp;
+ buffers[i].flags = repBuffer.flags;
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return buffers;
}
-void DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
- CARD32 dest, CARD32 src)
+void
+DRI2CopyRegion(Display * dpy, XID drawable, XserverRegion region,
+ CARD32 dest, CARD32 src)
{
- XExtDisplayInfo *info = DRI2FindDisplay(dpy);
- xDRI2CopyRegionReq *req;
- xDRI2CopyRegionReply rep;
+ XExtDisplayInfo *info = DRI2FindDisplay(dpy);
+ xDRI2CopyRegionReq *req;
+ xDRI2CopyRegionReply rep;
- XextSimpleCheckExtension (dpy, info, dri2ExtensionName);
+ XextSimpleCheckExtension(dpy, info, dri2ExtensionName);
- LockDisplay(dpy);
- GetReq(DRI2CopyRegion, req);
- req->reqType = info->codes->major_opcode;
- req->dri2ReqType = X_DRI2CopyRegion;
- req->drawable = drawable;
- req->region = region;
- req->dest = dest;
- req->src = src;
+ LockDisplay(dpy);
+ GetReq(DRI2CopyRegion, req);
+ req->reqType = info->codes->major_opcode;
+ req->dri2ReqType = X_DRI2CopyRegion;
+ req->drawable = drawable;
+ req->region = region;
+ req->dest = dest;
+ req->src = src;
- _XReply(dpy, (xReply *)&rep, 0, xFalse);
+ _XReply(dpy, (xReply *) & rep, 0, xFalse);
- UnlockDisplay(dpy);
- SyncHandle();
+ UnlockDisplay(dpy);
+ SyncHandle();
}
diff --git a/src/glx/x11/dri2.h b/src/glx/x11/dri2.h
index b0e61f80d7..a6fe66e136 100644
--- a/src/glx/x11/dri2.h
+++ b/src/glx/x11/dri2.h
@@ -36,45 +36,53 @@
#include <X11/extensions/Xfixes.h>
#include <X11/extensions/dri2tokens.h>
-typedef struct {
- unsigned int attachment;
- unsigned int name;
- unsigned int pitch;
- unsigned int cpp;
- unsigned int flags;
+typedef struct
+{
+ unsigned int attachment;
+ unsigned int name;
+ unsigned int pitch;
+ unsigned int cpp;
+ unsigned int flags;
} DRI2Buffer;
extern Bool
-DRI2QueryExtension(Display *display, int *eventBase, int *errorBase);
+DRI2QueryExtension(Display * display, int *eventBase, int *errorBase);
+
extern Bool
-DRI2QueryVersion(Display *display, int *major, int *minor);
+DRI2QueryVersion(Display * display, int *major, int *minor);
+
extern Bool
-DRI2Connect(Display *display, XID window,
- char **driverName, char **deviceName);
+DRI2Connect(Display * display, XID window,
+ char **driverName, char **deviceName);
+
extern Bool
-DRI2Authenticate(Display *display, XID window, drm_magic_t magic);
+DRI2Authenticate(Display * display, XID window, drm_magic_t magic);
+
extern void
-DRI2CreateDrawable(Display *display, XID drawable);
+DRI2CreateDrawable(Display * display, XID drawable);
+
extern void
-DRI2DestroyDrawable(Display *display, XID handle);
-extern DRI2Buffer *
-DRI2GetBuffers(Display *dpy, XID drawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *outCount);
+DRI2DestroyDrawable(Display * display, XID handle);
+
+extern DRI2Buffer*
+DRI2GetBuffers(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *outCount);
/**
* \note
* This function is only supported with DRI2 version 1.1 or later.
*/
-extern DRI2Buffer *
-DRI2GetBuffersWithFormat(Display *dpy, XID drawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *outCount);
+extern DRI2Buffer*
+DRI2GetBuffersWithFormat(Display * dpy, XID drawable,
+ int *width, int *height,
+ unsigned int *attachments,
+ int count, int *outCount);
extern void
-DRI2CopyRegion(Display *dpy, XID drawable, XserverRegion region,
- CARD32 dest, CARD32 src);
+DRI2CopyRegion(Display * dpy, XID drawable,
+ XserverRegion region,
+ CARD32 dest, CARD32 src);
#endif
diff --git a/src/glx/x11/dri2_glx.c b/src/glx/x11/dri2_glx.c
index f4865aecb1..89efe3ab29 100644
--- a/src/glx/x11/dri2_glx.c
+++ b/src/glx/x11/dri2_glx.c
@@ -54,249 +54,260 @@ typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
typedef struct __GLXDRIdrawablePrivateRec __GLXDRIdrawablePrivate;
-struct __GLXDRIdisplayPrivateRec {
- __GLXDRIdisplay base;
+struct __GLXDRIdisplayPrivateRec
+{
+ __GLXDRIdisplay base;
- /*
+ /*
** XFree86-DRI version information
*/
- int driMajor;
- int driMinor;
- int driPatch;
+ int driMajor;
+ int driMinor;
+ int driPatch;
};
-struct __GLXDRIcontextPrivateRec {
- __GLXDRIcontext base;
- __DRIcontext *driContext;
- __GLXscreenConfigs *psc;
+struct __GLXDRIcontextPrivateRec
+{
+ __GLXDRIcontext base;
+ __DRIcontext *driContext;
+ __GLXscreenConfigs *psc;
};
-struct __GLXDRIdrawablePrivateRec {
- __GLXDRIdrawable base;
- __DRIbuffer buffers[5];
- int bufferCount;
- int width, height;
- int have_back;
- int have_fake_front;
+struct __GLXDRIdrawablePrivateRec
+{
+ __GLXDRIdrawable base;
+ __DRIbuffer buffers[5];
+ int bufferCount;
+ int width, height;
+ int have_back;
+ int have_fake_front;
};
-static void dri2WaitX(__GLXDRIdrawable *pdraw);
+static void dri2WaitX(__GLXDRIdrawable * pdraw);
-static void dri2DestroyContext(__GLXDRIcontext *context,
- __GLXscreenConfigs *psc, Display *dpy)
+static void
+dri2DestroyContext(__GLXDRIcontext * context,
+ __GLXscreenConfigs * psc, Display * dpy)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- const __DRIcoreExtension *core = pcp->psc->core;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- (*core->destroyContext)(pcp->driContext);
+ (*core->destroyContext) (pcp->driContext);
- Xfree(pcp);
+ Xfree(pcp);
}
-static Bool dri2BindContext(__GLXDRIcontext *context,
- __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
+static Bool
+dri2BindContext(__GLXDRIcontext * context,
+ __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- const __DRIcoreExtension *core = pcp->psc->core;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- return (*core->bindContext)(pcp->driContext,
- draw->driDrawable,
- read->driDrawable);
+ return (*core->bindContext) (pcp->driContext,
+ draw->driDrawable, read->driDrawable);
}
-static void dri2UnbindContext(__GLXDRIcontext *context)
+static void
+dri2UnbindContext(__GLXDRIcontext * context)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- const __DRIcoreExtension *core = pcp->psc->core;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- (*core->unbindContext)(pcp->driContext);
+ (*core->unbindContext) (pcp->driContext);
}
-static __GLXDRIcontext *dri2CreateContext(__GLXscreenConfigs *psc,
- const __GLcontextModes *mode,
- GLXContext gc,
- GLXContext shareList, int renderType)
+static __GLXDRIcontext *
+dri2CreateContext(__GLXscreenConfigs * psc,
+ const __GLcontextModes * mode,
+ GLXContext gc, GLXContext shareList, int renderType)
{
- __GLXDRIcontextPrivate *pcp, *pcp_shared;
- __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
- __DRIcontext *shared = NULL;
-
- if (shareList) {
- pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
- shared = pcp_shared->driContext;
- }
-
- pcp = Xmalloc(sizeof *pcp);
- if (pcp == NULL)
- return NULL;
-
- pcp->psc = psc;
- pcp->driContext =
- (*psc->dri2->createNewContext)(psc->__driScreen,
- config->driConfig, shared, pcp);
- gc->__driContext = pcp->driContext;
-
- if (pcp->driContext == NULL) {
- Xfree(pcp);
- return NULL;
- }
-
- pcp->base.destroyContext = dri2DestroyContext;
- pcp->base.bindContext = dri2BindContext;
- pcp->base.unbindContext = dri2UnbindContext;
-
- return &pcp->base;
+ __GLXDRIcontextPrivate *pcp, *pcp_shared;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
+ __DRIcontext *shared = NULL;
+
+ if (shareList) {
+ pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+ shared = pcp_shared->driContext;
+ }
+
+ pcp = Xmalloc(sizeof *pcp);
+ if (pcp == NULL)
+ return NULL;
+
+ pcp->psc = psc;
+ pcp->driContext =
+ (*psc->dri2->createNewContext) (psc->__driScreen,
+ config->driConfig, shared, pcp);
+ gc->__driContext = pcp->driContext;
+
+ if (pcp->driContext == NULL) {
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->base.destroyContext = dri2DestroyContext;
+ pcp->base.bindContext = dri2BindContext;
+ pcp->base.unbindContext = dri2UnbindContext;
+
+ return &pcp->base;
}
-static void dri2DestroyDrawable(__GLXDRIdrawable *pdraw)
+static void
+dri2DestroyDrawable(__GLXDRIdrawable * pdraw)
{
- const __DRIcoreExtension *core = pdraw->psc->core;
+ const __DRIcoreExtension *core = pdraw->psc->core;
- (*core->destroyDrawable)(pdraw->driDrawable);
- DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->drawable);
- Xfree(pdraw);
+ (*core->destroyDrawable) (pdraw->driDrawable);
+ DRI2DestroyDrawable(pdraw->psc->dpy, pdraw->xDrawable);
+ Xfree(pdraw);
}
-static __GLXDRIdrawable *dri2CreateDrawable(__GLXscreenConfigs *psc,
- XID xDrawable,
- GLXDrawable drawable,
- const __GLcontextModes *modes)
+static __GLXDRIdrawable *
+dri2CreateDrawable(__GLXscreenConfigs * psc,
+ XID xDrawable,
+ GLXDrawable drawable, const __GLcontextModes * modes)
{
- __GLXDRIdrawablePrivate *pdraw;
- __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+ __GLXDRIdrawablePrivate *pdraw;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
- pdraw = Xmalloc(sizeof(*pdraw));
- if (!pdraw)
- return NULL;
+ pdraw = Xmalloc(sizeof(*pdraw));
+ if (!pdraw)
+ return NULL;
- pdraw->base.destroyDrawable = dri2DestroyDrawable;
- pdraw->base.xDrawable = xDrawable;
- pdraw->base.drawable = drawable;
- pdraw->base.psc = psc;
- pdraw->bufferCount = 0;
+ pdraw->base.destroyDrawable = dri2DestroyDrawable;
+ pdraw->base.xDrawable = xDrawable;
+ pdraw->base.drawable = drawable;
+ pdraw->base.psc = psc;
+ pdraw->bufferCount = 0;
- DRI2CreateDrawable(psc->dpy, xDrawable);
+ DRI2CreateDrawable(psc->dpy, xDrawable);
- /* Create a new drawable */
- pdraw->base.driDrawable =
- (*psc->dri2->createNewDrawable)(psc->__driScreen,
- config->driConfig, pdraw);
+ /* Create a new drawable */
+ pdraw->base.driDrawable =
+ (*psc->dri2->createNewDrawable) (psc->__driScreen,
+ config->driConfig, pdraw);
- if (!pdraw->base.driDrawable) {
- DRI2DestroyDrawable(psc->dpy, drawable);
- Xfree(pdraw);
- return NULL;
- }
+ if (!pdraw->base.driDrawable) {
+ DRI2DestroyDrawable(psc->dpy, xDrawable);
+ Xfree(pdraw);
+ return NULL;
+ }
- return &pdraw->base;
+ return &pdraw->base;
}
-static void dri2CopySubBuffer(__GLXDRIdrawable *pdraw,
- int x, int y, int width, int height)
+static void
+dri2CopySubBuffer(__GLXDRIdrawable * pdraw,
+ int x, int y, int width, int height)
{
- __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
- XRectangle xrect;
- XserverRegion region;
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ XRectangle xrect;
+ XserverRegion region;
- /* Check we have the right attachments */
- if (!priv->have_back)
- return;
+ /* Check we have the right attachments */
+ if (!priv->have_back)
+ return;
- xrect.x = x;
- xrect.y = priv->height - y - height;
- xrect.width = width;
- xrect.height = height;
+ xrect.x = x;
+ xrect.y = priv->height - y - height;
+ xrect.width = width;
+ xrect.height = height;
#ifdef __DRI2_FLUSH
- if (pdraw->psc->f)
- (*pdraw->psc->f->flush)(pdraw->driDrawable);
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush) (pdraw->driDrawable);
#endif
- region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
- /* should get a fence ID back from here at some point */
- DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
- DRI2BufferFrontLeft, DRI2BufferBackLeft);
- XFixesDestroyRegion(pdraw->psc->dpy, region);
+ region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+ /* should get a fence ID back from here at some point */
+ DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
+ DRI2BufferFrontLeft, DRI2BufferBackLeft);
+ XFixesDestroyRegion(pdraw->psc->dpy, region);
- /* Refresh the fake front (if present) after we just damaged the real
- * front.
- */
- dri2WaitX(pdraw);
+ /* Refresh the fake front (if present) after we just damaged the real
+ * front.
+ */
+ dri2WaitX(pdraw);
}
-static void dri2SwapBuffers(__GLXDRIdrawable *pdraw)
+static void
+dri2SwapBuffers(__GLXDRIdrawable * pdraw)
{
- __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
- dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
+ dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
}
-static void dri2WaitX(__GLXDRIdrawable *pdraw)
+static void
+dri2WaitX(__GLXDRIdrawable * pdraw)
{
- __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
- XRectangle xrect;
- XserverRegion region;
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ XRectangle xrect;
+ XserverRegion region;
- /* Check we have the right attachments */
- if (!priv->have_fake_front)
- return;
+ /* Check we have the right attachments */
+ if (!priv->have_fake_front)
+ return;
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = priv->width;
- xrect.height = priv->height;
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = priv->width;
+ xrect.height = priv->height;
#ifdef __DRI2_FLUSH
- if (pdraw->psc->f)
- (*pdraw->psc->f->flush)(pdraw->driDrawable);
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush) (pdraw->driDrawable);
#endif
- region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
- DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
- DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
- XFixesDestroyRegion(pdraw->psc->dpy, region);
+ region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+ DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
+ DRI2BufferFakeFrontLeft, DRI2BufferFrontLeft);
+ XFixesDestroyRegion(pdraw->psc->dpy, region);
}
-static void dri2WaitGL(__GLXDRIdrawable *pdraw)
+static void
+dri2WaitGL(__GLXDRIdrawable * pdraw)
{
- __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
- XRectangle xrect;
- XserverRegion region;
+ __GLXDRIdrawablePrivate *priv = (__GLXDRIdrawablePrivate *) pdraw;
+ XRectangle xrect;
+ XserverRegion region;
- if (!priv->have_fake_front)
- return;
+ if (!priv->have_fake_front)
+ return;
- xrect.x = 0;
- xrect.y = 0;
- xrect.width = priv->width;
- xrect.height = priv->height;
+ xrect.x = 0;
+ xrect.y = 0;
+ xrect.width = priv->width;
+ xrect.height = priv->height;
#ifdef __DRI2_FLUSH
- if (pdraw->psc->f)
- (*pdraw->psc->f->flush)(pdraw->driDrawable);
+ if (pdraw->psc->f)
+ (*pdraw->psc->f->flush) (pdraw->driDrawable);
#endif
- region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
- DRI2CopyRegion(pdraw->psc->dpy, pdraw->drawable, region,
- DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
- XFixesDestroyRegion(pdraw->psc->dpy, region);
+ region = XFixesCreateRegion(pdraw->psc->dpy, &xrect, 1);
+ DRI2CopyRegion(pdraw->psc->dpy, pdraw->xDrawable, region,
+ DRI2BufferFrontLeft, DRI2BufferFakeFrontLeft);
+ XFixesDestroyRegion(pdraw->psc->dpy, region);
}
-static void dri2FlushFrontBuffer(__DRIdrawable *driDrawable,
- void *loaderPrivate)
+static void
+dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate)
{
- (void) driDrawable;
- dri2WaitGL((__GLXDRIdrawable *) loaderPrivate);
+ (void) driDrawable;
+ dri2WaitGL((__GLXDRIdrawable *) loaderPrivate);
}
-static void dri2DestroyScreen(__GLXscreenConfigs *psc)
+static void
+dri2DestroyScreen(__GLXscreenConfigs * psc)
{
- /* Free the direct rendering per screen data */
- (*psc->core->destroyScreen)(psc->__driScreen);
- close(psc->fd);
- psc->__driScreen = NULL;
+ /* Free the direct rendering per screen data */
+ (*psc->core->destroyScreen) (psc->__driScreen);
+ close(psc->fd);
+ psc->__driScreen = NULL;
}
/**
@@ -306,219 +317,222 @@ static void dri2DestroyScreen(__GLXscreenConfigs *psc)
* \c DRI2GetBuffers or \c DRI2GetBuffersWithFormat.
*/
static void
-process_buffers(__GLXDRIdrawablePrivate *pdraw, DRI2Buffer *buffers,
- unsigned count)
+process_buffers(__GLXDRIdrawablePrivate * pdraw, DRI2Buffer * buffers,
+ unsigned count)
{
- int i;
-
- pdraw->bufferCount = count;
- pdraw->have_fake_front = 0;
- pdraw->have_back = 0;
-
- /* This assumes the DRI2 buffer attachment tokens matches the
- * __DRIbuffer tokens. */
- for (i = 0; i < count; i++) {
- pdraw->buffers[i].attachment = buffers[i].attachment;
- pdraw->buffers[i].name = buffers[i].name;
- pdraw->buffers[i].pitch = buffers[i].pitch;
- pdraw->buffers[i].cpp = buffers[i].cpp;
- pdraw->buffers[i].flags = buffers[i].flags;
- if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
- pdraw->have_fake_front = 1;
- if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
- pdraw->have_back = 1;
- }
+ int i;
+
+ pdraw->bufferCount = count;
+ pdraw->have_fake_front = 0;
+ pdraw->have_back = 0;
+
+ /* This assumes the DRI2 buffer attachment tokens matches the
+ * __DRIbuffer tokens. */
+ for (i = 0; i < count; i++) {
+ pdraw->buffers[i].attachment = buffers[i].attachment;
+ pdraw->buffers[i].name = buffers[i].name;
+ pdraw->buffers[i].pitch = buffers[i].pitch;
+ pdraw->buffers[i].cpp = buffers[i].cpp;
+ pdraw->buffers[i].flags = buffers[i].flags;
+ if (pdraw->buffers[i].attachment == __DRI_BUFFER_FAKE_FRONT_LEFT)
+ pdraw->have_fake_front = 1;
+ if (pdraw->buffers[i].attachment == __DRI_BUFFER_BACK_LEFT)
+ pdraw->have_back = 1;
+ }
}
static __DRIbuffer *
-dri2GetBuffers(__DRIdrawable *driDrawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *out_count, void *loaderPrivate)
+dri2GetBuffers(__DRIdrawable * driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
{
- __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
- DRI2Buffer *buffers;
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ DRI2Buffer *buffers;
- buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
- width, height, attachments, count, out_count);
- if (buffers == NULL)
- return NULL;
+ buffers = DRI2GetBuffers(pdraw->base.psc->dpy, pdraw->base.xDrawable,
+ width, height, attachments, count, out_count);
+ if (buffers == NULL)
+ return NULL;
- pdraw->width = *width;
- pdraw->height = *height;
- process_buffers(pdraw, buffers, *out_count);
+ pdraw->width = *width;
+ pdraw->height = *height;
+ process_buffers(pdraw, buffers, *out_count);
- Xfree(buffers);
+ Xfree(buffers);
- return pdraw->buffers;
+ return pdraw->buffers;
}
static __DRIbuffer *
-dri2GetBuffersWithFormat(__DRIdrawable *driDrawable,
- int *width, int *height,
- unsigned int *attachments, int count,
- int *out_count, void *loaderPrivate)
+dri2GetBuffersWithFormat(__DRIdrawable * driDrawable,
+ int *width, int *height,
+ unsigned int *attachments, int count,
+ int *out_count, void *loaderPrivate)
{
- __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
- DRI2Buffer *buffers;
+ __GLXDRIdrawablePrivate *pdraw = loaderPrivate;
+ DRI2Buffer *buffers;
- buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
- pdraw->base.xDrawable,
- width, height, attachments,
- count, out_count);
- if (buffers == NULL)
- return NULL;
+ buffers = DRI2GetBuffersWithFormat(pdraw->base.psc->dpy,
+ pdraw->base.xDrawable,
+ width, height, attachments,
+ count, out_count);
+ if (buffers == NULL)
+ return NULL;
- pdraw->width = *width;
- pdraw->height = *height;
- process_buffers(pdraw, buffers, *out_count);
+ pdraw->width = *width;
+ pdraw->height = *height;
+ process_buffers(pdraw, buffers, *out_count);
- Xfree(buffers);
+ Xfree(buffers);
- return pdraw->buffers;
+ return pdraw->buffers;
}
static const __DRIdri2LoaderExtension dri2LoaderExtension = {
- { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
- dri2GetBuffers,
- dri2FlushFrontBuffer,
- dri2GetBuffersWithFormat,
+ {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
+ dri2GetBuffers,
+ dri2FlushFrontBuffer,
+ dri2GetBuffersWithFormat,
};
static const __DRIdri2LoaderExtension dri2LoaderExtension_old = {
- { __DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION },
- dri2GetBuffers,
- dri2FlushFrontBuffer,
- NULL,
+ {__DRI_DRI2_LOADER, __DRI_DRI2_LOADER_VERSION},
+ dri2GetBuffers,
+ dri2FlushFrontBuffer,
+ NULL,
};
static const __DRIextension *loader_extensions[] = {
- &dri2LoaderExtension.base,
- &systemTimeExtension.base,
- NULL
+ &dri2LoaderExtension.base,
+ &systemTimeExtension.base,
+ NULL
};
static const __DRIextension *loader_extensions_old[] = {
- &dri2LoaderExtension_old.base,
- &systemTimeExtension.base,
- NULL
+ &dri2LoaderExtension_old.base,
+ &systemTimeExtension.base,
+ NULL
};
-static __GLXDRIscreen *dri2CreateScreen(__GLXscreenConfigs *psc, int screen,
- __GLXdisplayPrivate *priv)
+static __GLXDRIscreen *
+dri2CreateScreen(__GLXscreenConfigs * psc, int screen,
+ __GLXdisplayPrivate * priv)
{
- const __DRIconfig **driver_configs;
- const __DRIextension **extensions;
- const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
+ const __DRIconfig **driver_configs;
+ const __DRIextension **extensions;
+ const __GLXDRIdisplayPrivate *const pdp = (__GLXDRIdisplayPrivate *)
priv->dri2Display;
- __GLXDRIscreen *psp;
- char *driverName, *deviceName;
- drm_magic_t magic;
- int i;
-
- psp = Xmalloc(sizeof *psp);
- if (psp == NULL)
- return NULL;
-
- /* Initialize per screen dynamic client GLX extensions */
- psc->ext_list_first_time = GL_TRUE;
-
- if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
- &driverName, &deviceName))
- return NULL;
-
- psc->driver = driOpenDriver(driverName);
- if (psc->driver == NULL) {
- ErrorMessageF("driver pointer missing\n");
- goto handle_error;
- }
-
- extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
- if (extensions == NULL) {
- ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
- goto handle_error;
- }
-
- for (i = 0; extensions[i]; i++) {
- if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
- psc->core = (__DRIcoreExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
- psc->dri2 = (__DRIdri2Extension *) extensions[i];
- }
-
- if (psc->core == NULL || psc->dri2 == NULL) {
- ErrorMessageF("core dri or dri2 extension not found\n");
- goto handle_error;
- }
-
- psc->fd = open(deviceName, O_RDWR);
- if (psc->fd < 0) {
- ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
- return NULL;
- }
-
- if (drmGetMagic(psc->fd, &magic)) {
- ErrorMessageF("failed to get magic\n");
- return NULL;
- }
-
- if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
- ErrorMessageF("failed to authenticate magic %d\n", magic);
- return NULL;
- }
-
- /* If the server does not support the protocol for
- * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
- */
- psc->__driScreen =
- psc->dri2->createNewScreen(screen, psc->fd,
- ((pdp->driMinor < 1)
- ? loader_extensions_old
- : loader_extensions),
- &driver_configs, psc);
-
- if (psc->__driScreen == NULL) {
- ErrorMessageF("failed to create dri screen\n");
- return NULL;
- }
-
- driBindExtensions(psc, 1);
-
- psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
- psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
-
- psp->destroyScreen = dri2DestroyScreen;
- psp->createContext = dri2CreateContext;
- psp->createDrawable = dri2CreateDrawable;
- psp->swapBuffers = dri2SwapBuffers;
- psp->waitGL = dri2WaitGL;
- psp->waitX = dri2WaitX;
-
- /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
- * available.*/
- psp->copySubBuffer = dri2CopySubBuffer;
- __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
-
- Xfree(driverName);
- Xfree(deviceName);
-
- return psp;
+ __GLXDRIscreen *psp;
+ char *driverName, *deviceName;
+ drm_magic_t magic;
+ int i;
+
+ psp = Xmalloc(sizeof *psp);
+ if (psp == NULL)
+ return NULL;
+
+ /* Initialize per screen dynamic client GLX extensions */
+ psc->ext_list_first_time = GL_TRUE;
+
+ if (!DRI2Connect(psc->dpy, RootWindow(psc->dpy, screen),
+ &driverName, &deviceName))
+ return NULL;
+
+ psc->driver = driOpenDriver(driverName);
+ if (psc->driver == NULL) {
+ ErrorMessageF("driver pointer missing\n");
+ goto handle_error;
+ }
+
+ extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
+ goto handle_error;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
+ psc->core = (__DRIcoreExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_DRI2) == 0)
+ psc->dri2 = (__DRIdri2Extension *) extensions[i];
+ }
+
+ if (psc->core == NULL || psc->dri2 == NULL) {
+ ErrorMessageF("core dri or dri2 extension not found\n");
+ goto handle_error;
+ }
+
+ psc->fd = open(deviceName, O_RDWR);
+ if (psc->fd < 0) {
+ ErrorMessageF("failed to open drm device: %s\n", strerror(errno));
+ return NULL;
+ }
+
+ if (drmGetMagic(psc->fd, &magic)) {
+ ErrorMessageF("failed to get magic\n");
+ return NULL;
+ }
+
+ if (!DRI2Authenticate(psc->dpy, RootWindow(psc->dpy, screen), magic)) {
+ ErrorMessageF("failed to authenticate magic %d\n", magic);
+ return NULL;
+ }
+
+ /* If the server does not support the protocol for
+ * DRI2GetBuffersWithFormat, don't supply that interface to the driver.
+ */
+ psc->__driScreen =
+ psc->dri2->createNewScreen(screen, psc->fd, ((pdp->driMinor < 1)
+ ? loader_extensions_old
+ : loader_extensions),
+ &driver_configs, psc);
+
+ if (psc->__driScreen == NULL) {
+ ErrorMessageF("failed to create dri screen\n");
+ return NULL;
+ }
+
+ driBindExtensions(psc, 1);
+
+ psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
+ psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+
+ psc->driver_configs = driver_configs;
+
+ psp->destroyScreen = dri2DestroyScreen;
+ psp->createContext = dri2CreateContext;
+ psp->createDrawable = dri2CreateDrawable;
+ psp->swapBuffers = dri2SwapBuffers;
+ psp->waitGL = dri2WaitGL;
+ psp->waitX = dri2WaitX;
+
+ /* DRI2 suports SubBuffer through DRI2CopyRegion, so it's always
+ * available.*/
+ psp->copySubBuffer = dri2CopySubBuffer;
+ __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
+
+ Xfree(driverName);
+ Xfree(deviceName);
+
+ return psp;
handle_error:
- Xfree(driverName);
- Xfree(deviceName);
+ Xfree(driverName);
+ Xfree(deviceName);
- /* FIXME: clean up here */
+ /* FIXME: clean up here */
- return NULL;
+ return NULL;
}
/* Called from __glXFreeDisplayPrivate.
*/
-static void dri2DestroyDisplay(__GLXDRIdisplay *dpy)
+static void
+dri2DestroyDisplay(__GLXDRIdisplay * dpy)
{
- Xfree(dpy);
+ Xfree(dpy);
}
/*
@@ -526,29 +540,30 @@ static void dri2DestroyDisplay(__GLXDRIdisplay *dpy)
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
-_X_HIDDEN __GLXDRIdisplay *dri2CreateDisplay(Display *dpy)
+_X_HIDDEN __GLXDRIdisplay *
+dri2CreateDisplay(Display * dpy)
{
- __GLXDRIdisplayPrivate *pdp;
- int eventBase, errorBase;
+ __GLXDRIdisplayPrivate *pdp;
+ int eventBase, errorBase;
- if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
- return NULL;
+ if (!DRI2QueryExtension(dpy, &eventBase, &errorBase))
+ return NULL;
- pdp = Xmalloc(sizeof *pdp);
- if (pdp == NULL)
- return NULL;
+ pdp = Xmalloc(sizeof *pdp);
+ if (pdp == NULL)
+ return NULL;
- if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) {
- Xfree(pdp);
- return NULL;
- }
+ if (!DRI2QueryVersion(dpy, &pdp->driMajor, &pdp->driMinor)) {
+ Xfree(pdp);
+ return NULL;
+ }
- pdp->driPatch = 0;
+ pdp->driPatch = 0;
- pdp->base.destroyDisplay = dri2DestroyDisplay;
- pdp->base.createScreen = dri2CreateScreen;
+ pdp->base.destroyDisplay = dri2DestroyDisplay;
+ pdp->base.createScreen = dri2CreateScreen;
- return &pdp->base;
+ return &pdp->base;
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri_common.c b/src/glx/x11/dri_common.c
index 6de4111113..9c825ad74a 100644
--- a/src/glx/x11/dri_common.c
+++ b/src/glx/x11/dri_common.c
@@ -49,33 +49,35 @@
#define RTLD_GLOBAL 0
#endif
-_X_HIDDEN void InfoMessageF(const char *f, ...)
+_X_HIDDEN void
+InfoMessageF(const char *f, ...)
{
- va_list args;
- const char *env;
-
- if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
- fprintf(stderr, "libGL: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- }
+ va_list args;
+ const char *env;
+
+ if ((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) {
+ fprintf(stderr, "libGL: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ }
}
/**
* Print error to stderr, unless LIBGL_DEBUG=="quiet".
*/
-_X_HIDDEN void ErrorMessageF(const char *f, ...)
+_X_HIDDEN void
+ErrorMessageF(const char *f, ...)
{
- va_list args;
- const char *env;
-
- if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
- fprintf(stderr, "libGL error: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- }
+ va_list args;
+ const char *env;
+
+ if ((env = getenv("LIBGL_DEBUG")) && !strstr(env, "quiet")) {
+ fprintf(stderr, "libGL error: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ }
}
#ifndef DEFAULT_DRIVER_DIR
@@ -95,7 +97,8 @@ _X_HIDDEN void ErrorMessageF(const char *f, ...)
* \returns
* A handle from \c dlopen, or \c NULL if driver file not found.
*/
-_X_HIDDEN void *driOpenDriver(const char *driverName)
+_X_HIDDEN void *
+driOpenDriver(const char *driverName)
{
void *glhandle, *handle;
const char *libPaths, *p, *next;
@@ -110,40 +113,41 @@ _X_HIDDEN void *driOpenDriver(const char *driverName)
/* don't allow setuid apps to use LIBGL_DRIVERS_PATH */
libPaths = getenv("LIBGL_DRIVERS_PATH");
if (!libPaths)
- libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
+ libPaths = getenv("LIBGL_DRIVERS_DIR"); /* deprecated */
}
if (libPaths == NULL)
- libPaths = DEFAULT_DRIVER_DIR;
+ libPaths = DEFAULT_DRIVER_DIR;
handle = NULL;
for (p = libPaths; *p; p = next) {
- next = strchr(p, ':');
- if (next == NULL) {
- len = strlen(p);
- next = p + len;
- } else {
- len = next - p;
- next++;
- }
+ next = strchr(p, ':');
+ if (next == NULL) {
+ len = strlen(p);
+ next = p + len;
+ }
+ else {
+ len = next - p;
+ next++;
+ }
#ifdef GLX_USE_TLS
snprintf(realDriverName, sizeof realDriverName,
- "%.*s/tls/%s_dri.so", len, p, driverName);
+ "%.*s/tls/%s_dri.so", len, p, driverName);
InfoMessageF("OpenDriver: trying %s\n", realDriverName);
handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
#endif
- if ( handle == NULL ) {
- snprintf(realDriverName, sizeof realDriverName,
- "%.*s/%s_dri.so", len, p, driverName);
- InfoMessageF("OpenDriver: trying %s\n", realDriverName);
- handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
+ if (handle == NULL) {
+ snprintf(realDriverName, sizeof realDriverName,
+ "%.*s/%s_dri.so", len, p, driverName);
+ InfoMessageF("OpenDriver: trying %s\n", realDriverName);
+ handle = dlopen(realDriverName, RTLD_NOW | RTLD_GLOBAL);
}
- if ( handle != NULL )
- break;
+ if (handle != NULL)
+ break;
else
- ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
+ ErrorMessageF("dlopen %s failed (%s)\n", realDriverName, dlerror());
}
if (!handle)
@@ -156,253 +160,258 @@ _X_HIDDEN void *driOpenDriver(const char *driverName)
}
_X_HIDDEN const __DRIsystemTimeExtension systemTimeExtension = {
- { __DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION },
- __glXGetUST,
- __driGetMscRateOML
+ {__DRI_SYSTEM_TIME, __DRI_SYSTEM_TIME_VERSION},
+ __glXGetUST,
+ __driGetMscRateOML
};
#define __ATTRIB(attrib, field) \
{ attrib, offsetof(__GLcontextModes, field) }
-static const struct { unsigned int attrib, offset; } attribMap[] = {
- __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
- __ATTRIB(__DRI_ATTRIB_LEVEL, level),
- __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
- __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
- __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
- __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
- __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
- __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
- __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
- __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
- __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
- __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
- __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
+static const struct
+{
+ unsigned int attrib, offset;
+} attribMap[] = {
+ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
+ __ATTRIB(__DRI_ATTRIB_LEVEL, level),
+ __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
+ __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
+ __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
+ __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
+ __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
+ __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
+ __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
+ __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
+ __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
+ __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
#if 0
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
- __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
- __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
- __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
- __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentIndex),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
+ __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
+ __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
+ __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
#endif
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
#if 0
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
#endif
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
-};
+__ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE,
+ bindToMipmapTexture),
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),};
#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
static int
-scalarEqual(__GLcontextModes *mode, unsigned int attrib, unsigned int value)
+scalarEqual(__GLcontextModes * mode, unsigned int attrib, unsigned int value)
{
- unsigned int glxValue;
- int i;
+ unsigned int glxValue;
+ int i;
- for (i = 0; i < ARRAY_SIZE(attribMap); i++)
- if (attribMap[i].attrib == attrib) {
- glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
- return glxValue == GLX_DONT_CARE || glxValue == value;
- }
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib) {
+ glxValue = *(unsigned int *) ((char *) mode + attribMap[i].offset);
+ return glxValue == GLX_DONT_CARE || glxValue == value;
+ }
- return GL_TRUE; /* Is a non-existing attribute equal to value? */
+ return GL_TRUE; /* Is a non-existing attribute equal to value? */
}
static int
-driConfigEqual(const __DRIcoreExtension *core,
- __GLcontextModes *modes, const __DRIconfig *driConfig)
+driConfigEqual(const __DRIcoreExtension * core,
+ __GLcontextModes * modes, const __DRIconfig * driConfig)
{
- unsigned int attrib, value, glxValue;
- int i;
-
- i = 0;
- while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
- switch (attrib) {
- case __DRI_ATTRIB_RENDER_TYPE:
- glxValue = 0;
- if (value & __DRI_ATTRIB_RGBA_BIT) {
- glxValue |= GLX_RGBA_BIT;
- } else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
- glxValue |= GLX_COLOR_INDEX_BIT;
- }
- if (glxValue != modes->renderType)
- return GL_FALSE;
- break;
-
- case __DRI_ATTRIB_CONFIG_CAVEAT:
- if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
- glxValue = GLX_NON_CONFORMANT_CONFIG;
- else if (value & __DRI_ATTRIB_SLOW_BIT)
- glxValue = GLX_SLOW_CONFIG;
- else
- glxValue = GLX_NONE;
- if (glxValue != modes->visualRating)
- return GL_FALSE;
- break;
-
- case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
- glxValue = 0;
- if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
- glxValue |= GLX_TEXTURE_1D_BIT_EXT;
- if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
- glxValue |= GLX_TEXTURE_2D_BIT_EXT;
- if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
- glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
- if (modes->bindToTextureTargets != GLX_DONT_CARE &&
- glxValue != modes->bindToTextureTargets)
- return GL_FALSE;
- break;
-
- default:
- if (!scalarEqual(modes, attrib, value))
- return GL_FALSE;
- }
- }
-
- return GL_TRUE;
+ unsigned int attrib, value, glxValue;
+ int i;
+
+ i = 0;
+ while (core->indexConfigAttrib(driConfig, i++, &attrib, &value)) {
+ switch (attrib) {
+ case __DRI_ATTRIB_RENDER_TYPE:
+ glxValue = 0;
+ if (value & __DRI_ATTRIB_RGBA_BIT) {
+ glxValue |= GLX_RGBA_BIT;
+ }
+ else if (value & __DRI_ATTRIB_COLOR_INDEX_BIT) {
+ glxValue |= GLX_COLOR_INDEX_BIT;
+ }
+ if (glxValue != modes->renderType)
+ return GL_FALSE;
+ break;
+
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (value & __DRI_ATTRIB_NON_CONFORMANT_CONFIG)
+ glxValue = GLX_NON_CONFORMANT_CONFIG;
+ else if (value & __DRI_ATTRIB_SLOW_BIT)
+ glxValue = GLX_SLOW_CONFIG;
+ else
+ glxValue = GLX_NONE;
+ if (glxValue != modes->visualRating)
+ return GL_FALSE;
+ break;
+
+ case __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS:
+ glxValue = 0;
+ if (value & __DRI_ATTRIB_TEXTURE_1D_BIT)
+ glxValue |= GLX_TEXTURE_1D_BIT_EXT;
+ if (value & __DRI_ATTRIB_TEXTURE_2D_BIT)
+ glxValue |= GLX_TEXTURE_2D_BIT_EXT;
+ if (value & __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT)
+ glxValue |= GLX_TEXTURE_RECTANGLE_BIT_EXT;
+ if (modes->bindToTextureTargets != GLX_DONT_CARE &&
+ glxValue != modes->bindToTextureTargets)
+ return GL_FALSE;
+ break;
+
+ default:
+ if (!scalarEqual(modes, attrib, value))
+ return GL_FALSE;
+ }
+ }
+
+ return GL_TRUE;
}
static __GLcontextModes *
-createDriMode(const __DRIcoreExtension *core,
- __GLcontextModes *modes, const __DRIconfig **driConfigs)
+createDriMode(const __DRIcoreExtension * core,
+ __GLcontextModes * modes, const __DRIconfig ** driConfigs)
{
- __GLXDRIconfigPrivate *config;
- int i;
+ __GLXDRIconfigPrivate *config;
+ int i;
- for (i = 0; driConfigs[i]; i++) {
- if (driConfigEqual(core, modes, driConfigs[i]))
- break;
- }
+ for (i = 0; driConfigs[i]; i++) {
+ if (driConfigEqual(core, modes, driConfigs[i]))
+ break;
+ }
- if (driConfigs[i] == NULL)
- return NULL;
+ if (driConfigs[i] == NULL)
+ return NULL;
- config = Xmalloc(sizeof *config);
- if (config == NULL)
- return NULL;
+ config = Xmalloc(sizeof *config);
+ if (config == NULL)
+ return NULL;
- config->modes = *modes;
- config->driConfig = driConfigs[i];
+ config->modes = *modes;
+ config->driConfig = driConfigs[i];
- return &config->modes;
+ return &config->modes;
}
_X_HIDDEN __GLcontextModes *
-driConvertConfigs(const __DRIcoreExtension *core,
- __GLcontextModes *modes, const __DRIconfig **configs)
+driConvertConfigs(const __DRIcoreExtension * core,
+ __GLcontextModes * modes, const __DRIconfig ** configs)
{
- __GLcontextModes head, *tail, *m;
-
- tail = &head;
- head.next = NULL;
- for (m = modes; m; m = m->next) {
- tail->next = createDriMode(core, m, configs);
- if (tail->next == NULL) {
- /* no matching dri config for m */
- continue;
- }
+ __GLcontextModes head, *tail, *m;
+
+ tail = &head;
+ head.next = NULL;
+ for (m = modes; m; m = m->next) {
+ tail->next = createDriMode(core, m, configs);
+ if (tail->next == NULL) {
+ /* no matching dri config for m */
+ continue;
+ }
- tail = tail->next;
- }
+ tail = tail->next;
+ }
- _gl_context_modes_destroy(modes);
+ _gl_context_modes_destroy(modes);
- return head.next;
+ return head.next;
}
_X_HIDDEN void
-driBindExtensions(__GLXscreenConfigs *psc, int dri2)
+driBindExtensions(__GLXscreenConfigs * psc, int dri2)
{
- const __DRIextension **extensions;
- int i;
+ const __DRIextension **extensions;
+ int i;
- extensions = psc->core->getExtensions(psc->__driScreen);
+ extensions = psc->core->getExtensions(psc->__driScreen);
- for (i = 0; extensions[i]; i++) {
+ for (i = 0; extensions[i]; i++) {
#ifdef __DRI_COPY_SUB_BUFFER
- if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
- psc->driCopySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
- }
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ psc->driCopySubBuffer =
+ (__DRIcopySubBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_copy_sub_buffer");
+ }
#endif
#ifdef __DRI_SWAP_CONTROL
- /* No DRI2 support for swap_control at the moment, since SwapBuffers
- * is done by the X server */
- if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
- psc->swapControl = (__DRIswapControlExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
- __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
- }
+ /* No DRI2 support for swap_control at the moment, since SwapBuffers
+ * is done by the X server */
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0 && !dri2) {
+ psc->swapControl = (__DRIswapControlExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_SGI_swap_control");
+ __glXEnableDirectExtension(psc, "GLX_MESA_swap_control");
+ }
#endif
#ifdef __DRI_ALLOCATE
- if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
- psc->allocate = (__DRIallocateExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
- }
+ if (strcmp(extensions[i]->name, __DRI_ALLOCATE) == 0) {
+ psc->allocate = (__DRIallocateExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_allocate_memory");
+ }
#endif
#ifdef __DRI_FRAME_TRACKING
- if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
- psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
- }
+ if (strcmp(extensions[i]->name, __DRI_FRAME_TRACKING) == 0) {
+ psc->frameTracking = (__DRIframeTrackingExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_MESA_swap_frame_usage");
+ }
#endif
#ifdef __DRI_MEDIA_STREAM_COUNTER
- if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
- psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
- }
+ if (strcmp(extensions[i]->name, __DRI_MEDIA_STREAM_COUNTER) == 0) {
+ psc->msc = (__DRImediaStreamCounterExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_SGI_video_sync");
+ }
#endif
#ifdef __DRI_SWAP_BUFFER_COUNTER
- /* No driver supports this at this time and the extension is
- * not defined in dri_interface.h. Will enable
- * GLX_OML_sync_control if implemented. */
+ /* No driver supports this at this time and the extension is
+ * not defined in dri_interface.h. Will enable
+ * GLX_OML_sync_control if implemented. */
#endif
#ifdef __DRI_READ_DRAWABLE
- if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
- __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
- }
+ if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+ __glXEnableDirectExtension(psc, "GLX_SGI_make_current_read");
+ }
#endif
#ifdef __DRI_TEX_BUFFER
- if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) {
- psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
- __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
- }
+ if ((strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) && dri2) {
+ psc->texBuffer = (__DRItexBufferExtension *) extensions[i];
+ __glXEnableDirectExtension(psc, "GLX_EXT_texture_from_pixmap");
+ }
#endif
#ifdef __DRI2_FLUSH
- if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
- psc->f = (__DRI2flushExtension *) extensions[i];
- /* internal driver extension, no GL extension exposed */
- }
+ if ((strcmp(extensions[i]->name, __DRI2_FLUSH) == 0) && dri2) {
+ psc->f = (__DRI2flushExtension *) extensions[i];
+ /* internal driver extension, no GL extension exposed */
+ }
#endif
- /* Ignore unknown extensions */
- }
+ /* Ignore unknown extensions */
+ }
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/dri_glx.c b/src/glx/x11/dri_glx.c
index ac2eb05341..ab24bd8ffe 100644
--- a/src/glx/x11/dri_glx.c
+++ b/src/glx/x11/dri_glx.c
@@ -51,22 +51,24 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
typedef struct __GLXDRIdisplayPrivateRec __GLXDRIdisplayPrivate;
typedef struct __GLXDRIcontextPrivateRec __GLXDRIcontextPrivate;
-struct __GLXDRIdisplayPrivateRec {
- __GLXDRIdisplay base;
+struct __GLXDRIdisplayPrivateRec
+{
+ __GLXDRIdisplay base;
- /*
+ /*
** XFree86-DRI version information
*/
- int driMajor;
- int driMinor;
- int driPatch;
+ int driMajor;
+ int driMinor;
+ int driPatch;
};
-struct __GLXDRIcontextPrivateRec {
- __GLXDRIcontext base;
- __DRIcontext *driContext;
- XID hwContextID;
- __GLXscreenConfigs *psc;
+struct __GLXDRIcontextPrivateRec
+{
+ __GLXDRIcontext base;
+ __DRIcontext *driContext;
+ XID hwContextID;
+ __GLXscreenConfigs *psc;
};
/*
@@ -74,47 +76,51 @@ struct __GLXDRIcontextPrivateRec {
* the DRI driver for the screen. (I.e. "r128", "tdfx", etc).
* Return True for success, False for failure.
*/
-static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
+static Bool
+driGetDriverName(Display * dpy, int scrNum, char **driverName)
{
- int directCapable;
- Bool b;
- int event, error;
- int driverMajor, driverMinor, driverPatch;
-
- *driverName = NULL;
-
- if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */
- if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
- ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
- return False;
- }
- if (!directCapable) {
- ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
- return False;
- }
-
- b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
- &driverPatch, driverName);
- if (!b) {
- ErrorMessageF("Cannot determine driver name for screen %d\n", scrNum);
- return False;
- }
-
- InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
- driverMajor, driverMinor, driverPatch, *driverName, scrNum);
-
- return True;
- } else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */
- char *dev;
- Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
-
- if (ret)
- Xfree(dev);
-
- return ret;
- }
-
- return False;
+ int directCapable;
+ Bool b;
+ int event, error;
+ int driverMajor, driverMinor, driverPatch;
+
+ *driverName = NULL;
+
+ if (XF86DRIQueryExtension(dpy, &event, &error)) { /* DRI1 */
+ if (!XF86DRIQueryDirectRenderingCapable(dpy, scrNum, &directCapable)) {
+ ErrorMessageF("XF86DRIQueryDirectRenderingCapable failed\n");
+ return False;
+ }
+ if (!directCapable) {
+ ErrorMessageF("XF86DRIQueryDirectRenderingCapable returned false\n");
+ return False;
+ }
+
+ b = XF86DRIGetClientDriverName(dpy, scrNum, &driverMajor, &driverMinor,
+ &driverPatch, driverName);
+ if (!b) {
+ ErrorMessageF("Cannot determine driver name for screen %d\n",
+ scrNum);
+ return False;
+ }
+
+ InfoMessageF("XF86DRIGetClientDriverName: %d.%d.%d %s (screen %d)\n",
+ driverMajor, driverMinor, driverPatch, *driverName,
+ scrNum);
+
+ return True;
+ }
+ else if (DRI2QueryExtension(dpy, &event, &error)) { /* DRI2 */
+ char *dev;
+ Bool ret = DRI2Connect(dpy, RootWindow(dpy, scrNum), driverName, &dev);
+
+ if (ret)
+ Xfree(dev);
+
+ return ret;
+ }
+
+ return False;
}
/*
@@ -123,17 +129,19 @@ static Bool driGetDriverName(Display *dpy, int scrNum, char **driverName)
* The returned char pointer points to a static array that will be
* overwritten by subsequent calls.
*/
-PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
+PUBLIC const char *
+glXGetScreenDriver(Display * dpy, int scrNum)
+{
static char ret[32];
char *driverName;
if (driGetDriverName(dpy, scrNum, &driverName)) {
int len;
if (!driverName)
- return NULL;
- len = strlen (driverName);
+ return NULL;
+ len = strlen(driverName);
if (len >= 31)
- return NULL;
- memcpy (ret, driverName, len+1);
+ return NULL;
+ memcpy(ret, driverName, len + 1);
Xfree(driverName);
return ret;
}
@@ -151,121 +159,125 @@ PUBLIC const char *glXGetScreenDriver (Display *dpy, int scrNum) {
*
* Note: The driver remains opened after this function returns.
*/
-PUBLIC const char *glXGetDriverConfig (const char *driverName)
+PUBLIC const char *
+glXGetDriverConfig(const char *driverName)
{
- void *handle = driOpenDriver (driverName);
+ void *handle = driOpenDriver(driverName);
if (handle)
- return dlsym (handle, "__driConfigOptions");
+ return dlsym(handle, "__driConfigOptions");
else
return NULL;
}
#ifdef XDAMAGE_1_1_INTERFACE
-static GLboolean has_damage_post(Display *dpy)
+static GLboolean
+has_damage_post(Display * dpy)
{
- static GLboolean inited = GL_FALSE;
- static GLboolean has_damage;
-
- if (!inited) {
- int major, minor;
-
- if (XDamageQueryVersion(dpy, &major, &minor) &&
- major == 1 && minor >= 1)
- {
- has_damage = GL_TRUE;
- } else {
- has_damage = GL_FALSE;
- }
- inited = GL_TRUE;
- }
-
- return has_damage;
+ static GLboolean inited = GL_FALSE;
+ static GLboolean has_damage;
+
+ if (!inited) {
+ int major, minor;
+
+ if (XDamageQueryVersion(dpy, &major, &minor) &&
+ major == 1 && minor >= 1) {
+ has_damage = GL_TRUE;
+ }
+ else {
+ has_damage = GL_FALSE;
+ }
+ inited = GL_TRUE;
+ }
+
+ return has_damage;
}
-static void __glXReportDamage(__DRIdrawable *driDraw,
- int x, int y,
- drm_clip_rect_t *rects, int num_rects,
- GLboolean front_buffer,
- void *loaderPrivate)
+static void
+__glXReportDamage(__DRIdrawable * driDraw,
+ int x, int y,
+ drm_clip_rect_t * rects, int num_rects,
+ GLboolean front_buffer, void *loaderPrivate)
{
- XRectangle *xrects;
- XserverRegion region;
- int i;
- int x_off, y_off;
- __GLXDRIdrawable *glxDraw = loaderPrivate;
- __GLXscreenConfigs *psc = glxDraw->psc;
- Display *dpy = psc->dpy;
- Drawable drawable;
-
- if (!has_damage_post(dpy))
- return;
-
- if (front_buffer) {
- x_off = x;
- y_off = y;
- drawable = RootWindow(dpy, psc->scr);
- } else{
- x_off = 0;
- y_off = 0;
- drawable = glxDraw->xDrawable;
- }
-
- xrects = malloc(sizeof(XRectangle) * num_rects);
- if (xrects == NULL)
- return;
-
- for (i = 0; i < num_rects; i++) {
- xrects[i].x = rects[i].x1 + x_off;
- xrects[i].y = rects[i].y1 + y_off;
- xrects[i].width = rects[i].x2 - rects[i].x1;
- xrects[i].height = rects[i].y2 - rects[i].y1;
- }
- region = XFixesCreateRegion(dpy, xrects, num_rects);
- free(xrects);
- XDamageAdd(dpy, drawable, region);
- XFixesDestroyRegion(dpy, region);
+ XRectangle *xrects;
+ XserverRegion region;
+ int i;
+ int x_off, y_off;
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
+ Drawable drawable;
+
+ if (!has_damage_post(dpy))
+ return;
+
+ if (front_buffer) {
+ x_off = x;
+ y_off = y;
+ drawable = RootWindow(dpy, psc->scr);
+ }
+ else {
+ x_off = 0;
+ y_off = 0;
+ drawable = glxDraw->xDrawable;
+ }
+
+ xrects = malloc(sizeof(XRectangle) * num_rects);
+ if (xrects == NULL)
+ return;
+
+ for (i = 0; i < num_rects; i++) {
+ xrects[i].x = rects[i].x1 + x_off;
+ xrects[i].y = rects[i].y1 + y_off;
+ xrects[i].width = rects[i].x2 - rects[i].x1;
+ xrects[i].height = rects[i].y2 - rects[i].y1;
+ }
+ region = XFixesCreateRegion(dpy, xrects, num_rects);
+ free(xrects);
+ XDamageAdd(dpy, drawable, region);
+ XFixesDestroyRegion(dpy, region);
}
static const __DRIdamageExtension damageExtension = {
- { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
- __glXReportDamage,
+ {__DRI_DAMAGE, __DRI_DAMAGE_VERSION},
+ __glXReportDamage,
};
#endif
static GLboolean
-__glXDRIGetDrawableInfo(__DRIdrawable *drawable,
- unsigned int *index, unsigned int *stamp,
- int *X, int *Y, int *W, int *H,
- int *numClipRects, drm_clip_rect_t ** pClipRects,
- int *backX, int *backY,
- int *numBackClipRects, drm_clip_rect_t **pBackClipRects,
- void *loaderPrivate)
+__glXDRIGetDrawableInfo(__DRIdrawable * drawable,
+ unsigned int *index, unsigned int *stamp,
+ int *X, int *Y, int *W, int *H,
+ int *numClipRects, drm_clip_rect_t ** pClipRects,
+ int *backX, int *backY,
+ int *numBackClipRects,
+ drm_clip_rect_t ** pBackClipRects,
+ void *loaderPrivate)
{
- __GLXDRIdrawable *glxDraw = loaderPrivate;
- __GLXscreenConfigs *psc = glxDraw->psc;
- Display *dpy = psc->dpy;
-
- return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
- index, stamp, X, Y, W, H,
- numClipRects, pClipRects,
- backX, backY,
- numBackClipRects, pBackClipRects);
+ __GLXDRIdrawable *glxDraw = loaderPrivate;
+ __GLXscreenConfigs *psc = glxDraw->psc;
+ Display *dpy = psc->dpy;
+
+ return XF86DRIGetDrawableInfo(dpy, psc->scr, glxDraw->drawable,
+ index, stamp, X, Y, W, H,
+ numClipRects, pClipRects,
+ backX, backY,
+ numBackClipRects, pBackClipRects);
}
static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
- { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
- __glXDRIGetDrawableInfo
+ {__DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION},
+ __glXDRIGetDrawableInfo
};
static const __DRIextension *loader_extensions[] = {
- &systemTimeExtension.base,
- &getDrawableInfoExtension.base,
+ &systemTimeExtension.base,
+ &getDrawableInfoExtension.base,
#ifdef XDAMAGE_1_1_INTERFACE
- &damageExtension.base,
+ &damageExtension.base,
#endif
- NULL
+ NULL
};
#ifndef GLX_USE_APPLEGL
@@ -284,425 +296,429 @@ static const __DRIextension *loader_extensions[] = {
* the client-side driver on success, or \c NULL on failure.
*/
static void *
-CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
- __GLXDRIdisplayPrivate * driDpy)
+CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
+ __GLXDRIdisplayPrivate * driDpy)
{
- void *psp = NULL;
- drm_handle_t hSAREA;
- drmAddress pSAREA = MAP_FAILED;
- char *BusID;
- __DRIversion ddx_version;
- __DRIversion dri_version;
- __DRIversion drm_version;
- __DRIframebuffer framebuffer;
- int fd = -1;
- int status;
-
- drm_magic_t magic;
- drmVersionPtr version;
- int newlyopened;
- char *driverName;
- drm_handle_t hFB;
- int junk;
- const __DRIconfig **driver_configs;
- __GLcontextModes *visual;
-
- /* DRI protocol version. */
- dri_version.major = driDpy->driMajor;
- dri_version.minor = driDpy->driMinor;
- dri_version.patch = driDpy->driPatch;
-
- framebuffer.base = MAP_FAILED;
- framebuffer.dev_priv = NULL;
-
- if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
- ErrorMessageF("XF86DRIOpenConnection failed\n");
- goto handle_error;
- }
-
- fd = drmOpenOnce(NULL, BusID, &newlyopened);
-
- Xfree(BusID); /* No longer needed */
-
- if (fd < 0) {
- ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
- goto handle_error;
- }
-
- if (drmGetMagic(fd, &magic)) {
- ErrorMessageF("drmGetMagic failed\n");
- goto handle_error;
- }
-
- version = drmGetVersion(fd);
- if (version) {
- drm_version.major = version->version_major;
- drm_version.minor = version->version_minor;
- drm_version.patch = version->version_patchlevel;
- drmFreeVersion(version);
- }
- else {
- drm_version.major = -1;
- drm_version.minor = -1;
- drm_version.patch = -1;
- }
-
- if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
- ErrorMessageF("XF86DRIAuthConnection failed\n");
- goto handle_error;
- }
-
- /* Get device name (like "tdfx") and the ddx version numbers.
- * We'll check the version in each DRI driver's "createNewScreen"
- * function. */
- if (!XF86DRIGetClientDriverName(dpy, scrn,
- &ddx_version.major,
- &ddx_version.minor,
- &ddx_version.patch,
- &driverName)) {
- ErrorMessageF("XF86DRIGetClientDriverName failed\n");
- goto handle_error;
- }
-
- Xfree(driverName); /* No longer needed. */
-
- /*
- * Get device-specific info. pDevPriv will point to a struct
- * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
- * has information about the screen size, depth, pitch, ancilliary
- * buffers, DRM mmap handles, etc.
- */
- if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
- &framebuffer.size, &framebuffer.stride,
- &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
- ErrorMessageF("XF86DRIGetDeviceInfo failed");
- goto handle_error;
- }
-
- framebuffer.width = DisplayWidth(dpy, scrn);
- framebuffer.height = DisplayHeight(dpy, scrn);
-
- /* Map the framebuffer region. */
- status = drmMap(fd, hFB, framebuffer.size,
- (drmAddressPtr)&framebuffer.base);
- if (status != 0) {
- ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
- goto handle_error;
- }
-
- /* Map the SAREA region. Further mmap regions may be setup in
- * each DRI driver's "createNewScreen" function.
- */
- status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
- if (status != 0) {
- ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
- goto handle_error;
- }
-
- psp = (*psc->legacy->createNewScreen)(scrn,
- &ddx_version,
- &dri_version,
- &drm_version,
- &framebuffer,
- pSAREA,
- fd,
- loader_extensions,
- &driver_configs,
- psc);
-
- if (psp == NULL) {
- ErrorMessageF("Calling driver entry point failed");
- goto handle_error;
- }
-
- psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
- psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
-
- /* Visuals with depth != screen depth are subject to automatic compositing
- * in the X server, so DRI1 can't render to them properly. Mark them as
- * non-conformant to prevent apps from picking them up accidentally.
- */
- for (visual = psc->visuals; visual; visual = visual->next) {
- XVisualInfo template;
- XVisualInfo *visuals;
- int num_visuals;
- long mask;
-
- template.visualid = visual->visualID;
- mask = VisualIDMask;
- visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
-
- if (visuals) {
- if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
- visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
-
- XFree(visuals);
- }
- }
-
- return psp;
+ void *psp = NULL;
+ drm_handle_t hSAREA;
+ drmAddress pSAREA = MAP_FAILED;
+ char *BusID;
+ __DRIversion ddx_version;
+ __DRIversion dri_version;
+ __DRIversion drm_version;
+ __DRIframebuffer framebuffer;
+ int fd = -1;
+ int status;
+
+ drm_magic_t magic;
+ drmVersionPtr version;
+ int newlyopened;
+ char *driverName;
+ drm_handle_t hFB;
+ int junk;
+ const __DRIconfig **driver_configs;
+ __GLcontextModes *visual;
+
+ /* DRI protocol version. */
+ dri_version.major = driDpy->driMajor;
+ dri_version.minor = driDpy->driMinor;
+ dri_version.patch = driDpy->driPatch;
+
+ framebuffer.base = MAP_FAILED;
+ framebuffer.dev_priv = NULL;
+
+ if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) {
+ ErrorMessageF("XF86DRIOpenConnection failed\n");
+ goto handle_error;
+ }
+
+ fd = drmOpenOnce(NULL, BusID, &newlyopened);
+
+ Xfree(BusID); /* No longer needed */
+
+ if (fd < 0) {
+ ErrorMessageF("drmOpenOnce failed (%s)\n", strerror(-fd));
+ goto handle_error;
+ }
+
+ if (drmGetMagic(fd, &magic)) {
+ ErrorMessageF("drmGetMagic failed\n");
+ goto handle_error;
+ }
+
+ version = drmGetVersion(fd);
+ if (version) {
+ drm_version.major = version->version_major;
+ drm_version.minor = version->version_minor;
+ drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ }
+ else {
+ drm_version.major = -1;
+ drm_version.minor = -1;
+ drm_version.patch = -1;
+ }
+
+ if (newlyopened && !XF86DRIAuthConnection(dpy, scrn, magic)) {
+ ErrorMessageF("XF86DRIAuthConnection failed\n");
+ goto handle_error;
+ }
+
+ /* Get device name (like "tdfx") and the ddx version numbers.
+ * We'll check the version in each DRI driver's "createNewScreen"
+ * function. */
+ if (!XF86DRIGetClientDriverName(dpy, scrn,
+ &ddx_version.major,
+ &ddx_version.minor,
+ &ddx_version.patch, &driverName)) {
+ ErrorMessageF("XF86DRIGetClientDriverName failed\n");
+ goto handle_error;
+ }
+
+ Xfree(driverName); /* No longer needed. */
+
+ /*
+ * Get device-specific info. pDevPriv will point to a struct
+ * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
+ * has information about the screen size, depth, pitch, ancilliary
+ * buffers, DRM mmap handles, etc.
+ */
+ if (!XF86DRIGetDeviceInfo(dpy, scrn, &hFB, &junk,
+ &framebuffer.size, &framebuffer.stride,
+ &framebuffer.dev_priv_size,
+ &framebuffer.dev_priv)) {
+ ErrorMessageF("XF86DRIGetDeviceInfo failed");
+ goto handle_error;
+ }
+
+ framebuffer.width = DisplayWidth(dpy, scrn);
+ framebuffer.height = DisplayHeight(dpy, scrn);
+
+ /* Map the framebuffer region. */
+ status = drmMap(fd, hFB, framebuffer.size,
+ (drmAddressPtr) & framebuffer.base);
+ if (status != 0) {
+ ErrorMessageF("drmMap of framebuffer failed (%s)", strerror(-status));
+ goto handle_error;
+ }
+
+ /* Map the SAREA region. Further mmap regions may be setup in
+ * each DRI driver's "createNewScreen" function.
+ */
+ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+ if (status != 0) {
+ ErrorMessageF("drmMap of SAREA failed (%s)", strerror(-status));
+ goto handle_error;
+ }
+
+ psp = (*psc->legacy->createNewScreen) (scrn,
+ &ddx_version,
+ &dri_version,
+ &drm_version,
+ &framebuffer,
+ pSAREA,
+ fd,
+ loader_extensions,
+ &driver_configs, psc);
+
+ if (psp == NULL) {
+ ErrorMessageF("Calling driver entry point failed");
+ goto handle_error;
+ }
+
+ psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
+ psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
+
+ psc->driver_configs = driver_configs;
+
+ /* Visuals with depth != screen depth are subject to automatic compositing
+ * in the X server, so DRI1 can't render to them properly. Mark them as
+ * non-conformant to prevent apps from picking them up accidentally.
+ */
+ for (visual = psc->visuals; visual; visual = visual->next) {
+ XVisualInfo template;
+ XVisualInfo *visuals;
+ int num_visuals;
+ long mask;
+
+ template.visualid = visual->visualID;
+ mask = VisualIDMask;
+ visuals = XGetVisualInfo(dpy, mask, &template, &num_visuals);
+
+ if (visuals) {
+ if (num_visuals > 0 && visuals->depth != DefaultDepth(dpy, scrn))
+ visual->visualRating = GLX_NON_CONFORMANT_CONFIG;
+
+ XFree(visuals);
+ }
+ }
+
+ return psp;
handle_error:
- if (pSAREA != MAP_FAILED)
- drmUnmap(pSAREA, SAREA_MAX);
+ if (pSAREA != MAP_FAILED)
+ drmUnmap(pSAREA, SAREA_MAX);
- if (framebuffer.base != MAP_FAILED)
- drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+ if (framebuffer.base != MAP_FAILED)
+ drmUnmap((drmAddress) framebuffer.base, framebuffer.size);
- if (framebuffer.dev_priv != NULL)
- Xfree(framebuffer.dev_priv);
+ if (framebuffer.dev_priv != NULL)
+ Xfree(framebuffer.dev_priv);
- if (fd >= 0)
- drmCloseOnce(fd);
+ if (fd >= 0)
+ drmCloseOnce(fd);
- XF86DRICloseConnection(dpy, scrn);
+ XF86DRICloseConnection(dpy, scrn);
- ErrorMessageF("reverting to software direct rendering\n");
+ ErrorMessageF("reverting to software direct rendering\n");
- return NULL;
+ return NULL;
}
#else /* !GLX_USE_APPLEGL */
static void *
-CallCreateNewScreen(Display *dpy, int scrn, __GLXscreenConfigs *psc,
- __GLXDRIdisplayPrivate * driDpy)
+CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc,
+ __GLXDRIdisplayPrivate * driDpy)
{
- return NULL;
+ return NULL;
}
#endif /* !GLX_USE_APPLEGL */
-static void driDestroyContext(__GLXDRIcontext *context,
- __GLXscreenConfigs *psc, Display *dpy)
+static void
+driDestroyContext(__GLXDRIcontext * context,
+ __GLXscreenConfigs * psc, Display * dpy)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
-
- (*psc->core->destroyContext)(pcp->driContext);
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
- Xfree(pcp);
+ (*psc->core->destroyContext) (pcp->driContext);
+
+ XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+ Xfree(pcp);
}
-static Bool driBindContext(__GLXDRIcontext *context,
- __GLXDRIdrawable *draw, __GLXDRIdrawable *read)
+static Bool
+driBindContext(__GLXDRIcontext * context,
+ __GLXDRIdrawable * draw, __GLXDRIdrawable * read)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- const __DRIcoreExtension *core = pcp->psc->core;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- return (*core->bindContext)(pcp->driContext,
- draw->driDrawable,
- read->driDrawable);
+ return (*core->bindContext) (pcp->driContext,
+ draw->driDrawable, read->driDrawable);
}
-static void driUnbindContext(__GLXDRIcontext *context)
+static void
+driUnbindContext(__GLXDRIcontext * context)
{
- __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
- const __DRIcoreExtension *core = pcp->psc->core;
+ __GLXDRIcontextPrivate *pcp = (__GLXDRIcontextPrivate *) context;
+ const __DRIcoreExtension *core = pcp->psc->core;
- (*core->unbindContext)(pcp->driContext);
+ (*core->unbindContext) (pcp->driContext);
}
-static __GLXDRIcontext *driCreateContext(__GLXscreenConfigs *psc,
- const __GLcontextModes *mode,
- GLXContext gc,
- GLXContext shareList, int renderType)
+static __GLXDRIcontext *
+driCreateContext(__GLXscreenConfigs * psc,
+ const __GLcontextModes * mode,
+ GLXContext gc, GLXContext shareList, int renderType)
{
- __GLXDRIcontextPrivate *pcp, *pcp_shared;
- drm_context_t hwContext;
- __DRIcontext *shared = NULL;
- __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
-
- if (!psc || !psc->driScreen)
- return NULL;
-
- if (shareList) {
- pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
- shared = pcp_shared->driContext;
- }
-
- pcp = Xmalloc(sizeof *pcp);
- if (pcp == NULL)
- return NULL;
-
- pcp->psc = psc;
- if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
- mode->visualID,
- &pcp->hwContextID, &hwContext)) {
- Xfree(pcp);
- return NULL;
- }
-
- pcp->driContext =
- (*psc->legacy->createNewContext)(psc->__driScreen,
- config->driConfig,
- renderType,
- shared,
- hwContext,
- pcp);
- if (pcp->driContext == NULL) {
- XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
- Xfree(pcp);
- return NULL;
- }
-
- pcp->base.destroyContext = driDestroyContext;
- pcp->base.bindContext = driBindContext;
- pcp->base.unbindContext = driUnbindContext;
-
- return &pcp->base;
+ __GLXDRIcontextPrivate *pcp, *pcp_shared;
+ drm_context_t hwContext;
+ __DRIcontext *shared = NULL;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) mode;
+
+ if (!psc || !psc->driScreen)
+ return NULL;
+
+ if (shareList) {
+ pcp_shared = (__GLXDRIcontextPrivate *) shareList->driContext;
+ shared = pcp_shared->driContext;
+ }
+
+ pcp = Xmalloc(sizeof *pcp);
+ if (pcp == NULL)
+ return NULL;
+
+ pcp->psc = psc;
+ if (!XF86DRICreateContextWithConfig(psc->dpy, psc->scr,
+ mode->visualID,
+ &pcp->hwContextID, &hwContext)) {
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->driContext =
+ (*psc->legacy->createNewContext) (psc->__driScreen,
+ config->driConfig,
+ renderType, shared, hwContext, pcp);
+ if (pcp->driContext == NULL) {
+ XF86DRIDestroyContext(psc->dpy, psc->scr, pcp->hwContextID);
+ Xfree(pcp);
+ return NULL;
+ }
+
+ pcp->base.destroyContext = driDestroyContext;
+ pcp->base.bindContext = driBindContext;
+ pcp->base.unbindContext = driUnbindContext;
+
+ return &pcp->base;
}
-static void driDestroyDrawable(__GLXDRIdrawable *pdraw)
+static void
+driDestroyDrawable(__GLXDRIdrawable * pdraw)
{
- __GLXscreenConfigs *psc = pdraw->psc;
+ __GLXscreenConfigs *psc = pdraw->psc;
- (*psc->core->destroyDrawable)(pdraw->driDrawable);
- XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
- Xfree(pdraw);
+ (*psc->core->destroyDrawable) (pdraw->driDrawable);
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, pdraw->drawable);
+ Xfree(pdraw);
}
-static __GLXDRIdrawable *driCreateDrawable(__GLXscreenConfigs *psc,
- XID xDrawable,
- GLXDrawable drawable,
- const __GLcontextModes *modes)
+static __GLXDRIdrawable *
+driCreateDrawable(__GLXscreenConfigs * psc,
+ XID xDrawable,
+ GLXDrawable drawable, const __GLcontextModes * modes)
{
- __GLXDRIdrawable *pdraw;
- drm_drawable_t hwDrawable;
- void *empty_attribute_list = NULL;
- __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
-
- /* Old dri can't handle GLX 1.3+ drawable constructors. */
- if (xDrawable != drawable)
- return NULL;
-
- pdraw = Xmalloc(sizeof(*pdraw));
- if (!pdraw)
- return NULL;
-
- pdraw->drawable = drawable;
- pdraw->psc = psc;
-
- if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable))
- return NULL;
-
- /* Create a new drawable */
- pdraw->driDrawable =
- (*psc->legacy->createNewDrawable)(psc->__driScreen,
- config->driConfig,
- hwDrawable,
- GLX_WINDOW_BIT,
- empty_attribute_list,
- pdraw);
-
- if (!pdraw->driDrawable) {
- XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
- Xfree(pdraw);
- return NULL;
- }
-
- pdraw->destroyDrawable = driDestroyDrawable;
-
- return pdraw;
+ __GLXDRIdrawable *pdraw;
+ drm_drawable_t hwDrawable;
+ void *empty_attribute_list = NULL;
+ __GLXDRIconfigPrivate *config = (__GLXDRIconfigPrivate *) modes;
+
+ /* Old dri can't handle GLX 1.3+ drawable constructors. */
+ if (xDrawable != drawable)
+ return NULL;
+
+ pdraw = Xmalloc(sizeof(*pdraw));
+ if (!pdraw)
+ return NULL;
+
+ pdraw->drawable = drawable;
+ pdraw->psc = psc;
+
+ if (!XF86DRICreateDrawable(psc->dpy, psc->scr, drawable, &hwDrawable))
+ return NULL;
+
+ /* Create a new drawable */
+ pdraw->driDrawable =
+ (*psc->legacy->createNewDrawable) (psc->__driScreen,
+ config->driConfig,
+ hwDrawable,
+ GLX_WINDOW_BIT,
+ empty_attribute_list, pdraw);
+
+ if (!pdraw->driDrawable) {
+ XF86DRIDestroyDrawable(psc->dpy, psc->scr, drawable);
+ Xfree(pdraw);
+ return NULL;
+ }
+
+ pdraw->destroyDrawable = driDestroyDrawable;
+
+ return pdraw;
}
-static void driSwapBuffers(__GLXDRIdrawable *pdraw)
+static void
+driSwapBuffers(__GLXDRIdrawable * pdraw)
{
- (*pdraw->psc->core->swapBuffers)(pdraw->driDrawable);
+ (*pdraw->psc->core->swapBuffers) (pdraw->driDrawable);
}
-static void driCopySubBuffer(__GLXDRIdrawable *pdraw,
- int x, int y, int width, int height)
+static void
+driCopySubBuffer(__GLXDRIdrawable * pdraw,
+ int x, int y, int width, int height)
{
- (*pdraw->psc->driCopySubBuffer->copySubBuffer)(pdraw->driDrawable,
- x, y, width, height);
+ (*pdraw->psc->driCopySubBuffer->copySubBuffer) (pdraw->driDrawable,
+ x, y, width, height);
}
-static void driDestroyScreen(__GLXscreenConfigs *psc)
+static void
+driDestroyScreen(__GLXscreenConfigs * psc)
{
- /* Free the direct rendering per screen data */
- if (psc->__driScreen)
- (*psc->core->destroyScreen)(psc->__driScreen);
- psc->__driScreen = NULL;
- if (psc->driver)
- dlclose(psc->driver);
+ /* Free the direct rendering per screen data */
+ if (psc->__driScreen)
+ (*psc->core->destroyScreen) (psc->__driScreen);
+ psc->__driScreen = NULL;
+ if (psc->driver)
+ dlclose(psc->driver);
}
-static __GLXDRIscreen *driCreateScreen(__GLXscreenConfigs *psc, int screen,
- __GLXdisplayPrivate *priv)
+static __GLXDRIscreen *
+driCreateScreen(__GLXscreenConfigs * psc, int screen,
+ __GLXdisplayPrivate * priv)
{
- __GLXDRIdisplayPrivate *pdp;
- __GLXDRIscreen *psp;
- const __DRIextension **extensions;
- char *driverName;
- int i;
-
- psp = Xcalloc(1, sizeof *psp);
- if (psp == NULL)
- return NULL;
-
- /* Initialize per screen dynamic client GLX extensions */
- psc->ext_list_first_time = GL_TRUE;
-
- if (!driGetDriverName(priv->dpy, screen, &driverName)) {
- Xfree(psp);
- return NULL;
- }
-
- psc->driver = driOpenDriver(driverName);
- Xfree(driverName);
- if (psc->driver == NULL) {
- Xfree(psp);
- return NULL;
- }
-
- extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
- if (extensions == NULL) {
- ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
- Xfree(psp);
- return NULL;
- }
-
- for (i = 0; extensions[i]; i++) {
- if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
- psc->core = (__DRIcoreExtension *) extensions[i];
- if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
- psc->legacy = (__DRIlegacyExtension *) extensions[i];
- }
-
- if (psc->core == NULL || psc->legacy == NULL) {
- Xfree(psp);
- return NULL;
- }
-
- pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
- psc->__driScreen =
- CallCreateNewScreen(psc->dpy, screen, psc, pdp);
- if (psc->__driScreen == NULL) {
- dlclose(psc->driver);
- Xfree(psp);
- return NULL;
- }
-
- driBindExtensions(psc, 0);
- if (psc->driCopySubBuffer)
- psp->copySubBuffer = driCopySubBuffer;
-
- psp->destroyScreen = driDestroyScreen;
- psp->createContext = driCreateContext;
- psp->createDrawable = driCreateDrawable;
- psp->swapBuffers = driSwapBuffers;
- psp->waitX = NULL;
- psp->waitGL = NULL;
-
- return psp;
+ __GLXDRIdisplayPrivate *pdp;
+ __GLXDRIscreen *psp;
+ const __DRIextension **extensions;
+ char *driverName;
+ int i;
+
+ psp = Xcalloc(1, sizeof *psp);
+ if (psp == NULL)
+ return NULL;
+
+ /* Initialize per screen dynamic client GLX extensions */
+ psc->ext_list_first_time = GL_TRUE;
+
+ if (!driGetDriverName(priv->dpy, screen, &driverName)) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ psc->driver = driOpenDriver(driverName);
+ Xfree(driverName);
+ if (psc->driver == NULL) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ extensions = dlsym(psc->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ ErrorMessageF("driver exports no extensions (%s)\n", dlerror());
+ Xfree(psp);
+ return NULL;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0)
+ psc->core = (__DRIcoreExtension *) extensions[i];
+ if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0)
+ psc->legacy = (__DRIlegacyExtension *) extensions[i];
+ }
+
+ if (psc->core == NULL || psc->legacy == NULL) {
+ Xfree(psp);
+ return NULL;
+ }
+
+ pdp = (__GLXDRIdisplayPrivate *) priv->driDisplay;
+ psc->__driScreen = CallCreateNewScreen(psc->dpy, screen, psc, pdp);
+ if (psc->__driScreen == NULL) {
+ dlclose(psc->driver);
+ Xfree(psp);
+ return NULL;
+ }
+
+ driBindExtensions(psc, 0);
+ if (psc->driCopySubBuffer)
+ psp->copySubBuffer = driCopySubBuffer;
+
+ psp->destroyScreen = driDestroyScreen;
+ psp->createContext = driCreateContext;
+ psp->createDrawable = driCreateDrawable;
+ psp->swapBuffers = driSwapBuffers;
+ psp->waitX = NULL;
+ psp->waitGL = NULL;
+
+ return psp;
}
/* Called from __glXFreeDisplayPrivate.
*/
-static void driDestroyDisplay(__GLXDRIdisplay *dpy)
+static void
+driDestroyDisplay(__GLXDRIdisplay * dpy)
{
- Xfree(dpy);
+ Xfree(dpy);
}
/*
@@ -710,33 +726,34 @@ static void driDestroyDisplay(__GLXDRIdisplay *dpy)
* This is called from __glXInitialize() when we are given a new
* display pointer.
*/
-_X_HIDDEN __GLXDRIdisplay *driCreateDisplay(Display *dpy)
+_X_HIDDEN __GLXDRIdisplay *
+driCreateDisplay(Display * dpy)
{
- __GLXDRIdisplayPrivate *pdpyp;
- int eventBase, errorBase;
- int major, minor, patch;
+ __GLXDRIdisplayPrivate *pdpyp;
+ int eventBase, errorBase;
+ int major, minor, patch;
- if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
- return NULL;
- }
+ if (!XF86DRIQueryExtension(dpy, &eventBase, &errorBase)) {
+ return NULL;
+ }
- if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
- return NULL;
- }
+ if (!XF86DRIQueryVersion(dpy, &major, &minor, &patch)) {
+ return NULL;
+ }
- pdpyp = Xmalloc(sizeof *pdpyp);
- if (!pdpyp) {
- return NULL;
- }
+ pdpyp = Xmalloc(sizeof *pdpyp);
+ if (!pdpyp) {
+ return NULL;
+ }
- pdpyp->driMajor = major;
- pdpyp->driMinor = minor;
- pdpyp->driPatch = patch;
+ pdpyp->driMajor = major;
+ pdpyp->driMinor = minor;
+ pdpyp->driPatch = patch;
- pdpyp->base.destroyDisplay = driDestroyDisplay;
- pdpyp->base.createScreen = driCreateScreen;
+ pdpyp->base.destroyDisplay = driDestroyDisplay;
+ pdpyp->base.createScreen = driCreateScreen;
- return &pdpyp->base;
+ return &pdpyp->base;
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/drisw_glx.c b/src/glx/x11/drisw_glx.c
index 1c229dde90..15e1586658 100644
--- a/src/glx/x11/drisw_glx.c
+++ b/src/glx/x11/drisw_glx.c
@@ -401,7 +401,7 @@ driCreateScreen(__GLXscreenConfigs * psc, int screen,
psc->configs = driConvertConfigs(psc->core, psc->configs, driver_configs);
psc->visuals = driConvertConfigs(psc->core, psc->visuals, driver_configs);
- free(driver_configs);
+ psc->driver_configs = driver_configs;
psp->destroyScreen = driDestroyScreen;
psp->createContext = driCreateContext;
diff --git a/src/glx/x11/glx_pbuffer.c b/src/glx/x11/glx_pbuffer.c
index a06331fd7f..501500afc3 100644
--- a/src/glx/x11/glx_pbuffer.c
+++ b/src/glx/x11/glx_pbuffer.c
@@ -25,7 +25,7 @@
/**
* \file glx_pbuffer.c
* Implementation of pbuffer related functions.
- *
+ *
* \author Ian Romanick <idr@us.ibm.com>
*/
@@ -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.
@@ -114,7 +138,7 @@ ChangeDrawableAttribute(Display * dpy, GLXDrawable drawable,
* \note
* This function dynamically determines whether to use the SGIX_pbuffer
* version of the protocol or the GLX 1.3 version of the protocol.
- *
+ *
* \todo
* This function needs to be modified to work with direct-rendering drivers.
*/
@@ -198,7 +222,7 @@ determineTextureFormat(const int *attribs, int numAttribs)
for (i = 0; i < numAttribs; i++) {
if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
- return attribs[2 * i + 1];
+ return attribs[2 * i + 1];
}
return 0;
@@ -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);
}
@@ -681,11 +716,11 @@ GLX_ALIAS_VOID(glXDestroyGLXPbufferSGIX,
PUBLIC
GLX_ALIAS_VOID(glXSelectEventSGIX,
(Display * dpy, GLXDrawable drawable,
- unsigned long mask), (dpy, drawable, mask),
- glXSelectEvent)
+ unsigned long mask), (dpy, drawable, mask), glXSelectEvent)
PUBLIC
GLX_ALIAS_VOID(glXGetSelectedEventSGIX,
(Display * dpy, GLXDrawable drawable,
unsigned long *mask), (dpy, drawable, mask),
glXGetSelectedEvent)
+
diff --git a/src/glx/x11/glx_query.c b/src/glx/x11/glx_query.c
index 2789b841b1..efad13d376 100644
--- a/src/glx/x11/glx_query.c
+++ b/src/glx/x11/glx_query.c
@@ -25,7 +25,7 @@
/**
* \file glx_query.c
* Generic utility functions to query internal data from the server.
- *
+ *
* \author Ian Romanick <idr@us.ibm.com>
*/
@@ -43,13 +43,10 @@
* Exchange a protocol request for glXQueryServerString.
*/
char *
-__glXQueryServerString(Display* dpy,
- int opcode,
- CARD32 screen,
- CARD32 name)
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
{
xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_glx_query_server_string_reply_t* reply =
+ xcb_glx_query_server_string_reply_t *reply =
xcb_glx_query_server_string_reply(c,
xcb_glx_query_server_string(c,
screen,
@@ -59,7 +56,7 @@ __glXQueryServerString(Display* dpy,
/* The spec doesn't mention this, but the Xorg server replies with
* a string already terminated with '\0'. */
uint32_t len = xcb_glx_query_server_string_string_length(reply);
- char* buf = Xmalloc(len);
+ char *buf = Xmalloc(len);
memcpy(buf, xcb_glx_query_server_string_string(reply), len);
free(reply);
@@ -70,23 +67,20 @@ __glXQueryServerString(Display* dpy,
* Exchange a protocol request for glGetString.
*/
char *
-__glXGetString(Display* dpy,
- int opcode,
- CARD32 contextTag,
- CARD32 name)
+__glXGetString(Display * dpy, int opcode, CARD32 contextTag, CARD32 name)
{
xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_glx_get_string_reply_t* reply =
- xcb_glx_get_string_reply(c,
- xcb_glx_get_string(c,
- contextTag,
- name),
- NULL);
+ xcb_glx_get_string_reply_t *reply = xcb_glx_get_string_reply(c,
+ xcb_glx_get_string
+ (c,
+ contextTag,
+ name),
+ NULL);
/* The spec doesn't mention this, but the Xorg server replies with
* a string already terminated with '\0'. */
uint32_t len = xcb_glx_get_string_string_length(reply);
- char* buf = Xmalloc(len);
+ char *buf = Xmalloc(len);
memcpy(buf, xcb_glx_get_string_string(reply), len);
free(reply);
@@ -97,7 +91,7 @@ __glXGetString(Display* dpy,
/**
* GLX protocol structure for the ficticious "GXLGenericGetString" request.
- *
+ *
* This is a non-existant protocol packet. It just so happens that all of
* the real protocol packets used to request a string from the server have
* an identical binary layout. The only difference between them is the
@@ -167,25 +161,17 @@ __glXGetStringFromServer(Display * dpy, int opcode, CARD32 glxCode,
}
char *
-__glXQueryServerString(Display* dpy,
- int opcode,
- CARD32 screen,
- CARD32 name)
+__glXQueryServerString(Display * dpy, int opcode, CARD32 screen, CARD32 name)
{
return __glXGetStringFromServer(dpy, opcode,
- X_GLXQueryServerString,
- screen, name);
+ X_GLXQueryServerString, screen, name);
}
char *
-__glXGetString(Display* dpy,
- int opcode,
- CARD32 contextTag,
- CARD32 name)
+__glXGetString(Display * dpy, int opcode, CARD32 contextTag, CARD32 name)
{
return __glXGetStringFromServer(dpy, opcode, X_GLsop_GetString,
contextTag, name);
}
#endif /* USE_XCB */
-
diff --git a/src/glx/x11/glxclient.h b/src/glx/x11/glxclient.h
index bf68d0f891..00ee14fb05 100644
--- a/src/glx/x11/glxclient.h
+++ b/src/glx/x11/glxclient.h
@@ -55,9 +55,7 @@
#include "GL/internal/glcore.h"
#include "glapi/glapitable.h"
#include "glxhash.h"
-#if defined( USE_XTHREADS )
-# include <X11/Xthreads.h>
-#elif defined( PTHREADS )
+#if defined( PTHREADS )
# include <pthread.h>
#endif
@@ -67,7 +65,7 @@
/* If we build the library with gcc's -fvisibility=hidden flag, we'll
* use the PUBLIC macro to mark functions that are to be exported.
*
- * We also need to define a USED attribute, so the optimizer doesn't
+ * We also need to define a USED attribute, so the optimizer doesn't
* inline a static function that we later use in an alias. - ajax
*/
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 303
@@ -80,8 +78,8 @@
-#define GLX_MAJOR_VERSION 1 /* current version numbers */
-#define GLX_MINOR_VERSION 4
+#define GLX_MAJOR_VERSION 1 /* current version numbers */
+#define GLX_MINOR_VERSION 4
#define __GLX_MAX_TEXTURE_UNITS 32
@@ -95,7 +93,7 @@ typedef struct _glapi_table __GLapi;
#ifdef GLX_DIRECT_RENDERING
-#define containerOf(ptr, type, member) \
+#define containerOf(ptr, type, member) \
(type *)( (char *)ptr - offsetof(type,member) )
#include <GL/internal/dri_interface.h>
@@ -112,75 +110,78 @@ typedef struct __GLXDRIcontextRec __GLXDRIcontext;
#include "glxextensions.h"
-struct __GLXDRIdisplayRec {
+struct __GLXDRIdisplayRec
+{
/**
* Method to destroy the private DRI display data.
*/
- void (*destroyDisplay)(__GLXDRIdisplay *display);
+ void (*destroyDisplay) (__GLXDRIdisplay * display);
- __GLXDRIscreen *(*createScreen)(__GLXscreenConfigs *psc, int screen,
- __GLXdisplayPrivate *priv);
+ __GLXDRIscreen *(*createScreen) (__GLXscreenConfigs * psc, int screen,
+ __GLXdisplayPrivate * priv);
};
-struct __GLXDRIscreenRec {
-
- void (*destroyScreen)(__GLXscreenConfigs *psc);
-
- __GLXDRIcontext *(*createContext)(__GLXscreenConfigs *psc,
- const __GLcontextModes *mode,
- GLXContext gc,
- GLXContext shareList, int renderType);
-
- __GLXDRIdrawable *(*createDrawable)(__GLXscreenConfigs *psc,
- XID drawable,
- GLXDrawable glxDrawable,
- const __GLcontextModes *modes);
-
- void (*swapBuffers)(__GLXDRIdrawable *pdraw);
- void (*copySubBuffer)(__GLXDRIdrawable *pdraw,
- int x, int y, int width, int height);
- void (*waitX)(__GLXDRIdrawable *pdraw);
- void (*waitGL)(__GLXDRIdrawable *pdraw);
+struct __GLXDRIscreenRec
+{
+
+ void (*destroyScreen) (__GLXscreenConfigs * psc);
+
+ __GLXDRIcontext *(*createContext) (__GLXscreenConfigs * psc,
+ const __GLcontextModes * mode,
+ GLXContext gc,
+ GLXContext shareList, int renderType);
+
+ __GLXDRIdrawable *(*createDrawable) (__GLXscreenConfigs * psc,
+ XID drawable,
+ GLXDrawable glxDrawable,
+ const __GLcontextModes * modes);
+
+ void (*swapBuffers) (__GLXDRIdrawable * pdraw);
+ void (*copySubBuffer) (__GLXDRIdrawable * pdraw,
+ int x, int y, int width, int height);
+ void (*waitX) (__GLXDRIdrawable * pdraw);
+ void (*waitGL) (__GLXDRIdrawable * pdraw);
};
-struct __GLXDRIcontextRec {
- void (*destroyContext)(__GLXDRIcontext *context, __GLXscreenConfigs *psc,
- Display *dpy);
- Bool (*bindContext)(__GLXDRIcontext *context,
- __GLXDRIdrawable *pdraw,
- __GLXDRIdrawable *pread);
-
- void (*unbindContext)(__GLXDRIcontext *context);
+struct __GLXDRIcontextRec
+{
+ void (*destroyContext) (__GLXDRIcontext * context,
+ __GLXscreenConfigs * psc, Display * dpy);
+ Bool(*bindContext) (__GLXDRIcontext * context, __GLXDRIdrawable * pdraw,
+ __GLXDRIdrawable * pread);
+
+ void (*unbindContext) (__GLXDRIcontext * context);
};
-struct __GLXDRIdrawableRec {
- void (*destroyDrawable)(__GLXDRIdrawable *drawable);
+struct __GLXDRIdrawableRec
+{
+ void (*destroyDrawable) (__GLXDRIdrawable * drawable);
- XID xDrawable;
- XID drawable;
- __GLXscreenConfigs *psc;
- GLenum textureTarget;
- __DRIdrawable *driDrawable;
- GLenum textureFormat; /* EXT_texture_from_pixmap support */
+ XID xDrawable;
+ XID drawable;
+ __GLXscreenConfigs *psc;
+ GLenum textureTarget;
+ __DRIdrawable *driDrawable;
+ GLenum textureFormat; /* EXT_texture_from_pixmap support */
};
/*
** Function to create and DRI display data and initialize the display
** dependent methods.
*/
-extern __GLXDRIdisplay *driswCreateDisplay(Display *dpy);
-extern __GLXDRIdisplay *driCreateDisplay(Display *dpy);
-extern __GLXDRIdisplay *dri2CreateDisplay(Display *dpy);
+extern __GLXDRIdisplay *driswCreateDisplay(Display * dpy);
+extern __GLXDRIdisplay *driCreateDisplay(Display * dpy);
+extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy);
-extern void DRI_glXUseXFont( Font font, int first, int count, int listbase );
+extern void DRI_glXUseXFont(Font font, int first, int count, int listbase);
/*
** Functions to obtain driver configuration information from a direct
** rendering client application
*/
-extern const char *glXGetScreenDriver (Display *dpy, int scrNum);
+extern const char *glXGetScreenDriver(Display * dpy, int scrNum);
-extern const char *glXGetDriverConfig (const char *driverName);
+extern const char *glXGetDriverConfig(const char *driverName);
#endif
@@ -188,53 +189,57 @@ extern const char *glXGetDriverConfig (const char *driverName);
#define __GL_CLIENT_ATTRIB_STACK_DEPTH 16
-typedef struct __GLXpixelStoreModeRec {
- GLboolean swapEndian;
- GLboolean lsbFirst;
- GLuint rowLength;
- GLuint imageHeight;
- GLuint imageDepth;
- GLuint skipRows;
- GLuint skipPixels;
- GLuint skipImages;
- GLuint alignment;
+typedef struct __GLXpixelStoreModeRec
+{
+ GLboolean swapEndian;
+ GLboolean lsbFirst;
+ GLuint rowLength;
+ GLuint imageHeight;
+ GLuint imageDepth;
+ GLuint skipRows;
+ GLuint skipPixels;
+ GLuint skipImages;
+ GLuint alignment;
} __GLXpixelStoreMode;
-typedef struct __GLXattributeRec {
- GLuint mask;
+typedef struct __GLXattributeRec
+{
+ GLuint mask;
/**
* Pixel storage state. Most of the pixel store mode state is kept
* here and used by the client code to manage the packing and
* unpacking of data sent to/received from the server.
*/
- __GLXpixelStoreMode storePack, storeUnpack;
+ __GLXpixelStoreMode storePack, storeUnpack;
/**
* Is EXT_vertex_array / GL 1.1 DrawArrays protocol specifically
* disabled?
*/
- GLboolean NoDrawArraysProtocol;
-
+ GLboolean NoDrawArraysProtocol;
+
/**
* Vertex Array storage state. The vertex array component
* state is stored here and is used to manage the packing of
* DrawArrays data sent to the server.
*/
- struct array_state_vector * array_state;
+ struct array_state_vector *array_state;
} __GLXattribute;
-typedef struct __GLXattributeMachineRec {
- __GLXattribute *stack[__GL_CLIENT_ATTRIB_STACK_DEPTH];
- __GLXattribute **stackPointer;
+typedef struct __GLXattributeMachineRec
+{
+ __GLXattribute *stack[__GL_CLIENT_ATTRIB_STACK_DEPTH];
+ __GLXattribute **stackPointer;
} __GLXattributeMachine;
/**
* GLX state that needs to be kept on the client. One of these records
* exist for each context that has been made current by this client.
*/
-struct __GLXcontextRec {
+struct __GLXcontextRec
+{
/**
* \name Drawing command buffer.
*
@@ -251,13 +256,13 @@ struct __GLXcontextRec {
* These must be the first 6 fields since they are static initialized
* in the dummy context in glxext.c
*/
- /*@{*/
- GLubyte *buf;
- GLubyte *pc;
- GLubyte *limit;
- GLubyte *bufEnd;
- GLint bufSize;
- /*@}*/
+ /*@{ */
+ GLubyte *buf;
+ GLubyte *pc;
+ GLubyte *limit;
+ GLubyte *bufEnd;
+ GLint bufSize;
+ /*@} */
/**
* The XID of this rendering context. When the context is created a
@@ -265,24 +270,24 @@ struct __GLXcontextRec {
* destroyed but is still current to some thread. In this case the
* context will be freed on next MakeCurrent.
*/
- XID xid;
+ XID xid;
/**
* The XID of the \c shareList context.
*/
- XID share_xid;
+ XID share_xid;
/**
* Screen number.
*/
- GLint screen;
- __GLXscreenConfigs *psc;
+ GLint screen;
+ __GLXscreenConfigs *psc;
/**
* \c GL_TRUE if the context was created with ImportContext, which
* means the server-side context was created by another X client.
*/
- GLboolean imported;
+ GLboolean imported;
/**
* The context tag returned by MakeCurrent when this context is made
@@ -292,7 +297,7 @@ struct __GLXcontextRec {
* \c WaitX, \c WaitGL, \c UseXFont, and \c MakeCurrent (for the old
* context)).
*/
- GLXContextTag currentContextTag;
+ GLXContextTag currentContextTag;
/**
* \name Rendering mode
@@ -301,11 +306,11 @@ struct __GLXcontextRec {
* When \c glRenderMode is called, the buffer associated with the
* previous rendering mode (feedback or select) is filled.
*/
- /*@{*/
- GLenum renderMode;
- GLfloat *feedbackBuf;
- GLuint *selectBuf;
- /*@}*/
+ /*@{ */
+ GLenum renderMode;
+ GLfloat *feedbackBuf;
+ GLuint *selectBuf;
+ /*@} */
/**
* This is \c GL_TRUE if the pixel unpack modes are such that an image
@@ -313,43 +318,43 @@ struct __GLXcontextRec {
* still be true that the server will have to do some work. This
* just promises that a straight copy will fetch the correct bytes.
*/
- GLboolean fastImageUnpack;
+ GLboolean fastImageUnpack;
/**
* Fill newImage with the unpacked form of \c oldImage getting it
* ready for transport to the server.
*/
- void (*fillImage)(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
- GLenum, const GLvoid*, GLubyte*, GLubyte*);
+ void (*fillImage) (__GLXcontext *, GLint, GLint, GLint, GLint, GLenum,
+ GLenum, const GLvoid *, GLubyte *, GLubyte *);
/**
* Client side attribs.
*/
- __GLXattributeMachine attributes;
+ __GLXattributeMachine attributes;
/**
* Client side error code. This is set when client side gl API
* routines need to set an error because of a bad enumerant or
* running out of memory, etc.
*/
- GLenum error;
+ GLenum error;
/**
* Whether this context does direct rendering.
*/
- Bool isDirect;
+ Bool isDirect;
/**
* \c dpy of current display for this context. Will be \c NULL if not
* current to any display, or if this is the "dummy context".
*/
- Display *currentDpy;
+ Display *currentDpy;
/**
* The current drawable for this context. Will be None if this
* context is not current to any drawable. currentReadable is below.
*/
- GLXDrawable currentDrawable;
+ GLXDrawable currentDrawable;
/**
* \name GL Constant Strings
@@ -358,38 +363,38 @@ struct __GLXcontextRec {
* These pertain to GL attributes, not to be confused with
* GLX versioning attributes.
*/
- /*@{*/
- GLubyte *vendor;
- GLubyte *renderer;
- GLubyte *version;
- GLubyte *extensions;
- /*@}*/
+ /*@{ */
+ GLubyte *vendor;
+ GLubyte *renderer;
+ GLubyte *version;
+ GLubyte *extensions;
+ /*@} */
/**
* Record the dpy this context was created on for later freeing
*/
- Display *createDpy;
+ Display *createDpy;
/**
* Maximum small render command size. This is the smaller of 64k and
* the size of the above buffer.
*/
- GLint maxSmallRenderCommandSize;
+ GLint maxSmallRenderCommandSize;
/**
* Major opcode for the extension. Copied here so a lookup isn't
* needed.
*/
- GLint majorOpcode;
+ GLint majorOpcode;
/**
* Pointer to the mode used to create this context.
*/
- const __GLcontextModes * mode;
+ const __GLcontextModes *mode;
#ifdef GLX_DIRECT_RENDERING
- __GLXDRIcontext *driContext;
- __DRIcontext *__driContext;
+ __GLXDRIcontext *driContext;
+ __DRIcontext *__driContext;
#endif
/**
@@ -398,22 +403,22 @@ struct __GLXcontextRec {
*
* \since Internal API version 20030606.
*/
- GLXDrawable currentReadable;
+ GLXDrawable currentReadable;
- /**
+ /**
* Pointer to client-state data that is private to libGL. This is only
* used for indirect rendering contexts.
*
* No internal API version change was made for this change. Client-side
* drivers should NEVER use this data or even care that it exists.
*/
- void * client_state_private;
+ void *client_state_private;
/**
* Stored value for \c glXQueryContext attribute \c GLX_RENDER_TYPE.
*/
int renderType;
-
+
/**
* \name Raw server GL version
*
@@ -421,23 +426,23 @@ struct __GLXcontextRec {
* returned by the server, and it may not reflect what is actually
* supported (or reported) by the client-side library.
*/
- /*@{*/
+ /*@{ */
int server_major; /**< Major version number. */
int server_minor; /**< Minor version number. */
- /*@}*/
+ /*@} */
/**
* Thread ID we're currently current in. Zero if none.
*/
unsigned long thread_id;
- char gl_extension_bits[ __GL_EXT_BYTES ];
+ char gl_extension_bits[__GL_EXT_BYTES];
};
-#define __glXSetError(gc,code) \
- if (!(gc)->error) { \
- (gc)->error = code; \
- }
+#define __glXSetError(gc,code) \
+ if (!(gc)->error) { \
+ (gc)->error = code; \
+ }
extern void __glFreeAttributeState(__GLXcontext *);
@@ -448,7 +453,7 @@ extern void __glFreeAttributeState(__GLXcontext *);
* that will use the GLXRender GLX command. In this case it is
* \c glPolygonStipple.
*/
-#define __GLX_MAX_SMALL_RENDER_CMD_SIZE 156
+#define __GLX_MAX_SMALL_RENDER_CMD_SIZE 156
/**
* To keep the implementation fast, the code uses a "limit" pointer
@@ -460,73 +465,76 @@ extern void __glFreeAttributeState(__GLXcontext *);
* efficacy of the buffer. The "+32" is just to keep the code working
* in case somebody counts wrong.
*/
-#define __GLX_BUFFER_LIMIT_SIZE (__GLX_MAX_SMALL_RENDER_CMD_SIZE + 32)
+#define __GLX_BUFFER_LIMIT_SIZE (__GLX_MAX_SMALL_RENDER_CMD_SIZE + 32)
/**
* This implementation uses a smaller threshold for switching
* to the RenderLarge protocol than the protcol requires so that
* large copies don't occur.
*/
-#define __GLX_RENDER_CMD_SIZE_LIMIT 4096
+#define __GLX_RENDER_CMD_SIZE_LIMIT 4096
/**
* One of these records exists per screen of the display. It contains
* a pointer to the config data for that screen (if the screen supports GL).
*/
-struct __GLXscreenConfigsRec {
+struct __GLXscreenConfigsRec
+{
/**
* GLX extension string reported by the X-server.
*/
- const char *serverGLXexts;
+ const char *serverGLXexts;
/**
* GLX extension string to be reported to applications. This is the
* set of extensions that the application can actually use.
*/
- char *effectiveGLXexts;
+ char *effectiveGLXexts;
#ifdef GLX_DIRECT_RENDERING
/**
* Per screen direct rendering interface functions and data.
*/
- __DRIscreen *__driScreen;
- const __DRIcoreExtension *core;
- const __DRIlegacyExtension *legacy;
- const __DRIswrastExtension *swrast;
- const __DRIdri2Extension *dri2;
- __glxHashTable *drawHash;
- Display *dpy;
- int scr, fd;
- void *driver;
+ __DRIscreen *__driScreen;
+ const __DRIcoreExtension *core;
+ const __DRIlegacyExtension *legacy;
+ const __DRIswrastExtension *swrast;
+ const __DRIdri2Extension *dri2;
+ __glxHashTable *drawHash;
+ Display *dpy;
+ int scr, fd;
+ void *driver;
- __GLXDRIscreen *driScreen;
+ __GLXDRIscreen *driScreen;
+
+ const __DRIconfig **driver_configs;
#ifdef __DRI_COPY_SUB_BUFFER
- const __DRIcopySubBufferExtension *driCopySubBuffer;
+ const __DRIcopySubBufferExtension *driCopySubBuffer;
#endif
#ifdef __DRI_SWAP_CONTROL
- const __DRIswapControlExtension *swapControl;
+ const __DRIswapControlExtension *swapControl;
#endif
#ifdef __DRI_ALLOCATE
- const __DRIallocateExtension *allocate;
+ const __DRIallocateExtension *allocate;
#endif
#ifdef __DRI_FRAME_TRACKING
- const __DRIframeTrackingExtension *frameTracking;
+ const __DRIframeTrackingExtension *frameTracking;
#endif
#ifdef __DRI_MEDIA_STREAM_COUNTER
- const __DRImediaStreamCounterExtension *msc;
+ const __DRImediaStreamCounterExtension *msc;
#endif
#ifdef __DRI_TEX_BUFFER
- const __DRItexBufferExtension *texBuffer;
+ const __DRItexBufferExtension *texBuffer;
#endif
#ifdef __DRI2_FLUSH
- const __DRI2flushExtension *f;
+ const __DRI2flushExtension *f;
#endif
#endif
@@ -534,7 +542,7 @@ struct __GLXscreenConfigsRec {
/**
* Linked list of glx visuals and fbconfigs for this screen.
*/
- __GLcontextModes *visuals, *configs;
+ __GLcontextModes *visuals, *configs;
/**
* Per-screen dynamic GLX extension tracking. The \c direct_support
@@ -543,10 +551,10 @@ struct __GLXscreenConfigsRec {
* this field. The \c __GLXscreenConfigs structure is not used outside
* libGL.
*/
- /*@{*/
- unsigned char direct_support[8];
- GLboolean ext_list_first_time;
- /*@}*/
+ /*@{ */
+ unsigned char direct_support[8];
+ GLboolean ext_list_first_time;
+ /*@} */
};
@@ -554,67 +562,68 @@ struct __GLXscreenConfigsRec {
* Per display private data. One of these records exists for each display
* that is using the OpenGL (GLX) extension.
*/
-struct __GLXdisplayPrivateRec {
+struct __GLXdisplayPrivateRec
+{
/**
* Back pointer to the display
*/
- Display *dpy;
+ Display *dpy;
/**
* The \c majorOpcode is common to all connections to the same server.
* It is also copied into the context structure.
*/
- int majorOpcode;
+ int majorOpcode;
/**
* \name Server Version
*
* Major and minor version returned by the server during initialization.
*/
- /*@{*/
- int majorVersion, minorVersion;
- /*@}*/
+ /*@{ */
+ int majorVersion, minorVersion;
+ /*@} */
/**
* \name Storage for the servers GLX vendor and versions strings.
- *
+ *
* These are the same for all screens on this display. These fields will
* be filled in on demand.
*/
- /*@{*/
- const char *serverGLXvendor;
- const char *serverGLXversion;
- /*@}*/
+ /*@{ */
+ const char *serverGLXvendor;
+ const char *serverGLXversion;
+ /*@} */
/**
* Configurations of visuals for all screens on this display.
* Also, per screen data which now includes the server \c GLX_EXTENSION
* string.
*/
- __GLXscreenConfigs *screenConfigs;
+ __GLXscreenConfigs *screenConfigs;
#ifdef GLX_DIRECT_RENDERING
/**
* Per display direct rendering interface functions and data.
*/
- __GLXDRIdisplay *driswDisplay;
- __GLXDRIdisplay *driDisplay;
- __GLXDRIdisplay *dri2Display;
+ __GLXDRIdisplay *driswDisplay;
+ __GLXDRIdisplay *driDisplay;
+ __GLXDRIdisplay *dri2Display;
#endif
};
-extern GLubyte *__glXFlushRenderBuffer(__GLXcontext*, GLubyte*);
+extern GLubyte *__glXFlushRenderBuffer(__GLXcontext *, GLubyte *);
-extern void __glXSendLargeChunk(__GLXcontext *gc, GLint requestNumber,
- GLint totalRequests,
- const GLvoid * data, GLint dataLen);
+extern void __glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber,
+ GLint totalRequests,
+ const GLvoid * data, GLint dataLen);
extern void __glXSendLargeCommand(__GLXcontext *, const GLvoid *, GLint,
- const GLvoid *, GLint);
+ const GLvoid *, GLint);
/* Initialize the GLX extension for dpy */
-extern __GLXdisplayPrivate *__glXInitialize(Display*);
+extern __GLXdisplayPrivate *__glXInitialize(Display *);
extern void __glXPreferEGL(int state);
@@ -623,16 +632,16 @@ extern void __glXPreferEGL(int state);
extern int __glXDebug;
/* This is per-thread storage in an MT environment */
-#if defined( USE_XTHREADS ) || defined( PTHREADS )
+#if defined( PTHREADS )
-extern void __glXSetCurrentContext(__GLXcontext *c);
+extern void __glXSetCurrentContext(__GLXcontext * c);
# if defined( GLX_USE_TLS )
-extern __thread void * __glX_tls_Context
- __attribute__((tls_model("initial-exec")));
+extern __thread void *__glX_tls_Context
+ __attribute__ ((tls_model("initial-exec")));
-# define __glXGetCurrentContext() __glX_tls_Context
+# define __glXGetCurrentContext() __glX_tls_Context
# else
@@ -643,25 +652,21 @@ extern __GLXcontext *__glXGetCurrentContext(void);
#else
extern __GLXcontext *__glXcurrentContext;
-#define __glXGetCurrentContext() __glXcurrentContext
-#define __glXSetCurrentContext(gc) __glXcurrentContext = gc
+#define __glXGetCurrentContext() __glXcurrentContext
+#define __glXSetCurrentContext(gc) __glXcurrentContext = gc
-#endif /* defined( USE_XTHREADS ) || defined( PTHREADS ) */
+#endif /* defined( PTHREADS ) */
extern void __glXSetCurrentContextNull(void);
-extern void __glXFreeContext(__GLXcontext*);
+extern void __glXFreeContext(__GLXcontext *);
/*
** Global lock for all threads in this address space using the GLX
** extension
*/
-#if defined( USE_XTHREADS )
-extern xmutex_rec __glXmutex;
-#define __glXLock() xmutex_lock(&__glXmutex)
-#define __glXUnlock() xmutex_unlock(&__glXmutex)
-#elif defined( PTHREADS )
+#if defined( PTHREADS )
extern pthread_mutex_t __glXmutex;
#define __glXLock() pthread_mutex_lock(&__glXmutex)
#define __glXUnlock() pthread_mutex_unlock(&__glXmutex)
@@ -673,7 +678,7 @@ extern pthread_mutex_t __glXmutex;
/*
** Setup for a command. Initialize the extension for dpy if necessary.
*/
-extern CARD8 __glXSetupForCommand(Display *dpy);
+extern CARD8 __glXSetupForCommand(Display * dpy);
/************************************************************************/
@@ -684,9 +689,11 @@ extern CARD8 __glXSetupForCommand(Display *dpy);
extern const GLuint __glXDefaultPixelStore[9];
/* Send an image to the server using RenderLarge. */
-extern void __glXSendLargeImage(__GLXcontext *gc, GLint compsize, GLint dim,
- GLint width, GLint height, GLint depth, GLenum format, GLenum type,
- const GLvoid *src, GLubyte *pc, GLubyte *modes);
+extern void __glXSendLargeImage(__GLXcontext * gc, GLint compsize, GLint dim,
+ GLint width, GLint height, GLint depth,
+ GLenum format, GLenum type,
+ const GLvoid * src, GLubyte * pc,
+ GLubyte * modes);
/* Return the size, in bytes, of some pixel data */
extern GLint __glImageSize(GLint, GLint, GLint, GLenum, GLenum, GLenum);
@@ -706,23 +713,23 @@ extern GLint __glBytesPerElement(GLenum type);
** updated to contain the modes needed by the server to decode the
** sent data.
*/
-extern void __glFillImage(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
- GLenum, const GLvoid*, GLubyte*, GLubyte*);
+extern void __glFillImage(__GLXcontext *, GLint, GLint, GLint, GLint, GLenum,
+ GLenum, const GLvoid *, GLubyte *, GLubyte *);
/* Copy map data with a stride into a packed buffer */
extern void __glFillMap1f(GLint, GLint, GLint, const GLfloat *, GLubyte *);
extern void __glFillMap1d(GLint, GLint, GLint, const GLdouble *, GLubyte *);
extern void __glFillMap2f(GLint, GLint, GLint, GLint, GLint,
- const GLfloat *, GLfloat *);
+ const GLfloat *, GLfloat *);
extern void __glFillMap2d(GLint, GLint, GLint, GLint, GLint,
- const GLdouble *, GLdouble *);
+ const GLdouble *, GLdouble *);
/*
** Empty an image out of the reply buffer into the clients memory applying
** the pack modes to pack back into the clients requested format.
*/
-extern void __glEmptyImage(__GLXcontext*, GLint, GLint, GLint, GLint, GLenum,
- GLenum, const GLubyte *, GLvoid *);
+extern void __glEmptyImage(__GLXcontext *, GLint, GLint, GLint, GLint, GLenum,
+ GLenum, const GLubyte *, GLvoid *);
/*
@@ -735,7 +742,7 @@ extern void __glXFreeVertexArrayState(__GLXcontext *);
** Inform the Server of the major and minor numbers and of the client
** libraries extension string.
*/
-extern void __glXClientInfo ( Display *dpy, int opcode );
+extern void __glXClientInfo(Display * dpy, int opcode);
/************************************************************************/
@@ -743,20 +750,22 @@ extern void __glXClientInfo ( Display *dpy, int opcode );
** Declarations that should be in Xlib
*/
#ifdef __GL_USE_OUR_PROTOTYPES
-extern void _XFlush(Display*);
-extern Status _XReply(Display*, xReply*, int, Bool);
-extern void _XRead(Display*, void*, long);
-extern void _XSend(Display*, const void*, long);
+extern void _XFlush(Display *);
+extern Status _XReply(Display *, xReply *, int, Bool);
+extern void _XRead(Display *, void *, long);
+extern void _XSend(Display *, const void *, long);
#endif
-extern void __glXInitializeVisualConfigFromTags( __GLcontextModes *config,
- int count, const INT32 *bp, Bool tagged_only, Bool fbconfig_style_tags );
+extern void __glXInitializeVisualConfigFromTags(__GLcontextModes * config,
+ int count, const INT32 * bp,
+ Bool tagged_only,
+ Bool fbconfig_style_tags);
-extern char * __glXQueryServerString(Display* dpy, int opcode,
- CARD32 screen, CARD32 name);
-extern char * __glXGetString(Display* dpy, int opcode,
- CARD32 screen, CARD32 name);
+extern char *__glXQueryServerString(Display * dpy, int opcode,
+ CARD32 screen, CARD32 name);
+extern char *__glXGetString(Display * dpy, int opcode,
+ CARD32 screen, CARD32 name);
extern char *__glXstrdup(const char *str);
@@ -765,15 +774,16 @@ extern const char __glXGLClientVersion[];
extern const char __glXGLClientExtensions[];
/* Get the unadjusted system time */
-extern int __glXGetUST( int64_t * ust );
+extern int __glXGetUST(int64_t * ust);
extern GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
- int32_t * numerator, int32_t * denominator);
+ int32_t * numerator,
+ int32_t * denominator);
#ifdef GLX_DIRECT_RENDERING
GLboolean
-__driGetMscRateOML(__DRIdrawable *draw,
- int32_t *numerator, int32_t *denominator, void *private);
+__driGetMscRateOML(__DRIdrawable * draw,
+ int32_t * numerator, int32_t * denominator, void *private);
#endif
#endif /* !__GLX_client_h__ */
diff --git a/src/glx/x11/glxcmds.c b/src/glx/x11/glxcmds.c
index 820d8b9868..ea55cc49ef 100644
--- a/src/glx/x11/glxcmds.c
+++ b/src/glx/x11/glxcmds.c
@@ -59,56 +59,59 @@ static const char __glXGLXClientVersion[] = "1.4";
#ifdef GLX_DIRECT_RENDERING
static Bool windowExistsFlag;
-static int windowExistsErrorHandler(Display *dpy, XErrorEvent *xerr)
+static int
+windowExistsErrorHandler(Display * dpy, XErrorEvent * xerr)
{
- if (xerr->error_code == BadWindow) {
- windowExistsFlag = GL_FALSE;
- }
- return 0;
+ if (xerr->error_code == BadWindow) {
+ windowExistsFlag = GL_FALSE;
+ }
+ return 0;
}
/**
* Find drawables in the local hash that have been destroyed on the
* server.
- *
+ *
* \param dpy Display to destroy drawables for
* \param screen Screen number to destroy drawables for
*/
-static void GarbageCollectDRIDrawables(Display *dpy, __GLXscreenConfigs *sc)
-{
- XID draw;
- __GLXDRIdrawable *pdraw;
- XWindowAttributes xwa;
- int (*oldXErrorHandler)(Display *, XErrorEvent *);
-
- /* Set no-op error handler so Xlib doesn't bail out if the windows
- * has alreay been destroyed on the server. */
- XSync(dpy, GL_FALSE);
- oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
-
- if (__glxHashFirst(sc->drawHash, &draw, (void *)&pdraw) == 1) {
- do {
- windowExistsFlag = GL_TRUE;
- XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
- if (!windowExistsFlag) {
- /* Destroy the local drawable data, if the drawable no
- longer exists in the Xserver */
- (*pdraw->destroyDrawable)(pdraw);
- __glxHashDelete(sc->drawHash, draw);
- }
- } while (__glxHashNext(sc->drawHash, &draw, (void *)&pdraw) == 1);
- }
-
- XSync(dpy, GL_FALSE);
- XSetErrorHandler(oldXErrorHandler);
-}
-
-extern __GLXDRIdrawable *
-GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
+static void
+GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc)
+{
+ XID draw;
+ __GLXDRIdrawable *pdraw;
+ XWindowAttributes xwa;
+ int (*oldXErrorHandler) (Display *, XErrorEvent *);
+
+ /* Set no-op error handler so Xlib doesn't bail out if the windows
+ * has alreay been destroyed on the server. */
+ XSync(dpy, GL_FALSE);
+ oldXErrorHandler = XSetErrorHandler(windowExistsErrorHandler);
+
+ if (__glxHashFirst(sc->drawHash, &draw, (void *) &pdraw) == 1) {
+ do {
+ windowExistsFlag = GL_TRUE;
+ XGetWindowAttributes(dpy, draw, &xwa); /* dummy request */
+ if (!windowExistsFlag) {
+ /* Destroy the local drawable data, if the drawable no
+ longer exists in the Xserver */
+ (*pdraw->destroyDrawable) (pdraw);
+ __glxHashDelete(sc->drawHash, draw);
+ }
+ } while (__glxHashNext(sc->drawHash, &draw, (void *) &pdraw) == 1);
+ }
+
+ XSync(dpy, GL_FALSE);
+ XSetErrorHandler(oldXErrorHandler);
+}
+
+extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy,
+ GLXDrawable drawable,
+ int *const scrn_num);
/**
* Get the __DRIdrawable for the drawable associated with a GLXContext
- *
+ *
* \param dpy The display associated with \c drawable.
* \param drawable GLXDrawable whose __DRIdrawable part is to be retrieved.
* \param scrn_num If non-NULL, the drawables screen is stored there
@@ -116,30 +119,30 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num);
* the drawable is not associated with a direct-rendering context.
*/
_X_HIDDEN __GLXDRIdrawable *
-GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num)
+GetGLXDRIDrawable(Display * dpy, GLXDrawable drawable, int *const scrn_num)
{
- __GLXdisplayPrivate *priv = __glXInitialize(dpy);
- __GLXDRIdrawable *pdraw;
- const unsigned screen_count = ScreenCount(dpy);
- unsigned i;
- __GLXscreenConfigs *psc;
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw;
+ const unsigned screen_count = ScreenCount(dpy);
+ unsigned i;
+ __GLXscreenConfigs *psc;
- if (priv == NULL)
- return NULL;
-
- for (i = 0; i < screen_count; i++) {
- psc = &priv->screenConfigs[i];
- if (psc->drawHash == NULL)
- continue;
+ if (priv == NULL)
+ return NULL;
- if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {
- if (scrn_num != NULL)
- *scrn_num = i;
- return pdraw;
- }
- }
+ for (i = 0; i < screen_count; i++) {
+ psc = &priv->screenConfigs[i];
+ if (psc->drawHash == NULL)
+ continue;
+
+ if (__glxHashLookup(psc->drawHash, drawable, (void *) &pdraw) == 0) {
+ if (scrn_num != NULL)
+ *scrn_num = i;
+ return pdraw;
+ }
+ }
- return NULL;
+ return NULL;
}
#endif
@@ -147,57 +150,59 @@ GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int * const scrn_num)
/**
* Get the GLX per-screen data structure associated with a GLX context.
- *
+ *
* \param dpy Display for which the GLX per-screen information is to be
* retrieved.
* \param scrn Screen on \c dpy for which the GLX per-screen information is
* to be retrieved.
* \returns A pointer to the GLX per-screen data if \c dpy and \c scrn
* specify a valid GLX screen, or NULL otherwise.
- *
+ *
* \todo Should this function validate that \c scrn is within the screen
* number range for \c dpy?
*/
static __GLXscreenConfigs *
-GetGLXScreenConfigs(Display *dpy, int scrn)
+GetGLXScreenConfigs(Display * dpy, int scrn)
{
- __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
+ __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
- return (priv && priv->screenConfigs != NULL) ? &priv->screenConfigs[scrn] : NULL;
+ return (priv
+ && priv->screenConfigs !=
+ NULL) ? &priv->screenConfigs[scrn] : NULL;
}
static int
-GetGLXPrivScreenConfig( Display *dpy, int scrn, __GLXdisplayPrivate ** ppriv,
- __GLXscreenConfigs ** ppsc )
+GetGLXPrivScreenConfig(Display * dpy, int scrn, __GLXdisplayPrivate ** ppriv,
+ __GLXscreenConfigs ** ppsc)
{
- /* Initialize the extension, if needed . This has the added value
- * of initializing/allocating the display private
- */
-
- if ( dpy == NULL ) {
- return GLX_NO_EXTENSION;
- }
+ /* Initialize the extension, if needed . This has the added value
+ * of initializing/allocating the display private
+ */
- *ppriv = __glXInitialize(dpy);
- if ( *ppriv == NULL ) {
- return GLX_NO_EXTENSION;
- }
+ if (dpy == NULL) {
+ return GLX_NO_EXTENSION;
+ }
- /* Check screen number to see if its valid */
- if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
- return GLX_BAD_SCREEN;
- }
+ *ppriv = __glXInitialize(dpy);
+ if (*ppriv == NULL) {
+ return GLX_NO_EXTENSION;
+ }
- /* Check to see if the GL is supported on this screen */
- *ppsc = &((*ppriv)->screenConfigs[scrn]);
- if ( (*ppsc)->configs == NULL ) {
- /* No support for GL on this screen regardless of visual */
- return GLX_BAD_VISUAL;
- }
+ /* Check screen number to see if its valid */
+ if ((scrn < 0) || (scrn >= ScreenCount(dpy))) {
+ return GLX_BAD_SCREEN;
+ }
- return Success;
+ /* Check to see if the GL is supported on this screen */
+ *ppsc = &((*ppriv)->screenConfigs[scrn]);
+ if ((*ppsc)->configs == NULL) {
+ /* No support for GL on this screen regardless of visual */
+ return GLX_BAD_VISUAL;
+ }
+
+ return Success;
}
@@ -212,27 +217,26 @@ GetGLXPrivScreenConfig( Display *dpy, int scrn, __GLXdisplayPrivate ** ppriv,
* is returned.
*/
static __GLcontextModes *
-ValidateGLXFBConfig( Display * dpy, GLXFBConfig config )
-{
- __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
- const unsigned num_screens = ScreenCount(dpy);
- unsigned i;
- const __GLcontextModes * modes;
-
-
- if ( priv != NULL ) {
- for ( i = 0 ; i < num_screens ; i++ ) {
- for ( modes = priv->screenConfigs[i].configs
- ; modes != NULL
- ; modes = modes->next ) {
- if ( modes == (__GLcontextModes *) config ) {
- return (__GLcontextModes *) config;
- }
- }
- }
- }
+ValidateGLXFBConfig(Display * dpy, GLXFBConfig config)
+{
+ __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
+ const unsigned num_screens = ScreenCount(dpy);
+ unsigned i;
+ const __GLcontextModes *modes;
+
+
+ if (priv != NULL) {
+ for (i = 0; i < num_screens; i++) {
+ for (modes = priv->screenConfigs[i].configs; modes != NULL;
+ modes = modes->next) {
+ if (modes == (__GLcontextModes *) config) {
+ return (__GLcontextModes *) config;
+ }
+ }
+ }
+ }
- return NULL;
+ return NULL;
}
@@ -241,471 +245,497 @@ ValidateGLXFBConfig( Display * dpy, GLXFBConfig config )
* later in the function for direct-rendering contexts. Direct-rendering
* contexts don't need to track client state, so they don't need that memory
* at all.
- *
+ *
* \todo Eliminate \c __glXInitVertexArrayState. Replace it with a new
* function called \c __glXAllocateClientState that allocates the memory and
* does all the initialization (including the pixel pack / unpack).
*/
-static
-GLXContext AllocateGLXContext( Display *dpy )
-{
- GLXContext gc;
- int bufSize;
- CARD8 opcode;
- __GLXattribute *state;
-
- if (!dpy)
- return NULL;
-
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return NULL;
- }
-
- /* Allocate our context record */
- gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec));
- if (!gc) {
- /* Out of memory */
- return NULL;
- }
- memset(gc, 0, sizeof(struct __GLXcontextRec));
-
- state = Xmalloc(sizeof(struct __GLXattributeRec));
- if (state == NULL) {
- /* Out of memory */
- Xfree(gc);
- return NULL;
- }
- gc->client_state_private = state;
- memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
- state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
-
- /*
+static GLXContext
+AllocateGLXContext(Display * dpy)
+{
+ GLXContext gc;
+ int bufSize;
+ CARD8 opcode;
+ __GLXattribute *state;
+
+ if (!dpy)
+ return NULL;
+
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return NULL;
+ }
+
+ /* Allocate our context record */
+ gc = (GLXContext) Xmalloc(sizeof(struct __GLXcontextRec));
+ if (!gc) {
+ /* Out of memory */
+ return NULL;
+ }
+ memset(gc, 0, sizeof(struct __GLXcontextRec));
+
+ state = Xmalloc(sizeof(struct __GLXattributeRec));
+ if (state == NULL) {
+ /* Out of memory */
+ Xfree(gc);
+ return NULL;
+ }
+ gc->client_state_private = state;
+ memset(gc->client_state_private, 0, sizeof(struct __GLXattributeRec));
+ state->NoDrawArraysProtocol = (getenv("LIBGL_NO_DRAWARRAYS") != NULL);
+
+ /*
** Create a temporary buffer to hold GLX rendering commands. The size
** of the buffer is selected so that the maximum number of GLX rendering
** commands can fit in a single X packet and still have room in the X
** packet for the GLXRenderReq header.
*/
- bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
- gc->buf = (GLubyte *) Xmalloc(bufSize);
- if (!gc->buf) {
- Xfree(gc->client_state_private);
- Xfree(gc);
- return NULL;
- }
- gc->bufSize = bufSize;
+ bufSize = (XMaxRequestSize(dpy) * 4) - sz_xGLXRenderReq;
+ gc->buf = (GLubyte *) Xmalloc(bufSize);
+ if (!gc->buf) {
+ Xfree(gc->client_state_private);
+ Xfree(gc);
+ return NULL;
+ }
+ gc->bufSize = bufSize;
- /* Fill in the new context */
- gc->renderMode = GL_RENDER;
+ /* Fill in the new context */
+ gc->renderMode = GL_RENDER;
- state->storePack.alignment = 4;
- state->storeUnpack.alignment = 4;
+ state->storePack.alignment = 4;
+ state->storeUnpack.alignment = 4;
- gc->attributes.stackPointer = &gc->attributes.stack[0];
+ gc->attributes.stackPointer = &gc->attributes.stack[0];
- /*
+ /*
** PERFORMANCE NOTE: A mode dependent fill image can speed things up.
** Other code uses the fastImageUnpack bit, but it is never set
** to GL_TRUE.
*/
- gc->fastImageUnpack = GL_FALSE;
- gc->fillImage = __glFillImage;
- gc->pc = gc->buf;
- gc->bufEnd = gc->buf + bufSize;
- gc->isDirect = GL_FALSE;
- if (__glXDebug) {
- /*
- ** Set limit register so that there will be one command per packet
- */
- gc->limit = gc->buf;
- } else {
- gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
- }
- gc->createDpy = dpy;
- gc->majorOpcode = opcode;
-
- /*
+ gc->fastImageUnpack = GL_FALSE;
+ gc->fillImage = __glFillImage;
+ gc->pc = gc->buf;
+ gc->bufEnd = gc->buf + bufSize;
+ gc->isDirect = GL_FALSE;
+ if (__glXDebug) {
+ /*
+ ** Set limit register so that there will be one command per packet
+ */
+ gc->limit = gc->buf;
+ }
+ else {
+ gc->limit = gc->buf + bufSize - __GLX_BUFFER_LIMIT_SIZE;
+ }
+ gc->createDpy = dpy;
+ gc->majorOpcode = opcode;
+
+ /*
** Constrain the maximum drawing command size allowed to be
** transfered using the X_GLXRender protocol request. First
** constrain by a software limit, then constrain by the protocl
** limit.
*/
- if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
- bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
- }
- if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
- bufSize = __GLX_MAX_RENDER_CMD_SIZE;
- }
- gc->maxSmallRenderCommandSize = bufSize;
- return gc;
+ if (bufSize > __GLX_RENDER_CMD_SIZE_LIMIT) {
+ bufSize = __GLX_RENDER_CMD_SIZE_LIMIT;
+ }
+ if (bufSize > __GLX_MAX_RENDER_CMD_SIZE) {
+ bufSize = __GLX_MAX_RENDER_CMD_SIZE;
+ }
+ gc->maxSmallRenderCommandSize = bufSize;
+ return gc;
}
/**
* Create a new context. Exactly one of \c vis and \c fbconfig should be
* non-NULL.
- *
+ *
* \param use_glx_1_3 For FBConfigs, should GLX 1.3 protocol or
* SGIX_fbconfig protocol be used?
* \param renderType For FBConfigs, what is the rendering type?
*/
static GLXContext
-CreateContext(Display *dpy, XVisualInfo *vis,
- const __GLcontextModes * const fbconfig,
- GLXContext shareList,
- Bool allowDirect, GLXContextID contextID,
- Bool use_glx_1_3, int renderType)
+CreateContext(Display * dpy, XVisualInfo * vis,
+ const __GLcontextModes * const fbconfig,
+ GLXContext shareList,
+ Bool allowDirect, GLXContextID contextID,
+ Bool use_glx_1_3, int renderType)
{
- GLXContext gc;
+ GLXContext gc;
#ifdef GLX_DIRECT_RENDERING
- int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+ int screen = (fbconfig == NULL) ? vis->screen : fbconfig->screen;
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
#endif
- if ( dpy == NULL )
- return NULL;
+ if (dpy == NULL)
+ return NULL;
- gc = AllocateGLXContext(dpy);
- if (!gc)
- return NULL;
+ gc = AllocateGLXContext(dpy);
+ if (!gc)
+ return NULL;
- if (None == contextID) {
- if ( (vis == NULL) && (fbconfig == NULL) )
- return NULL;
+ if (None == contextID) {
+ if ((vis == NULL) && (fbconfig == NULL))
+ return NULL;
#ifdef GLX_DIRECT_RENDERING
- if (allowDirect && psc->driScreen) {
- const __GLcontextModes * mode;
-
- if (fbconfig == NULL) {
- mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
- if (mode == NULL) {
- xError error;
-
- error.errorCode = BadValue;
- error.resourceID = vis->visualid;
- error.sequenceNumber = dpy->request;
- error.type = X_Error;
- error.majorCode = gc->majorOpcode;
- error.minorCode = X_GLXCreateContext;
- _XError(dpy, &error);
- return None;
- }
- }
- else {
- mode = fbconfig;
- }
-
- gc->driContext = psc->driScreen->createContext(psc, mode, gc,
- shareList,
- renderType);
- if (gc->driContext != NULL) {
- gc->screen = mode->screen;
- gc->psc = psc;
- gc->mode = mode;
- gc->isDirect = GL_TRUE;
- }
- }
+ if (allowDirect && psc->driScreen) {
+ const __GLcontextModes *mode;
+
+ if (fbconfig == NULL) {
+ mode = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+ if (mode == NULL) {
+ xError error;
+
+ error.errorCode = BadValue;
+ error.resourceID = vis->visualid;
+ error.sequenceNumber = dpy->request;
+ error.type = X_Error;
+ error.majorCode = gc->majorOpcode;
+ error.minorCode = X_GLXCreateContext;
+ _XError(dpy, &error);
+ return None;
+ }
+ }
+ else {
+ mode = fbconfig;
+ }
+
+ gc->driContext = psc->driScreen->createContext(psc, mode, gc,
+ shareList,
+ renderType);
+ if (gc->driContext != NULL) {
+ gc->screen = mode->screen;
+ gc->psc = psc;
+ gc->mode = mode;
+ gc->isDirect = GL_TRUE;
+ }
+ }
#endif
- LockDisplay(dpy);
- if ( fbconfig == NULL ) {
- xGLXCreateContextReq *req;
-
- /* Send the glXCreateContext request */
- GetReq(GLXCreateContext,req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXCreateContext;
- req->context = gc->xid = XAllocID(dpy);
- req->visual = vis->visualid;
- req->screen = vis->screen;
- req->shareList = shareList ? shareList->xid : None;
+ LockDisplay(dpy);
+ if (fbconfig == NULL) {
+ xGLXCreateContextReq *req;
+
+ /* Send the glXCreateContext request */
+ GetReq(GLXCreateContext, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXCreateContext;
+ req->context = gc->xid = XAllocID(dpy);
+ req->visual = vis->visualid;
+ req->screen = vis->screen;
+ req->shareList = shareList ? shareList->xid : None;
#ifdef GLX_DIRECT_RENDERING
- req->isDirect = gc->driContext != NULL;
+ req->isDirect = gc->driContext != NULL;
#else
- req->isDirect = 0;
+ req->isDirect = 0;
#endif
- }
- else if ( use_glx_1_3 ) {
- xGLXCreateNewContextReq *req;
-
- /* Send the glXCreateNewContext request */
- GetReq(GLXCreateNewContext,req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXCreateNewContext;
- req->context = gc->xid = XAllocID(dpy);
- req->fbconfig = fbconfig->fbconfigID;
- req->screen = fbconfig->screen;
- req->renderType = renderType;
- req->shareList = shareList ? shareList->xid : None;
+ }
+ else if (use_glx_1_3) {
+ xGLXCreateNewContextReq *req;
+
+ /* Send the glXCreateNewContext request */
+ GetReq(GLXCreateNewContext, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXCreateNewContext;
+ req->context = gc->xid = XAllocID(dpy);
+ req->fbconfig = fbconfig->fbconfigID;
+ req->screen = fbconfig->screen;
+ req->renderType = renderType;
+ req->shareList = shareList ? shareList->xid : None;
#ifdef GLX_DIRECT_RENDERING
- req->isDirect = gc->driContext != NULL;
+ req->isDirect = gc->driContext != NULL;
#else
- req->isDirect = 0;
+ req->isDirect = 0;
#endif
- }
- else {
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXCreateContextWithConfigSGIXReq *req;
-
- /* Send the glXCreateNewContext request */
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXCreateContextWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
- req = (xGLXCreateContextWithConfigSGIXReq *)vpreq;
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXVendorPrivateWithReply;
- req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
- req->context = gc->xid = XAllocID(dpy);
- req->fbconfig = fbconfig->fbconfigID;
- req->screen = fbconfig->screen;
- req->renderType = renderType;
- req->shareList = shareList ? shareList->xid : None;
+ }
+ else {
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXCreateContextWithConfigSGIXReq *req;
+
+ /* Send the glXCreateNewContext request */
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXCreateContextWithConfigSGIXReq -
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ req = (xGLXCreateContextWithConfigSGIXReq *) vpreq;
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXVendorPrivateWithReply;
+ req->vendorCode = X_GLXvop_CreateContextWithConfigSGIX;
+ req->context = gc->xid = XAllocID(dpy);
+ req->fbconfig = fbconfig->fbconfigID;
+ req->screen = fbconfig->screen;
+ req->renderType = renderType;
+ req->shareList = shareList ? shareList->xid : None;
#ifdef GLX_DIRECT_RENDERING
- req->isDirect = gc->driContext != NULL;
+ req->isDirect = gc->driContext != NULL;
#else
- req->isDirect = 0;
+ req->isDirect = 0;
#endif
- }
+ }
- UnlockDisplay(dpy);
- SyncHandle();
- gc->imported = GL_FALSE;
- }
- else {
- gc->xid = contextID;
- gc->imported = GL_TRUE;
- }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ gc->imported = GL_FALSE;
+ }
+ else {
+ gc->xid = contextID;
+ gc->imported = GL_TRUE;
+ }
- return gc;
+ return gc;
}
-PUBLIC GLXContext glXCreateContext(Display *dpy, XVisualInfo *vis,
- GLXContext shareList, Bool allowDirect)
+PUBLIC GLXContext
+glXCreateContext(Display * dpy, XVisualInfo * vis,
+ GLXContext shareList, Bool allowDirect)
{
return CreateContext(dpy, vis, NULL, shareList, allowDirect, None,
- False, 0);
+ False, 0);
}
-_X_HIDDEN void __glXFreeContext(__GLXcontext *gc)
+_X_HIDDEN void
+__glXFreeContext(__GLXcontext * gc)
{
- if (gc->vendor) XFree((char *) gc->vendor);
- if (gc->renderer) XFree((char *) gc->renderer);
- if (gc->version) XFree((char *) gc->version);
- if (gc->extensions) XFree((char *) gc->extensions);
- __glFreeAttributeState(gc);
- XFree((char *) gc->buf);
- Xfree((char *) gc->client_state_private);
- XFree((char *) gc);
-
+ if (gc->vendor)
+ XFree((char *) gc->vendor);
+ if (gc->renderer)
+ XFree((char *) gc->renderer);
+ if (gc->version)
+ XFree((char *) gc->version);
+ if (gc->extensions)
+ XFree((char *) gc->extensions);
+ __glFreeAttributeState(gc);
+ XFree((char *) gc->buf);
+ Xfree((char *) gc->client_state_private);
+ XFree((char *) gc);
+
}
/*
** Destroy the named context
*/
-static void
-DestroyContext(Display *dpy, GLXContext gc)
+static void
+DestroyContext(Display * dpy, GLXContext gc)
{
- xGLXDestroyContextReq *req;
- GLXContextID xid;
- CARD8 opcode;
- GLboolean imported;
+ xGLXDestroyContextReq *req;
+ GLXContextID xid;
+ CARD8 opcode;
+ GLboolean imported;
- opcode = __glXSetupForCommand(dpy);
- if (!opcode || !gc) {
- return;
- }
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode || !gc) {
+ return;
+ }
- __glXLock();
- xid = gc->xid;
- imported = gc->imported;
- gc->xid = None;
+ __glXLock();
+ xid = gc->xid;
+ imported = gc->imported;
+ gc->xid = None;
#ifdef GLX_DIRECT_RENDERING
- /* Destroy the direct rendering context */
- if (gc->driContext) {
- (*gc->driContext->destroyContext)(gc->driContext, gc->psc, dpy);
- gc->driContext = NULL;
- GarbageCollectDRIDrawables(dpy, gc->psc);
- }
+ /* Destroy the direct rendering context */
+ if (gc->driContext) {
+ (*gc->driContext->destroyContext) (gc->driContext, gc->psc, dpy);
+ gc->driContext = NULL;
+ GarbageCollectDRIDrawables(dpy, gc->psc);
+ }
#endif
- __glXFreeVertexArrayState(gc);
+ __glXFreeVertexArrayState(gc);
- if (gc->currentDpy) {
- /* Have to free later cuz it's in use now */
- __glXUnlock();
- } else {
- /* Destroy the handle if not current to anybody */
- __glXUnlock();
- __glXFreeContext(gc);
- }
+ if (gc->currentDpy) {
+ /* Have to free later cuz it's in use now */
+ __glXUnlock();
+ }
+ else {
+ /* Destroy the handle if not current to anybody */
+ __glXUnlock();
+ __glXFreeContext(gc);
+ }
- if (!imported) {
- /*
- ** This dpy also created the server side part of the context.
- ** Send the glXDestroyContext request.
- */
- LockDisplay(dpy);
- GetReq(GLXDestroyContext,req);
- req->reqType = opcode;
- req->glxCode = X_GLXDestroyContext;
- req->context = xid;
- UnlockDisplay(dpy);
- SyncHandle();
- }
+ if (!imported) {
+ /*
+ ** This dpy also created the server side part of the context.
+ ** Send the glXDestroyContext request.
+ */
+ LockDisplay(dpy);
+ GetReq(GLXDestroyContext, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXDestroyContext;
+ req->context = xid;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
}
-PUBLIC void glXDestroyContext(Display *dpy, GLXContext gc)
+PUBLIC void
+glXDestroyContext(Display * dpy, GLXContext gc)
{
- DestroyContext(dpy, gc);
+ DestroyContext(dpy, gc);
}
/*
** Return the major and minor version #s for the GLX extension
*/
-PUBLIC Bool glXQueryVersion(Display *dpy, int *major, int *minor)
+PUBLIC Bool
+glXQueryVersion(Display * dpy, int *major, int *minor)
{
- __GLXdisplayPrivate *priv;
+ __GLXdisplayPrivate *priv;
- /* Init the extension. This fetches the major and minor version. */
- priv = __glXInitialize(dpy);
- if (!priv) return GL_FALSE;
+ /* Init the extension. This fetches the major and minor version. */
+ priv = __glXInitialize(dpy);
+ if (!priv)
+ return GL_FALSE;
- if (major) *major = priv->majorVersion;
- if (minor) *minor = priv->minorVersion;
- return GL_TRUE;
+ if (major)
+ *major = priv->majorVersion;
+ if (minor)
+ *minor = priv->minorVersion;
+ return GL_TRUE;
}
/*
** Query the existance of the GLX extension
*/
-PUBLIC Bool glXQueryExtension(Display *dpy, int *errorBase, int *eventBase)
-{
- int major_op, erb, evb;
- Bool rv;
-
- rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
- if (rv) {
- if (errorBase) *errorBase = erb;
- if (eventBase) *eventBase = evb;
- }
- return rv;
+PUBLIC Bool
+glXQueryExtension(Display * dpy, int *errorBase, int *eventBase)
+{
+ int major_op, erb, evb;
+ Bool rv;
+
+ rv = XQueryExtension(dpy, GLX_EXTENSION_NAME, &major_op, &evb, &erb);
+ if (rv) {
+ if (errorBase)
+ *errorBase = erb;
+ if (eventBase)
+ *eventBase = evb;
+ }
+ return rv;
}
/*
** Put a barrier in the token stream that forces the GL to finish its
** work before X can proceed.
*/
-PUBLIC void glXWaitGL(void)
+PUBLIC void
+glXWaitGL(void)
{
- xGLXWaitGLReq *req;
- GLXContext gc = __glXGetCurrentContext();
- Display *dpy = gc->currentDpy;
+ xGLXWaitGLReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ Display *dpy = gc->currentDpy;
- if (!dpy) return;
+ if (!dpy)
+ return;
- /* Flush any pending commands out */
- __glXFlushRenderBuffer(gc, gc->pc);
+ /* Flush any pending commands out */
+ __glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext) {
- int screen;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
-
- if ( pdraw != NULL ) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
- glFlush();
- if (psc->driScreen->waitGL != NULL)
- (*psc->driScreen->waitGL)(pdraw);
- }
- return;
- }
+ if (gc->driContext) {
+ int screen;
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
+
+ if (pdraw != NULL) {
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ glFlush();
+ if (psc->driScreen->waitGL != NULL)
+ (*psc->driScreen->waitGL) (pdraw);
+ }
+ return;
+ }
#endif
- /* Send the glXWaitGL request */
- LockDisplay(dpy);
- GetReq(GLXWaitGL,req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXWaitGL;
- req->contextTag = gc->currentContextTag;
- UnlockDisplay(dpy);
- SyncHandle();
+ /* Send the glXWaitGL request */
+ LockDisplay(dpy);
+ GetReq(GLXWaitGL, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXWaitGL;
+ req->contextTag = gc->currentContextTag;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
/*
** Put a barrier in the token stream that forces X to finish its
** work before GL can proceed.
*/
-PUBLIC void glXWaitX(void)
+PUBLIC void
+glXWaitX(void)
{
- xGLXWaitXReq *req;
- GLXContext gc = __glXGetCurrentContext();
- Display *dpy = gc->currentDpy;
+ xGLXWaitXReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ Display *dpy = gc->currentDpy;
- if (!dpy) return;
+ if (!dpy)
+ return;
- /* Flush any pending commands out */
- __glXFlushRenderBuffer(gc, gc->pc);
+ /* Flush any pending commands out */
+ __glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext) {
- int screen;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
-
- if ( pdraw != NULL ) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
- if (psc->driScreen->waitX != NULL)
- (*psc->driScreen->waitX)(pdraw);
- } else
- XSync(dpy, False);
- return;
- }
+ if (gc->driContext) {
+ int screen;
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(dpy, gc->currentDrawable, &screen);
+
+ if (pdraw != NULL) {
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ if (psc->driScreen->waitX != NULL)
+ (*psc->driScreen->waitX) (pdraw);
+ }
+ else
+ XSync(dpy, False);
+ return;
+ }
#endif
- /*
+ /*
** Send the glXWaitX request.
*/
- LockDisplay(dpy);
- GetReq(GLXWaitX,req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXWaitX;
- req->contextTag = gc->currentContextTag;
- UnlockDisplay(dpy);
- SyncHandle();
+ LockDisplay(dpy);
+ GetReq(GLXWaitX, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXWaitX;
+ req->contextTag = gc->currentContextTag;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
-PUBLIC void glXUseXFont(Font font, int first, int count, int listBase)
+PUBLIC void
+glXUseXFont(Font font, int first, int count, int listBase)
{
- xGLXUseXFontReq *req;
- GLXContext gc = __glXGetCurrentContext();
- Display *dpy = gc->currentDpy;
+ xGLXUseXFontReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ Display *dpy = gc->currentDpy;
- if (!dpy) return;
+ if (!dpy)
+ return;
- /* Flush any pending commands out */
- (void) __glXFlushRenderBuffer(gc, gc->pc);
+ /* Flush any pending commands out */
+ (void) __glXFlushRenderBuffer(gc, gc->pc);
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext) {
+ if (gc->driContext) {
DRI_glXUseXFont(font, first, count, listBase);
return;
- }
+ }
#endif
- /* Send the glXUseFont request */
- LockDisplay(dpy);
- GetReq(GLXUseXFont,req);
- req->reqType = gc->majorOpcode;
- req->glxCode = X_GLXUseXFont;
- req->contextTag = gc->currentContextTag;
- req->font = font;
- req->first = first;
- req->count = count;
- req->listBase = listBase;
- UnlockDisplay(dpy);
- SyncHandle();
+ /* Send the glXUseFont request */
+ LockDisplay(dpy);
+ GetReq(GLXUseXFont, req);
+ req->reqType = gc->majorOpcode;
+ req->glxCode = X_GLXUseXFont;
+ req->contextTag = gc->currentContextTag;
+ req->font = font;
+ req->first = first;
+ req->count = count;
+ req->listBase = listBase;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
/************************************************************************/
@@ -714,46 +744,48 @@ PUBLIC void glXUseXFont(Font font, int first, int count, int listBase)
** Copy the source context to the destination context using the
** attribute "mask".
*/
-PUBLIC void glXCopyContext(Display *dpy, GLXContext source,
- GLXContext dest, unsigned long mask)
+PUBLIC void
+glXCopyContext(Display * dpy, GLXContext source,
+ GLXContext dest, unsigned long mask)
{
- xGLXCopyContextReq *req;
- GLXContext gc = __glXGetCurrentContext();
- GLXContextTag tag;
- CARD8 opcode;
+ xGLXCopyContextReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ GLXContextTag tag;
+ CARD8 opcode;
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return;
- }
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return;
+ }
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext) {
- /* NOT_DONE: This does not work yet */
- }
+ if (gc->driContext) {
+ /* NOT_DONE: This does not work yet */
+ }
#endif
- /*
+ /*
** If the source is the current context, send its tag so that the context
** can be flushed before the copy.
*/
- if (source == gc && dpy == gc->currentDpy) {
- tag = gc->currentContextTag;
- } else {
- tag = 0;
- }
-
- /* Send the glXCopyContext request */
- LockDisplay(dpy);
- GetReq(GLXCopyContext,req);
- req->reqType = opcode;
- req->glxCode = X_GLXCopyContext;
- req->source = source ? source->xid : None;
- req->dest = dest ? dest->xid : None;
- req->mask = mask;
- req->contextTag = tag;
- UnlockDisplay(dpy);
- SyncHandle();
+ if (source == gc && dpy == gc->currentDpy) {
+ tag = gc->currentContextTag;
+ }
+ else {
+ tag = 0;
+ }
+
+ /* Send the glXCopyContext request */
+ LockDisplay(dpy);
+ GetReq(GLXCopyContext, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXCopyContext;
+ req->source = source ? source->xid : None;
+ req->dest = dest ? dest->xid : None;
+ req->mask = mask;
+ req->contextTag = tag;
+ UnlockDisplay(dpy);
+ SyncHandle();
}
@@ -765,42 +797,43 @@ PUBLIC void glXCopyContext(Display *dpy, GLXContext source,
*
* \returns \c GL_TRUE if the context is direct rendering or not.
*/
-static Bool __glXIsDirect(Display *dpy, GLXContextID contextID)
+static Bool
+__glXIsDirect(Display * dpy, GLXContextID contextID)
{
#if !defined(USE_XCB)
- xGLXIsDirectReq *req;
- xGLXIsDirectReply reply;
+ xGLXIsDirectReq *req;
+ xGLXIsDirectReply reply;
#endif
- CARD8 opcode;
+ CARD8 opcode;
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return GL_FALSE;
- }
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return GL_FALSE;
+ }
#ifdef USE_XCB
- xcb_connection_t* c = XGetXCBConnection(dpy);
- xcb_glx_is_direct_reply_t* reply =
- xcb_glx_is_direct_reply(c,
- xcb_glx_is_direct(c, contextID),
- NULL);
+ xcb_connection_t *c = XGetXCBConnection(dpy);
+ xcb_glx_is_direct_reply_t *reply = xcb_glx_is_direct_reply(c,
+ xcb_glx_is_direct
+ (c, contextID),
+ NULL);
const Bool is_direct = reply->is_direct ? True : False;
free(reply);
return is_direct;
#else
- /* Send the glXIsDirect request */
- LockDisplay(dpy);
- GetReq(GLXIsDirect,req);
- req->reqType = opcode;
- req->glxCode = X_GLXIsDirect;
- req->context = contextID;
- _XReply(dpy, (xReply*) &reply, 0, False);
- UnlockDisplay(dpy);
- SyncHandle();
-
- return reply.isDirect;
+ /* Send the glXIsDirect request */
+ LockDisplay(dpy);
+ GetReq(GLXIsDirect, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXIsDirect;
+ req->context = contextID;
+ _XReply(dpy, (xReply *) & reply, 0, False);
+ UnlockDisplay(dpy);
+ SyncHandle();
+
+ return reply.isDirect;
#endif /* USE_XCB */
}
@@ -810,134 +843,168 @@ static Bool __glXIsDirect(Display *dpy, GLXContextID contextID)
* \c GLX_DIRECT_RENDERING is not defined? Do we really need to bother with
* the GLX protocol here at all?
*/
-PUBLIC Bool glXIsDirect(Display *dpy, GLXContext gc)
+PUBLIC Bool
+glXIsDirect(Display * dpy, GLXContext gc)
{
- if (!gc) {
- return GL_FALSE;
+ if (!gc) {
+ return GL_FALSE;
#ifdef GLX_DIRECT_RENDERING
- } else if (gc->driContext) {
- return GL_TRUE;
+ }
+ else if (gc->driContext) {
+ return GL_TRUE;
#endif
- }
- return __glXIsDirect(dpy, gc->xid);
+ }
+ return __glXIsDirect(dpy, gc->xid);
}
-PUBLIC GLXPixmap glXCreateGLXPixmap(Display *dpy, XVisualInfo *vis,
- Pixmap pixmap)
+PUBLIC GLXPixmap
+glXCreateGLXPixmap(Display * dpy, XVisualInfo * vis, Pixmap pixmap)
{
- xGLXCreateGLXPixmapReq *req;
- GLXPixmap xid;
- CARD8 opcode;
+ xGLXCreateGLXPixmapReq *req;
+ GLXPixmap xid;
+ CARD8 opcode;
+
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return None;
+ }
+
+ /* Send the glXCreateGLXPixmap request */
+ LockDisplay(dpy);
+ GetReq(GLXCreateGLXPixmap, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXCreateGLXPixmap;
+ req->screen = vis->screen;
+ req->visual = vis->visualid;
+ req->pixmap = pixmap;
+ req->glxpixmap = xid = XAllocID(dpy);
+ UnlockDisplay(dpy);
+ SyncHandle();
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return None;
- }
+#ifdef GLX_DIRECT_RENDERING
+ do {
+ /* FIXME: Maybe delay __DRIdrawable creation until the drawable
+ * is actually bound to a context... */
+
+ __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw;
+ __GLXscreenConfigs *psc;
+ __GLcontextModes *modes;
+
+ psc = &priv->screenConfigs[vis->screen];
+ if (psc->driScreen == NULL)
+ break;
+ modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+ pdraw = psc->driScreen->createDrawable(psc, pixmap, req->glxpixmap, modes);
+ if (pdraw == NULL) {
+ fprintf(stderr, "failed to create pixmap\n");
+ break;
+ }
- /* Send the glXCreateGLXPixmap request */
- LockDisplay(dpy);
- GetReq(GLXCreateGLXPixmap,req);
- req->reqType = opcode;
- req->glxCode = X_GLXCreateGLXPixmap;
- req->screen = vis->screen;
- req->visual = vis->visualid;
- req->pixmap = pixmap;
- req->glxpixmap = xid = XAllocID(dpy);
- UnlockDisplay(dpy);
- SyncHandle();
- return xid;
+ if (__glxHashInsert(psc->drawHash, req->glxpixmap, pdraw)) {
+ (*pdraw->destroyDrawable) (pdraw);
+ return None; /* FIXME: Check what we're supposed to do here... */
+ }
+ } while (0);
+#endif
+
+ return xid;
}
/*
** Destroy the named pixmap
*/
-PUBLIC void glXDestroyGLXPixmap(Display *dpy, GLXPixmap glxpixmap)
-{
- xGLXDestroyGLXPixmapReq *req;
- CARD8 opcode;
-
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return;
- }
-
- /* Send the glXDestroyGLXPixmap request */
- LockDisplay(dpy);
- GetReq(GLXDestroyGLXPixmap,req);
- req->reqType = opcode;
- req->glxCode = X_GLXDestroyGLXPixmap;
- req->glxpixmap = glxpixmap;
- UnlockDisplay(dpy);
- SyncHandle();
+PUBLIC void
+glXDestroyGLXPixmap(Display * dpy, GLXPixmap glxpixmap)
+{
+ xGLXDestroyGLXPixmapReq *req;
+ CARD8 opcode;
+
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return;
+ }
+
+ /* Send the glXDestroyGLXPixmap request */
+ LockDisplay(dpy);
+ GetReq(GLXDestroyGLXPixmap, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXDestroyGLXPixmap;
+ req->glxpixmap = glxpixmap;
+ UnlockDisplay(dpy);
+ SyncHandle();
#ifdef GLX_DIRECT_RENDERING
- {
- int screen;
- __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap, &screen);
- __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
-
- if (pdraw != NULL) {
- (*pdraw->destroyDrawable) (pdraw);
- __glxHashDelete(psc->drawHash, glxpixmap);
- }
- }
+ {
+ int screen;
+ __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, glxpixmap, &screen);
+ __GLXscreenConfigs *psc = &priv->screenConfigs[screen];
+
+ if (pdraw != NULL) {
+ (*pdraw->destroyDrawable) (pdraw);
+ __glxHashDelete(psc->drawHash, glxpixmap);
+ }
+ }
#endif
}
-PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
+PUBLIC void
+glXSwapBuffers(Display * dpy, GLXDrawable drawable)
{
- GLXContext gc;
- GLXContextTag tag;
- CARD8 opcode;
+ GLXContext gc;
+ GLXContextTag tag;
+ CARD8 opcode;
#ifdef USE_XCB
- xcb_connection_t *c;
+ xcb_connection_t *c;
#else
- xGLXSwapBuffersReq *req;
+ xGLXSwapBuffersReq *req;
#endif
#ifdef GLX_DIRECT_RENDERING
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
- if (pdraw != NULL) {
- glFlush();
- (*pdraw->psc->driScreen->swapBuffers)(pdraw);
- return;
- }
+ if (pdraw != NULL) {
+ glFlush();
+ (*pdraw->psc->driScreen->swapBuffers) (pdraw);
+ return;
+ }
#endif
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return;
- }
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return;
+ }
- /*
+ /*
** The calling thread may or may not have a current context. If it
** does, send the context tag so the server can do a flush.
*/
- gc = __glXGetCurrentContext();
- if ((gc != NULL) && (dpy == gc->currentDpy) &&
- ((drawable == gc->currentDrawable) || (drawable == gc->currentReadable)) ) {
- tag = gc->currentContextTag;
- } else {
- tag = 0;
- }
+ gc = __glXGetCurrentContext();
+ if ((gc != NULL) && (dpy == gc->currentDpy) &&
+ ((drawable == gc->currentDrawable)
+ || (drawable == gc->currentReadable))) {
+ tag = gc->currentContextTag;
+ }
+ else {
+ tag = 0;
+ }
#ifdef USE_XCB
- c = XGetXCBConnection(dpy);
- xcb_glx_swap_buffers(c, tag, drawable);
- xcb_flush(c);
+ c = XGetXCBConnection(dpy);
+ xcb_glx_swap_buffers(c, tag, drawable);
+ xcb_flush(c);
#else
- /* Send the glXSwapBuffers request */
- LockDisplay(dpy);
- GetReq(GLXSwapBuffers,req);
- req->reqType = opcode;
- req->glxCode = X_GLXSwapBuffers;
- req->drawable = drawable;
- req->contextTag = tag;
- UnlockDisplay(dpy);
- SyncHandle();
- XFlush(dpy);
+ /* Send the glXSwapBuffers request */
+ LockDisplay(dpy);
+ GetReq(GLXSwapBuffers, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXSwapBuffers;
+ req->drawable = drawable;
+ req->contextTag = tag;
+ UnlockDisplay(dpy);
+ SyncHandle();
+ XFlush(dpy);
#endif /* USE_XCB */
}
@@ -946,94 +1013,96 @@ PUBLIC void glXSwapBuffers(Display *dpy, GLXDrawable drawable)
** Return configuration information for the given display, screen and
** visual combination.
*/
-PUBLIC int glXGetConfig(Display *dpy, XVisualInfo *vis, int attribute,
- int *value_return)
-{
- __GLXdisplayPrivate *priv;
- __GLXscreenConfigs *psc;
- __GLcontextModes *modes;
- int status;
-
- status = GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc );
- if ( status == Success ) {
- modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
-
- /* Lookup attribute after first finding a match on the visual */
- if ( modes != NULL ) {
- return _gl_get_context_mode_data( modes, attribute, value_return );
- }
-
- status = GLX_BAD_VISUAL;
- }
-
- /*
+PUBLIC int
+glXGetConfig(Display * dpy, XVisualInfo * vis, int attribute,
+ int *value_return)
+{
+ __GLXdisplayPrivate *priv;
+ __GLXscreenConfigs *psc;
+ __GLcontextModes *modes;
+ int status;
+
+ status = GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc);
+ if (status == Success) {
+ modes = _gl_context_modes_find_visual(psc->visuals, vis->visualid);
+
+ /* Lookup attribute after first finding a match on the visual */
+ if (modes != NULL) {
+ return _gl_get_context_mode_data(modes, attribute, value_return);
+ }
+
+ status = GLX_BAD_VISUAL;
+ }
+
+ /*
** If we can't find the config for this visual, this visual is not
** supported by the OpenGL implementation on the server.
*/
- if ( (status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL) ) {
- *value_return = GL_FALSE;
- status = Success;
- }
+ if ((status == GLX_BAD_VISUAL) && (attribute == GLX_USE_GL)) {
+ *value_return = GL_FALSE;
+ status = Success;
+ }
- return status;
+ return status;
}
/************************************************************************/
static void
-init_fbconfig_for_chooser( __GLcontextModes * config,
- GLboolean fbconfig_style_tags )
-{
- memset( config, 0, sizeof( __GLcontextModes ) );
- config->visualID = (XID) GLX_DONT_CARE;
- config->visualType = GLX_DONT_CARE;
-
- /* glXChooseFBConfig specifies different defaults for these two than
- * glXChooseVisual.
- */
- if ( fbconfig_style_tags ) {
- config->rgbMode = GL_TRUE;
- config->doubleBufferMode = GLX_DONT_CARE;
- }
-
- config->visualRating = GLX_DONT_CARE;
- config->transparentPixel = GLX_NONE;
- config->transparentRed = GLX_DONT_CARE;
- config->transparentGreen = GLX_DONT_CARE;
- config->transparentBlue = GLX_DONT_CARE;
- config->transparentAlpha = GLX_DONT_CARE;
- config->transparentIndex = GLX_DONT_CARE;
-
- config->drawableType = GLX_WINDOW_BIT;
- config->renderType = (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
- config->xRenderable = GLX_DONT_CARE;
- config->fbconfigID = (GLXFBConfigID)(GLX_DONT_CARE);
-
- config->swapMethod = GLX_DONT_CARE;
-}
-
-#define MATCH_DONT_CARE( param ) \
- do { \
- if ( (a-> param != GLX_DONT_CARE) \
- && (a-> param != b-> param) ) { \
- return False; \
- } \
- } while ( 0 )
-
-#define MATCH_MINIMUM( param ) \
- do { \
- if ( (a-> param != GLX_DONT_CARE) \
- && (a-> param > b-> param) ) { \
- return False; \
- } \
- } while ( 0 )
-
-#define MATCH_EXACT( param ) \
- do { \
- if ( a-> param != b-> param) { \
- return False; \
- } \
- } while ( 0 )
+init_fbconfig_for_chooser(__GLcontextModes * config,
+ GLboolean fbconfig_style_tags)
+{
+ memset(config, 0, sizeof(__GLcontextModes));
+ config->visualID = (XID) GLX_DONT_CARE;
+ config->visualType = GLX_DONT_CARE;
+
+ /* glXChooseFBConfig specifies different defaults for these two than
+ * glXChooseVisual.
+ */
+ if (fbconfig_style_tags) {
+ config->rgbMode = GL_TRUE;
+ config->doubleBufferMode = GLX_DONT_CARE;
+ }
+
+ config->visualRating = GLX_DONT_CARE;
+ config->transparentPixel = GLX_NONE;
+ config->transparentRed = GLX_DONT_CARE;
+ config->transparentGreen = GLX_DONT_CARE;
+ config->transparentBlue = GLX_DONT_CARE;
+ config->transparentAlpha = GLX_DONT_CARE;
+ config->transparentIndex = GLX_DONT_CARE;
+
+ config->drawableType = GLX_WINDOW_BIT;
+ config->renderType =
+ (config->rgbMode) ? GLX_RGBA_BIT : GLX_COLOR_INDEX_BIT;
+ config->xRenderable = GLX_DONT_CARE;
+ config->fbconfigID = (GLXFBConfigID) (GLX_DONT_CARE);
+
+ config->swapMethod = GLX_DONT_CARE;
+}
+
+#define MATCH_DONT_CARE( param ) \
+ do { \
+ if ( (a-> param != GLX_DONT_CARE) \
+ && (a-> param != b-> param) ) { \
+ return False; \
+ } \
+ } while ( 0 )
+
+#define MATCH_MINIMUM( param ) \
+ do { \
+ if ( (a-> param != GLX_DONT_CARE) \
+ && (a-> param > b-> param) ) { \
+ return False; \
+ } \
+ } while ( 0 )
+
+#define MATCH_EXACT( param ) \
+ do { \
+ if ( a-> param != b-> param) { \
+ return False; \
+ } \
+ } while ( 0 )
/**
* Determine if two GLXFBConfigs are compatible.
@@ -1042,80 +1111,80 @@ init_fbconfig_for_chooser( __GLcontextModes * config,
* \param b Server specified config to test against \c a.
*/
static Bool
-fbconfigs_compatible( const __GLcontextModes * const a,
- const __GLcontextModes * const b )
-{
- MATCH_DONT_CARE( doubleBufferMode );
- MATCH_DONT_CARE( visualType );
- MATCH_DONT_CARE( visualRating );
- MATCH_DONT_CARE( xRenderable );
- MATCH_DONT_CARE( fbconfigID );
- MATCH_DONT_CARE( swapMethod );
-
- MATCH_MINIMUM( rgbBits );
- MATCH_MINIMUM( numAuxBuffers );
- MATCH_MINIMUM( redBits );
- MATCH_MINIMUM( greenBits );
- MATCH_MINIMUM( blueBits );
- MATCH_MINIMUM( alphaBits );
- MATCH_MINIMUM( depthBits );
- MATCH_MINIMUM( stencilBits );
- MATCH_MINIMUM( accumRedBits );
- MATCH_MINIMUM( accumGreenBits );
- MATCH_MINIMUM( accumBlueBits );
- MATCH_MINIMUM( accumAlphaBits );
- MATCH_MINIMUM( sampleBuffers );
- MATCH_MINIMUM( maxPbufferWidth );
- MATCH_MINIMUM( maxPbufferHeight );
- MATCH_MINIMUM( maxPbufferPixels );
- MATCH_MINIMUM( samples );
-
- MATCH_DONT_CARE( stereoMode );
- MATCH_EXACT( level );
-
- if ( ((a->drawableType & b->drawableType) == 0)
- || ((a->renderType & b->renderType) == 0) ) {
- return False;
- }
-
-
- /* There is a bug in a few of the XFree86 DDX drivers. They contain
- * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
- * Technically speaking, it is a bug in the DDX driver, but there is
- * enough of an installed base to work around the problem here. In any
- * case, 0 is not a valid value of the transparent type, so we'll treat 0
- * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
- * 0 from the server to be a match to maintain backward compatibility with
- * the (broken) drivers.
- */
-
- if ( a->transparentPixel != GLX_DONT_CARE
- && a->transparentPixel != 0 ) {
- if ( a->transparentPixel == GLX_NONE ) {
- if ( b->transparentPixel != GLX_NONE && b->transparentPixel != 0 )
- return False;
- } else {
- MATCH_EXACT( transparentPixel );
- }
-
- switch ( a->transparentPixel ) {
- case GLX_TRANSPARENT_RGB:
- MATCH_DONT_CARE( transparentRed );
- MATCH_DONT_CARE( transparentGreen );
- MATCH_DONT_CARE( transparentBlue );
- MATCH_DONT_CARE( transparentAlpha );
- break;
-
- case GLX_TRANSPARENT_INDEX:
- MATCH_DONT_CARE( transparentIndex );
- break;
-
- default:
- break;
- }
- }
-
- return True;
+fbconfigs_compatible(const __GLcontextModes * const a,
+ const __GLcontextModes * const b)
+{
+ MATCH_DONT_CARE(doubleBufferMode);
+ MATCH_DONT_CARE(visualType);
+ MATCH_DONT_CARE(visualRating);
+ MATCH_DONT_CARE(xRenderable);
+ MATCH_DONT_CARE(fbconfigID);
+ MATCH_DONT_CARE(swapMethod);
+
+ MATCH_MINIMUM(rgbBits);
+ MATCH_MINIMUM(numAuxBuffers);
+ MATCH_MINIMUM(redBits);
+ MATCH_MINIMUM(greenBits);
+ MATCH_MINIMUM(blueBits);
+ MATCH_MINIMUM(alphaBits);
+ MATCH_MINIMUM(depthBits);
+ MATCH_MINIMUM(stencilBits);
+ MATCH_MINIMUM(accumRedBits);
+ MATCH_MINIMUM(accumGreenBits);
+ MATCH_MINIMUM(accumBlueBits);
+ MATCH_MINIMUM(accumAlphaBits);
+ MATCH_MINIMUM(sampleBuffers);
+ MATCH_MINIMUM(maxPbufferWidth);
+ MATCH_MINIMUM(maxPbufferHeight);
+ MATCH_MINIMUM(maxPbufferPixels);
+ MATCH_MINIMUM(samples);
+
+ MATCH_DONT_CARE(stereoMode);
+ MATCH_EXACT(level);
+
+ if (((a->drawableType & b->drawableType) == 0)
+ || ((a->renderType & b->renderType) == 0)) {
+ return False;
+ }
+
+
+ /* There is a bug in a few of the XFree86 DDX drivers. They contain
+ * visuals with a "transparent type" of 0 when they really mean GLX_NONE.
+ * Technically speaking, it is a bug in the DDX driver, but there is
+ * enough of an installed base to work around the problem here. In any
+ * case, 0 is not a valid value of the transparent type, so we'll treat 0
+ * from the app as GLX_DONT_CARE. We'll consider GLX_NONE from the app and
+ * 0 from the server to be a match to maintain backward compatibility with
+ * the (broken) drivers.
+ */
+
+ if (a->transparentPixel != GLX_DONT_CARE && a->transparentPixel != 0) {
+ if (a->transparentPixel == GLX_NONE) {
+ if (b->transparentPixel != GLX_NONE && b->transparentPixel != 0)
+ return False;
+ }
+ else {
+ MATCH_EXACT(transparentPixel);
+ }
+
+ switch (a->transparentPixel) {
+ case GLX_TRANSPARENT_RGB:
+ MATCH_DONT_CARE(transparentRed);
+ MATCH_DONT_CARE(transparentGreen);
+ MATCH_DONT_CARE(transparentBlue);
+ MATCH_DONT_CARE(transparentAlpha);
+ break;
+
+ case GLX_TRANSPARENT_INDEX:
+ MATCH_DONT_CARE(transparentIndex);
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return True;
}
@@ -1125,39 +1194,39 @@ fbconfigs_compatible( const __GLcontextModes * const a,
* Well, that's really hard to do with the code as-is. This behavior is
* closer to correct, but still not technically right.
*/
-#define PREFER_LARGER_OR_ZERO(comp) \
- do { \
- if ( ((*a)-> comp) != ((*b)-> comp) ) { \
- if ( ((*a)-> comp) == 0 ) { \
- return -1; \
- } \
- else if ( ((*b)-> comp) == 0 ) { \
- return 1; \
- } \
- else { \
- return ((*b)-> comp) - ((*a)-> comp) ; \
- } \
- } \
- } while( 0 )
-
-#define PREFER_LARGER(comp) \
- do { \
- if ( ((*a)-> comp) != ((*b)-> comp) ) { \
- return ((*b)-> comp) - ((*a)-> comp) ; \
- } \
- } while( 0 )
-
-#define PREFER_SMALLER(comp) \
- do { \
- if ( ((*a)-> comp) != ((*b)-> comp) ) { \
- return ((*a)-> comp) - ((*b)-> comp) ; \
- } \
- } while( 0 )
+#define PREFER_LARGER_OR_ZERO(comp) \
+ do { \
+ if ( ((*a)-> comp) != ((*b)-> comp) ) { \
+ if ( ((*a)-> comp) == 0 ) { \
+ return -1; \
+ } \
+ else if ( ((*b)-> comp) == 0 ) { \
+ return 1; \
+ } \
+ else { \
+ return ((*b)-> comp) - ((*a)-> comp) ; \
+ } \
+ } \
+ } while( 0 )
+
+#define PREFER_LARGER(comp) \
+ do { \
+ if ( ((*a)-> comp) != ((*b)-> comp) ) { \
+ return ((*b)-> comp) - ((*a)-> comp) ; \
+ } \
+ } while( 0 )
+
+#define PREFER_SMALLER(comp) \
+ do { \
+ if ( ((*a)-> comp) != ((*b)-> comp) ) { \
+ return ((*a)-> comp) - ((*b)-> comp) ; \
+ } \
+ } while( 0 )
/**
* Compare two GLXFBConfigs. This function is intended to be used as the
* compare function passed in to qsort.
- *
+ *
* \returns If \c a is a "better" config, according to the specification of
* SGIX_fbconfig, a number less than zero is returned. If \c b is
* better, then a number greater than zero is return. If both are
@@ -1165,66 +1234,66 @@ fbconfigs_compatible( const __GLcontextModes * const a,
* \sa qsort, glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
*/
static int
-fbconfig_compare( const __GLcontextModes * const * const a,
- const __GLcontextModes * const * const b )
+fbconfig_compare(const __GLcontextModes * const *const a,
+ const __GLcontextModes * const *const b)
{
- /* The order of these comparisons must NOT change. It is defined by
- * the GLX 1.3 spec and ARB_multisample.
- */
+ /* The order of these comparisons must NOT change. It is defined by
+ * the GLX 1.3 spec and ARB_multisample.
+ */
- PREFER_SMALLER( visualSelectGroup );
+ PREFER_SMALLER(visualSelectGroup);
- /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
- * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
- * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
- */
- PREFER_SMALLER( visualRating );
+ /* The sort order for the visualRating is GLX_NONE, GLX_SLOW, and
+ * GLX_NON_CONFORMANT_CONFIG. It just so happens that this is the
+ * numerical sort order of the enums (0x8000, 0x8001, and 0x800D).
+ */
+ PREFER_SMALLER(visualRating);
- /* This isn't quite right. It is supposed to compare the sum of the
- * components the user specifically set minimums for.
- */
- PREFER_LARGER_OR_ZERO( redBits );
- PREFER_LARGER_OR_ZERO( greenBits );
- PREFER_LARGER_OR_ZERO( blueBits );
- PREFER_LARGER_OR_ZERO( alphaBits );
+ /* This isn't quite right. It is supposed to compare the sum of the
+ * components the user specifically set minimums for.
+ */
+ PREFER_LARGER_OR_ZERO(redBits);
+ PREFER_LARGER_OR_ZERO(greenBits);
+ PREFER_LARGER_OR_ZERO(blueBits);
+ PREFER_LARGER_OR_ZERO(alphaBits);
- PREFER_SMALLER( rgbBits );
+ PREFER_SMALLER(rgbBits);
- if ( ((*a)->doubleBufferMode != (*b)->doubleBufferMode) ) {
- /* Prefer single-buffer.
- */
- return ( !(*a)->doubleBufferMode ) ? -1 : 1;
- }
+ if (((*a)->doubleBufferMode != (*b)->doubleBufferMode)) {
+ /* Prefer single-buffer.
+ */
+ return (!(*a)->doubleBufferMode) ? -1 : 1;
+ }
- PREFER_SMALLER( numAuxBuffers );
+ PREFER_SMALLER(numAuxBuffers);
- PREFER_LARGER_OR_ZERO( depthBits );
- PREFER_SMALLER( stencilBits );
+ PREFER_LARGER_OR_ZERO(depthBits);
+ PREFER_SMALLER(stencilBits);
- /* This isn't quite right. It is supposed to compare the sum of the
- * components the user specifically set minimums for.
- */
- PREFER_LARGER_OR_ZERO( accumRedBits );
- PREFER_LARGER_OR_ZERO( accumGreenBits );
- PREFER_LARGER_OR_ZERO( accumBlueBits );
- PREFER_LARGER_OR_ZERO( accumAlphaBits );
+ /* This isn't quite right. It is supposed to compare the sum of the
+ * components the user specifically set minimums for.
+ */
+ PREFER_LARGER_OR_ZERO(accumRedBits);
+ PREFER_LARGER_OR_ZERO(accumGreenBits);
+ PREFER_LARGER_OR_ZERO(accumBlueBits);
+ PREFER_LARGER_OR_ZERO(accumAlphaBits);
- PREFER_SMALLER( visualType );
+ PREFER_SMALLER(visualType);
- /* None of the multisample specs say where this comparison should happen,
- * so I put it near the end.
- */
- PREFER_SMALLER( sampleBuffers );
- PREFER_SMALLER( samples );
+ /* None of the multisample specs say where this comparison should happen,
+ * so I put it near the end.
+ */
+ PREFER_SMALLER(sampleBuffers);
+ PREFER_SMALLER(samples);
- /* None of the pbuffer or fbconfig specs say that this comparison needs
- * to happen at all, but it seems like it should.
- */
- PREFER_LARGER( maxPbufferWidth );
- PREFER_LARGER( maxPbufferHeight );
- PREFER_LARGER( maxPbufferPixels );
+ /* None of the pbuffer or fbconfig specs say that this comparison needs
+ * to happen at all, but it seems like it should.
+ */
+ PREFER_LARGER(maxPbufferWidth);
+ PREFER_LARGER(maxPbufferHeight);
+ PREFER_LARGER(maxPbufferPixels);
- return 0;
+ return 0;
}
@@ -1232,7 +1301,7 @@ fbconfig_compare( const __GLcontextModes * const * const a,
* Selects and sorts a subset of the supplied configs based on the attributes.
* This function forms to basis of \c glXChooseVisual, \c glXChooseFBConfig,
* and \c glXChooseFBConfigSGIX.
- *
+ *
* \param configs Array of pointers to possible configs. The elements of
* this array that do not meet the criteria will be set to
* NULL. The remaining elements will be sorted according to
@@ -1247,53 +1316,52 @@ fbconfig_compare( const __GLcontextModes * const * const a,
* \c glXChooseVisual style or
* \c glXChooseFBConfig style.
* \returns The number of valid elements left in \c configs.
- *
+ *
* \sa glXChooseVisual, glXChooseFBConfig, glXChooseFBConfigSGIX
*/
static int
-choose_visual( __GLcontextModes ** configs, int num_configs,
- const int *attribList, GLboolean fbconfig_style_tags )
-{
- __GLcontextModes test_config;
- int base;
- int i;
-
- /* This is a fairly direct implementation of the selection method
- * described by GLX_SGIX_fbconfig. Start by culling out all the
- * configs that are not compatible with the selected parameter
- * list.
- */
-
- init_fbconfig_for_chooser( & test_config, fbconfig_style_tags );
- __glXInitializeVisualConfigFromTags( & test_config, 512,
- (const INT32 *) attribList,
- GL_TRUE, fbconfig_style_tags );
-
- base = 0;
- for ( i = 0 ; i < num_configs ; i++ ) {
- if ( fbconfigs_compatible( & test_config, configs[i] ) ) {
- configs[ base ] = configs[ i ];
- base++;
- }
- }
-
- if ( base == 0 ) {
- return 0;
- }
-
- if ( base < num_configs ) {
- (void) memset( & configs[ base ], 0,
- sizeof( void * ) * (num_configs - base) );
- }
-
- /* After the incompatible configs are removed, the resulting
- * list is sorted according to the rules set out in the various
- * specifications.
- */
-
- qsort( configs, base, sizeof( __GLcontextModes * ),
- (int (*)(const void*, const void*)) fbconfig_compare );
- return base;
+choose_visual(__GLcontextModes ** configs, int num_configs,
+ const int *attribList, GLboolean fbconfig_style_tags)
+{
+ __GLcontextModes test_config;
+ int base;
+ int i;
+
+ /* This is a fairly direct implementation of the selection method
+ * described by GLX_SGIX_fbconfig. Start by culling out all the
+ * configs that are not compatible with the selected parameter
+ * list.
+ */
+
+ init_fbconfig_for_chooser(&test_config, fbconfig_style_tags);
+ __glXInitializeVisualConfigFromTags(&test_config, 512,
+ (const INT32 *) attribList,
+ GL_TRUE, fbconfig_style_tags);
+
+ base = 0;
+ for (i = 0; i < num_configs; i++) {
+ if (fbconfigs_compatible(&test_config, configs[i])) {
+ configs[base] = configs[i];
+ base++;
+ }
+ }
+
+ if (base == 0) {
+ return 0;
+ }
+
+ if (base < num_configs) {
+ (void) memset(&configs[base], 0, sizeof(void *) * (num_configs - base));
+ }
+
+ /* After the incompatible configs are removed, the resulting
+ * list is sorted according to the rules set out in the various
+ * specifications.
+ */
+
+ qsort(configs, base, sizeof(__GLcontextModes *),
+ (int (*)(const void *, const void *)) fbconfig_compare);
+ return base;
}
@@ -1303,33 +1371,34 @@ choose_visual( __GLcontextModes ** configs, int num_configs,
** Return the visual that best matches the template. Return None if no
** visual matches the template.
*/
-PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
+PUBLIC XVisualInfo *
+glXChooseVisual(Display * dpy, int screen, int *attribList)
{
- XVisualInfo *visualList = NULL;
- __GLXdisplayPrivate *priv;
- __GLXscreenConfigs *psc;
- __GLcontextModes test_config;
- __GLcontextModes *modes;
- const __GLcontextModes *best_config = NULL;
+ XVisualInfo *visualList = NULL;
+ __GLXdisplayPrivate *priv;
+ __GLXscreenConfigs *psc;
+ __GLcontextModes test_config;
+ __GLcontextModes *modes;
+ const __GLcontextModes *best_config = NULL;
- /*
+ /*
** Get a list of all visuals, return if list is empty
*/
- if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
- return None;
- }
-
+ if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
+ return None;
+ }
+
- /*
+ /*
** Build a template from the defaults and the attribute list
** Free visual list and return if an unexpected token is encountered
*/
- init_fbconfig_for_chooser( & test_config, GL_FALSE );
- __glXInitializeVisualConfigFromTags( & test_config, 512,
- (const INT32 *) attribList,
- GL_TRUE, GL_FALSE );
+ init_fbconfig_for_chooser(&test_config, GL_FALSE);
+ __glXInitializeVisualConfigFromTags(&test_config, 512,
+ (const INT32 *) attribList,
+ GL_TRUE, GL_FALSE);
- /*
+ /*
** Eliminate visuals that don't meet minimum requirements
** Compute a score for those that do
** Remember which visual, if any, got the highest score
@@ -1337,136 +1406,141 @@ PUBLIC XVisualInfo *glXChooseVisual(Display *dpy, int screen, int *attribList)
** Otherwise, create an XVisualInfo list with just the selected X visual
** and return this.
*/
- for ( modes = psc->visuals ; modes != NULL ; modes = modes->next ) {
- if ( fbconfigs_compatible( & test_config, modes )
- && ((best_config == NULL)
- || (fbconfig_compare( (const __GLcontextModes * const * const)&modes, &best_config ) < 0)) ) {
- XVisualInfo visualTemplate;
- XVisualInfo *newList;
- int i;
-
- visualTemplate.screen = screen;
- visualTemplate.visualid = modes->visualID;
- newList = XGetVisualInfo( dpy, VisualScreenMask|VisualIDMask,
- &visualTemplate, &i );
-
- if (newList) {
- Xfree(visualList);
- visualList = newList;
- best_config = modes;
- }
- }
- }
+ for (modes = psc->visuals; modes != NULL; modes = modes->next) {
+ if (fbconfigs_compatible(&test_config, modes)
+ && ((best_config == NULL)
+ ||
+ (fbconfig_compare
+ ((const __GLcontextModes * const *const) &modes,
+ &best_config) < 0))) {
+ XVisualInfo visualTemplate;
+ XVisualInfo *newList;
+ int i;
+
+ visualTemplate.screen = screen;
+ visualTemplate.visualid = modes->visualID;
+ newList = XGetVisualInfo(dpy, VisualScreenMask | VisualIDMask,
+ &visualTemplate, &i);
+
+ if (newList) {
+ Xfree(visualList);
+ visualList = newList;
+ best_config = modes;
+ }
+ }
+ }
- return visualList;
+ return visualList;
}
-PUBLIC const char *glXQueryExtensionsString( Display *dpy, int screen )
+PUBLIC const char *
+glXQueryExtensionsString(Display * dpy, int screen)
{
- __GLXscreenConfigs *psc;
- __GLXdisplayPrivate *priv;
+ __GLXscreenConfigs *psc;
+ __GLXdisplayPrivate *priv;
- if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
- return NULL;
- }
+ if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
+ return NULL;
+ }
- if (!psc->effectiveGLXexts) {
- if (!psc->serverGLXexts) {
- psc->serverGLXexts =
- __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
- }
+ if (!psc->effectiveGLXexts) {
+ if (!psc->serverGLXexts) {
+ psc->serverGLXexts =
+ __glXQueryServerString(dpy, priv->majorOpcode, screen,
+ GLX_EXTENSIONS);
+ }
- __glXCalculateUsableExtensions(psc,
+ __glXCalculateUsableExtensions(psc,
#ifdef GLX_DIRECT_RENDERING
- (psc->driScreen != NULL),
+ (psc->driScreen != NULL),
#else
- GL_FALSE,
+ GL_FALSE,
#endif
- priv->minorVersion);
- }
+ priv->minorVersion);
+ }
- return psc->effectiveGLXexts;
+ return psc->effectiveGLXexts;
}
-PUBLIC const char *glXGetClientString( Display *dpy, int name )
+PUBLIC const char *
+glXGetClientString(Display * dpy, int name)
{
- switch(name) {
- case GLX_VENDOR:
- return (__glXGLXClientVendorName);
- case GLX_VERSION:
- return (__glXGLXClientVersion);
- case GLX_EXTENSIONS:
- return (__glXGetClientExtensions());
- default:
- return NULL;
- }
+ switch (name) {
+ case GLX_VENDOR:
+ return (__glXGLXClientVendorName);
+ case GLX_VERSION:
+ return (__glXGLXClientVersion);
+ case GLX_EXTENSIONS:
+ return (__glXGetClientExtensions());
+ default:
+ return NULL;
+ }
}
-PUBLIC const char *glXQueryServerString( Display *dpy, int screen, int name )
+PUBLIC const char *
+glXQueryServerString(Display * dpy, int screen, int name)
{
- __GLXscreenConfigs *psc;
- __GLXdisplayPrivate *priv;
- const char ** str;
+ __GLXscreenConfigs *psc;
+ __GLXdisplayPrivate *priv;
+ const char **str;
- if ( GetGLXPrivScreenConfig( dpy, screen, & priv, & psc ) != Success ) {
- return NULL;
- }
+ if (GetGLXPrivScreenConfig(dpy, screen, &priv, &psc) != Success) {
+ return NULL;
+ }
+
+ switch (name) {
+ case GLX_VENDOR:
+ str = &priv->serverGLXvendor;
+ break;
+ case GLX_VERSION:
+ str = &priv->serverGLXversion;
+ break;
+ case GLX_EXTENSIONS:
+ str = &psc->serverGLXexts;
+ break;
+ default:
+ return NULL;
+ }
- switch(name) {
- case GLX_VENDOR:
- str = & priv->serverGLXvendor;
- break;
- case GLX_VERSION:
- str = & priv->serverGLXversion;
- break;
- case GLX_EXTENSIONS:
- str = & psc->serverGLXexts;
- break;
- default:
- return NULL;
- }
+ if (*str == NULL) {
+ *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
+ }
- if ( *str == NULL ) {
- *str = __glXQueryServerString(dpy, priv->majorOpcode, screen, name);
- }
-
- return *str;
+ return *str;
}
-void __glXClientInfo ( Display *dpy, int opcode )
+void
+__glXClientInfo(Display * dpy, int opcode)
{
- char * ext_str = __glXGetClientGLExtensionString();
- int size = strlen( ext_str ) + 1;
+ char *ext_str = __glXGetClientGLExtensionString();
+ int size = strlen(ext_str) + 1;
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_glx_client_info(c,
- GLX_MAJOR_VERSION,
- GLX_MINOR_VERSION,
- size,
- (const uint8_t *)ext_str);
+ GLX_MAJOR_VERSION, GLX_MINOR_VERSION, size, ext_str);
#else
- xGLXClientInfoReq *req;
-
- /* Send the glXClientInfo request */
- LockDisplay(dpy);
- GetReq(GLXClientInfo,req);
- req->reqType = opcode;
- req->glxCode = X_GLXClientInfo;
- req->major = GLX_MAJOR_VERSION;
- req->minor = GLX_MINOR_VERSION;
-
- req->length += (size + 3) >> 2;
- req->numbytes = size;
- Data(dpy, ext_str, size);
-
- UnlockDisplay(dpy);
- SyncHandle();
+ xGLXClientInfoReq *req;
+
+ /* Send the glXClientInfo request */
+ LockDisplay(dpy);
+ GetReq(GLXClientInfo, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXClientInfo;
+ req->major = GLX_MAJOR_VERSION;
+ req->minor = GLX_MINOR_VERSION;
+
+ req->length += (size + 3) >> 2;
+ req->numbytes = size;
+ Data(dpy, ext_str, size);
+
+ UnlockDisplay(dpy);
+ SyncHandle();
#endif /* USE_XCB */
- Xfree( ext_str );
+ Xfree(ext_str);
}
@@ -1474,194 +1548,201 @@ void __glXClientInfo ( Display *dpy, int opcode )
** EXT_import_context
*/
-PUBLIC Display *glXGetCurrentDisplay(void)
+PUBLIC Display *
+glXGetCurrentDisplay(void)
{
- GLXContext gc = __glXGetCurrentContext();
- if (NULL == gc) return NULL;
- return gc->currentDpy;
+ GLXContext gc = __glXGetCurrentContext();
+ if (NULL == gc)
+ return NULL;
+ return gc->currentDpy;
}
-PUBLIC GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
- glXGetCurrentDisplay)
+PUBLIC
+GLX_ALIAS(Display *, glXGetCurrentDisplayEXT, (void), (),
+ glXGetCurrentDisplay)
/**
* Used internally by libGL to send \c xGLXQueryContextinfoExtReq requests
* to the X-server.
- *
+ *
* \param dpy Display where \c ctx was created.
* \param ctx Context to query.
* \returns \c Success on success. \c GLX_BAD_CONTEXT if \c ctx is invalid,
* or zero if the request failed due to internal problems (i.e.,
* unable to allocate temporary memory, etc.)
- *
+ *
* \note
* This function dynamically determines whether to use the EXT_import_context
* version of the protocol or the GLX 1.3 version of the protocol.
*/
-static int __glXQueryContextInfo(Display *dpy, GLXContext ctx)
-{
- __GLXdisplayPrivate *priv = __glXInitialize(dpy);
- xGLXQueryContextReply reply;
- CARD8 opcode;
- GLuint numValues;
- int retval;
-
- if (ctx == NULL) {
- return GLX_BAD_CONTEXT;
- }
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return 0;
- }
-
- /* Send the glXQueryContextInfoEXT request */
- LockDisplay(dpy);
-
- if ( (priv->majorVersion > 1) || (priv->minorVersion >= 3) ) {
- xGLXQueryContextReq *req;
-
- GetReq(GLXQueryContext, req);
-
- req->reqType = opcode;
- req->glxCode = X_GLXQueryContext;
- req->context = (unsigned int)(ctx->xid);
- }
- else {
- xGLXVendorPrivateReq *vpreq;
- xGLXQueryContextInfoEXTReq *req;
-
- GetReqExtra( GLXVendorPrivate,
- sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
- vpreq );
- req = (xGLXQueryContextInfoEXTReq *)vpreq;
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivateWithReply;
- req->vendorCode = X_GLXvop_QueryContextInfoEXT;
- req->context = (unsigned int)(ctx->xid);
- }
-
- _XReply(dpy, (xReply*) &reply, 0, False);
-
- numValues = reply.n;
- if (numValues == 0)
- retval = Success;
- else if (numValues > __GLX_MAX_CONTEXT_PROPS)
- retval = 0;
- else
- {
- int *propList, *pProp;
- int nPropListBytes;
- int i;
-
- nPropListBytes = numValues << 3;
- propList = (int *) Xmalloc(nPropListBytes);
- if (NULL == propList) {
- retval = 0;
- } else {
- _XRead(dpy, (char *)propList, nPropListBytes);
- pProp = propList;
- for (i=0; i < numValues; i++) {
- switch (*pProp++) {
- case GLX_SHARE_CONTEXT_EXT:
- ctx->share_xid = *pProp++;
- break;
- case GLX_VISUAL_ID_EXT:
- ctx->mode =
- _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
- break;
- case GLX_SCREEN:
- ctx->screen = *pProp++;
- break;
- case GLX_FBCONFIG_ID:
- ctx->mode =
- _gl_context_modes_find_fbconfig(ctx->psc->configs, *pProp++);
- break;
- case GLX_RENDER_TYPE:
- ctx->renderType = *pProp++;
- break;
- default:
- pProp++;
- continue;
- }
- }
- Xfree((char *)propList);
- retval = Success;
- }
- }
- UnlockDisplay(dpy);
- SyncHandle();
- return retval;
+ static int __glXQueryContextInfo(Display * dpy, GLXContext ctx)
+{
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+ xGLXQueryContextReply reply;
+ CARD8 opcode;
+ GLuint numValues;
+ int retval;
+
+ if (ctx == NULL) {
+ return GLX_BAD_CONTEXT;
+ }
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return 0;
+ }
+
+ /* Send the glXQueryContextInfoEXT request */
+ LockDisplay(dpy);
+
+ if ((priv->majorVersion > 1) || (priv->minorVersion >= 3)) {
+ xGLXQueryContextReq *req;
+
+ GetReq(GLXQueryContext, req);
+
+ req->reqType = opcode;
+ req->glxCode = X_GLXQueryContext;
+ req->context = (unsigned int) (ctx->xid);
+ }
+ else {
+ xGLXVendorPrivateReq *vpreq;
+ xGLXQueryContextInfoEXTReq *req;
+
+ GetReqExtra(GLXVendorPrivate,
+ sz_xGLXQueryContextInfoEXTReq - sz_xGLXVendorPrivateReq,
+ vpreq);
+ req = (xGLXQueryContextInfoEXTReq *) vpreq;
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivateWithReply;
+ req->vendorCode = X_GLXvop_QueryContextInfoEXT;
+ req->context = (unsigned int) (ctx->xid);
+ }
+
+ _XReply(dpy, (xReply *) & reply, 0, False);
+
+ numValues = reply.n;
+ if (numValues == 0)
+ retval = Success;
+ else if (numValues > __GLX_MAX_CONTEXT_PROPS)
+ retval = 0;
+ else {
+ int *propList, *pProp;
+ int nPropListBytes;
+ int i;
+
+ nPropListBytes = numValues << 3;
+ propList = (int *) Xmalloc(nPropListBytes);
+ if (NULL == propList) {
+ retval = 0;
+ }
+ else {
+ _XRead(dpy, (char *) propList, nPropListBytes);
+ pProp = propList;
+ for (i = 0; i < numValues; i++) {
+ switch (*pProp++) {
+ case GLX_SHARE_CONTEXT_EXT:
+ ctx->share_xid = *pProp++;
+ break;
+ case GLX_VISUAL_ID_EXT:
+ ctx->mode =
+ _gl_context_modes_find_visual(ctx->psc->visuals, *pProp++);
+ break;
+ case GLX_SCREEN:
+ ctx->screen = *pProp++;
+ break;
+ case GLX_FBCONFIG_ID:
+ ctx->mode =
+ _gl_context_modes_find_fbconfig(ctx->psc->configs,
+ *pProp++);
+ break;
+ case GLX_RENDER_TYPE:
+ ctx->renderType = *pProp++;
+ break;
+ default:
+ pProp++;
+ continue;
+ }
+ }
+ Xfree((char *) propList);
+ retval = Success;
+ }
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ return retval;
}
PUBLIC int
-glXQueryContext(Display *dpy, GLXContext ctx, int attribute, int *value)
+glXQueryContext(Display * dpy, GLXContext ctx, int attribute, int *value)
{
- int retVal;
+ int retVal;
- /* get the information from the server if we don't have it already */
+ /* get the information from the server if we don't have it already */
#ifdef GLX_DIRECT_RENDERING
- if (!ctx->driContext && (ctx->mode == NULL)) {
+ if (!ctx->driContext && (ctx->mode == NULL)) {
#else
- if (ctx->mode == NULL) {
+ if (ctx->mode == NULL) {
#endif
- retVal = __glXQueryContextInfo(dpy, ctx);
- if (Success != retVal) return retVal;
- }
- switch (attribute) {
- case GLX_SHARE_CONTEXT_EXT:
- *value = (int)(ctx->share_xid);
- break;
- case GLX_VISUAL_ID_EXT:
- *value = ctx->mode ? ctx->mode->visualID : None;
- break;
- case GLX_SCREEN:
- *value = (int)(ctx->screen);
- break;
- case GLX_FBCONFIG_ID:
- *value = ctx->mode ? ctx->mode->fbconfigID : None;
- break;
- case GLX_RENDER_TYPE:
- *value = (int)(ctx->renderType);
- break;
- default:
- return GLX_BAD_ATTRIBUTE;
- }
- return Success;
+ retVal = __glXQueryContextInfo(dpy, ctx);
+ if (Success != retVal)
+ return retVal;
+ }
+ switch (attribute) {
+ case GLX_SHARE_CONTEXT_EXT:
+ *value = (int) (ctx->share_xid);
+ break;
+ case GLX_VISUAL_ID_EXT:
+ *value = ctx->mode ? ctx->mode->visualID : None;
+ break;
+ case GLX_SCREEN:
+ *value = (int) (ctx->screen);
+ break;
+ case GLX_FBCONFIG_ID:
+ *value = ctx->mode ? ctx->mode->fbconfigID : None;
+ break;
+ case GLX_RENDER_TYPE:
+ *value = (int) (ctx->renderType);
+ break;
+ default:
+ return GLX_BAD_ATTRIBUTE;
+ }
+ return Success;
}
-PUBLIC GLX_ALIAS( int, glXQueryContextInfoEXT,
- (Display *dpy, GLXContext ctx, int attribute, int *value),
- (dpy, ctx, attribute, value),
- glXQueryContext )
+PUBLIC
+GLX_ALIAS(int, glXQueryContextInfoEXT,
+ (Display * dpy, GLXContext ctx, int attribute, int *value),
+ (dpy, ctx, attribute, value), glXQueryContext)
-PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
+ PUBLIC GLXContextID glXGetContextIDEXT(const GLXContext ctx)
{
- return ctx->xid;
+ return ctx->xid;
}
-PUBLIC GLXContext glXImportContextEXT(Display *dpy, GLXContextID contextID)
+PUBLIC GLXContext
+glXImportContextEXT(Display * dpy, GLXContextID contextID)
{
- GLXContext ctx;
+ GLXContext ctx;
- if (contextID == None) {
- return NULL;
- }
- if (__glXIsDirect(dpy, contextID)) {
- return NULL;
- }
+ if (contextID == None) {
+ return NULL;
+ }
+ if (__glXIsDirect(dpy, contextID)) {
+ return NULL;
+ }
- ctx = CreateContext(dpy, NULL, NULL, NULL, False, contextID, False, 0);
- if (NULL != ctx) {
- if (Success != __glXQueryContextInfo(dpy, ctx)) {
- return NULL;
- }
- }
- return ctx;
+ ctx = CreateContext(dpy, NULL, NULL, NULL, False, contextID, False, 0);
+ if (NULL != ctx) {
+ if (Success != __glXQueryContextInfo(dpy, ctx)) {
+ return NULL;
+ }
+ }
+ return ctx;
}
-PUBLIC void glXFreeContextEXT(Display *dpy, GLXContext ctx)
+PUBLIC void
+glXFreeContextEXT(Display * dpy, GLXContext ctx)
{
- DestroyContext(dpy, ctx);
+ DestroyContext(dpy, ctx);
}
@@ -1670,147 +1751,149 @@ PUBLIC void glXFreeContextEXT(Display *dpy, GLXContext ctx)
* GLX 1.3 functions - these are just stubs for now!
*/
-PUBLIC GLXFBConfig *glXChooseFBConfig(Display *dpy, int screen,
- const int *attribList, int *nitems)
+PUBLIC GLXFBConfig *
+glXChooseFBConfig(Display * dpy, int screen,
+ const int *attribList, int *nitems)
{
- __GLcontextModes ** config_list;
- int list_size;
+ __GLcontextModes **config_list;
+ int list_size;
- config_list = (__GLcontextModes **)
- glXGetFBConfigs( dpy, screen, & list_size );
+ config_list = (__GLcontextModes **)
+ glXGetFBConfigs(dpy, screen, &list_size);
- if ( (config_list != NULL) && (list_size > 0) && (attribList != NULL) ) {
- list_size = choose_visual( config_list, list_size, attribList,
- GL_TRUE );
- if ( list_size == 0 ) {
- XFree( config_list );
- config_list = NULL;
- }
- }
+ if ((config_list != NULL) && (list_size > 0) && (attribList != NULL)) {
+ list_size = choose_visual(config_list, list_size, attribList, GL_TRUE);
+ if (list_size == 0) {
+ XFree(config_list);
+ config_list = NULL;
+ }
+ }
- *nitems = list_size;
- return (GLXFBConfig *) config_list;
+ *nitems = list_size;
+ return (GLXFBConfig *) config_list;
}
-PUBLIC GLXContext glXCreateNewContext(Display *dpy, GLXFBConfig config,
- int renderType, GLXContext shareList,
- Bool allowDirect)
+PUBLIC GLXContext
+glXCreateNewContext(Display * dpy, GLXFBConfig config,
+ int renderType, GLXContext shareList, Bool allowDirect)
{
- return CreateContext( dpy, NULL, (__GLcontextModes *) config, shareList,
- allowDirect, None, True, renderType );
+ return CreateContext(dpy, NULL, (__GLcontextModes *) config, shareList,
+ allowDirect, None, True, renderType);
}
-PUBLIC GLXDrawable glXGetCurrentReadDrawable(void)
+PUBLIC GLXDrawable
+glXGetCurrentReadDrawable(void)
{
- GLXContext gc = __glXGetCurrentContext();
- return gc->currentReadable;
+ GLXContext gc = __glXGetCurrentContext();
+ return gc->currentReadable;
}
-PUBLIC GLXFBConfig *glXGetFBConfigs(Display *dpy, int screen, int *nelements)
+PUBLIC GLXFBConfig *
+glXGetFBConfigs(Display * dpy, int screen, int *nelements)
{
- __GLXdisplayPrivate *priv = __glXInitialize(dpy);
- __GLcontextModes ** config = NULL;
- int i;
+ __GLXdisplayPrivate *priv = __glXInitialize(dpy);
+ __GLcontextModes **config = NULL;
+ int i;
- *nelements = 0;
- if ( priv
- && (priv->screenConfigs != NULL)
- && (screen >= 0) && (screen <= ScreenCount(dpy))
- && (priv->screenConfigs[screen].configs != NULL)
- && (priv->screenConfigs[screen].configs->fbconfigID != GLX_DONT_CARE) ) {
- unsigned num_configs = 0;
- __GLcontextModes * modes;
+ *nelements = 0;
+ if (priv && (priv->screenConfigs != NULL)
+ && (screen >= 0) && (screen <= ScreenCount(dpy))
+ && (priv->screenConfigs[screen].configs != NULL)
+ && (priv->screenConfigs[screen].configs->fbconfigID != GLX_DONT_CARE)) {
+ unsigned num_configs = 0;
+ __GLcontextModes *modes;
- for ( modes = priv->screenConfigs[screen].configs
- ; modes != NULL
- ; modes = modes->next ) {
- if ( modes->fbconfigID != GLX_DONT_CARE ) {
- num_configs++;
- }
- }
+ for (modes = priv->screenConfigs[screen].configs; modes != NULL;
+ modes = modes->next) {
+ if (modes->fbconfigID != GLX_DONT_CARE) {
+ num_configs++;
+ }
+ }
- config = (__GLcontextModes **) Xmalloc( sizeof(__GLcontextModes *)
- * num_configs );
- if ( config != NULL ) {
- *nelements = num_configs;
- i = 0;
- for ( modes = priv->screenConfigs[screen].configs
- ; modes != NULL
- ; modes = modes->next ) {
- if ( modes->fbconfigID != GLX_DONT_CARE ) {
- config[i] = modes;
- i++;
- }
- }
- }
- }
- return (GLXFBConfig *) config;
+ config = (__GLcontextModes **) Xmalloc(sizeof(__GLcontextModes *)
+ * num_configs);
+ if (config != NULL) {
+ *nelements = num_configs;
+ i = 0;
+ for (modes = priv->screenConfigs[screen].configs; modes != NULL;
+ modes = modes->next) {
+ if (modes->fbconfigID != GLX_DONT_CARE) {
+ config[i] = modes;
+ i++;
+ }
+ }
+ }
+ }
+ return (GLXFBConfig *) config;
}
-PUBLIC int glXGetFBConfigAttrib(Display *dpy, GLXFBConfig config,
- int attribute, int *value)
+PUBLIC int
+glXGetFBConfigAttrib(Display * dpy, GLXFBConfig config,
+ int attribute, int *value)
{
- __GLcontextModes * const modes = ValidateGLXFBConfig( dpy, config );
+ __GLcontextModes *const modes = ValidateGLXFBConfig(dpy, config);
- return (modes != NULL)
- ? _gl_get_context_mode_data( modes, attribute, value )
- : GLXBadFBConfig;
+ return (modes != NULL)
+ ? _gl_get_context_mode_data(modes, attribute, value)
+ : GLXBadFBConfig;
}
-PUBLIC XVisualInfo *glXGetVisualFromFBConfig(Display *dpy, GLXFBConfig config)
+PUBLIC XVisualInfo *
+glXGetVisualFromFBConfig(Display * dpy, GLXFBConfig config)
{
- XVisualInfo visualTemplate;
- __GLcontextModes * fbconfig = (__GLcontextModes *) config;
- int count;
+ XVisualInfo visualTemplate;
+ __GLcontextModes *fbconfig = (__GLcontextModes *) config;
+ int count;
- /*
+ /*
** Get a list of all visuals, return if list is empty
*/
- visualTemplate.visualid = fbconfig->visualID;
- return XGetVisualInfo(dpy,VisualIDMask,&visualTemplate,&count);
+ visualTemplate.visualid = fbconfig->visualID;
+ return XGetVisualInfo(dpy, VisualIDMask, &visualTemplate, &count);
}
/*
** GLX_SGI_swap_control
*/
-static int __glXSwapIntervalSGI(int interval)
+static int
+__glXSwapIntervalSGI(int interval)
{
xGLXVendorPrivateReq *req;
GLXContext gc = __glXGetCurrentContext();
- Display * dpy;
- CARD32 * interval_ptr;
+ Display *dpy;
+ CARD32 *interval_ptr;
CARD8 opcode;
- if ( gc == NULL ) {
+ if (gc == NULL) {
return GLX_BAD_CONTEXT;
}
-
- if ( interval <= 0 ) {
+
+ if (interval <= 0) {
return GLX_BAD_VALUE;
}
#ifdef __DRI_SWAP_CONTROL
if (gc->driContext) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
- gc->screen );
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
- gc->currentDrawable,
- NULL);
- if (psc->swapControl != NULL && pdraw != NULL) {
- psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
- return 0;
- }
- else {
- return GLX_BAD_CONTEXT;
- }
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
+ gc->screen);
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(gc->currentDpy,
+ gc->currentDrawable,
+ NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
+ return 0;
+ }
+ else {
+ return GLX_BAD_CONTEXT;
+ }
}
#endif
dpy = gc->currentDpy;
@@ -1821,7 +1904,7 @@ static int __glXSwapIntervalSGI(int interval)
/* Send the glXSwapIntervalSGI request */
LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate,sizeof(CARD32),req);
+ GetReqExtra(GLXVendorPrivate, sizeof(CARD32), req);
req->reqType = opcode;
req->glxCode = X_GLXVendorPrivate;
req->vendorCode = X_GLXvop_SwapIntervalSGI;
@@ -1841,26 +1924,27 @@ static int __glXSwapIntervalSGI(int interval)
/*
** GLX_MESA_swap_control
*/
-static int __glXSwapIntervalMESA(unsigned int interval)
+static int
+__glXSwapIntervalMESA(unsigned int interval)
{
#ifdef __DRI_SWAP_CONTROL
GLXContext gc = __glXGetCurrentContext();
- if ( interval < 0 ) {
+ if (interval < 0) {
return GLX_BAD_VALUE;
}
if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
- gc->screen );
-
- if ( (psc != NULL) && (psc->driScreen != NULL) ) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- if (psc->swapControl != NULL && pdraw != NULL) {
- psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
- return 0;
- }
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
+ gc->screen);
+
+ if ((psc != NULL) && (psc->driScreen != NULL)) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ psc->swapControl->setSwapInterval(pdraw->driDrawable, interval);
+ return 0;
+ }
}
}
#else
@@ -1869,23 +1953,24 @@ static int __glXSwapIntervalMESA(unsigned int interval)
return GLX_BAD_CONTEXT;
}
-
-static int __glXGetSwapIntervalMESA(void)
+
+static int
+__glXGetSwapIntervalMESA(void)
{
#ifdef __DRI_SWAP_CONTROL
GLXContext gc = __glXGetCurrentContext();
if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
- gc->screen );
-
- if ( (psc != NULL) && (psc->driScreen != NULL) ) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- if (psc->swapControl != NULL && pdraw != NULL) {
- return psc->swapControl->getSwapInterval(pdraw->driDrawable);
- }
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
+ gc->screen);
+
+ if ((psc != NULL) && (psc->driScreen != NULL)) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ if (psc->swapControl != NULL && pdraw != NULL) {
+ return psc->swapControl->getSwapInterval(pdraw->driDrawable);
+ }
}
}
#endif
@@ -1898,16 +1983,17 @@ static int __glXGetSwapIntervalMESA(void)
** GLX_MESA_swap_frame_usage
*/
-static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
+static GLint
+__glXBeginFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
{
- int status = GLX_BAD_CONTEXT;
+ int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
- int screen;
+ int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
if (pdraw != NULL && psc->frameTracking != NULL)
- status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
+ status = psc->frameTracking->frameTracking(pdraw->driDrawable, GL_TRUE);
#else
(void) dpy;
(void) drawable;
@@ -1915,18 +2001,19 @@ static GLint __glXBeginFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
return status;
}
-
-static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
+
+static GLint
+__glXEndFrameTrackingMESA(Display * dpy, GLXDrawable drawable)
{
- int status = GLX_BAD_CONTEXT;
+ int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
- int screen;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
+ int screen = 0;
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
__GLXscreenConfigs *psc = GetGLXScreenConfigs(dpy, screen);
if (pdraw != NULL && psc->frameTracking != NULL)
- status = psc->frameTracking->frameTracking(pdraw->driDrawable,
- GL_FALSE);
+ status = psc->frameTracking->frameTracking(pdraw->driDrawable,
+ GL_FALSE);
#else
(void) dpy;
(void) drawable;
@@ -1935,24 +2022,24 @@ static GLint __glXEndFrameTrackingMESA(Display *dpy, GLXDrawable drawable)
}
-static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
- GLfloat *usage)
+static GLint
+__glXGetFrameUsageMESA(Display * dpy, GLXDrawable drawable, GLfloat * usage)
{
- int status = GLX_BAD_CONTEXT;
+ int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
- int screen;
- __GLXDRIdrawable * const pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+ int screen = 0;
+ __GLXDRIdrawable *const pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
if (pdraw != NULL && psc->frameTracking != NULL) {
- int64_t sbc, missedFrames;
- float lastMissedUsage;
+ int64_t sbc, missedFrames;
+ float lastMissedUsage;
- status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
- &sbc,
- &missedFrames,
- &lastMissedUsage,
- usage);
+ status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
+ &sbc,
+ &missedFrames,
+ &lastMissedUsage,
+ usage);
}
#else
(void) dpy;
@@ -1963,22 +2050,24 @@ static GLint __glXGetFrameUsageMESA(Display *dpy, GLXDrawable drawable,
}
-static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
- int64_t *sbc, int64_t *missedFrames,
- GLfloat *lastMissedUsage)
+static GLint
+__glXQueryFrameTrackingMESA(Display * dpy, GLXDrawable drawable,
+ int64_t * sbc, int64_t * missedFrames,
+ GLfloat * lastMissedUsage)
{
- int status = GLX_BAD_CONTEXT;
+ int status = GLX_BAD_CONTEXT;
#ifdef __DRI_FRAME_TRACKING
- int screen;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, & screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
+ int screen = 0;
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
if (pdraw != NULL && psc->frameTracking != NULL) {
- float usage;
+ float usage;
status = psc->frameTracking->queryFrameTracking(pdraw->driDrawable,
- sbc, missedFrames,
- lastMissedUsage, &usage);
+ sbc, missedFrames,
+ lastMissedUsage,
+ &usage);
}
#else
(void) dpy;
@@ -1994,7 +2083,8 @@ static GLint __glXQueryFrameTrackingMESA(Display *dpy, GLXDrawable drawable,
/*
** GLX_SGI_video_sync
*/
-static int __glXGetVideoSyncSGI(unsigned int *count)
+static int
+__glXGetVideoSyncSGI(unsigned int *count)
{
/* FIXME: Looking at the GLX_SGI_video_sync spec in the extension registry,
* FIXME: there should be a GLX encoding for this call. I can find no
@@ -2005,49 +2095,50 @@ static int __glXGetVideoSyncSGI(unsigned int *count)
if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
- gc->screen );
- if ( psc->msc && psc->driScreen ) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- int64_t temp;
- int ret;
-
- ret = (*psc->msc->getDrawableMSC)(psc->__driScreen,
- pdraw->driDrawable, &temp);
- *count = (unsigned) temp;
-
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
+ gc->screen);
+ if (psc->msc && psc->driScreen) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ int64_t temp;
+ int ret;
+
+ ret = (*psc->msc->getDrawableMSC) (psc->__driScreen,
+ pdraw->driDrawable, &temp);
+ *count = (unsigned) temp;
+
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
- (void) count;
+ (void) count;
#endif
return GLX_BAD_CONTEXT;
}
-static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
+static int
+__glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count)
{
#ifdef __DRI_MEDIA_STREAM_COUNTER
GLXContext gc = __glXGetCurrentContext();
- if ( divisor <= 0 || remainder < 0 )
- return GLX_BAD_VALUE;
+ if (divisor <= 0 || remainder < 0)
+ return GLX_BAD_VALUE;
if (gc != NULL && gc->driContext) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( gc->currentDpy,
- gc->screen );
- if (psc->msc != NULL && psc->driScreen ) {
- __GLXDRIdrawable *pdraw =
- GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
- int ret;
- int64_t msc;
- int64_t sbc;
-
- ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, 0,
- divisor, remainder, &msc, &sbc);
- *count = (unsigned) msc;
- return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(gc->currentDpy,
+ gc->screen);
+ if (psc->msc != NULL && psc->driScreen) {
+ __GLXDRIdrawable *pdraw =
+ GetGLXDRIDrawable(gc->currentDpy, gc->currentDrawable, NULL);
+ int ret;
+ int64_t msc;
+ int64_t sbc;
+
+ ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, 0,
+ divisor, remainder, &msc, &sbc);
+ *count = (unsigned) msc;
+ return (ret == 0) ? 0 : GLX_BAD_CONTEXT;
}
}
#else
@@ -2063,109 +2154,112 @@ static int __glXWaitVideoSyncSGI(int divisor, int remainder, unsigned int *count
** GLX_functions table.
*/
-PUBLIC GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
- (Display *dpy, GLXFBConfigSGIX config, int attribute, int *value),
- (dpy, config, attribute, value),
- glXGetFBConfigAttrib)
+PUBLIC
+GLX_ALIAS(int, glXGetFBConfigAttribSGIX,
+ (Display * dpy, GLXFBConfigSGIX config, int attribute, int *value),
+ (dpy, config, attribute, value), glXGetFBConfigAttrib)
-PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
- (Display *dpy, int screen, int *attrib_list, int *nelements),
- (dpy, screen, attrib_list, nelements),
- glXChooseFBConfig)
+ PUBLIC GLX_ALIAS(GLXFBConfigSGIX *, glXChooseFBConfigSGIX,
+ (Display * dpy, int screen, int *attrib_list,
+ int *nelements), (dpy, screen, attrib_list, nelements),
+ glXChooseFBConfig)
-PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
- (Display * dpy, GLXFBConfigSGIX config),
- (dpy, config),
- glXGetVisualFromFBConfig)
+ PUBLIC GLX_ALIAS(XVisualInfo *, glXGetVisualFromFBConfigSGIX,
+ (Display * dpy, GLXFBConfigSGIX config),
+ (dpy, config), glXGetVisualFromFBConfig)
-PUBLIC GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display *dpy,
- GLXFBConfigSGIX config, Pixmap pixmap)
+ PUBLIC GLXPixmap glXCreateGLXPixmapWithConfigSGIX(Display * dpy,
+ GLXFBConfigSGIX config,
+ Pixmap pixmap)
{
- xGLXVendorPrivateWithReplyReq *vpreq;
- xGLXCreateGLXPixmapWithConfigSGIXReq *req;
- GLXPixmap xid = None;
- CARD8 opcode;
- const __GLcontextModes * const fbconfig = (__GLcontextModes *) config;
- __GLXscreenConfigs * psc;
+ xGLXVendorPrivateWithReplyReq *vpreq;
+ xGLXCreateGLXPixmapWithConfigSGIXReq *req;
+ GLXPixmap xid = None;
+ CARD8 opcode;
+ const __GLcontextModes *const fbconfig = (__GLcontextModes *) config;
+ __GLXscreenConfigs *psc;
- if ( (dpy == NULL) || (config == NULL) ) {
- return None;
- }
+ if ((dpy == NULL) || (config == NULL)) {
+ return None;
+ }
- psc = GetGLXScreenConfigs( dpy, fbconfig->screen );
- if ( (psc != NULL)
- && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
- opcode = __glXSetupForCommand(dpy);
- if (!opcode) {
- return None;
- }
+ psc = GetGLXScreenConfigs(dpy, fbconfig->screen);
+ if ((psc != NULL)
+ && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode) {
+ return None;
+ }
- /* Send the glXCreateGLXPixmapWithConfigSGIX request */
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivateWithReply,
- sz_xGLXCreateGLXPixmapWithConfigSGIXReq-sz_xGLXVendorPrivateWithReplyReq,vpreq);
- req = (xGLXCreateGLXPixmapWithConfigSGIXReq *)vpreq;
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivateWithReply;
- req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
- req->screen = fbconfig->screen;
- req->fbconfig = fbconfig->fbconfigID;
- req->pixmap = pixmap;
- req->glxpixmap = xid = XAllocID(dpy);
- UnlockDisplay(dpy);
- SyncHandle();
- }
+ /* Send the glXCreateGLXPixmapWithConfigSGIX request */
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivateWithReply,
+ sz_xGLXCreateGLXPixmapWithConfigSGIXReq -
+ sz_xGLXVendorPrivateWithReplyReq, vpreq);
+ req = (xGLXCreateGLXPixmapWithConfigSGIXReq *) vpreq;
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivateWithReply;
+ req->vendorCode = X_GLXvop_CreateGLXPixmapWithConfigSGIX;
+ req->screen = fbconfig->screen;
+ req->fbconfig = fbconfig->fbconfigID;
+ req->pixmap = pixmap;
+ req->glxpixmap = xid = XAllocID(dpy);
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
- return xid;
+ return xid;
}
-PUBLIC GLXContext glXCreateContextWithConfigSGIX(Display *dpy,
- GLXFBConfigSGIX config, int renderType,
- GLXContext shareList, Bool allowDirect)
+PUBLIC GLXContext
+glXCreateContextWithConfigSGIX(Display * dpy,
+ GLXFBConfigSGIX config, int renderType,
+ GLXContext shareList, Bool allowDirect)
{
- GLXContext gc = NULL;
- const __GLcontextModes * const fbconfig = (__GLcontextModes *) config;
- __GLXscreenConfigs * psc;
+ GLXContext gc = NULL;
+ const __GLcontextModes *const fbconfig = (__GLcontextModes *) config;
+ __GLXscreenConfigs *psc;
- if ( (dpy == NULL) || (config == NULL) ) {
- return None;
- }
+ if ((dpy == NULL) || (config == NULL)) {
+ return None;
+ }
- psc = GetGLXScreenConfigs( dpy, fbconfig->screen );
- if ( (psc != NULL)
- && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit ) ) {
- gc = CreateContext( dpy, NULL, (__GLcontextModes *) config, shareList,
- allowDirect, None, False, renderType );
- }
+ psc = GetGLXScreenConfigs(dpy, fbconfig->screen);
+ if ((psc != NULL)
+ && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)) {
+ gc = CreateContext(dpy, NULL, (__GLcontextModes *) config, shareList,
+ allowDirect, None, False, renderType);
+ }
- return gc;
+ return gc;
}
-PUBLIC GLXFBConfigSGIX glXGetFBConfigFromVisualSGIX(Display *dpy,
- XVisualInfo *vis)
+PUBLIC GLXFBConfigSGIX
+glXGetFBConfigFromVisualSGIX(Display * dpy, XVisualInfo * vis)
{
- __GLXdisplayPrivate *priv;
- __GLXscreenConfigs *psc;
+ __GLXdisplayPrivate *priv;
+ __GLXscreenConfigs *psc = NULL;
- if ( (GetGLXPrivScreenConfig( dpy, vis->screen, & priv, & psc ) != Success)
- && __glXExtensionBitIsEnabled( psc, SGIX_fbconfig_bit )
- && (psc->configs->fbconfigID != GLX_DONT_CARE) ) {
- return (GLXFBConfigSGIX) _gl_context_modes_find_visual( psc->configs,
- vis->visualid );
- }
+ if ((GetGLXPrivScreenConfig(dpy, vis->screen, &priv, &psc) != Success)
+ && __glXExtensionBitIsEnabled(psc, SGIX_fbconfig_bit)
+ && (psc->configs->fbconfigID != GLX_DONT_CARE)) {
+ return (GLXFBConfigSGIX) _gl_context_modes_find_visual(psc->configs,
+ vis->visualid);
+ }
- return NULL;
+ return NULL;
}
/*
** GLX_SGIX_swap_group
*/
-static void __glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
- GLXDrawable member)
+static void
+__glXJoinSwapGroupSGIX(Display * dpy, GLXDrawable drawable,
+ GLXDrawable member)
{
(void) dpy;
(void) drawable;
@@ -2176,15 +2270,16 @@ static void __glXJoinSwapGroupSGIX(Display *dpy, GLXDrawable drawable,
/*
** GLX_SGIX_swap_barrier
*/
-static void __glXBindSwapBarrierSGIX(Display *dpy, GLXDrawable drawable,
- int barrier)
+static void
+__glXBindSwapBarrierSGIX(Display * dpy, GLXDrawable drawable, int barrier)
{
(void) dpy;
(void) drawable;
(void) barrier;
}
-static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
+static Bool
+__glXQueryMaxSwapBarriersSGIX(Display * dpy, int screen, int *max)
{
(void) dpy;
(void) screen;
@@ -2196,23 +2291,24 @@ static Bool __glXQueryMaxSwapBarriersSGIX(Display *dpy, int screen, int *max)
/*
** GLX_OML_sync_control
*/
-static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
- int64_t *ust, int64_t *msc, int64_t *sbc)
+static Bool
+__glXGetSyncValuesOML(Display * dpy, GLXDrawable drawable,
+ int64_t * ust, int64_t * msc, int64_t * sbc)
{
#if defined(__DRI_SWAP_BUFFER_COUNTER) && defined(__DRI_MEDIA_STREAM_COUNTER)
- __GLXdisplayPrivate * const priv = __glXInitialize(dpy);
-
- if ( priv != NULL ) {
- int i;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
- __GLXscreenConfigs * const psc = &priv->screenConfigs[i];
-
- assert( (pdraw == NULL) || (i != -1) );
- return ( (pdraw && psc->sbc && psc->msc)
- && ((*psc->msc->getMSC)(psc->driScreen, msc) == 0)
- && ((*psc->sbc->getSBC)(pdraw->driDrawable, sbc) == 0)
- && (__glXGetUST(ust) == 0) );
- }
+ __GLXdisplayPrivate *const priv = __glXInitialize(dpy);
+
+ if (priv != NULL) {
+ int i;
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &i);
+ __GLXscreenConfigs *const psc = &priv->screenConfigs[i];
+
+ assert((pdraw == NULL) || (i != -1));
+ return ((pdraw && psc->sbc && psc->msc)
+ && ((*psc->msc->getMSC) (psc->driScreen, msc) == 0)
+ && ((*psc->sbc->getSBC) (pdraw->driDrawable, sbc) == 0)
+ && (__glXGetUST(ust) == 0));
+ }
#else
(void) dpy;
(void) drawable;
@@ -2225,94 +2321,94 @@ static Bool __glXGetSyncValuesOML(Display *dpy, GLXDrawable drawable,
#ifdef GLX_DIRECT_RENDERING
_X_HIDDEN GLboolean
-__driGetMscRateOML(__DRIdrawable *draw,
- int32_t *numerator, int32_t *denominator, void *private)
+__driGetMscRateOML(__DRIdrawable * draw,
+ int32_t * numerator, int32_t * denominator, void *private)
{
#ifdef XF86VIDMODE
- __GLXscreenConfigs *psc;
- XF86VidModeModeLine mode_line;
- int dot_clock;
- int i;
- __GLXDRIdrawable *glxDraw = private;
-
- psc = glxDraw->psc;
- if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
- XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line) ) {
- unsigned n = dot_clock * 1000;
- unsigned d = mode_line.vtotal * mode_line.htotal;
-
+ __GLXscreenConfigs *psc;
+ XF86VidModeModeLine mode_line;
+ int dot_clock;
+ int i;
+ __GLXDRIdrawable *glxDraw = private;
+
+ psc = glxDraw->psc;
+ if (XF86VidModeQueryVersion(psc->dpy, &i, &i) &&
+ XF86VidModeGetModeLine(psc->dpy, psc->scr, &dot_clock, &mode_line)) {
+ unsigned n = dot_clock * 1000;
+ unsigned d = mode_line.vtotal * mode_line.htotal;
+
# define V_INTERLACE 0x010
# define V_DBLSCAN 0x020
- if (mode_line.flags & V_INTERLACE)
- n *= 2;
- else if (mode_line.flags & V_DBLSCAN)
- d *= 2;
-
- /* The OML_sync_control spec requires that if the refresh rate is a
- * whole number, that the returned numerator be equal to the refresh
- * rate and the denominator be 1.
- */
-
- if (n % d == 0) {
- n /= d;
- d = 1;
- }
- else {
- static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
-
- /* This is a poor man's way to reduce a fraction. It's far from
- * perfect, but it will work well enough for this situation.
- */
-
- for (i = 0; f[i] != 0; i++) {
- while (n % f[i] == 0 && d % f[i] == 0) {
- d /= f[i];
- n /= f[i];
- }
- }
- }
-
- *numerator = n;
- *denominator = d;
-
- return True;
- }
- else
- return False;
+ if (mode_line.flags & V_INTERLACE)
+ n *= 2;
+ else if (mode_line.flags & V_DBLSCAN)
+ d *= 2;
+
+ /* The OML_sync_control spec requires that if the refresh rate is a
+ * whole number, that the returned numerator be equal to the refresh
+ * rate and the denominator be 1.
+ */
+
+ if (n % d == 0) {
+ n /= d;
+ d = 1;
+ }
+ else {
+ static const unsigned f[] = { 13, 11, 7, 5, 3, 2, 0 };
+
+ /* This is a poor man's way to reduce a fraction. It's far from
+ * perfect, but it will work well enough for this situation.
+ */
+
+ for (i = 0; f[i] != 0; i++) {
+ while (n % f[i] == 0 && d % f[i] == 0) {
+ d /= f[i];
+ n /= f[i];
+ }
+ }
+ }
+
+ *numerator = n;
+ *denominator = d;
+
+ return True;
+ }
+ else
+ return False;
#else
- return False;
+ return False;
#endif
}
#endif
/**
* Determine the refresh rate of the specified drawable and display.
- *
+ *
* \param dpy Display whose refresh rate is to be determined.
* \param drawable Drawable whose refresh rate is to be determined.
* \param numerator Numerator of the refresh rate.
* \param demoninator Denominator of the refresh rate.
* \return If the refresh rate for the specified display and drawable could
* be calculated, True is returned. Otherwise False is returned.
- *
+ *
* \note This function is implemented entirely client-side. A lot of other
* functionality is required to export GLX_OML_sync_control, so on
* XFree86 this function can be called for direct-rendering contexts
* when GLX_OML_sync_control appears in the client extension string.
*/
-_X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
- int32_t * numerator,
- int32_t * denominator)
+_X_HIDDEN GLboolean
+__glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
+ int32_t * numerator, int32_t * denominator)
{
#if defined( GLX_DIRECT_RENDERING ) && defined( XF86VIDMODE )
- __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
+ __GLXDRIdrawable *draw = GetGLXDRIDrawable(dpy, drawable, NULL);
- if (draw == NULL)
- return False;
+ if (draw == NULL)
+ return False;
- return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
+ return __driGetMscRateOML(draw->driDrawable, numerator, denominator, draw);
#else
(void) dpy;
(void) drawable;
@@ -2323,28 +2419,28 @@ _X_HIDDEN GLboolean __glXGetMscRateOML(Display * dpy, GLXDrawable drawable,
}
-static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
- int64_t target_msc, int64_t divisor,
- int64_t remainder)
+static int64_t
+__glXSwapBuffersMscOML(Display * dpy, GLXDrawable drawable,
+ int64_t target_msc, int64_t divisor, int64_t remainder)
{
#ifdef __DRI_SWAP_BUFFER_COUNTER
int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
* error", but it also says "It [glXSwapBuffersMscOML] will return a value
* of -1 if the function failed because of errors detected in the input
* parameters"
*/
- if ( divisor < 0 || remainder < 0 || target_msc < 0 )
+ if (divisor < 0 || remainder < 0 || target_msc < 0)
return -1;
- if ( divisor > 0 && remainder >= divisor )
+ if (divisor > 0 && remainder >= divisor)
return -1;
if (pdraw != NULL && psc->counters != NULL)
- return (*psc->sbc->swapBuffersMSC)(pdraw->driDrawable, target_msc,
- divisor, remainder);
+ return (*psc->sbc->swapBuffersMSC) (pdraw->driDrawable, target_msc,
+ divisor, remainder);
#else
(void) dpy;
@@ -2357,33 +2453,34 @@ static int64_t __glXSwapBuffersMscOML(Display *dpy, GLXDrawable drawable,
}
-static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
- int64_t target_msc, int64_t divisor,
- int64_t remainder, int64_t *ust,
- int64_t *msc, int64_t *sbc)
+static Bool
+__glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
+ int64_t target_msc, int64_t divisor,
+ int64_t remainder, int64_t * ust,
+ int64_t * msc, int64_t * sbc)
{
#ifdef __DRI_MEDIA_STREAM_COUNTER
- int screen;
+ int screen = 0;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
- int ret;
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ int ret;
/* The OML_sync_control spec says these should "generate a GLX_BAD_VALUE
* error", but the return type in the spec is Bool.
*/
- if ( divisor < 0 || remainder < 0 || target_msc < 0 )
+ if (divisor < 0 || remainder < 0 || target_msc < 0)
return False;
- if ( divisor > 0 && remainder >= divisor )
+ if (divisor > 0 && remainder >= divisor)
return False;
if (pdraw != NULL && psc->msc != NULL) {
- ret = (*psc->msc->waitForMSC)(pdraw->driDrawable, target_msc,
- divisor, remainder, msc, sbc);
+ ret = (*psc->msc->waitForMSC) (pdraw->driDrawable, target_msc,
+ divisor, remainder, msc, sbc);
/* __glXGetUST returns zero on success and non-zero on failure.
* This function returns True on success and False on failure.
*/
- return ( (ret == 0) && (__glXGetUST( ust ) == 0) );
+ return ((ret == 0) && (__glXGetUST(ust) == 0));
}
#else
(void) dpy;
@@ -2399,29 +2496,31 @@ static Bool __glXWaitForMscOML(Display * dpy, GLXDrawable drawable,
}
-static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
- int64_t target_sbc, int64_t *ust,
- int64_t *msc, int64_t *sbc )
+static Bool
+__glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
+ int64_t target_sbc, int64_t * ust,
+ int64_t * msc, int64_t * sbc)
{
#ifdef __DRI_SWAP_BUFFER_COUNTER
int screen;
__GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, screen );
- int ret;
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ int ret;
/* The OML_sync_control spec says this should "generate a GLX_BAD_VALUE
* error", but the return type in the spec is Bool.
*/
- if ( target_sbc < 0 )
+ if (target_sbc < 0)
return False;
if (pdraw != NULL && psc->sbc != NULL) {
- ret = (*psc->sbc->waitForSBC)(pdraw->driDrawable, target_sbc, msc, sbc);
+ ret =
+ (*psc->sbc->waitForSBC) (pdraw->driDrawable, target_sbc, msc, sbc);
/* __glXGetUST returns zero on success and non-zero on failure.
* This function returns True on success and False on failure.
*/
- return( (ret == 0) && (__glXGetUST( ust ) == 0) );
+ return ((ret == 0) && (__glXGetUST(ust) == 0));
}
#else
(void) dpy;
@@ -2440,16 +2539,17 @@ static Bool __glXWaitForSbcOML(Display * dpy, GLXDrawable drawable,
*/
/*@{*/
-PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
- size_t size, float readFreq,
- float writeFreq, float priority)
+PUBLIC void *
+glXAllocateMemoryMESA(Display * dpy, int scrn,
+ size_t size, float readFreq,
+ float writeFreq, float priority)
{
#ifdef __DRI_ALLOCATE
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
if (psc && psc->allocate)
- return (*psc->allocate->allocateMemory)(psc->__driScreen, size,
- readFreq, writeFreq, priority);
+ return (*psc->allocate->allocateMemory) (psc->__driScreen, size,
+ readFreq, writeFreq, priority);
#else
(void) dpy;
@@ -2464,13 +2564,14 @@ PUBLIC void *glXAllocateMemoryMESA(Display *dpy, int scrn,
}
-PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
+PUBLIC void
+glXFreeMemoryMESA(Display * dpy, int scrn, void *pointer)
{
#ifdef __DRI_ALLOCATE
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
if (psc && psc->allocate)
- (*psc->allocate->freeMemory)(psc->__driScreen, pointer);
+ (*psc->allocate->freeMemory) (psc->__driScreen, pointer);
#else
(void) dpy;
@@ -2480,14 +2581,14 @@ PUBLIC void glXFreeMemoryMESA(Display *dpy, int scrn, void *pointer)
}
-PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
- const void *pointer )
+PUBLIC GLuint
+glXGetMemoryOffsetMESA(Display * dpy, int scrn, const void *pointer)
{
#ifdef __DRI_ALLOCATE
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs( dpy, scrn );
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, scrn);
if (psc && psc->allocate)
- return (*psc->allocate->memoryOffset)(psc->__driScreen, pointer);
+ return (*psc->allocate->memoryOffset) (psc->__driScreen, pointer);
#else
(void) dpy;
@@ -2497,6 +2598,7 @@ PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
return ~0L;
}
+
/*@}*/
@@ -2527,7 +2629,8 @@ PUBLIC GLuint glXGetMemoryOffsetMESA( Display *dpy, int scrn,
* glXDestroyPbuffer glXDestroyPixmap glXDestroyWindow
* glXDestroyGLXPbufferSGIX glXDestroyGLXVideoSourceSGIX
*/
-static Bool __glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
+static Bool
+__glXReleaseBuffersMESA(Display * dpy, GLXDrawable d)
{
(void) dpy;
(void) d;
@@ -2535,8 +2638,9 @@ static Bool __glXReleaseBuffersMESA( Display *dpy, GLXDrawable d )
}
-PUBLIC GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
- Pixmap pixmap, Colormap cmap )
+PUBLIC GLXPixmap
+glXCreateGLXPixmapMESA(Display * dpy, XVisualInfo * visual,
+ Pixmap pixmap, Colormap cmap)
{
(void) dpy;
(void) visual;
@@ -2544,6 +2648,7 @@ PUBLIC GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
(void) cmap;
return 0;
}
+
/*@}*/
@@ -2551,68 +2656,70 @@ PUBLIC GLXPixmap glXCreateGLXPixmapMESA( Display *dpy, XVisualInfo *visual,
* GLX_MESA_copy_sub_buffer
*/
#define X_GLXvop_CopySubBufferMESA 5154 /* temporary */
-static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
- int x, int y, int width, int height)
+static void
+__glXCopySubBufferMESA(Display * dpy, GLXDrawable drawable,
+ int x, int y, int width, int height)
{
- xGLXVendorPrivateReq *req;
- GLXContext gc;
- GLXContextTag tag;
- CARD32 *drawable_ptr;
- INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
- CARD8 opcode;
+ xGLXVendorPrivateReq *req;
+ GLXContext gc;
+ GLXContextTag tag;
+ CARD32 *drawable_ptr;
+ INT32 *x_ptr, *y_ptr, *w_ptr, *h_ptr;
+ CARD8 opcode;
#ifdef __DRI_COPY_SUB_BUFFER
- int screen;
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
- if ( pdraw != NULL ) {
- __GLXscreenConfigs * const psc = GetGLXScreenConfigs(dpy, screen);
- if (psc->driScreen->copySubBuffer != NULL) {
- glFlush();
- (*psc->driScreen->copySubBuffer)(pdraw, x, y, width, height);
- }
-
- return;
- }
+ int screen;
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, &screen);
+ if (pdraw != NULL) {
+ __GLXscreenConfigs *const psc = GetGLXScreenConfigs(dpy, screen);
+ if (psc->driScreen->copySubBuffer != NULL) {
+ glFlush();
+ (*psc->driScreen->copySubBuffer) (pdraw, x, y, width, height);
+ }
+
+ return;
+ }
#endif
- opcode = __glXSetupForCommand(dpy);
- if (!opcode)
- return;
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode)
+ return;
- /*
+ /*
** The calling thread may or may not have a current context. If it
** does, send the context tag so the server can do a flush.
*/
- gc = __glXGetCurrentContext();
- if ((gc != NULL) && (dpy == gc->currentDpy) &&
- ((drawable == gc->currentDrawable) ||
- (drawable == gc->currentReadable)) ) {
- tag = gc->currentContextTag;
- } else {
- tag = 0;
- }
-
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4,req);
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivate;
- req->vendorCode = X_GLXvop_CopySubBufferMESA;
- req->contextTag = tag;
-
- drawable_ptr = (CARD32 *) (req + 1);
- x_ptr = (INT32 *) (drawable_ptr + 1);
- y_ptr = (INT32 *) (drawable_ptr + 2);
- w_ptr = (INT32 *) (drawable_ptr + 3);
- h_ptr = (INT32 *) (drawable_ptr + 4);
-
- *drawable_ptr = drawable;
- *x_ptr = x;
- *y_ptr = y;
- *w_ptr = width;
- *h_ptr = height;
-
- UnlockDisplay(dpy);
- SyncHandle();
+ gc = __glXGetCurrentContext();
+ if ((gc != NULL) && (dpy == gc->currentDpy) &&
+ ((drawable == gc->currentDrawable) ||
+ (drawable == gc->currentReadable))) {
+ tag = gc->currentContextTag;
+ }
+ else {
+ tag = 0;
+ }
+
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32) * 4, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivate;
+ req->vendorCode = X_GLXvop_CopySubBufferMESA;
+ req->contextTag = tag;
+
+ drawable_ptr = (CARD32 *) (req + 1);
+ x_ptr = (INT32 *) (drawable_ptr + 1);
+ y_ptr = (INT32 *) (drawable_ptr + 2);
+ w_ptr = (INT32 *) (drawable_ptr + 3);
+ h_ptr = (INT32 *) (drawable_ptr + 4);
+
+ *drawable_ptr = drawable;
+ *x_ptr = x;
+ *y_ptr = y;
+ *w_ptr = width;
+ *h_ptr = height;
+
+ UnlockDisplay(dpy);
+ SyncHandle();
}
@@ -2620,128 +2727,127 @@ static void __glXCopySubBufferMESA(Display *dpy, GLXDrawable drawable,
* GLX_EXT_texture_from_pixmap
*/
/*@{*/
-static void __glXBindTexImageEXT(Display *dpy,
- GLXDrawable drawable,
- int buffer,
- const int *attrib_list)
-{
- xGLXVendorPrivateReq *req;
- GLXContext gc = __glXGetCurrentContext();
- CARD32 *drawable_ptr;
- INT32 *buffer_ptr;
- CARD32 *num_attrib_ptr;
- CARD32 *attrib_ptr;
- CARD8 opcode;
- unsigned int i;
-
- if (gc == NULL)
- return;
-
- i = 0;
- if (attrib_list) {
- while (attrib_list[i * 2] != None)
- i++;
- }
-
+static void
+__glXBindTexImageEXT(Display * dpy,
+ GLXDrawable drawable, int buffer, const int *attrib_list)
+{
+ xGLXVendorPrivateReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ CARD32 *drawable_ptr;
+ INT32 *buffer_ptr;
+ CARD32 *num_attrib_ptr;
+ CARD32 *attrib_ptr;
+ CARD8 opcode;
+ unsigned int i;
+
+ if (gc == NULL)
+ return;
+
+ i = 0;
+ if (attrib_list) {
+ while (attrib_list[i * 2] != None)
+ i++;
+ }
+
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext) {
- __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
-
- if (pdraw != NULL) {
- if (pdraw->psc->texBuffer->base.version >= 2 &&
- pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
- (*pdraw->psc->texBuffer->setTexBuffer2)(gc->__driContext,
- pdraw->textureTarget,
- pdraw->textureFormat,
- pdraw->driDrawable);
- } else {
- (*pdraw->psc->texBuffer->setTexBuffer)(gc->__driContext,
- pdraw->textureTarget,
- pdraw->driDrawable);
- }
- }
- return;
- }
+ if (gc->driContext) {
+ __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL);
+
+ if (pdraw != NULL) {
+ if (pdraw->psc->texBuffer->base.version >= 2 &&
+ pdraw->psc->texBuffer->setTexBuffer2 != NULL) {
+ (*pdraw->psc->texBuffer->setTexBuffer2) (gc->__driContext,
+ pdraw->textureTarget,
+ pdraw->textureFormat,
+ pdraw->driDrawable);
+ }
+ else {
+ (*pdraw->psc->texBuffer->setTexBuffer) (gc->__driContext,
+ pdraw->textureTarget,
+ pdraw->driDrawable);
+ }
+ }
+ return;
+ }
#endif
- opcode = __glXSetupForCommand(dpy);
- if (!opcode)
- return;
-
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate, 12 + 8 * i,req);
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivate;
- req->vendorCode = X_GLXvop_BindTexImageEXT;
- req->contextTag = gc->currentContextTag;
-
- drawable_ptr = (CARD32 *) (req + 1);
- buffer_ptr = (INT32 *) (drawable_ptr + 1);
- num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
- attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
-
- *drawable_ptr = drawable;
- *buffer_ptr = buffer;
- *num_attrib_ptr = (CARD32) i;
-
- i = 0;
- if (attrib_list) {
- while (attrib_list[i * 2] != None)
- {
- *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
- *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
- i++;
- }
- }
-
- UnlockDisplay(dpy);
- SyncHandle();
-}
-
-static void __glXReleaseTexImageEXT(Display *dpy,
- GLXDrawable drawable,
- int buffer)
-{
- xGLXVendorPrivateReq *req;
- GLXContext gc = __glXGetCurrentContext();
- CARD32 *drawable_ptr;
- INT32 *buffer_ptr;
- CARD8 opcode;
-
- if (gc == NULL)
- return;
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode)
+ return;
+
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivate, 12 + 8 * i, req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivate;
+ req->vendorCode = X_GLXvop_BindTexImageEXT;
+ req->contextTag = gc->currentContextTag;
+
+ drawable_ptr = (CARD32 *) (req + 1);
+ buffer_ptr = (INT32 *) (drawable_ptr + 1);
+ num_attrib_ptr = (CARD32 *) (buffer_ptr + 1);
+ attrib_ptr = (CARD32 *) (num_attrib_ptr + 1);
+
+ *drawable_ptr = drawable;
+ *buffer_ptr = buffer;
+ *num_attrib_ptr = (CARD32) i;
+
+ i = 0;
+ if (attrib_list) {
+ while (attrib_list[i * 2] != None) {
+ *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 0];
+ *attrib_ptr++ = (CARD32) attrib_list[i * 2 + 1];
+ i++;
+ }
+ }
+
+ UnlockDisplay(dpy);
+ SyncHandle();
+}
+
+static void
+__glXReleaseTexImageEXT(Display * dpy, GLXDrawable drawable, int buffer)
+{
+ xGLXVendorPrivateReq *req;
+ GLXContext gc = __glXGetCurrentContext();
+ CARD32 *drawable_ptr;
+ INT32 *buffer_ptr;
+ CARD8 opcode;
+
+ if (gc == NULL)
+ return;
#ifdef GLX_DIRECT_RENDERING
- if (gc->driContext)
- return;
+ if (gc->driContext)
+ return;
#endif
- opcode = __glXSetupForCommand(dpy);
- if (!opcode)
- return;
+ opcode = __glXSetupForCommand(dpy);
+ if (!opcode)
+ return;
- LockDisplay(dpy);
- GetReqExtra(GLXVendorPrivate, sizeof(CARD32)+sizeof(INT32),req);
- req->reqType = opcode;
- req->glxCode = X_GLXVendorPrivate;
- req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
- req->contextTag = gc->currentContextTag;
+ LockDisplay(dpy);
+ GetReqExtra(GLXVendorPrivate, sizeof(CARD32) + sizeof(INT32), req);
+ req->reqType = opcode;
+ req->glxCode = X_GLXVendorPrivate;
+ req->vendorCode = X_GLXvop_ReleaseTexImageEXT;
+ req->contextTag = gc->currentContextTag;
- drawable_ptr = (CARD32 *) (req + 1);
- buffer_ptr = (INT32 *) (drawable_ptr + 1);
+ drawable_ptr = (CARD32 *) (req + 1);
+ buffer_ptr = (INT32 *) (drawable_ptr + 1);
- *drawable_ptr = drawable;
- *buffer_ptr = buffer;
+ *drawable_ptr = drawable;
+ *buffer_ptr = buffer;
- UnlockDisplay(dpy);
- SyncHandle();
+ UnlockDisplay(dpy);
+ SyncHandle();
}
+
/*@}*/
/**
* \c strdup is actually not a standard ANSI C or POSIX routine.
* Irix will not define it if ANSI mode is in effect.
- *
+ *
* \sa strdup
*/
_X_HIDDEN char *
@@ -2759,7 +2865,8 @@ __glXstrdup(const char *str)
** glXGetProcAddress support
*/
-struct name_address_pair {
+struct name_address_pair
+{
const char *Name;
GLvoid *Address;
};
@@ -2769,139 +2876,139 @@ struct name_address_pair {
static const struct name_address_pair GLX_functions[] = {
/*** GLX_VERSION_1_0 ***/
- GLX_FUNCTION( glXChooseVisual ),
- GLX_FUNCTION( glXCopyContext ),
- GLX_FUNCTION( glXCreateContext ),
- GLX_FUNCTION( glXCreateGLXPixmap ),
- GLX_FUNCTION( glXDestroyContext ),
- GLX_FUNCTION( glXDestroyGLXPixmap ),
- GLX_FUNCTION( glXGetConfig ),
- GLX_FUNCTION( glXGetCurrentContext ),
- GLX_FUNCTION( glXGetCurrentDrawable ),
- GLX_FUNCTION( glXIsDirect ),
- GLX_FUNCTION( glXMakeCurrent ),
- GLX_FUNCTION( glXQueryExtension ),
- GLX_FUNCTION( glXQueryVersion ),
- GLX_FUNCTION( glXSwapBuffers ),
- GLX_FUNCTION( glXUseXFont ),
- GLX_FUNCTION( glXWaitGL ),
- GLX_FUNCTION( glXWaitX ),
+ GLX_FUNCTION(glXChooseVisual),
+ GLX_FUNCTION(glXCopyContext),
+ GLX_FUNCTION(glXCreateContext),
+ GLX_FUNCTION(glXCreateGLXPixmap),
+ GLX_FUNCTION(glXDestroyContext),
+ GLX_FUNCTION(glXDestroyGLXPixmap),
+ GLX_FUNCTION(glXGetConfig),
+ GLX_FUNCTION(glXGetCurrentContext),
+ GLX_FUNCTION(glXGetCurrentDrawable),
+ GLX_FUNCTION(glXIsDirect),
+ GLX_FUNCTION(glXMakeCurrent),
+ GLX_FUNCTION(glXQueryExtension),
+ GLX_FUNCTION(glXQueryVersion),
+ GLX_FUNCTION(glXSwapBuffers),
+ GLX_FUNCTION(glXUseXFont),
+ GLX_FUNCTION(glXWaitGL),
+ GLX_FUNCTION(glXWaitX),
/*** GLX_VERSION_1_1 ***/
- GLX_FUNCTION( glXGetClientString ),
- GLX_FUNCTION( glXQueryExtensionsString ),
- GLX_FUNCTION( glXQueryServerString ),
+ GLX_FUNCTION(glXGetClientString),
+ GLX_FUNCTION(glXQueryExtensionsString),
+ GLX_FUNCTION(glXQueryServerString),
/*** GLX_VERSION_1_2 ***/
- GLX_FUNCTION( glXGetCurrentDisplay ),
+ GLX_FUNCTION(glXGetCurrentDisplay),
/*** GLX_VERSION_1_3 ***/
- GLX_FUNCTION( glXChooseFBConfig ),
- GLX_FUNCTION( glXCreateNewContext ),
- GLX_FUNCTION( glXCreatePbuffer ),
- GLX_FUNCTION( glXCreatePixmap ),
- GLX_FUNCTION( glXCreateWindow ),
- GLX_FUNCTION( glXDestroyPbuffer ),
- GLX_FUNCTION( glXDestroyPixmap ),
- GLX_FUNCTION( glXDestroyWindow ),
- GLX_FUNCTION( glXGetCurrentReadDrawable ),
- GLX_FUNCTION( glXGetFBConfigAttrib ),
- GLX_FUNCTION( glXGetFBConfigs ),
- GLX_FUNCTION( glXGetSelectedEvent ),
- GLX_FUNCTION( glXGetVisualFromFBConfig ),
- GLX_FUNCTION( glXMakeContextCurrent ),
- GLX_FUNCTION( glXQueryContext ),
- GLX_FUNCTION( glXQueryDrawable ),
- GLX_FUNCTION( glXSelectEvent ),
+ GLX_FUNCTION(glXChooseFBConfig),
+ GLX_FUNCTION(glXCreateNewContext),
+ GLX_FUNCTION(glXCreatePbuffer),
+ GLX_FUNCTION(glXCreatePixmap),
+ GLX_FUNCTION(glXCreateWindow),
+ GLX_FUNCTION(glXDestroyPbuffer),
+ GLX_FUNCTION(glXDestroyPixmap),
+ GLX_FUNCTION(glXDestroyWindow),
+ GLX_FUNCTION(glXGetCurrentReadDrawable),
+ GLX_FUNCTION(glXGetFBConfigAttrib),
+ GLX_FUNCTION(glXGetFBConfigs),
+ GLX_FUNCTION(glXGetSelectedEvent),
+ GLX_FUNCTION(glXGetVisualFromFBConfig),
+ GLX_FUNCTION(glXMakeContextCurrent),
+ GLX_FUNCTION(glXQueryContext),
+ GLX_FUNCTION(glXQueryDrawable),
+ GLX_FUNCTION(glXSelectEvent),
/*** GLX_SGI_swap_control ***/
- GLX_FUNCTION2( glXSwapIntervalSGI, __glXSwapIntervalSGI ),
+ GLX_FUNCTION2(glXSwapIntervalSGI, __glXSwapIntervalSGI),
/*** GLX_SGI_video_sync ***/
- GLX_FUNCTION2( glXGetVideoSyncSGI, __glXGetVideoSyncSGI ),
- GLX_FUNCTION2( glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI ),
+ GLX_FUNCTION2(glXGetVideoSyncSGI, __glXGetVideoSyncSGI),
+ GLX_FUNCTION2(glXWaitVideoSyncSGI, __glXWaitVideoSyncSGI),
/*** GLX_SGI_make_current_read ***/
- GLX_FUNCTION2( glXMakeCurrentReadSGI, glXMakeContextCurrent ),
- GLX_FUNCTION2( glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable ),
+ GLX_FUNCTION2(glXMakeCurrentReadSGI, glXMakeContextCurrent),
+ GLX_FUNCTION2(glXGetCurrentReadDrawableSGI, glXGetCurrentReadDrawable),
/*** GLX_EXT_import_context ***/
- GLX_FUNCTION( glXFreeContextEXT ),
- GLX_FUNCTION( glXGetContextIDEXT ),
- GLX_FUNCTION2( glXGetCurrentDisplayEXT, glXGetCurrentDisplay ),
- GLX_FUNCTION( glXImportContextEXT ),
- GLX_FUNCTION2( glXQueryContextInfoEXT, glXQueryContext ),
+ GLX_FUNCTION(glXFreeContextEXT),
+ GLX_FUNCTION(glXGetContextIDEXT),
+ GLX_FUNCTION2(glXGetCurrentDisplayEXT, glXGetCurrentDisplay),
+ GLX_FUNCTION(glXImportContextEXT),
+ GLX_FUNCTION2(glXQueryContextInfoEXT, glXQueryContext),
/*** GLX_SGIX_fbconfig ***/
- GLX_FUNCTION2( glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib ),
- GLX_FUNCTION2( glXChooseFBConfigSGIX, glXChooseFBConfig ),
- GLX_FUNCTION( glXCreateGLXPixmapWithConfigSGIX ),
- GLX_FUNCTION( glXCreateContextWithConfigSGIX ),
- GLX_FUNCTION2( glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig ),
- GLX_FUNCTION( glXGetFBConfigFromVisualSGIX ),
+ GLX_FUNCTION2(glXGetFBConfigAttribSGIX, glXGetFBConfigAttrib),
+ GLX_FUNCTION2(glXChooseFBConfigSGIX, glXChooseFBConfig),
+ GLX_FUNCTION(glXCreateGLXPixmapWithConfigSGIX),
+ GLX_FUNCTION(glXCreateContextWithConfigSGIX),
+ GLX_FUNCTION2(glXGetVisualFromFBConfigSGIX, glXGetVisualFromFBConfig),
+ GLX_FUNCTION(glXGetFBConfigFromVisualSGIX),
/*** GLX_SGIX_pbuffer ***/
- GLX_FUNCTION( glXCreateGLXPbufferSGIX ),
- GLX_FUNCTION( glXDestroyGLXPbufferSGIX ),
- GLX_FUNCTION( glXQueryGLXPbufferSGIX ),
- GLX_FUNCTION( glXSelectEventSGIX ),
- GLX_FUNCTION( glXGetSelectedEventSGIX ),
+ GLX_FUNCTION(glXCreateGLXPbufferSGIX),
+ GLX_FUNCTION(glXDestroyGLXPbufferSGIX),
+ GLX_FUNCTION(glXQueryGLXPbufferSGIX),
+ GLX_FUNCTION(glXSelectEventSGIX),
+ GLX_FUNCTION(glXGetSelectedEventSGIX),
/*** GLX_SGIX_swap_group ***/
- GLX_FUNCTION2( glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX ),
+ GLX_FUNCTION2(glXJoinSwapGroupSGIX, __glXJoinSwapGroupSGIX),
/*** GLX_SGIX_swap_barrier ***/
- GLX_FUNCTION2( glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX ),
- GLX_FUNCTION2( glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX ),
+ GLX_FUNCTION2(glXBindSwapBarrierSGIX, __glXBindSwapBarrierSGIX),
+ GLX_FUNCTION2(glXQueryMaxSwapBarriersSGIX, __glXQueryMaxSwapBarriersSGIX),
/*** GLX_MESA_allocate_memory ***/
- GLX_FUNCTION( glXAllocateMemoryMESA ),
- GLX_FUNCTION( glXFreeMemoryMESA ),
- GLX_FUNCTION( glXGetMemoryOffsetMESA ),
+ GLX_FUNCTION(glXAllocateMemoryMESA),
+ GLX_FUNCTION(glXFreeMemoryMESA),
+ GLX_FUNCTION(glXGetMemoryOffsetMESA),
/*** GLX_MESA_copy_sub_buffer ***/
- GLX_FUNCTION2( glXCopySubBufferMESA, __glXCopySubBufferMESA ),
+ GLX_FUNCTION2(glXCopySubBufferMESA, __glXCopySubBufferMESA),
/*** GLX_MESA_pixmap_colormap ***/
- GLX_FUNCTION( glXCreateGLXPixmapMESA ),
+ GLX_FUNCTION(glXCreateGLXPixmapMESA),
/*** GLX_MESA_release_buffers ***/
- GLX_FUNCTION2( glXReleaseBuffersMESA, __glXReleaseBuffersMESA ),
+ GLX_FUNCTION2(glXReleaseBuffersMESA, __glXReleaseBuffersMESA),
/*** GLX_MESA_swap_control ***/
- GLX_FUNCTION2( glXSwapIntervalMESA, __glXSwapIntervalMESA ),
- GLX_FUNCTION2( glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA ),
+ GLX_FUNCTION2(glXSwapIntervalMESA, __glXSwapIntervalMESA),
+ GLX_FUNCTION2(glXGetSwapIntervalMESA, __glXGetSwapIntervalMESA),
/*** GLX_MESA_swap_frame_usage ***/
- GLX_FUNCTION2( glXBeginFrameTrackingMESA, __glXBeginFrameTrackingMESA ),
- GLX_FUNCTION2( glXEndFrameTrackingMESA, __glXEndFrameTrackingMESA ),
- GLX_FUNCTION2( glXGetFrameUsageMESA, __glXGetFrameUsageMESA ),
- GLX_FUNCTION2( glXQueryFrameTrackingMESA, __glXQueryFrameTrackingMESA ),
+ GLX_FUNCTION2(glXBeginFrameTrackingMESA, __glXBeginFrameTrackingMESA),
+ GLX_FUNCTION2(glXEndFrameTrackingMESA, __glXEndFrameTrackingMESA),
+ GLX_FUNCTION2(glXGetFrameUsageMESA, __glXGetFrameUsageMESA),
+ GLX_FUNCTION2(glXQueryFrameTrackingMESA, __glXQueryFrameTrackingMESA),
/*** GLX_ARB_get_proc_address ***/
- GLX_FUNCTION( glXGetProcAddressARB ),
+ GLX_FUNCTION(glXGetProcAddressARB),
/*** GLX 1.4 ***/
- GLX_FUNCTION2( glXGetProcAddress, glXGetProcAddressARB ),
+ GLX_FUNCTION2(glXGetProcAddress, glXGetProcAddressARB),
/*** GLX_OML_sync_control ***/
- GLX_FUNCTION2( glXWaitForSbcOML, __glXWaitForSbcOML ),
- GLX_FUNCTION2( glXWaitForMscOML, __glXWaitForMscOML ),
- GLX_FUNCTION2( glXSwapBuffersMscOML, __glXSwapBuffersMscOML ),
- GLX_FUNCTION2( glXGetMscRateOML, __glXGetMscRateOML ),
- GLX_FUNCTION2( glXGetSyncValuesOML, __glXGetSyncValuesOML ),
+ GLX_FUNCTION2(glXWaitForSbcOML, __glXWaitForSbcOML),
+ GLX_FUNCTION2(glXWaitForMscOML, __glXWaitForMscOML),
+ GLX_FUNCTION2(glXSwapBuffersMscOML, __glXSwapBuffersMscOML),
+ GLX_FUNCTION2(glXGetMscRateOML, __glXGetMscRateOML),
+ GLX_FUNCTION2(glXGetSyncValuesOML, __glXGetSyncValuesOML),
/*** GLX_EXT_texture_from_pixmap ***/
- GLX_FUNCTION2( glXBindTexImageEXT, __glXBindTexImageEXT ),
- GLX_FUNCTION2( glXReleaseTexImageEXT, __glXReleaseTexImageEXT ),
+ GLX_FUNCTION2(glXBindTexImageEXT, __glXBindTexImageEXT),
+ GLX_FUNCTION2(glXReleaseTexImageEXT, __glXReleaseTexImageEXT),
#ifdef GLX_DIRECT_RENDERING
/*** DRI configuration ***/
- GLX_FUNCTION( glXGetScreenDriver ),
- GLX_FUNCTION( glXGetDriverConfig ),
+ GLX_FUNCTION(glXGetScreenDriver),
+ GLX_FUNCTION(glXGetDriverConfig),
#endif
- { NULL, NULL } /* end of list */
+ {NULL, NULL} /* end of list */
};
@@ -2913,7 +3020,7 @@ get_glx_proc_address(const char *funcName)
/* try static functions */
for (i = 0; GLX_functions[i].Name; i++) {
if (strcmp(GLX_functions[i].Name, funcName) == 0)
- return GLX_functions[i].Address;
+ return GLX_functions[i].Address;
}
return NULL;
@@ -2929,9 +3036,9 @@ get_glx_proc_address(const char *funcName)
*
* \sa glXGetProcAddress
*/
-PUBLIC void (*glXGetProcAddressARB(const GLubyte *procName))( void )
+PUBLIC void (*glXGetProcAddressARB(const GLubyte * procName)) (void)
{
- typedef void (*gl_function)( void );
+ typedef void (*gl_function) (void);
gl_function f;
@@ -2943,8 +3050,8 @@ PUBLIC void (*glXGetProcAddressARB(const GLubyte *procName))( void )
*/
f = (gl_function) get_glx_proc_address((const char *) procName);
- if ( (f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
- && (procName[2] != 'X') ) {
+ if ((f == NULL) && (procName[0] == 'g') && (procName[1] == 'l')
+ && (procName[2] != 'X')) {
f = (gl_function) _glapi_get_proc_address((const char *) procName);
}
@@ -2960,9 +3067,9 @@ PUBLIC void (*glXGetProcAddressARB(const GLubyte *procName))( void )
*
* \sa glXGetProcAddressARB
*/
-PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )
+PUBLIC void (*glXGetProcAddress(const GLubyte * procName)) (void)
#if defined(__GNUC__) && !defined(GLX_ALIAS_UNSUPPORTED)
- __attribute__ ((alias ("glXGetProcAddressARB")));
+ __attribute__ ((alias("glXGetProcAddressARB")));
#else
{
return glXGetProcAddressARB(procName);
@@ -2980,24 +3087,26 @@ PUBLIC void (*glXGetProcAddress(const GLubyte *procName))( void )
*
* \param ust Location to store the 64-bit UST
* \returns Zero on success or a negative errno value on failure.
- *
+ *
* \sa glXGetProcAddress, PFNGLXGETUSTPROC
*
* \since Internal API version 20030317.
*/
-_X_HIDDEN int __glXGetUST( int64_t * ust )
-{
- struct timeval tv;
-
- if ( ust == NULL ) {
- return -EFAULT;
- }
-
- if ( gettimeofday( & tv, NULL ) == 0 ) {
- ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
- return 0;
- } else {
- return -errno;
- }
+_X_HIDDEN int
+__glXGetUST(int64_t * ust)
+{
+ struct timeval tv;
+
+ if (ust == NULL) {
+ return -EFAULT;
+ }
+
+ if (gettimeofday(&tv, NULL) == 0) {
+ ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec;
+ return 0;
+ }
+ else {
+ return -errno;
+ }
}
#endif /* GLX_DIRECT_RENDERING */
diff --git a/src/glx/x11/glxcurrent.c b/src/glx/x11/glxcurrent.c
index d44e0dd1fc..f1e3e161be 100644
--- a/src/glx/x11/glxcurrent.c
+++ b/src/glx/x11/glxcurrent.c
@@ -73,45 +73,7 @@ static __GLapi *IndirectAPI = NULL;
* Current context management and locking
*/
-#if defined( USE_XTHREADS )
-
-/* thread safe */
-static GLboolean TSDinitialized = GL_FALSE;
-static xthread_key_t ContextTSD;
-
-_X_HIDDEN __GLXcontext *
-__glXGetCurrentContext(void)
-{
- if (!TSDinitialized) {
- xthread_key_create(&ContextTSD, NULL);
- TSDinitialized = GL_TRUE;
- return &dummyContext;
- }
- else {
- void *p;
- xthread_get_specific(ContextTSD, &p);
- if (!p)
- return &dummyContext;
- else
- return (__GLXcontext *) p;
- }
-}
-
-_X_HIDDEN void
-__glXSetCurrentContext(__GLXcontext * c)
-{
- if (!TSDinitialized) {
- xthread_key_create(&ContextTSD, NULL);
- TSDinitialized = GL_TRUE;
- }
- xthread_set_specific(ContextTSD, c);
-}
-
-
-/* Used by the __glXLock() and __glXUnlock() macros */
-_X_HIDDEN xmutex_rec __glXmutex;
-
-#elif defined( PTHREADS )
+#if defined( PTHREADS )
_X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
@@ -119,7 +81,7 @@ _X_HIDDEN pthread_mutex_t __glXmutex = PTHREAD_MUTEX_INITIALIZER;
/**
* Per-thread GLX context pointer.
- *
+ *
* \c __glXSetCurrentContext is written is such a way that this pointer can
* \b never be \c NULL. This is important! Because of this
* \c __glXGetCurrentContext can be implemented as trivial macro.
@@ -139,7 +101,7 @@ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
/**
* Per-thread data key.
- *
+ *
* Once \c init_thread_data has been called, the per-thread data key will
* take a value of \c NULL. As each new thread is created the default
* value, in that thread, will be \c NULL.
@@ -148,7 +110,7 @@ static pthread_key_t ContextTSD;
/**
* Initialize the per-thread data key.
- *
+ *
* This function is called \b exactly once per-process (not per-thread!) to
* initialize the per-thread data key. This is ideally done using the
* \c pthread_once mechanism.
@@ -340,8 +302,8 @@ FetchDRIDrawable(Display * dpy, GLXDrawable glxDrawable, GLXContext gc)
#endif /* GLX_DIRECT_RENDERING */
static void
-__glXGenerateError(Display *dpy, GLXContext gc, XID resource,
- BYTE errorCode, CARD16 minorCode)
+__glXGenerateError(Display * dpy, GLXContext gc, XID resource,
+ BYTE errorCode, CARD16 minorCode)
{
xError error;
@@ -356,7 +318,7 @@ __glXGenerateError(Display *dpy, GLXContext gc, XID resource,
/**
* Make a particular context current.
- *
+ *
* \note This is in this file so that it can access dummyContext.
*/
static Bool
@@ -385,21 +347,19 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
if (gc == NULL && (draw != None || read != None)) {
__glXGenerateError(dpy, gc, (draw != None) ? draw : read,
- BadMatch, X_GLXMakeContextCurrent);
+ BadMatch, X_GLXMakeContextCurrent);
return False;
}
if (gc != NULL && (draw == None || read == None)) {
- __glXGenerateError(dpy, gc, None,
- BadMatch, X_GLXMakeContextCurrent);
+ __glXGenerateError(dpy, gc, None, BadMatch, X_GLXMakeContextCurrent);
return False;
}
_glapi_check_multithread();
- if (gc != NULL && gc->thread_id != 0 &&
- gc->thread_id != _glthread_GetID()) {
+ if (gc != NULL && gc->thread_id != 0 && gc->thread_id != _glthread_GetID()) {
__glXGenerateError(dpy, gc, gc->xid,
- BadAccess, X_GLXMakeContextCurrent);
+ BadAccess, X_GLXMakeContextCurrent);
return False;
}
@@ -411,7 +371,7 @@ MakeContextCurrent(Display * dpy, GLXDrawable draw,
if ((pdraw == NULL) || (pread == NULL)) {
__glXGenerateError(dpy, gc, (pdraw == NULL) ? draw : read,
- GLXBadDrawable, X_GLXMakeContextCurrent);
+ GLXBadDrawable, X_GLXMakeContextCurrent);
return False;
}
@@ -559,6 +519,5 @@ GLX_ALIAS(Bool, glXMakeCurrentReadSGI,
PUBLIC
GLX_ALIAS(Bool, glXMakeContextCurrent,
- (Display * dpy, GLXDrawable d, GLXDrawable r,
- GLXContext ctx), (dpy, d, r, ctx),
- MakeContextCurrent)
+ (Display * dpy, GLXDrawable d, GLXDrawable r,
+ GLXContext ctx), (dpy, d, r, ctx), MakeContextCurrent)
diff --git a/src/glx/x11/glxext.c b/src/glx/x11/glxext.c
index b296b7c651..e5553cbf76 100644
--- a/src/glx/x11/glxext.c
+++ b/src/glx/x11/glxext.c
@@ -102,19 +102,19 @@ static
XEXT_GENERATE_ERROR_STRING(__glXErrorString, __glXExtensionName,
__GLX_NUMBER_ERRORS, error_list)
- static /* const */ XExtensionHooks __glXExtensionHooks = {
- NULL, /* create_gc */
- NULL, /* copy_gc */
- NULL, /* flush_gc */
- NULL, /* free_gc */
- NULL, /* create_font */
- NULL, /* free_font */
- __glXCloseDisplay, /* close_display */
- NULL, /* wire_to_event */
- NULL, /* event_to_wire */
- NULL, /* error */
- __glXErrorString, /* error_string */
- };
+static /* const */ XExtensionHooks __glXExtensionHooks = {
+ NULL, /* create_gc */
+ NULL, /* copy_gc */
+ NULL, /* flush_gc */
+ NULL, /* free_gc */
+ NULL, /* create_font */
+ NULL, /* free_font */
+ __glXCloseDisplay, /* close_display */
+ NULL, /* wire_to_event */
+ NULL, /* event_to_wire */
+ NULL, /* error */
+ __glXErrorString, /* error_string */
+};
static
XEXT_GENERATE_FIND_DISPLAY(__glXFindDisplay, __glXExtensionInfo,
@@ -149,6 +149,12 @@ FreeScreenConfigs(__GLXdisplayPrivate * priv)
Xfree((char *) psc->serverGLXexts);
#ifdef GLX_DIRECT_RENDERING
+ if (psc->driver_configs) {
+ for (unsigned int i = 0; psc->driver_configs[i]; i++)
+ free((__DRIconfig *) psc->driver_configs[i]);
+ free(psc->driver_configs);
+ psc->driver_configs = NULL;
+ }
if (psc->driScreen) {
psc->driScreen->destroyScreen(psc);
__glxHashDestroy(psc->drawHash);
@@ -211,15 +217,14 @@ QueryVersion(Display * dpy, int opcode, int *major, int *minor)
{
#ifdef USE_XCB
xcb_connection_t *c = XGetXCBConnection(dpy);
- xcb_glx_query_version_reply_t* reply =
- xcb_glx_query_version_reply(c,
- xcb_glx_query_version(c,
- GLX_MAJOR_VERSION,
- GLX_MINOR_VERSION),
- NULL);
-
- if(reply->major_version != GLX_MAJOR_VERSION)
- {
+ xcb_glx_query_version_reply_t *reply = xcb_glx_query_version_reply(c,
+ xcb_glx_query_version
+ (c,
+ GLX_MAJOR_VERSION,
+ GLX_MINOR_VERSION),
+ NULL);
+
+ if (reply->major_version != GLX_MAJOR_VERSION) {
free(reply);
return GL_FALSE;
}
@@ -537,7 +542,8 @@ getFBConfigs(Display * dpy, __GLXdisplayPrivate * priv, int screen)
__GLXscreenConfigs *psc;
psc = priv->screenConfigs + screen;
- psc->serverGLXexts = __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
+ psc->serverGLXexts =
+ __glXQueryServerString(dpy, priv->majorOpcode, screen, GLX_EXTENSIONS);
LockDisplay(dpy);
@@ -595,7 +601,8 @@ AllocAndFetchScreenConfigs(Display * dpy, __GLXdisplayPrivate * priv)
memset(psc, 0, screens * sizeof(__GLXscreenConfigs));
priv->screenConfigs = psc;
- priv->serverGLXversion = __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
+ priv->serverGLXversion =
+ __glXQueryServerString(dpy, priv->majorOpcode, 0, GLX_VERSION);
if (priv->serverGLXversion == NULL) {
FreeScreenConfigs(priv);
return GL_FALSE;
@@ -646,17 +653,6 @@ __glXInitialize(Display * dpy)
Bool glx_direct, glx_accel;
#endif
-#if defined(USE_XTHREADS)
- {
- static int firstCall = 1;
- if (firstCall) {
- /* initialize the GLX mutexes */
- xmutex_init(&__glXmutex);
- firstCall = 0;
- }
- }
-#endif
-
/* The one and only long long lock */
__glXLock();
@@ -791,10 +787,10 @@ __glXSetupForCommand(Display * dpy)
/**
* Flush the drawing command transport buffer.
- *
+ *
* \param ctx Context whose transport buffer is to be flushed.
* \param pc Pointer to first unused buffer location.
- *
+ *
* \todo
* Modify this function to use \c ctx->pc instead of the explicit
* \c pc parameter.
@@ -886,11 +882,11 @@ __glXSendLargeChunk(__GLXcontext * gc, GLint requestNumber,
/**
* Send a command that is too large for the GLXRender protocol request.
- *
+ *
* Send a large command, one that is too large for some reason to
* send using the GLXRender protocol request. One reason to send
* a large command is to avoid copying the data.
- *
+ *
* \param ctx GLX context
* \param header Header data.
* \param headerLen Size, in bytes, of the header data. It is assumed that
diff --git a/src/glx/x11/glxextensions.c b/src/glx/x11/glxextensions.c
index 051433a006..473f46d1e5 100644
--- a/src/glx/x11/glxextensions.c
+++ b/src/glx/x11/glxextensions.c
@@ -315,10 +315,10 @@ set_glx_extension(const struct extension_info *ext,
/**
* Convert the server's extension string to a bit-field.
- *
+ *
* \param server_string GLX extension string from the server.
* \param server_support Bit-field of supported extensions.
- *
+ *
* \note
* This function is used to process both GLX and GL extension strings. The
* bit-fields used to track each of these have different sizes. Therefore,
@@ -336,8 +336,7 @@ __glXProcessServerString(const struct extension_info *ext,
/* Determine the length of the next extension name.
*/
for (len = 0; (server_string[base + len] != SEPARATOR)
- && (server_string[base + len] != NUL);
- len++) {
+ && (server_string[base + len] != NUL); len++) {
/* empty */
}
@@ -351,8 +350,7 @@ __glXProcessServerString(const struct extension_info *ext,
* over the previous string and any trialing white-space.
*/
for (base += len; (server_string[base] == SEPARATOR)
- && (server_string[base] != NUL);
- base++) {
+ && (server_string[base] != NUL); base++) {
/* empty */
}
}
@@ -549,7 +547,7 @@ __glXGetClientExtensions(void)
/**
* Calculate the list of application usable extensions. The resulting
* string is stored in \c psc->effectiveGLXexts.
- *
+ *
* \param psc Pointer to GLX per-screen record.
* \param display_is_direct_capable True if the display is capable of
* direct rendering.
@@ -600,7 +598,7 @@ __glXCalculateUsableExtensions(__GLXscreenConfigs * psc,
* it and the "server" supports it. In this case that means that either
* the true server supports it or it is only for direct-rendering and
* the direct rendering driver supports it.
- *
+ *
* If the display is not capable of direct rendering, then the extension
* is enabled if and only if the client-side library and the server
* support it.
@@ -609,10 +607,10 @@ __glXCalculateUsableExtensions(__GLXscreenConfigs * psc,
if (display_is_direct_capable) {
for (i = 0; i < 8; i++) {
usable[i] = (client_glx_support[i] & client_glx_only[i])
- | (client_glx_support[i] & psc->
- direct_support[i] & server_support[i])
- | (client_glx_support[i] & psc->
- direct_support[i] & direct_glx_only[i]);
+ | (client_glx_support[i] & psc->direct_support[i] &
+ server_support[i])
+ | (client_glx_support[i] & psc->direct_support[i] &
+ direct_glx_only[i]);
}
}
else {
@@ -630,7 +628,7 @@ __glXCalculateUsableExtensions(__GLXscreenConfigs * psc,
/**
* Calculate the list of application usable extensions. The resulting
* string is stored in \c gc->extensions.
- *
+ *
* \param gc Pointer to GLX context.
* \param server_string Extension string from the server.
* \param major_version GL major version from the server.
diff --git a/src/glx/x11/glxhash.c b/src/glx/x11/glxhash.c
index 74cd4f344d..6f2c51d39d 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/glx/x11/indirect_size.c b/src/glx/x11/indirect_size.c
index 54c039dd6c..cdaf02ffe6 100644
--- a/src/glx/x11/indirect_size.c
+++ b/src/glx/x11/indirect_size.c
@@ -192,6 +192,10 @@ __glTexParameterfv_size(GLenum e)
case GL_TEXTURE_MAX_ANISOTROPY_EXT:
case GL_TEXTURE_LOD_BIAS:
/* case GL_TEXTURE_LOD_BIAS_EXT:*/
+ case GL_TEXTURE_STORAGE_HINT_APPLE:
+ case GL_STORAGE_PRIVATE_APPLE:
+ case GL_STORAGE_CACHED_APPLE:
+ case GL_STORAGE_SHARED_APPLE:
case GL_DEPTH_TEXTURE_MODE:
/* case GL_DEPTH_TEXTURE_MODE_ARB:*/
case GL_TEXTURE_COMPARE_MODE:
diff --git a/src/glx/x11/indirect_vertex_array.c b/src/glx/x11/indirect_vertex_array.c
index bb5232f618..ad9882528f 100644
--- a/src/glx/x11/indirect_vertex_array.c
+++ b/src/glx/x11/indirect_vertex_array.c
@@ -1,18 +1,18 @@
/*
* (C) Copyright IBM Corporation 2004, 2005
* All Rights Reserved.
- *
+ *
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and 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
@@ -39,7 +39,7 @@
/**
* \file indirect_vertex_array.c
* Implement GLX protocol for vertex arrays and vertex buffer objects.
- *
+ *
* The most important function in this fill is \c fill_array_info_cache.
* The \c array_state_vector contains a cache of the ARRAY_INFO data sent
* in the DrawArrays protocol. Certain operations, such as enabling or
@@ -47,7 +47,7 @@
* fills-in this data. Additionally, it examines the enabled state and
* other factors to determine what "version" of DrawArrays protocoal can be
* used.
- *
+ *
* Current, only two versions of DrawArrays protocol are implemented. The
* first version is the "none" protocol. This is the fallback when the
* server does not support GL 1.1 / EXT_vertex_arrays. It is implemented
@@ -90,11 +90,11 @@ static GLboolean validate_type(__GLXcontext * gc, GLenum type);
/**
- * Table of sizes, in bytes, of a GL types. All of the type enums are be in
+ * Table of sizes, in bytes, of a GL types. All of the type enums are be in
* the range 0x1400 - 0x140F. That includes types added by extensions (i.e.,
* \c GL_HALF_FLOAT_NV). This elements of this table correspond to the
* type enums masked with 0x0f.
- *
+ *
* \notes
* \c GL_HALF_FLOAT_NV is not included. Neither are \c GL_2_BYTES,
* \c GL_3_BYTES, or \c GL_4_BYTES.
@@ -131,15 +131,15 @@ __glXFreeVertexArrayState(__GLXcontext * gc)
/**
* Initialize vertex array state of a GLX context.
- *
+ *
* \param gc GLX context whose vertex array state is to be initialized.
- *
+ *
* \warning
* This function may only be called after __GLXcontext::gl_extension_bits,
* __GLXcontext::server_minor, and __GLXcontext::server_major have been
* initialized. These values are used to determine what vertex arrays are
* supported.
- *
+ *
* \bug
* Return values from malloc are not properly tested.
*/
@@ -171,7 +171,7 @@ __glXInitVertexArrayState(__GLXcontext * gc)
* are supported by the server are create. For example, if the server
* supports only 2 texture units, then only 2 texture coordinate arrays
* are created.
- *
+ *
* At the very least, GL_VERTEX_ARRAY, GL_NORMAL_ARRAY,
* GL_COLOR_ARRAY, GL_INDEX_ARRAY, GL_TEXTURE_COORD_ARRAY, and
* GL_EDGE_FLAG_ARRAY are supported.
@@ -532,7 +532,7 @@ emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
/**
* Emit the header data for the GL 1.1 / EXT_vertex_arrays DrawArrays
* protocol.
- *
+ *
* \param gc GLX context.
* \param arrays Array state.
* \param elements_per_request Location to store the number of elements that
@@ -543,7 +543,7 @@ emit_DrawArrays_none(GLenum mode, GLint first, GLsizei count)
* will be zero.
* \param mode Drawing mode.
* \param count Number of vertices.
- *
+ *
* \returns
* A pointer to the buffer for array data.
*/
@@ -594,7 +594,7 @@ emit_DrawArrays_header_old(__GLXcontext * gc,
/* Calculate the number of data packets that will be required to send
* the whole command. To do this, the number of verticies that
* will fit in a single buffer must be calculated.
- *
+ *
* The important value here is elements_per_request. This is the
* number of complete array elements that will fit in a single
* buffer. There may be some wasted space at the end of the buffer,
@@ -869,7 +869,7 @@ emit_DrawElements_old(GLenum mode, GLsizei count, GLenum type,
/**
* Validate that the \c mode parameter to \c glDrawArrays, et. al. is valid.
* If it is not valid, then an error code is set in the GLX context.
- *
+ *
* \returns
* \c GL_TRUE if the argument is valid, \c GL_FALSE if is not.
*/
@@ -902,7 +902,7 @@ validate_mode(__GLXcontext * gc, GLenum mode)
* A value less than zero is invalid and will result in \c GL_INVALID_VALUE
* being set. A value of zero will not result in an error being set, but
* will result in \c GL_FALSE being returned.
- *
+ *
* \returns
* \c GL_TRUE if the argument is valid, \c GL_FALSE if it is not.
*/
@@ -1084,21 +1084,21 @@ __indirect_glMultiDrawElementsEXT(GLenum mode, const GLsizei * count,
#define COMMON_ARRAY_DATA_INIT(a, PTR, TYPE, STRIDE, COUNT, NORMALIZED, HDR_SIZE, OPCODE) \
- do { \
- (a)->data = PTR; \
- (a)->data_type = TYPE; \
- (a)->user_stride = STRIDE; \
- (a)->count = COUNT; \
- (a)->normalized = NORMALIZED; \
- \
- (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
- (a)->true_stride = (STRIDE == 0) \
- ? (a)->element_size : STRIDE; \
- \
- (a)->header_size = HDR_SIZE; \
- ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
- ((uint16_t *) (a)->header)[1] = OPCODE; \
- } while(0)
+ do { \
+ (a)->data = PTR; \
+ (a)->data_type = TYPE; \
+ (a)->user_stride = STRIDE; \
+ (a)->count = COUNT; \
+ (a)->normalized = NORMALIZED; \
+ \
+ (a)->element_size = __glXTypeSize( TYPE ) * COUNT; \
+ (a)->true_stride = (STRIDE == 0) \
+ ? (a)->element_size : STRIDE; \
+ \
+ (a)->header_size = HDR_SIZE; \
+ ((uint16_t *) (a)->header)[0] = __GLX_PAD((a)->header_size + (a)->element_size); \
+ ((uint16_t *) (a)->header)[1] = OPCODE; \
+ } while(0)
void
@@ -1363,36 +1363,36 @@ __indirect_glTexCoordPointer(GLint size, GLenum type, GLsizei stride,
{
static const uint16_t short_ops[5] = {
0, X_GLrop_TexCoord1sv, X_GLrop_TexCoord2sv, X_GLrop_TexCoord3sv,
- X_GLrop_TexCoord4sv
+ X_GLrop_TexCoord4sv
};
static const uint16_t int_ops[5] = {
0, X_GLrop_TexCoord1iv, X_GLrop_TexCoord2iv, X_GLrop_TexCoord3iv,
- X_GLrop_TexCoord4iv
+ X_GLrop_TexCoord4iv
};
static const uint16_t float_ops[5] = {
0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2fv, X_GLrop_TexCoord3fv,
- X_GLrop_TexCoord4fv
+ X_GLrop_TexCoord4fv
};
static const uint16_t double_ops[5] = {
0, X_GLrop_TexCoord1dv, X_GLrop_TexCoord2dv, X_GLrop_TexCoord3dv,
- X_GLrop_TexCoord4dv
+ X_GLrop_TexCoord4dv
};
static const uint16_t mshort_ops[5] = {
0, X_GLrop_MultiTexCoord1svARB, X_GLrop_MultiTexCoord2svARB,
- X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
+ X_GLrop_MultiTexCoord3svARB, X_GLrop_MultiTexCoord4svARB
};
static const uint16_t mint_ops[5] = {
0, X_GLrop_MultiTexCoord1ivARB, X_GLrop_MultiTexCoord2ivARB,
- X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
+ X_GLrop_MultiTexCoord3ivARB, X_GLrop_MultiTexCoord4ivARB
};
static const uint16_t mfloat_ops[5] = {
0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2fvARB,
- X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
+ X_GLrop_MultiTexCoord3fvARB, X_GLrop_MultiTexCoord4fvARB
};
static const uint16_t mdouble_ops[5] = {
0, X_GLrop_MultiTexCoord1dvARB, X_GLrop_MultiTexCoord2dvARB,
- X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
+ X_GLrop_MultiTexCoord3dvARB, X_GLrop_MultiTexCoord4dvARB
};
uint16_t opcode;
diff --git a/src/glx/x11/single2.c b/src/glx/x11/single2.c
index 0b2d5113cc..d128ba2053 100644
--- a/src/glx/x11/single2.c
+++ b/src/glx/x11/single2.c
@@ -147,7 +147,7 @@ __indirect_glGetError(void)
/**
* Get the selected attribute from the client state.
- *
+ *
* \returns
* On success \c GL_TRUE is returned. Otherwise, \c GL_FALSE is returned.
*/
@@ -679,7 +679,8 @@ __indirect_glGetString(GLenum name)
*/
(void) __glXFlushRenderBuffer(gc, gc->pc);
- s = (GLubyte *) __glXGetString(dpy, gc->majorOpcode, gc->currentContextTag, name);
+ s = (GLubyte *) __glXGetString(dpy, gc->majorOpcode, gc->currentContextTag,
+ name);
if (!s) {
/* Throw data on the floor */
__glXSetError(gc, GL_OUT_OF_MEMORY);
@@ -753,7 +754,7 @@ __indirect_glGetString(GLenum name)
* hardware accelerated. For example, a TNT will show core
* version 1.5, but most of the post-1.2 functionality is a
* software fallback.
- *
+ *
* I don't want to break applications that rely on this odd
* behavior. At the same time, the code is written and tested,
* so I didn't want to throw it away. Therefore, the code is here
@@ -766,7 +767,7 @@ __indirect_glGetString(GLenum name)
* gc->server_minor are set. This version may be higher than we
* can completely support, but it may imply support for some
* extensions that we can support.
- *
+ *
* For example, at the time of this writing, the client-side
* library only supports upto core GL version 1.2. However, cubic
* textures, multitexture, multisampling, and some other 1.3
@@ -880,50 +881,50 @@ GLboolean
__indirect_glAreTexturesResident(GLsizei n, const GLuint * textures,
GLboolean * residences)
{
- __GLXcontext *const gc = __glXGetCurrentContext();
- Display *const dpy = gc->currentDpy;
- GLboolean retval = (GLboolean) 0;
- const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
- if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
+ __GLXcontext *const gc = __glXGetCurrentContext();
+ Display *const dpy = gc->currentDpy;
+ GLboolean retval = (GLboolean) 0;
+ const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
#ifdef USE_XCB
- xcb_connection_t *c = XGetXCBConnection(dpy);
- (void) __glXFlushRenderBuffer(gc, gc->pc);
- xcb_glx_are_textures_resident_reply_t *reply =
- xcb_glx_are_textures_resident_reply(c,
- xcb_glx_are_textures_resident
- (c, gc->currentContextTag, n,
- textures), NULL);
- (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
- xcb_glx_are_textures_resident_data_length(reply) *
- sizeof(GLboolean));
- retval = reply->ret_val;
- free(reply);
+ xcb_connection_t *c = XGetXCBConnection(dpy);
+ (void) __glXFlushRenderBuffer(gc, gc->pc);
+ xcb_glx_are_textures_resident_reply_t *reply =
+ xcb_glx_are_textures_resident_reply(c,
+ xcb_glx_are_textures_resident
+ (c, gc->currentContextTag, n,
+ textures), NULL);
+ (void) memcpy(residences, xcb_glx_are_textures_resident_data(reply),
+ xcb_glx_are_textures_resident_data_length(reply) *
+ sizeof(GLboolean));
+ retval = reply->ret_val;
+ free(reply);
#else
- GLubyte const *pc =
- __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen);
- (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
- (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
- if (n & 3) {
- /* n is not a multiple of four.
- * When reply_is_always_array is TRUE, __glXReadReply() will
- * put a multiple of four bytes into the dest buffer. If the
- * caller's buffer is not a multiple of four in size, we'll write
- * out of bounds. So use a temporary buffer that's a few bytes
- * larger.
- */
- GLboolean *res4 = malloc((n + 3) & ~3);
- retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
- memcpy(residences, res4, n);
- free(res4);
- }
- else {
- retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
- }
- UnlockDisplay(dpy);
- SyncHandle();
+ GLubyte const *pc =
+ __glXSetupSingleRequest(gc, X_GLsop_AreTexturesResident, cmdlen);
+ (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
+ (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
+ if (n & 3) {
+ /* n is not a multiple of four.
+ * When reply_is_always_array is TRUE, __glXReadReply() will
+ * put a multiple of four bytes into the dest buffer. If the
+ * caller's buffer is not a multiple of four in size, we'll write
+ * out of bounds. So use a temporary buffer that's a few bytes
+ * larger.
+ */
+ GLboolean *res4 = malloc((n + 3) & ~3);
+ retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
+ memcpy(residences, res4, n);
+ free(res4);
+ }
+ else {
+ retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
#endif /* USE_XCB */
- }
- return retval;
+ }
+ return retval;
}
@@ -936,36 +937,37 @@ GLboolean
glAreTexturesResidentEXT(GLsizei n, const GLuint * textures,
GLboolean * residences)
{
- __GLXcontext *const gc = __glXGetCurrentContext();
-
- if (gc->isDirect) {
- return CALL_AreTexturesResident(GET_DISPATCH(),
- (n, textures, residences));
- } else {
- __GLXcontext *const gc = __glXGetCurrentContext();
- Display *const dpy = gc->currentDpy;
- GLboolean retval = (GLboolean) 0;
- const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
- if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
- GLubyte const *pc =
- __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
- X_GLvop_AreTexturesResidentEXT,
- cmdlen);
- (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
- (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
- if (n & 3) {
- /* see comments in __indirect_glAreTexturesResident() */
- GLboolean *res4 = malloc((n + 3) & ~3);
- retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
- memcpy(residences, res4, n);
- free(res4);
- }
- else {
- retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
- }
- UnlockDisplay(dpy);
- SyncHandle();
- }
- return retval;
- }
+ __GLXcontext *const gc = __glXGetCurrentContext();
+
+ if (gc->isDirect) {
+ return CALL_AreTexturesResident(GET_DISPATCH(),
+ (n, textures, residences));
+ }
+ else {
+ __GLXcontext *const gc = __glXGetCurrentContext();
+ Display *const dpy = gc->currentDpy;
+ GLboolean retval = (GLboolean) 0;
+ const GLuint cmdlen = 4 + __GLX_PAD((n * 4));
+ if (__builtin_expect((n >= 0) && (dpy != NULL), 1)) {
+ GLubyte const *pc =
+ __glXSetupVendorRequest(gc, X_GLXVendorPrivateWithReply,
+ X_GLvop_AreTexturesResidentEXT,
+ cmdlen);
+ (void) memcpy((void *) (pc + 0), (void *) (&n), 4);
+ (void) memcpy((void *) (pc + 4), (void *) (textures), (n * 4));
+ if (n & 3) {
+ /* see comments in __indirect_glAreTexturesResident() */
+ GLboolean *res4 = malloc((n + 3) & ~3);
+ retval = (GLboolean) __glXReadReply(dpy, 1, res4, GL_TRUE);
+ memcpy(residences, res4, n);
+ free(res4);
+ }
+ else {
+ retval = (GLboolean) __glXReadReply(dpy, 1, residences, GL_TRUE);
+ }
+ UnlockDisplay(dpy);
+ SyncHandle();
+ }
+ return retval;
+ }
}
diff --git a/src/mesa/SConscript b/src/mesa/SConscript
index 9ffc15eeb7..cad5676320 100644
--- a/src/mesa/SConscript
+++ b/src/mesa/SConscript
@@ -84,6 +84,7 @@ if env['platform'] != 'winddk':
'main/shared.c',
'main/state.c',
'main/stencil.c',
+ 'main/syncobj.c',
'main/texcompress.c',
'main/texcompress_s3tc.c',
'main/texcompress_fxt1.c',
@@ -187,20 +188,26 @@ if env['platform'] != 'winddk':
'shader/arbprogram.c',
'shader/atifragshader.c',
'shader/grammar/grammar_mesa.c',
+ 'shader/hash_table.c',
+ 'shader/lex.yy.c',
'shader/nvfragparse.c',
'shader/nvprogram.c',
'shader/nvvertparse.c',
'shader/program.c',
+ 'shader/program_parse.tab.c',
+ 'shader/program_parse_extra.c',
'shader/prog_cache.c',
'shader/prog_execute.c',
'shader/prog_instruction.c',
'shader/prog_noise.c',
'shader/prog_optimize.c',
'shader/prog_parameter.c',
+ 'shader/prog_parameter_layout.c',
'shader/prog_print.c',
'shader/prog_statevars.c',
'shader/prog_uniform.c',
'shader/programopt.c',
+ 'shader/symbol_table.c',
'shader/shader_api.c',
]
diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c
index 3b397fef7d..f09106b77c 100644
--- a/src/mesa/drivers/common/driverfuncs.c
+++ b/src/mesa/drivers/common/driverfuncs.c
@@ -45,6 +45,9 @@
#include "main/fbobject.h"
#include "main/texrender.h"
#endif
+#if FEATURE_ARB_sync
+#include "main/syncobj.h"
+#endif
#include "shader/program.h"
#include "shader/prog_execute.h"
@@ -53,6 +56,7 @@
#include "swrast/swrast.h"
#include "driverfuncs.h"
+#include "meta.h"
@@ -97,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;
@@ -126,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;
@@ -200,6 +204,7 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
driver->GetDoublev = NULL;
driver->GetFloatv = NULL;
driver->GetIntegerv = NULL;
+ driver->GetInteger64v = NULL;
driver->GetPointerv = NULL;
/* buffer objects */
@@ -208,6 +213,10 @@ _mesa_init_driver_functions(struct dd_function_table *driver)
/* query objects */
_mesa_init_query_object_functions(driver);
+#if FEATURE_ARB_sync
+ _mesa_init_sync_object_functions(driver);
+#endif
+
#if FEATURE_EXT_framebuffer_object
driver->NewFramebuffer = _mesa_new_framebuffer;
driver->NewRenderbuffer = _mesa_new_soft_renderbuffer;
diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c
new file mode 100644
index 0000000000..21756786c5
--- /dev/null
+++ b/src/mesa/drivers/common/meta.c
@@ -0,0 +1,2471 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * Meta operations. Some GL operations can be expressed in terms of
+ * other GL operations. For example, glBlitFramebuffer() can be done
+ * with texture mapping and glClear() can be done with polygon rendering.
+ *
+ * \author Brian Paul
+ */
+
+
+#include "main/glheader.h"
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "main/arrayobj.h"
+#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"
+#include "main/image.h"
+#include "main/macros.h"
+#include "main/matrix.h"
+#include "main/mipmap.h"
+#include "main/polygon.h"
+#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"
+#include "main/teximage.h"
+#include "main/texparam.h"
+#include "main/texstate.h"
+#include "main/varray.h"
+#include "main/viewport.h"
+#include "shader/program.h"
+#include "shader/arbprogram.h"
+#include "swrast/swrast.h"
+#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...
+ */
+struct save_state
+{
+ GLbitfield SavedState; /**< bitmask of META_* flags */
+
+ /** META_ALPHA_TEST */
+ GLboolean AlphaEnabled;
+
+ /** META_BLEND */
+ GLboolean BlendEnabled;
+ GLboolean ColorLogicOpEnabled;
+
+ /** META_COLOR_MASK */
+ GLubyte ColorMask[4];
+
+ /** META_DEPTH_TEST */
+ struct gl_depthbuffer_attrib Depth;
+
+ /** META_FOG */
+ GLboolean Fog;
+
+ /** 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;
+ GLboolean PolygonSmooth;
+ GLboolean PolygonStipple;
+ GLboolean PolygonCull;
+
+ /** META_SCISSOR */
+ struct gl_scissor_attrib Scissor;
+
+ /** META_SHADER */
+ GLboolean VertexProgramEnabled;
+ struct gl_vertex_program *VertexProgram;
+ GLboolean FragmentProgramEnabled;
+ struct gl_fragment_program *FragmentProgram;
+ GLuint Shader;
+
+ /** META_STENCIL_TEST */
+ struct gl_stencil_attrib Stencil;
+
+ /** META_TRANSFORM */
+ GLenum MatrixMode;
+ GLfloat ModelviewMatrix[16];
+ GLfloat ProjectionMatrix[16];
+ GLfloat TextureMatrix[16];
+ GLbitfield ClipPlanesEnabled;
+
+ /** META_TEXTURE */
+ GLuint ActiveUnit;
+ GLuint ClientActiveUnit;
+ /** for unit[0] only */
+ struct gl_texture_object *CurrentTexture[NUM_TEXTURE_TARGETS];
+ /** mask of TEXTURE_2D_BIT, etc */
+ GLbitfield TexEnabled[MAX_TEXTURE_UNITS];
+ GLbitfield TexGenEnabled[MAX_TEXTURE_UNITS];
+ GLuint EnvMode; /* unit[0] only */
+
+ /** META_VERTEX */
+ struct gl_array_object *ArrayObj;
+ struct gl_buffer_object *ArrayBufferObj;
+
+ /** META_VIEWPORT */
+ GLint ViewportX, ViewportY, ViewportW, ViewportH;
+ GLclampd DepthNear, DepthFar;
+
+ /** Miscellaneous (always disabled) */
+ GLboolean Lighting;
+};
+
+
+/**
+ * Temporary texture used for glBlitFramebuffer, glDrawPixels, etc.
+ * This is currently shared by all the meta ops. But we could create a
+ * separate one for each of glDrawPixel, glBlitFramebuffer, glCopyPixels, etc.
+ */
+struct temp_texture
+{
+ GLuint TexObj;
+ GLenum Target; /**< GL_TEXTURE_2D or GL_TEXTURE_RECTANGLE */
+ GLsizei MinSize; /**< Min texture size to allocate */
+ GLsizei MaxSize; /**< Max possible texture size */
+ GLboolean NPOT; /**< Non-power of two size OK? */
+ GLsizei Width, Height; /**< Current texture size */
+ GLenum IntFormat;
+ GLfloat Sright, Ttop; /**< right, top texcoords */
+};
+
+
+/**
+ * State for glBlitFramebufer()
+ */
+struct blit_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLuint DepthFP;
+};
+
+
+/**
+ * State for glClear()
+ */
+struct clear_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+};
+
+
+/**
+ * State for glCopyPixels()
+ */
+struct copypix_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+};
+
+
+/**
+ * State for glDrawPixels()
+ */
+struct drawpix_state
+{
+ GLuint ArrayObj;
+
+ GLuint StencilFP; /**< Fragment program for drawing stencil images */
+ GLuint DepthFP; /**< Fragment program for drawing depth images */
+};
+
+
+/**
+ * State for glBitmap()
+ */
+struct bitmap_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+ struct temp_texture Tex; /**< separate texture from other meta ops */
+};
+
+
+/**
+ * State for _mesa_meta_generate_mipmap()
+ */
+struct gen_mipmap_state
+{
+ GLuint ArrayObj;
+ GLuint VBO;
+ GLuint FBO;
+};
+
+
+/**
+ * All per-context meta state.
+ */
+struct gl_meta_state
+{
+ struct save_state Save; /**< state saved during meta-ops */
+
+ struct temp_texture TempTex;
+
+ 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() */
+};
+
+
+/**
+ * Initialize meta-ops for a context.
+ * To be called once during context creation.
+ */
+void
+_mesa_meta_init(GLcontext *ctx)
+{
+ ASSERT(!ctx->Meta);
+
+ ctx->Meta = CALLOC_STRUCT(gl_meta_state);
+}
+
+
+/**
+ * Free context meta-op state.
+ * To be called once during context destruction.
+ */
+void
+_mesa_meta_free(GLcontext *ctx)
+{
+ struct gl_meta_state *meta = ctx->Meta;
+
+ if (_mesa_get_current_context()) {
+ /* if there's no current context, these textures, buffers, etc should
+ * still get freed by _mesa_free_context_data().
+ */
+
+ /* the temporary texture */
+ _mesa_DeleteTextures(1, &meta->TempTex.TexObj);
+
+ /* glBlitFramebuffer */
+ _mesa_DeleteBuffersARB(1, & meta->Blit.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->Blit.ArrayObj);
+ _mesa_DeletePrograms(1, &meta->Blit.DepthFP);
+
+ /* glClear */
+ _mesa_DeleteBuffersARB(1, & meta->Clear.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->Clear.ArrayObj);
+
+ /* glCopyPixels */
+ _mesa_DeleteBuffersARB(1, & meta->CopyPix.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->CopyPix.ArrayObj);
+
+ /* glDrawPixels */
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->DrawPix.ArrayObj);
+ _mesa_DeletePrograms(1, &meta->DrawPix.DepthFP);
+ _mesa_DeletePrograms(1, &meta->DrawPix.StencilFP);
+
+ /* glBitmap */
+ _mesa_DeleteBuffersARB(1, & meta->Bitmap.VBO);
+ _mesa_DeleteVertexArraysAPPLE(1, &meta->Bitmap.ArrayObj);
+ _mesa_DeleteTextures(1, &meta->Bitmap.Tex.TexObj);
+ }
+
+ _mesa_free(ctx->Meta);
+ ctx->Meta = NULL;
+}
+
+
+/**
+ * Enter meta state. This is like a light-weight version of glPushAttrib
+ * but it also resets most GL state back to default values.
+ *
+ * \param state bitmask of META_* flags indicating which attribute groups
+ * to save and reset to their defaults
+ */
+static void
+_mesa_meta_begin(GLcontext *ctx, GLbitfield state)
+{
+ struct save_state *save = &ctx->Meta->Save;
+
+ save->SavedState = state;
+
+ if (state & META_ALPHA_TEST) {
+ save->AlphaEnabled = ctx->Color.AlphaEnabled;
+ if (ctx->Color.AlphaEnabled)
+ _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_FALSE);
+ }
+
+ if (state & META_BLEND) {
+ save->BlendEnabled = ctx->Color.BlendEnabled;
+ if (ctx->Color.BlendEnabled)
+ _mesa_set_enable(ctx, GL_BLEND, GL_FALSE);
+ save->ColorLogicOpEnabled = ctx->Color.ColorLogicOpEnabled;
+ if (ctx->Color.ColorLogicOpEnabled)
+ _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, GL_FALSE);
+ }
+
+ if (state & META_COLOR_MASK) {
+ COPY_4V(save->ColorMask, ctx->Color.ColorMask);
+ if (!ctx->Color.ColorMask[0] ||
+ !ctx->Color.ColorMask[1] ||
+ !ctx->Color.ColorMask[2] ||
+ !ctx->Color.ColorMask[3])
+ _mesa_ColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
+ }
+
+ if (state & META_DEPTH_TEST) {
+ save->Depth = ctx->Depth; /* struct copy */
+ if (ctx->Depth.Test)
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_FALSE);
+ }
+
+ if (state & META_FOG) {
+ save->Fog = ctx->Fog.Enabled;
+ if (ctx->Fog.Enabled)
+ _mesa_set_enable(ctx, GL_FOG, GL_FALSE);
+ }
+
+ if (state & META_PIXEL_STORE) {
+ save->Pack = ctx->Pack;
+ save->Unpack = ctx->Unpack;
+ ctx->Pack = ctx->DefaultPacking;
+ 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;
+ save->PolygonOffset = ctx->Polygon.OffsetFill;
+ save->PolygonSmooth = ctx->Polygon.SmoothFlag;
+ save->PolygonStipple = ctx->Polygon.StippleFlag;
+ save->PolygonCull = ctx->Polygon.CullFlag;
+ _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, GL_FALSE);
+ _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, GL_FALSE);
+ _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, GL_FALSE);
+ _mesa_set_enable(ctx, GL_CULL_FACE, GL_FALSE);
+ }
+
+ if (state & META_SCISSOR) {
+ save->Scissor = ctx->Scissor; /* struct copy */
+ }
+
+ if (state & META_SHADER) {
+ if (ctx->Extensions.ARB_vertex_program) {
+ save->VertexProgramEnabled = ctx->VertexProgram.Enabled;
+ save->VertexProgram = ctx->VertexProgram.Current;
+ _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB, GL_FALSE);
+ }
+
+ if (ctx->Extensions.ARB_fragment_program) {
+ save->FragmentProgramEnabled = ctx->FragmentProgram.Enabled;
+ save->FragmentProgram = ctx->FragmentProgram.Current;
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_FALSE);
+ }
+
+ if (ctx->Extensions.ARB_shader_objects) {
+ save->Shader = ctx->Shader.CurrentProgram ?
+ ctx->Shader.CurrentProgram->Name : 0;
+ _mesa_UseProgramObjectARB(0);
+ }
+ }
+
+ if (state & META_STENCIL_TEST) {
+ save->Stencil = ctx->Stencil; /* struct copy */
+ if (ctx->Stencil.Enabled)
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_FALSE);
+ /* NOTE: other stencil state not reset */
+ }
+
+ if (state & META_TEXTURE) {
+ GLuint u, tgt;
+
+ save->ActiveUnit = ctx->Texture.CurrentUnit;
+ save->ClientActiveUnit = ctx->Array.ActiveTexture;
+ save->EnvMode = ctx->Texture.Unit[0].EnvMode;
+
+ /* Disable all texture units */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ save->TexEnabled[u] = ctx->Texture.Unit[u].Enabled;
+ save->TexGenEnabled[u] = ctx->Texture.Unit[u].TexGenEnabled;
+ if (ctx->Texture.Unit[u].Enabled ||
+ ctx->Texture.Unit[u].TexGenEnabled) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+ _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_FALSE);
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_FALSE);
+ _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++) {
+ _mesa_reference_texobj(&save->CurrentTexture[tgt],
+ ctx->Texture.Unit[0].CurrentTex[tgt]);
+ }
+
+ /* set defaults for unit[0] */
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+ }
+
+ if (state & META_TRANSFORM) {
+ GLuint activeTexture = ctx->Texture.CurrentUnit;
+ _mesa_memcpy(save->ModelviewMatrix, ctx->ModelviewMatrixStack.Top->m,
+ 16 * sizeof(GLfloat));
+ _mesa_memcpy(save->ProjectionMatrix, ctx->ProjectionMatrixStack.Top->m,
+ 16 * sizeof(GLfloat));
+ _mesa_memcpy(save->TextureMatrix, ctx->TextureMatrixStack[0].Top->m,
+ 16 * sizeof(GLfloat));
+ save->MatrixMode = ctx->Transform.MatrixMode;
+ /* set 1:1 vertex:pixel coordinate transform */
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_MatrixMode(GL_TEXTURE);
+ _mesa_LoadIdentity();
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_LoadIdentity();
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_LoadIdentity();
+ _mesa_Ortho(0.0F, ctx->DrawBuffer->Width,
+ 0.0F, ctx->DrawBuffer->Height,
+ -1.0F, 1.0F);
+ save->ClipPlanesEnabled = ctx->Transform.ClipPlanesEnabled;
+ if (ctx->Transform.ClipPlanesEnabled) {
+ GLuint i;
+ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_FALSE);
+ }
+ }
+ }
+
+ if (state & META_VERTEX) {
+ /* save vertex array object state */
+ _mesa_reference_array_object(ctx, &save->ArrayObj,
+ ctx->Array.ArrayObj);
+ _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj,
+ ctx->Array.ArrayBufferObj);
+ /* set some default state? */
+ }
+
+ if (state & META_VIEWPORT) {
+ /* save viewport state */
+ save->ViewportX = ctx->Viewport.X;
+ save->ViewportY = ctx->Viewport.Y;
+ save->ViewportW = ctx->Viewport.Width;
+ save->ViewportH = ctx->Viewport.Height;
+ /* set viewport to match window size */
+ if (ctx->Viewport.X != 0 ||
+ ctx->Viewport.Y != 0 ||
+ ctx->Viewport.Width != ctx->DrawBuffer->Width ||
+ ctx->Viewport.Height != ctx->DrawBuffer->Height) {
+ _mesa_set_viewport(ctx, 0, 0,
+ ctx->DrawBuffer->Width, ctx->DrawBuffer->Height);
+ }
+ /* save depth range state */
+ save->DepthNear = ctx->Viewport.Near;
+ save->DepthFar = ctx->Viewport.Far;
+ /* set depth range to default */
+ _mesa_DepthRange(0.0, 1.0);
+ }
+
+ /* misc */
+ {
+ save->Lighting = ctx->Light.Enabled;
+ if (ctx->Light.Enabled)
+ _mesa_set_enable(ctx, GL_LIGHTING, GL_FALSE);
+ }
+}
+
+
+/**
+ * Leave meta state. This is like a light-weight version of glPopAttrib().
+ */
+static void
+_mesa_meta_end(GLcontext *ctx)
+{
+ struct save_state *save = &ctx->Meta->Save;
+ const GLbitfield state = save->SavedState;
+
+ if (state & META_ALPHA_TEST) {
+ if (ctx->Color.AlphaEnabled != save->AlphaEnabled)
+ _mesa_set_enable(ctx, GL_ALPHA_TEST, save->AlphaEnabled);
+ }
+
+ if (state & META_BLEND) {
+ if (ctx->Color.BlendEnabled != save->BlendEnabled)
+ _mesa_set_enable(ctx, GL_BLEND, save->BlendEnabled);
+ if (ctx->Color.ColorLogicOpEnabled != save->ColorLogicOpEnabled)
+ _mesa_set_enable(ctx, GL_COLOR_LOGIC_OP, save->ColorLogicOpEnabled);
+ }
+
+ if (state & META_COLOR_MASK) {
+ if (!TEST_EQ_4V(ctx->Color.ColorMask, save->ColorMask))
+ _mesa_ColorMask(save->ColorMask[0], save->ColorMask[1],
+ save->ColorMask[2], save->ColorMask[3]);
+ }
+
+ if (state & META_DEPTH_TEST) {
+ if (ctx->Depth.Test != save->Depth.Test)
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, save->Depth.Test);
+ _mesa_DepthFunc(save->Depth.Func);
+ _mesa_DepthMask(save->Depth.Mask);
+ }
+
+ if (state & META_FOG) {
+ _mesa_set_enable(ctx, GL_FOG, save->Fog);
+ }
+
+ if (state & META_PIXEL_STORE) {
+ ctx->Pack = save->Pack;
+ 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);
+ _mesa_set_enable(ctx, GL_POLYGON_STIPPLE, save->PolygonStipple);
+ _mesa_set_enable(ctx, GL_POLYGON_OFFSET_FILL, save->PolygonOffset);
+ _mesa_set_enable(ctx, GL_POLYGON_SMOOTH, save->PolygonSmooth);
+ _mesa_set_enable(ctx, GL_CULL_FACE, save->PolygonCull);
+ }
+
+ if (state & META_SCISSOR) {
+ _mesa_set_enable(ctx, GL_SCISSOR_TEST, save->Scissor.Enabled);
+ _mesa_Scissor(save->Scissor.X, save->Scissor.Y,
+ save->Scissor.Width, save->Scissor.Height);
+ }
+
+ if (state & META_SHADER) {
+ if (ctx->Extensions.ARB_vertex_program) {
+ _mesa_set_enable(ctx, GL_VERTEX_PROGRAM_ARB,
+ save->VertexProgramEnabled);
+ _mesa_reference_vertprog(ctx, &ctx->VertexProgram.Current,
+ save->VertexProgram);
+ }
+
+ if (ctx->Extensions.ARB_fragment_program) {
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB,
+ save->FragmentProgramEnabled);
+ _mesa_reference_fragprog(ctx, &ctx->FragmentProgram.Current,
+ save->FragmentProgram);
+ }
+
+ if (ctx->Extensions.ARB_shader_objects) {
+ _mesa_UseProgramObjectARB(save->Shader);
+ }
+ }
+
+ if (state & META_STENCIL_TEST) {
+ const struct gl_stencil_attrib *stencil = &save->Stencil;
+
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, stencil->Enabled);
+ _mesa_ClearStencil(stencil->Clear);
+ if (ctx->Extensions.EXT_stencil_two_side) {
+ _mesa_set_enable(ctx, GL_STENCIL_TEST_TWO_SIDE_EXT,
+ stencil->TestTwoSide);
+ _mesa_ActiveStencilFaceEXT(stencil->ActiveFace
+ ? GL_BACK : GL_FRONT);
+ }
+ /* front state */
+ _mesa_StencilFuncSeparate(GL_FRONT,
+ stencil->Function[0],
+ stencil->Ref[0],
+ stencil->ValueMask[0]);
+ _mesa_StencilMaskSeparate(GL_FRONT, stencil->WriteMask[0]);
+ _mesa_StencilOpSeparate(GL_FRONT, stencil->FailFunc[0],
+ stencil->ZFailFunc[0],
+ stencil->ZPassFunc[0]);
+ /* back state */
+ _mesa_StencilFuncSeparate(GL_BACK,
+ stencil->Function[1],
+ stencil->Ref[1],
+ stencil->ValueMask[1]);
+ _mesa_StencilMaskSeparate(GL_BACK, stencil->WriteMask[1]);
+ _mesa_StencilOpSeparate(GL_BACK, stencil->FailFunc[1],
+ stencil->ZFailFunc[1],
+ stencil->ZPassFunc[1]);
+ }
+
+ if (state & META_TEXTURE) {
+ GLuint u, tgt;
+
+ ASSERT(ctx->Texture.CurrentUnit == 0);
+
+ /* restore texenv for unit[0] */
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, save->EnvMode);
+
+ /* restore texture objects for unit[0] only */
+ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) {
+ _mesa_reference_texobj(&ctx->Texture.Unit[0].CurrentTex[tgt],
+ save->CurrentTexture[tgt]);
+ }
+
+ /* Re-enable textures, texgen */
+ for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
+ if (save->TexEnabled[u]) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+
+ if (save->TexEnabled[u] & TEXTURE_1D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_1D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_2D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_2D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_3D_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_3D, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_CUBE_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_CUBE_MAP, GL_TRUE);
+ if (save->TexEnabled[u] & TEXTURE_RECT_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE, GL_TRUE);
+ }
+
+ if (save->TexGenEnabled[u]) {
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + u);
+
+ if (save->TexGenEnabled[u] & S_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, GL_TRUE);
+ if (save->TexGenEnabled[u] & T_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, GL_TRUE);
+ if (save->TexGenEnabled[u] & R_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, GL_TRUE);
+ if (save->TexGenEnabled[u] & Q_BIT)
+ _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, GL_TRUE);
+ }
+ }
+
+ /* restore current unit state */
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + save->ActiveUnit);
+ _mesa_ClientActiveTextureARB(GL_TEXTURE0 + save->ClientActiveUnit);
+ }
+
+ if (state & META_TRANSFORM) {
+ GLuint activeTexture = ctx->Texture.CurrentUnit;
+ _mesa_ActiveTextureARB(GL_TEXTURE0);
+ _mesa_MatrixMode(GL_TEXTURE);
+ _mesa_LoadMatrixf(save->TextureMatrix);
+ _mesa_ActiveTextureARB(GL_TEXTURE0 + activeTexture);
+
+ _mesa_MatrixMode(GL_MODELVIEW);
+ _mesa_LoadMatrixf(save->ModelviewMatrix);
+
+ _mesa_MatrixMode(GL_PROJECTION);
+ _mesa_LoadMatrixf(save->ProjectionMatrix);
+
+ _mesa_MatrixMode(save->MatrixMode);
+
+ if (save->ClipPlanesEnabled) {
+ GLuint i;
+ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) {
+ if (save->ClipPlanesEnabled & (1 << i)) {
+ _mesa_set_enable(ctx, GL_CLIP_PLANE0 + i, GL_TRUE);
+ }
+ }
+ }
+ }
+
+ if (state & META_VERTEX) {
+ /* restore vertex buffer object */
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, save->ArrayBufferObj->Name);
+ _mesa_reference_buffer_object(ctx, &save->ArrayBufferObj, NULL);
+
+ /* restore vertex array object */
+ _mesa_BindVertexArray(save->ArrayObj->Name);
+ _mesa_reference_array_object(ctx, &save->ArrayObj, NULL);
+ }
+
+ if (state & META_VIEWPORT) {
+ if (save->ViewportX != ctx->Viewport.X ||
+ save->ViewportY != ctx->Viewport.Y ||
+ save->ViewportW != ctx->Viewport.Width ||
+ save->ViewportH != ctx->Viewport.Height) {
+ _mesa_set_viewport(ctx, save->ViewportX, save->ViewportY,
+ save->ViewportW, save->ViewportH);
+ }
+ _mesa_DepthRange(save->DepthNear, save->DepthFar);
+ }
+
+ /* misc */
+ if (save->Lighting) {
+ _mesa_set_enable(ctx, GL_LIGHTING, GL_TRUE);
+ }
+}
+
+
+/**
+ * One-time init for a temp_texture object.
+ * Choose tex target, compute max tex size, etc.
+ */
+static void
+init_temp_texture(GLcontext *ctx, struct temp_texture *tex)
+{
+ /* prefer texture rectangle */
+ if (ctx->Extensions.NV_texture_rectangle) {
+ tex->Target = GL_TEXTURE_RECTANGLE;
+ tex->MaxSize = ctx->Const.MaxTextureRectSize;
+ tex->NPOT = GL_TRUE;
+ }
+ else {
+ /* use 2D texture, NPOT if possible */
+ tex->Target = GL_TEXTURE_2D;
+ tex->MaxSize = 1 << (ctx->Const.MaxTextureLevels - 1);
+ tex->NPOT = ctx->Extensions.ARB_texture_non_power_of_two;
+ }
+ tex->MinSize = 16; /* 16 x 16 at least */
+ assert(tex->MaxSize > 0);
+
+ _mesa_GenTextures(1, &tex->TexObj);
+ _mesa_BindTexture(tex->Target, tex->TexObj);
+}
+
+
+/**
+ * Return pointer to temp_texture info for non-bitmap ops.
+ * This does some one-time init if needed.
+ */
+static struct temp_texture *
+get_temp_texture(GLcontext *ctx)
+{
+ struct temp_texture *tex = &ctx->Meta->TempTex;
+
+ if (!tex->TexObj) {
+ init_temp_texture(ctx, tex);
+ }
+
+ return tex;
+}
+
+
+/**
+ * Return pointer to temp_texture info for _mesa_meta_bitmap().
+ * We use a separate texture for bitmaps to reduce texture
+ * allocation/deallocation.
+ */
+static struct temp_texture *
+get_bitmap_temp_texture(GLcontext *ctx)
+{
+ struct temp_texture *tex = &ctx->Meta->Bitmap.Tex;
+
+ if (!tex->TexObj) {
+ init_temp_texture(ctx, tex);
+ }
+
+ return tex;
+}
+
+
+/**
+ * Compute the width/height of texture needed to draw an image of the
+ * given size. Return a flag indicating whether the current texture
+ * can be re-used (glTexSubImage2D) or if a new texture needs to be
+ * allocated (glTexImage2D).
+ * Also, compute s/t texcoords for drawing.
+ *
+ * \return GL_TRUE if new texture is needed, GL_FALSE otherwise
+ */
+static GLboolean
+alloc_texture(struct temp_texture *tex,
+ GLsizei width, GLsizei height, GLenum intFormat)
+{
+ GLboolean newTex = GL_FALSE;
+
+ ASSERT(width <= tex->MaxSize);
+ ASSERT(height <= tex->MaxSize);
+
+ if (width > tex->Width ||
+ height > tex->Height ||
+ intFormat != tex->IntFormat) {
+ /* alloc new texture (larger or different format) */
+
+ if (tex->NPOT) {
+ /* use non-power of two size */
+ tex->Width = MAX2(tex->MinSize, width);
+ tex->Height = MAX2(tex->MinSize, height);
+ }
+ else {
+ /* find power of two size */
+ GLsizei w, h;
+ w = h = tex->MinSize;
+ while (w < width)
+ w *= 2;
+ while (h < height)
+ h *= 2;
+ tex->Width = w;
+ tex->Height = h;
+ }
+
+ tex->IntFormat = intFormat;
+
+ newTex = GL_TRUE;
+ }
+
+ /* compute texcoords */
+ if (tex->Target == GL_TEXTURE_RECTANGLE) {
+ tex->Sright = (GLfloat) width;
+ tex->Ttop = (GLfloat) height;
+ }
+ else {
+ tex->Sright = (GLfloat) width / tex->Width;
+ tex->Ttop = (GLfloat) height / tex->Height;
+ }
+
+ return newTex;
+}
+
+
+/**
+ * Setup/load texture for glCopyPixels or glBlitFramebuffer.
+ */
+static void
+setup_copypix_texture(struct temp_texture *tex,
+ GLboolean newTex,
+ GLint srcX, GLint srcY,
+ GLsizei width, GLsizei height, GLenum intFormat,
+ GLenum filter)
+{
+ _mesa_BindTexture(tex->Target, tex->TexObj);
+ _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, filter);
+ _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, filter);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ /* copy framebuffer image to texture */
+ if (newTex) {
+ /* create new tex image */
+ if (tex->Width == width && tex->Height == height) {
+ /* create new tex with framebuffer data */
+ _mesa_CopyTexImage2D(tex->Target, 0, tex->IntFormat,
+ srcX, srcY, width, height, 0);
+ }
+ else {
+ /* create empty texture */
+ _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
+ tex->Width, tex->Height, 0,
+ intFormat, GL_UNSIGNED_BYTE, NULL);
+ /* load image */
+ _mesa_CopyTexSubImage2D(tex->Target, 0,
+ 0, 0, srcX, srcY, width, height);
+ }
+ }
+ else {
+ /* replace existing tex image */
+ _mesa_CopyTexSubImage2D(tex->Target, 0,
+ 0, 0, srcX, srcY, width, height);
+ }
+}
+
+
+/**
+ * Setup/load texture for glDrawPixels.
+ */
+static void
+setup_drawpix_texture(struct temp_texture *tex,
+ GLboolean newTex,
+ GLenum texIntFormat,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels)
+{
+ _mesa_BindTexture(tex->Target, tex->TexObj);
+ _mesa_TexParameteri(tex->Target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ _mesa_TexParameteri(tex->Target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
+ _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
+
+ /* copy pixel data to texture */
+ if (newTex) {
+ /* create new tex image */
+ if (tex->Width == width && tex->Height == height) {
+ /* create new tex and load image data */
+ _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
+ tex->Width, tex->Height, 0, format, type, pixels);
+ }
+ else {
+ /* create empty texture */
+ _mesa_TexImage2D(tex->Target, 0, tex->IntFormat,
+ tex->Width, tex->Height, 0, format, type, NULL);
+ /* load image */
+ _mesa_TexSubImage2D(tex->Target, 0,
+ 0, 0, width, height, format, type, pixels);
+ }
+ }
+ else {
+ /* replace existing tex image */
+ _mesa_TexSubImage2D(tex->Target, 0,
+ 0, 0, width, height, format, type, pixels);
+ }
+}
+
+
+
+/**
+ * One-time init for drawing depth pixels.
+ */
+static void
+init_blit_depth_pixels(GLcontext *ctx)
+{
+ static const char *program =
+ "!!ARBfp1.0\n"
+ "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
+ "END \n";
+ char program2[200];
+ struct blit_state *blit = &ctx->Meta->Blit;
+ struct temp_texture *tex = get_temp_texture(ctx);
+ const char *texTarget;
+
+ assert(blit->DepthFP == 0);
+
+ /* replace %s with "RECT" or "2D" */
+ assert(strlen(program) + 4 < sizeof(program2));
+ if (tex->Target == GL_TEXTURE_RECTANGLE)
+ texTarget = "RECT";
+ else
+ texTarget = "2D";
+ _mesa_snprintf(program2, sizeof(program2), program, texTarget);
+
+ _mesa_GenPrograms(1, &blit->DepthFP);
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
+ _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(program2), (const GLubyte *) program2);
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.BlitFramebuffer() in terms
+ * of texture mapping and polygon rendering.
+ */
+void
+_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);
+ const GLsizei maxTexSize = tex->MaxSize;
+ const GLint srcX = MIN2(srcX0, srcX1);
+ const GLint srcY = MIN2(srcY0, srcY1);
+ const GLint srcW = abs(srcX1 - srcX0);
+ const GLint srcH = abs(srcY1 - srcY0);
+ const GLboolean srcFlipX = srcX1 < srcX0;
+ const GLboolean srcFlipY = srcY1 < srcY0;
+ struct vertex {
+ GLfloat x, y, s, t;
+ };
+ struct vertex verts[4];
+ GLboolean newTex;
+
+ if (srcW > maxTexSize || srcH > maxTexSize) {
+ /* XXX avoid this fallback */
+ _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+ return;
+ }
+
+ if (srcFlipX) {
+ GLint tmp = dstX0;
+ dstX0 = dstX1;
+ dstX1 = tmp;
+ }
+
+ if (srcFlipY) {
+ GLint tmp = dstY0;
+ dstY0 = dstY1;
+ dstY1 = tmp;
+ }
+
+ /* only scissor effects blit so save/clear all other relevant state */
+ _mesa_meta_begin(ctx, ~META_SCISSOR);
+
+ if (blit->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &blit->ArrayObj);
+ _mesa_BindVertexArray(blit->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &blit->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ NULL, GL_DYNAMIC_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _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);
+ }
+ else {
+ _mesa_BindVertexArray(blit->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, blit->VBO);
+ }
+
+ newTex = alloc_texture(tex, srcW, srcH, GL_RGBA);
+
+ /* vertex positions/texcoords (after texture allocation!) */
+ {
+ 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);
+ }
+
+ _mesa_set_enable(ctx, tex->Target, GL_TRUE);
+
+ if (mask & GL_COLOR_BUFFER_BIT) {
+ setup_copypix_texture(tex, newTex, srcX, srcY, srcW, srcH,
+ GL_RGBA, filter);
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ mask &= ~GL_COLOR_BUFFER_BIT;
+ }
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ GLuint *tmp = (GLuint *) _mesa_malloc(srcW * srcH * sizeof(GLuint));
+ if (tmp) {
+ if (!blit->DepthFP)
+ init_blit_depth_pixels(ctx);
+
+ /* maybe change tex format here */
+ newTex = alloc_texture(tex, srcW, srcH, GL_DEPTH_COMPONENT);
+
+ _mesa_ReadPixels(srcX, srcY, srcW, srcH,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
+
+ setup_drawpix_texture(tex, newTex, GL_DEPTH_COMPONENT, srcW, srcH,
+ GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, tmp);
+
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, blit->DepthFP);
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
+ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+ _mesa_DepthFunc(GL_ALWAYS);
+ _mesa_DepthMask(GL_TRUE);
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ mask &= ~GL_DEPTH_BUFFER_BIT;
+
+ _mesa_free(tmp);
+ }
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ /* XXX can't easily do stencil */
+ }
+
+ _mesa_set_enable(ctx, tex->Target, GL_FALSE);
+
+ _mesa_meta_end(ctx);
+
+ if (mask) {
+ _swrast_BlitFramebuffer(ctx, srcX0, srcY0, srcX1, srcY1,
+ dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.Clear() in terms of polygon rendering.
+ */
+void
+_mesa_meta_Clear(GLcontext *ctx, GLbitfield buffers)
+{
+ struct clear_state *clear = &ctx->Meta->Clear;
+ 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;
+
+ if (buffers & BUFFER_BITS_COLOR) {
+ /* if clearing color buffers, don't save/restore colormask */
+ metaSave -= META_COLOR_MASK;
+ }
+
+ _mesa_meta_begin(ctx, metaSave);
+
+ if (clear->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &clear->ArrayObj);
+ _mesa_BindVertexArray(clear->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &clear->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ NULL, GL_DYNAMIC_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _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);
+ }
+ else {
+ _mesa_BindVertexArray(clear->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, clear->VBO);
+ }
+
+ /* GL_COLOR_BUFFER_BIT */
+ if (buffers & BUFFER_BITS_COLOR) {
+ /* leave colormask, glDrawBuffer state as-is */
+ }
+ else {
+ ASSERT(metaSave & META_COLOR_MASK);
+ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+ }
+
+ /* GL_DEPTH_BUFFER_BIT */
+ if (buffers & BUFFER_BIT_DEPTH) {
+ _mesa_set_enable(ctx, GL_DEPTH_TEST, GL_TRUE);
+ _mesa_DepthFunc(GL_ALWAYS);
+ _mesa_DepthMask(GL_TRUE);
+ }
+ else {
+ assert(!ctx->Depth.Test);
+ }
+
+ /* GL_STENCIL_BUFFER_BIT */
+ if (buffers & BUFFER_BIT_STENCIL) {
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
+ _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
+ GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
+ ctx->Stencil.Clear & 0x7fffffff,
+ ctx->Stencil.WriteMask[0]);
+ }
+ else {
+ assert(!ctx->Stencil.Enabled);
+ }
+
+ /* vertex positions/colors */
+ {
+ const GLfloat x0 = (GLfloat) ctx->DrawBuffer->_Xmin;
+ const GLfloat y0 = (GLfloat) ctx->DrawBuffer->_Ymin;
+ const GLfloat x1 = (GLfloat) ctx->DrawBuffer->_Xmax;
+ const GLfloat y1 = (GLfloat) ctx->DrawBuffer->_Ymax;
+ const GLfloat z = 1.0 - 2.0 * ctx->Depth.Clear;
+ GLuint i;
+
+ 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++) {
+ 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 */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ }
+
+ /* draw quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_meta_end(ctx);
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.CopyPixels() in terms
+ * of texture mapping and polygon rendering.
+ */
+void
+_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);
+ struct vertex {
+ GLfloat x, y, z, s, t;
+ };
+ struct vertex verts[4];
+ GLboolean newTex;
+ GLenum intFormat = GL_RGBA;
+
+ if (type != GL_COLOR ||
+ ctx->_ImageTransferState ||
+ ctx->Fog.Enabled ||
+ width > tex->MaxSize ||
+ height > tex->MaxSize) {
+ /* XXX avoid this fallback */
+ _swrast_CopyPixels(ctx, srcX, srcY, width, height, dstX, dstY, type);
+ return;
+ }
+
+ /* Most GL state applies to glCopyPixels, but a there's a few things
+ * we need to override:
+ */
+ _mesa_meta_begin(ctx, (META_RASTERIZATION |
+ META_SHADER |
+ META_TEXTURE |
+ META_TRANSFORM |
+ META_VERTEX |
+ META_VIEWPORT));
+
+ if (copypix->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArrays(1, &copypix->ArrayObj);
+ _mesa_BindVertexArray(copypix->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &copypix->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ NULL, 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);
+ }
+ else {
+ _mesa_BindVertexArray(copypix->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, copypix->VBO);
+ }
+
+ newTex = alloc_texture(tex, width, height, intFormat);
+
+ /* vertex positions, texcoords (after texture allocation!) */
+ {
+ const GLfloat dstX0 = (GLfloat) dstX;
+ const GLfloat dstY0 = (GLfloat) dstY;
+ const GLfloat dstX1 = dstX + width * ctx->Pixel.ZoomX;
+ const GLfloat dstY1 = dstY + height * ctx->Pixel.ZoomY;
+ const GLfloat z = ctx->Current.RasterPos[2];
+
+ 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);
+ }
+
+ /* Alloc/setup texture */
+ setup_copypix_texture(tex, newTex, srcX, srcY, width, height,
+ GL_RGBA, GL_NEAREST);
+
+ _mesa_set_enable(ctx, tex->Target, GL_TRUE);
+
+ /* draw textured quad */
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_set_enable(ctx, tex->Target, GL_FALSE);
+
+ _mesa_meta_end(ctx);
+}
+
+
+
+/**
+ * When the glDrawPixels() image size is greater than the max rectangle
+ * texture size we use this function to break the glDrawPixels() image
+ * into tiles which fit into the max texture size.
+ */
+static void
+tiled_draw_pixels(GLcontext *ctx,
+ GLint tileSize,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLvoid *pixels)
+{
+ struct gl_pixelstore_attrib tileUnpack = *unpack;
+ GLint i, j;
+
+ if (tileUnpack.RowLength == 0)
+ tileUnpack.RowLength = width;
+
+ for (i = 0; i < width; i += tileSize) {
+ const GLint tileWidth = MIN2(tileSize, width - i);
+ const GLint tileX = (GLint) (x + i * ctx->Pixel.ZoomX);
+
+ tileUnpack.SkipPixels = unpack->SkipPixels + i;
+
+ for (j = 0; j < height; j += tileSize) {
+ const GLint tileHeight = MIN2(tileSize, height - j);
+ const GLint tileY = (GLint) (y + j * ctx->Pixel.ZoomY);
+
+ tileUnpack.SkipRows = unpack->SkipRows + j;
+
+ _mesa_meta_DrawPixels(ctx, tileX, tileY, tileWidth, tileHeight,
+ format, type, &tileUnpack, pixels);
+ }
+ }
+}
+
+
+/**
+ * One-time init for drawing stencil pixels.
+ */
+static void
+init_draw_stencil_pixels(GLcontext *ctx)
+{
+ /* This program is run eight times, once for each stencil bit.
+ * The stencil values to draw are found in an 8-bit alpha texture.
+ * We read the texture/stencil value and test if bit 'b' is set.
+ * If the bit is not set, use KIL to kill the fragment.
+ * Finally, we use the stencil test to update the stencil buffer.
+ *
+ * The basic algorithm for checking if a bit is set is:
+ * if (is_odd(value / (1 << bit)))
+ * result is one (or non-zero).
+ * else
+ * result is zero.
+ * The program parameter contains three values:
+ * parm.x = 255 / (1 << bit)
+ * parm.y = 0.5
+ * parm.z = 0.0
+ */
+ static const char *program =
+ "!!ARBfp1.0\n"
+ "PARAM parm = program.local[0]; \n"
+ "TEMP t; \n"
+ "TEX t, fragment.texcoord[0], texture[0], %s; \n" /* NOTE %s here! */
+ "# t = t * 255 / bit \n"
+ "MUL t.x, t.a, parm.x; \n"
+ "# t = (int) t \n"
+ "FRC t.y, t.x; \n"
+ "SUB t.x, t.x, t.y; \n"
+ "# t = t * 0.5 \n"
+ "MUL t.x, t.x, parm.y; \n"
+ "# t = fract(t.x) \n"
+ "FRC t.x, t.x; # if t.x != 0, then the bit is set \n"
+ "# t.x = (t.x == 0 ? 1 : 0) \n"
+ "SGE t.x, -t.x, parm.z; \n"
+ "KIL -t.x; \n"
+ "# for debug only \n"
+ "#MOV result.color, t.x; \n"
+ "END \n";
+ char program2[1000];
+ struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
+ struct temp_texture *tex = get_temp_texture(ctx);
+ const char *texTarget;
+
+ assert(drawpix->StencilFP == 0);
+
+ /* replace %s with "RECT" or "2D" */
+ assert(strlen(program) + 4 < sizeof(program2));
+ if (tex->Target == GL_TEXTURE_RECTANGLE)
+ texTarget = "RECT";
+ else
+ texTarget = "2D";
+ _mesa_snprintf(program2, sizeof(program2), program, texTarget);
+
+ _mesa_GenPrograms(1, &drawpix->StencilFP);
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
+ _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(program2), (const GLubyte *) program2);
+}
+
+
+/**
+ * One-time init for drawing depth pixels.
+ */
+static void
+init_draw_depth_pixels(GLcontext *ctx)
+{
+ static const char *program =
+ "!!ARBfp1.0\n"
+ "PARAM color = program.local[0]; \n"
+ "TEX result.depth, fragment.texcoord[0], texture[0], %s; \n"
+ "MOV result.color, color; \n"
+ "END \n";
+ char program2[200];
+ struct drawpix_state *drawpix = &ctx->Meta->DrawPix;
+ struct temp_texture *tex = get_temp_texture(ctx);
+ const char *texTarget;
+
+ assert(drawpix->DepthFP == 0);
+
+ /* replace %s with "RECT" or "2D" */
+ assert(strlen(program) + 4 < sizeof(program2));
+ if (tex->Target == GL_TEXTURE_RECTANGLE)
+ texTarget = "RECT";
+ else
+ texTarget = "2D";
+ _mesa_snprintf(program2, sizeof(program2), program, texTarget);
+
+ _mesa_GenPrograms(1, &drawpix->DepthFP);
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
+ _mesa_ProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB,
+ strlen(program2), (const GLubyte *) program2);
+}
+
+
+/**
+ * Meta implementation of ctx->Driver.DrawPixels() in terms
+ * of texture mapping and polygon rendering.
+ */
+void
+_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];
+ 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.
+ */
+ fallback = GL_FALSE;
+ if (ctx->_ImageTransferState ||
+ ctx->Fog.Enabled) {
+ fallback = GL_TRUE;
+ }
+
+ if (_mesa_is_color_format(format)) {
+ /* use more compact format when possible */
+ /* XXX disable special case for GL_LUMINANCE for now to work around
+ * apparent i965 driver bug (see bug #23670).
+ */
+ if (/*format == GL_LUMINANCE ||*/ format == GL_LUMINANCE_ALPHA)
+ texIntFormat = format;
+ else
+ texIntFormat = GL_RGBA;
+ }
+ else if (_mesa_is_stencil_format(format)) {
+ if (ctx->Extensions.ARB_fragment_program &&
+ ctx->Pixel.IndexShift == 0 &&
+ ctx->Pixel.IndexOffset == 0 &&
+ type == GL_UNSIGNED_BYTE) {
+ /* We'll store stencil as alpha. This only works for GLubyte
+ * image data because of how incoming values are mapped to alpha
+ * in [0,1].
+ */
+ texIntFormat = GL_ALPHA;
+ metaExtraSave = (META_COLOR_MASK |
+ META_DEPTH_TEST |
+ META_SHADER |
+ META_STENCIL_TEST);
+ }
+ else {
+ fallback = GL_TRUE;
+ }
+ }
+ else if (_mesa_is_depth_format(format)) {
+ if (ctx->Extensions.ARB_depth_texture &&
+ ctx->Extensions.ARB_fragment_program) {
+ texIntFormat = GL_DEPTH_COMPONENT;
+ metaExtraSave = (META_SHADER);
+ }
+ else {
+ fallback = GL_TRUE;
+ }
+ }
+ else {
+ fallback = GL_TRUE;
+ }
+
+ if (fallback) {
+ _swrast_DrawPixels(ctx, x, y, width, height,
+ format, type, unpack, pixels);
+ return;
+ }
+
+ /*
+ * Check image size against max texture size, draw as tiles if needed.
+ */
+ if (width > tex->MaxSize || height > tex->MaxSize) {
+ tiled_draw_pixels(ctx, tex->MaxSize, x, y, width, height,
+ format, type, unpack, pixels);
+ return;
+ }
+
+ /* Most GL state applies to glDrawPixels (like blending, stencil, etc),
+ * but a there's a few things we need to override:
+ */
+ _mesa_meta_begin(ctx, (META_RASTERIZATION |
+ META_SHADER |
+ META_TEXTURE |
+ META_TRANSFORM |
+ META_VERTEX |
+ META_VIEWPORT |
+ metaExtraSave));
+
+ newTex = alloc_texture(tex, width, height, texIntFormat);
+
+ /* vertex positions, texcoords (after texture allocation!) */
+ {
+ const GLfloat x0 = (GLfloat) x;
+ const GLfloat y0 = (GLfloat) y;
+ const GLfloat x1 = x + width * ctx->Pixel.ZoomX;
+ const GLfloat y1 = y + height * ctx->Pixel.ZoomY;
+ const GLfloat z = ctx->Current.RasterPos[2];
+
+ 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;
+ }
+
+ 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;
+
+ _mesa_set_enable(ctx, tex->Target, GL_TRUE);
+
+ if (_mesa_is_stencil_format(format)) {
+ /* Drawing stencil */
+ GLint bit;
+
+ if (!drawpix->StencilFP)
+ init_draw_stencil_pixels(ctx);
+
+ setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
+ GL_ALPHA, type, pixels);
+
+ _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
+
+ _mesa_set_enable(ctx, GL_STENCIL_TEST, GL_TRUE);
+
+ /* set all stencil bits to 0 */
+ _mesa_StencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
+ _mesa_StencilFunc(GL_ALWAYS, 0, 255);
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ /* set stencil bits to 1 where needed */
+ _mesa_StencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
+
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->StencilFP);
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
+
+ for (bit = 0; bit < ctx->Visual.stencilBits; bit++) {
+ const GLuint mask = 1 << bit;
+ if (mask & origStencilMask) {
+ _mesa_StencilFunc(GL_ALWAYS, mask, mask);
+ _mesa_StencilMask(mask);
+
+ _mesa_ProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0,
+ 255.0 / mask, 0.5, 0.0, 0.0);
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+ }
+ }
+ else if (_mesa_is_depth_format(format)) {
+ /* Drawing depth */
+ if (!drawpix->DepthFP)
+ init_draw_depth_pixels(ctx);
+
+ _mesa_BindProgram(GL_FRAGMENT_PROGRAM_ARB, drawpix->DepthFP);
+ _mesa_set_enable(ctx, GL_FRAGMENT_PROGRAM_ARB, GL_TRUE);
+
+ /* polygon color = current raster color */
+ _mesa_ProgramLocalParameter4fvARB(GL_FRAGMENT_PROGRAM_ARB, 0,
+ ctx->Current.RasterColor);
+
+ setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
+ format, type, pixels);
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+ else {
+ /* Drawing RGBA */
+ setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
+ format, type, pixels);
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ _mesa_set_enable(ctx, tex->Target, GL_FALSE);
+
+ _mesa_DeleteBuffersARB(1, &vbo);
+
+ /* restore unpack params */
+ ctx->Unpack = unpackSave;
+
+ _mesa_meta_end(ctx);
+}
+
+
+/**
+ * Do glBitmap with a alpha texture quad. Use the alpha test to
+ * cull the 'off' bits. If alpha test is already enabled, fall back
+ * to swrast (should be a rare case).
+ * A bitmap cache as in the gallium/mesa state tracker would
+ * improve performance a lot.
+ */
+void
+_mesa_meta_Bitmap(GLcontext *ctx,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap1)
+{
+ struct bitmap_state *bitmap = &ctx->Meta->Bitmap;
+ struct temp_texture *tex = get_bitmap_temp_texture(ctx);
+ const GLenum texIntFormat = GL_ALPHA;
+ const struct gl_pixelstore_attrib unpackSave = *unpack;
+ struct vertex {
+ GLfloat x, y, z, s, t, r, g, b, a;
+ };
+ struct vertex verts[4];
+ GLboolean newTex;
+ GLubyte *bitmap8;
+
+ /*
+ * Check if swrast fallback is needed.
+ */
+ if (ctx->_ImageTransferState ||
+ ctx->Color.AlphaEnabled ||
+ ctx->Fog.Enabled ||
+ ctx->Texture._EnabledUnits ||
+ width > tex->MaxSize ||
+ height > tex->MaxSize) {
+ _swrast_Bitmap(ctx, x, y, width, height, unpack, bitmap1);
+ return;
+ }
+
+ /* Most GL state applies to glBitmap (like blending, stencil, etc),
+ * but a there's a few things we need to override:
+ */
+ _mesa_meta_begin(ctx, (META_ALPHA_TEST |
+ META_PIXEL_STORE |
+ META_RASTERIZATION |
+ META_SHADER |
+ META_TEXTURE |
+ META_TRANSFORM |
+ META_VERTEX |
+ META_VIEWPORT));
+
+ if (bitmap->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArraysAPPLE(1, &bitmap->ArrayObj);
+ _mesa_BindVertexArrayAPPLE(bitmap->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &bitmap->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ NULL, 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_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);
+ }
+ else {
+ _mesa_BindVertexArray(bitmap->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, bitmap->VBO);
+ }
+
+ newTex = alloc_texture(tex, width, height, texIntFormat);
+
+ /* vertex positions, texcoords, colors (after texture allocation!) */
+ {
+ const GLfloat x0 = (GLfloat) x;
+ const GLfloat y0 = (GLfloat) y;
+ const GLfloat x1 = (GLfloat) (x + width);
+ const GLfloat y1 = (GLfloat) (y + height);
+ const GLfloat z = ctx->Current.RasterPos[2];
+ GLuint i;
+
+ 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].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 */
+ _mesa_BufferSubDataARB(GL_ARRAY_BUFFER_ARB, 0, sizeof(verts), verts);
+ }
+
+ bitmap1 = _mesa_map_pbo_source(ctx, &unpackSave, bitmap1);
+ if (!bitmap1)
+ return;
+
+ bitmap8 = (GLubyte *) _mesa_calloc(width * height);
+ if (bitmap8) {
+ _mesa_expand_bitmap(width, height, &unpackSave, bitmap1,
+ bitmap8, width, 0xff);
+
+ _mesa_set_enable(ctx, tex->Target, GL_TRUE);
+
+ _mesa_set_enable(ctx, GL_ALPHA_TEST, GL_TRUE);
+ _mesa_AlphaFunc(GL_GREATER, 0.0);
+
+ setup_drawpix_texture(tex, newTex, texIntFormat, width, height,
+ GL_ALPHA, GL_UNSIGNED_BYTE, bitmap8);
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+ _mesa_set_enable(ctx, tex->Target, GL_FALSE);
+
+ _mesa_free(bitmap8);
+ }
+
+ _mesa_unmap_pbo_source(ctx, &unpackSave);
+
+ _mesa_meta_end(ctx);
+}
+
+
+void
+_mesa_meta_GenerateMipmap(GLcontext *ctx, GLenum target,
+ struct gl_texture_object *texObj)
+{
+ struct gen_mipmap_state *mipmap = &ctx->Meta->Mipmap;
+ 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 GLuint fboSave = ctx->DrawBuffer->Name;
+ GLenum faceTarget;
+ GLuint level;
+ GLuint border = 0;
+
+ /* check for fallbacks */
+ if (!ctx->Extensions.EXT_framebuffer_object) {
+ _mesa_generate_mipmap(ctx, target, texObj);
+ return;
+ }
+
+ if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X &&
+ target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) {
+ faceTarget = target;
+ target = GL_TEXTURE_CUBE_MAP;
+ }
+ else {
+ faceTarget = target;
+ }
+
+ _mesa_meta_begin(ctx, META_ALL);
+
+ if (mipmap->ArrayObj == 0) {
+ /* one-time setup */
+
+ /* create vertex array object */
+ _mesa_GenVertexArraysAPPLE(1, &mipmap->ArrayObj);
+ _mesa_BindVertexArrayAPPLE(mipmap->ArrayObj);
+
+ /* create vertex array buffer */
+ _mesa_GenBuffersARB(1, &mipmap->VBO);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
+ _mesa_BufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(verts),
+ NULL, GL_DYNAMIC_DRAW_ARB);
+
+ /* setup vertex arrays */
+ _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);
+ }
+ else {
+ _mesa_BindVertexArray(mipmap->ArrayObj);
+ _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, mipmap->VBO);
+ }
+
+ if (!mipmap->FBO) {
+ /* Bind the new renderbuffer to the color attachment point. */
+ _mesa_GenFramebuffersEXT(1, &mipmap->FBO);
+ }
+
+ _mesa_BindFramebufferEXT(GL_FRAMEBUFFER_EXT, mipmap->FBO);
+
+ _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ _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_2D:
+ verts[0].s = 0.0F;
+ verts[0].t = 0.0F;
+ verts[0].r = 0.0F;
+ verts[1].s = 1.0F;
+ verts[1].t = 0.0F;
+ verts[1].r = 0.0F;
+ verts[2].s = 1.0F;
+ verts[2].t = 1.0F;
+ verts[2].r = 0.0F;
+ verts[3].s = 0.0F;
+ verts[3].t = 1.0F;
+ verts[3].r = 0.0F;
+ break;
+ }
+
+
+ for (level = baseLevel + 1; level <= maxLevel; level++) {
+ const struct gl_texture_image *srcImage;
+ const GLuint srcLevel = level - 1;
+ GLsizei srcWidth, srcHeight;
+ GLsizei newWidth, newHeight;
+ GLenum status;
+
+ srcImage = _mesa_select_tex_image(ctx, texObj, target, srcLevel);
+ assert(srcImage->Border == 0); /* XXX we can fix this */
+
+ srcWidth = srcImage->Width - 2 * border;
+ srcHeight = srcImage->Height - 2 * border;
+
+ newWidth = MAX2(1, srcWidth / 2) + 2 * border;
+ newHeight = MAX2(1, srcHeight / 2) + 2 * border;
+
+ if (newWidth == srcImage->Width && newHeight == srcImage->Height) {
+ break;
+ }
+
+ /* Create empty image */
+ _mesa_TexImage2D(GL_TEXTURE_2D, level, srcImage->InternalFormat,
+ newWidth, newHeight, border,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+
+ /* vertex positions */
+ {
+ verts[0].x = 0.0F;
+ verts[0].y = 0.0F;
+ verts[1].x = (GLfloat) newWidth;
+ verts[1].y = 0.0F;
+ verts[2].x = (GLfloat) newWidth;
+ verts[2].y = (GLfloat) newHeight;
+ verts[3].x = 0.0F;
+ verts[3].y = (GLfloat) newHeight;
+
+ /* 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);
+
+ /* Choose to render to the color attachment. */
+ _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
+
+ status = _mesa_CheckFramebufferStatusEXT (GL_FRAMEBUFFER_EXT);
+ if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ abort();
+ break;
+ }
+
+ _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
+ }
+
+ _mesa_meta_end(ctx);
+
+ _mesa_TexParameteri(target, GL_TEXTURE_MIN_FILTER, minFilterSave);
+ _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, magFilterSave);
+
+ /* 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
new file mode 100644
index 0000000000..7f659528dc
--- /dev/null
+++ b/src/mesa/drivers/common/meta.h
@@ -0,0 +1,114 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 7.6
+ *
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef META_H
+#define META_H
+
+
+extern void
+_mesa_meta_init(GLcontext *ctx);
+
+extern void
+_mesa_meta_free(GLcontext *ctx);
+
+extern void
+_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);
+
+extern void
+_mesa_meta_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
+ GLsizei width, GLsizei height,
+ GLint dstx, GLint dsty, GLenum type);
+
+extern void
+_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,
+ GLint x, GLint y, GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap);
+
+extern void
+_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/.gitignore b/src/mesa/drivers/dri/common/.gitignore
new file mode 100644
index 0000000000..1edeb79fd1
--- /dev/null
+++ b/src/mesa/drivers/dri/common/.gitignore
@@ -0,0 +1 @@
+*.os
diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c
index fe183c2e87..c7bea07dc9 100644
--- a/src/mesa/drivers/dri/common/dri_metaops.c
+++ b/src/mesa/drivers/dri/common/dri_metaops.c
@@ -287,247 +287,6 @@ meta_restore_texcoords(struct dri_metaops *meta)
}
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering. The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-
-/**
- * Per-context one-time init of things for intl_clear_tris().
- * Basically set up a private array object for vertex/color arrays.
- */
-static void
-meta_init_clear(struct dri_metaops *meta)
-{
- GLcontext *ctx = meta->ctx;
- struct gl_array_object *arraySave = NULL;
- const GLuint arrayBuffer = ctx->Array.ArrayBufferObj->Name;
- const GLuint elementBuffer = ctx->Array.ElementArrayBufferObj->Name;
-
- /* create new array object */
- meta->clear.arrayObj = _mesa_new_array_object(ctx, ~0);
-
- /* save current array object, bind new one */
- _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
- ctx->NewState |= _NEW_ARRAY;
- ctx->Array.NewState |= _NEW_ARRAY_ALL;
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj);
-
- /* one-time setup of vertex arrays (pos, color) */
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, 0);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0);
- _mesa_ColorPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), meta->clear.color);
- _mesa_VertexPointer(3, GL_FLOAT, 3 * sizeof(GLfloat), meta->clear.vertices);
- _mesa_Enable(GL_COLOR_ARRAY);
- _mesa_Enable(GL_VERTEX_ARRAY);
-
- /* restore original array object */
- ctx->NewState |= _NEW_ARRAY;
- ctx->Array.NewState |= _NEW_ARRAY_ALL;
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
- _mesa_reference_array_object(ctx, &arraySave, NULL);
-
- /* restore original buffer objects */
- _mesa_BindBufferARB(GL_ARRAY_BUFFER_ARB, arrayBuffer);
- _mesa_BindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, elementBuffer);
-}
-
-
-
-/**
- * Perform glClear where mask contains only color, depth, and/or stencil.
- *
- * The implementation is based on calling into Mesa to set GL state and
- * performing normal triangle rendering. The intent of this path is to
- * have as generic a path as possible, so that any driver could make use of
- * it.
- */
-void
-meta_clear_tris(struct dri_metaops *meta, GLbitfield mask)
-{
- GLcontext *ctx = meta->ctx;
- GLfloat dst_z;
- struct gl_framebuffer *fb = ctx->DrawBuffer;
- int i;
- GLboolean saved_fp_enable = GL_FALSE, saved_vp_enable = GL_FALSE;
- GLuint saved_shader_program = 0;
- unsigned int saved_active_texture;
- struct gl_array_object *arraySave = NULL;
-
- if (!meta->clear.arrayObj)
- meta_init_clear(meta);
-
- assert((mask & ~(TRI_CLEAR_COLOR_BITS | BUFFER_BIT_DEPTH |
- BUFFER_BIT_STENCIL)) == 0);
-
- _mesa_PushAttrib(GL_COLOR_BUFFER_BIT |
- GL_DEPTH_BUFFER_BIT |
- GL_ENABLE_BIT |
- GL_POLYGON_BIT |
- GL_STENCIL_BUFFER_BIT |
- GL_TRANSFORM_BIT |
- GL_CURRENT_BIT |
- GL_VIEWPORT_BIT);
- saved_active_texture = ctx->Texture.CurrentUnit;
-
- /* Disable existing GL state we don't want to apply to a clear. */
- _mesa_Disable(GL_ALPHA_TEST);
- _mesa_Disable(GL_BLEND);
- _mesa_Disable(GL_CULL_FACE);
- _mesa_Disable(GL_FOG);
- _mesa_Disable(GL_POLYGON_SMOOTH);
- _mesa_Disable(GL_POLYGON_STIPPLE);
- _mesa_Disable(GL_POLYGON_OFFSET_FILL);
- _mesa_Disable(GL_LIGHTING);
- _mesa_Disable(GL_CLIP_PLANE0);
- _mesa_Disable(GL_CLIP_PLANE1);
- _mesa_Disable(GL_CLIP_PLANE2);
- _mesa_Disable(GL_CLIP_PLANE3);
- _mesa_Disable(GL_CLIP_PLANE4);
- _mesa_Disable(GL_CLIP_PLANE5);
- _mesa_PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- if (ctx->Extensions.ARB_fragment_program && ctx->FragmentProgram.Enabled) {
- saved_fp_enable = GL_TRUE;
- _mesa_Disable(GL_FRAGMENT_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_vertex_program && ctx->VertexProgram.Enabled) {
- saved_vp_enable = GL_TRUE;
- _mesa_Disable(GL_VERTEX_PROGRAM_ARB);
- }
- if (ctx->Extensions.ARB_shader_objects && ctx->Shader.CurrentProgram) {
- saved_shader_program = ctx->Shader.CurrentProgram->Name;
- _mesa_UseProgramObjectARB(0);
- }
-
- if (ctx->Texture._EnabledUnits != 0) {
- int i;
-
- for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
- _mesa_ActiveTextureARB(GL_TEXTURE0 + i);
- _mesa_Disable(GL_TEXTURE_1D);
- _mesa_Disable(GL_TEXTURE_2D);
- _mesa_Disable(GL_TEXTURE_3D);
- if (ctx->Extensions.ARB_texture_cube_map)
- _mesa_Disable(GL_TEXTURE_CUBE_MAP_ARB);
- if (ctx->Extensions.NV_texture_rectangle)
- _mesa_Disable(GL_TEXTURE_RECTANGLE_NV);
- if (ctx->Extensions.MESA_texture_array) {
- _mesa_Disable(GL_TEXTURE_1D_ARRAY_EXT);
- _mesa_Disable(GL_TEXTURE_2D_ARRAY_EXT);
- }
- }
- }
-
- /* save current array object, bind our private one */
- _mesa_reference_array_object(ctx, &arraySave, ctx->Array.ArrayObj);
- ctx->NewState |= _NEW_ARRAY;
- ctx->Array.NewState |= _NEW_ARRAY_ALL;
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, meta->clear.arrayObj);
-
- meta_set_passthrough_transform(meta);
-
- for (i = 0; i < 4; i++) {
- COPY_4FV(meta->clear.color[i], ctx->Color.ClearColor);
- }
-
- /* convert clear Z from [0,1] to NDC coord in [-1,1] */
- dst_z = -1.0 + 2.0 * ctx->Depth.Clear;
-
- /* The ClearDepth value is unaffected by DepthRange, so do a default
- * mapping.
- */
- _mesa_DepthRange(0.0, 1.0);
-
- /* Prepare the vertices, which are the same regardless of which buffer we're
- * drawing to.
- */
- meta->clear.vertices[0][0] = fb->_Xmin;
- meta->clear.vertices[0][1] = fb->_Ymin;
- meta->clear.vertices[0][2] = dst_z;
- meta->clear.vertices[1][0] = fb->_Xmax;
- meta->clear.vertices[1][1] = fb->_Ymin;
- meta->clear.vertices[1][2] = dst_z;
- meta->clear.vertices[2][0] = fb->_Xmax;
- meta->clear.vertices[2][1] = fb->_Ymax;
- meta->clear.vertices[2][2] = dst_z;
- meta->clear.vertices[3][0] = fb->_Xmin;
- meta->clear.vertices[3][1] = fb->_Ymax;
- meta->clear.vertices[3][2] = dst_z;
-
- while (mask != 0) {
- GLuint this_mask = 0;
- GLuint color_bit;
-
- color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
- if (color_bit != 0)
- this_mask |= (1 << (color_bit - 1));
-
- /* Clear depth/stencil in the same pass as color. */
- this_mask |= (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL));
-
- /* Select the current color buffer and use the color write mask if
- * we have one, otherwise don't write any color channels.
- */
- if (this_mask & BUFFER_BIT_FRONT_LEFT)
- _mesa_DrawBuffer(GL_FRONT_LEFT);
- else if (this_mask & BUFFER_BIT_BACK_LEFT)
- _mesa_DrawBuffer(GL_BACK_LEFT);
- else if (color_bit != 0)
- _mesa_DrawBuffer(GL_COLOR_ATTACHMENT0 +
- (color_bit - BUFFER_COLOR0 - 1));
- else
- _mesa_ColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
-
- /* Control writing of the depth clear value to depth. */
- if (this_mask & BUFFER_BIT_DEPTH) {
- _mesa_DepthFunc(GL_ALWAYS);
- _mesa_Enable(GL_DEPTH_TEST);
- } else {
- _mesa_Disable(GL_DEPTH_TEST);
- _mesa_DepthMask(GL_FALSE);
- }
-
- /* Control writing of the stencil clear value to stencil. */
- if (this_mask & BUFFER_BIT_STENCIL) {
- _mesa_Enable(GL_STENCIL_TEST);
- _mesa_StencilOpSeparate(GL_FRONT_AND_BACK,
- GL_REPLACE, GL_REPLACE, GL_REPLACE);
- _mesa_StencilFuncSeparate(GL_FRONT_AND_BACK, GL_ALWAYS,
- ctx->Stencil.Clear & 0x7fffffff,
- ctx->Stencil.WriteMask[0]);
- } else {
- _mesa_Disable(GL_STENCIL_TEST);
- }
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- mask &= ~this_mask;
- }
-
- meta_restore_transform(meta);
-
- _mesa_ActiveTextureARB(GL_TEXTURE0 + saved_active_texture);
- if (saved_fp_enable)
- _mesa_Enable(GL_FRAGMENT_PROGRAM_ARB);
- if (saved_vp_enable)
- _mesa_Enable(GL_VERTEX_PROGRAM_ARB);
-
- if (saved_shader_program)
- _mesa_UseProgramObjectARB(saved_shader_program);
-
- _mesa_PopAttrib();
-
- /* restore current array object */
- ctx->NewState |= _NEW_ARRAY;
- ctx->Array.NewState |= _NEW_ARRAY_ALL;
- _mesa_reference_array_object(ctx, &ctx->Array.ArrayObj, arraySave);
- _mesa_reference_array_object(ctx, &arraySave, NULL);
-}
-
void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta)
{
meta->ctx = ctx;
@@ -535,7 +294,5 @@ void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta)
void meta_destroy_metaops(struct dri_metaops *meta)
{
- if (meta->clear.arrayObj)
- _mesa_delete_array_object(meta->ctx, meta->clear.arrayObj);
}
diff --git a/src/mesa/drivers/dri/common/dri_metaops.h b/src/mesa/drivers/dri/common/dri_metaops.h
index bb4079d535..2487145326 100644
--- a/src/mesa/drivers/dri/common/dri_metaops.h
+++ b/src/mesa/drivers/dri/common/dri_metaops.h
@@ -25,25 +25,10 @@
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
**************************************************************************/
+
#ifndef DRI_METAOPS_H
#define DRI_METAOPS_H
-#define TRI_CLEAR_COLOR_BITS (BUFFER_BIT_BACK_LEFT | \
- BUFFER_BIT_FRONT_LEFT | \
- BUFFER_BIT_COLOR0 | \
- BUFFER_BIT_COLOR1 | \
- BUFFER_BIT_COLOR2 | \
- BUFFER_BIT_COLOR3 | \
- BUFFER_BIT_COLOR4 | \
- BUFFER_BIT_COLOR5 | \
- BUFFER_BIT_COLOR6 | \
- BUFFER_BIT_COLOR7)
-
-struct dri_meta_clear {
- struct gl_array_object *arrayObj;
- GLfloat vertices[4][3];
- GLfloat color[4][4];
-};
struct dri_metaops {
GLcontext *ctx;
@@ -69,8 +54,6 @@ struct dri_metaops {
GLint saved_vp_x, saved_vp_y;
GLsizei saved_vp_width, saved_vp_height;
GLenum saved_matrix_mode;
-
- struct dri_meta_clear clear;
};
@@ -91,9 +74,8 @@ void meta_restore_fragment_program(struct dri_metaops *meta);
void meta_set_default_texrect(struct dri_metaops *meta);
void meta_restore_texcoords(struct dri_metaops *meta);
-void meta_clear_tris(struct dri_metaops *meta, GLbitfield mask);
void meta_init_metaops(GLcontext *ctx, struct dri_metaops *meta);
void meta_destroy_metaops(struct dri_metaops *meta);
-#endif
+#endif
diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c
index 1d940603fa..e48e10d7c0 100644
--- a/src/mesa/drivers/dri/common/dri_util.c
+++ b/src/mesa/drivers/dri/common/dri_util.c
@@ -778,7 +778,7 @@ dri2CreateNewScreen(int scrn, int fd,
if (driDriverAPI.InitScreen2 == NULL)
return NULL;
- psp = _mesa_malloc(sizeof(*psp));
+ psp = _mesa_calloc(sizeof(*psp));
if (!psp)
return NULL;
diff --git a/src/mesa/drivers/dri/common/extension_helper.h b/src/mesa/drivers/dri/common/extension_helper.h
index e308fd2831..5e86324eec 100644
--- a/src/mesa/drivers/dri/common/extension_helper.h
+++ b/src/mesa/drivers/dri/common/extension_helper.h
@@ -33,7 +33,7 @@
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char UniformMatrix3fvARB_names[] =
+static const char UniformMatrix3fvARB_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix3fv\0"
"glUniformMatrix3fvARB\0"
@@ -41,7 +41,7 @@ static const char UniformMatrix3fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_multisample)
-static const char SampleCoverageARB_names[] =
+static const char SampleCoverageARB_names[] =
"fi\0" /* Parameter signature */
"glSampleCoverage\0"
"glSampleCoverageARB\0"
@@ -49,7 +49,7 @@ static const char SampleCoverageARB_names[] =
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionFilter1D_names[] =
+static const char ConvolutionFilter1D_names[] =
"iiiiip\0" /* Parameter signature */
"glConvolutionFilter1D\0"
"glConvolutionFilter1DEXT\0"
@@ -57,7 +57,7 @@ static const char ConvolutionFilter1D_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char BeginQueryARB_names[] =
+static const char BeginQueryARB_names[] =
"ii\0" /* Parameter signature */
"glBeginQuery\0"
"glBeginQueryARB\0"
@@ -65,7 +65,7 @@ static const char BeginQueryARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_NV_point_sprite)
-static const char PointParameteriNV_names[] =
+static const char PointParameteriNV_names[] =
"ii\0" /* Parameter signature */
"glPointParameteri\0"
"glPointParameteriNV\0"
@@ -73,14 +73,14 @@ static const char PointParameteriNV_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char GetProgramiv_names[] =
+static const char GetProgramiv_names[] =
"iip\0" /* Parameter signature */
"glGetProgramiv\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3sARB_names[] =
+static const char MultiTexCoord3sARB_names[] =
"iiii\0" /* Parameter signature */
"glMultiTexCoord3s\0"
"glMultiTexCoord3sARB\0"
@@ -88,7 +88,7 @@ static const char MultiTexCoord3sARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3iEXT_names[] =
+static const char SecondaryColor3iEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3i\0"
"glSecondaryColor3iEXT\0"
@@ -96,7 +96,7 @@ static const char SecondaryColor3iEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3fMESA_names[] =
+static const char WindowPos3fMESA_names[] =
"fff\0" /* Parameter signature */
"glWindowPos3f\0"
"glWindowPos3fARB\0"
@@ -105,14 +105,14 @@ static const char WindowPos3fMESA_names[] =
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char PixelTexGenParameterfvSGIS_names[] =
+static const char PixelTexGenParameterfvSGIS_names[] =
"ip\0" /* Parameter signature */
"glPixelTexGenParameterfvSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char ActiveTextureARB_names[] =
+static const char ActiveTextureARB_names[] =
"i\0" /* Parameter signature */
"glActiveTexture\0"
"glActiveTextureARB\0"
@@ -120,7 +120,7 @@ static const char ActiveTextureARB_names[] =
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_blit)
-static const char BlitFramebufferEXT_names[] =
+static const char BlitFramebufferEXT_names[] =
"iiiiiiiiii\0" /* Parameter signature */
"glBlitFramebuffer\0"
"glBlitFramebufferEXT\0"
@@ -128,21 +128,21 @@ static const char BlitFramebufferEXT_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4ubvNV_names[] =
+static const char VertexAttrib4ubvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4ubvNV\0"
"";
#endif
#if defined(need_GL_NV_fragment_program)
-static const char GetProgramNamedParameterdvNV_names[] =
+static const char GetProgramNamedParameterdvNV_names[] =
"iipp\0" /* Parameter signature */
"glGetProgramNamedParameterdvNV\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char Histogram_names[] =
+static const char Histogram_names[] =
"iiii\0" /* Parameter signature */
"glHistogram\0"
"glHistogramEXT\0"
@@ -150,14 +150,14 @@ static const char Histogram_names[] =
#endif
#if defined(need_GL_SGIS_texture4D)
-static const char TexImage4DSGIS_names[] =
+static const char TexImage4DSGIS_names[] =
"iiiiiiiiiip\0" /* Parameter signature */
"glTexImage4DSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2dvMESA_names[] =
+static const char WindowPos2dvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos2dv\0"
"glWindowPos2dvARB\0"
@@ -166,14 +166,14 @@ static const char WindowPos2dvMESA_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor3fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiColor3fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glReplacementCodeuiColor3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_EXT_blend_equation_separate) || defined(need_GL_ATI_blend_equation_separate)
-static const char BlendEquationSeparateEXT_names[] =
+static const char BlendEquationSeparateEXT_names[] =
"ii\0" /* Parameter signature */
"glBlendEquationSeparate\0"
"glBlendEquationSeparateEXT\0"
@@ -182,14 +182,14 @@ static const char BlendEquationSeparateEXT_names[] =
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char ListParameterfSGIX_names[] =
+static const char ListParameterfSGIX_names[] =
"iif\0" /* Parameter signature */
"glListParameterfSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3bEXT_names[] =
+static const char SecondaryColor3bEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3b\0"
"glSecondaryColor3bEXT\0"
@@ -197,21 +197,21 @@ static const char SecondaryColor3bEXT_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord4fColor4fNormal3fVertex4fvSUN_names[] =
+static const char TexCoord4fColor4fNormal3fVertex4fvSUN_names[] =
"pppp\0" /* Parameter signature */
"glTexCoord4fColor4fNormal3fVertex4fvSUN\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4svNV_names[] =
+static const char VertexAttrib4svNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4svNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char GetBufferSubDataARB_names[] =
+static const char GetBufferSubDataARB_names[] =
"iiip\0" /* Parameter signature */
"glGetBufferSubData\0"
"glGetBufferSubDataARB\0"
@@ -219,7 +219,7 @@ static const char GetBufferSubDataARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char BufferSubDataARB_names[] =
+static const char BufferSubDataARB_names[] =
"iiip\0" /* Parameter signature */
"glBufferSubData\0"
"glBufferSubDataARB\0"
@@ -227,21 +227,21 @@ static const char BufferSubDataARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor4ubVertex3fvSUN_names[] =
+static const char TexCoord2fColor4ubVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glTexCoord2fColor4ubVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char AttachShader_names[] =
+static const char AttachShader_names[] =
"ii\0" /* Parameter signature */
"glAttachShader\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2fARB_names[] =
+static const char VertexAttrib2fARB_names[] =
"iff\0" /* Parameter signature */
"glVertexAttrib2f\0"
"glVertexAttrib2fARB\0"
@@ -249,14 +249,14 @@ static const char VertexAttrib2fARB_names[] =
#endif
#if defined(need_GL_MESA_shader_debug)
-static const char GetDebugLogLengthMESA_names[] =
+static const char GetDebugLogLengthMESA_names[] =
"iii\0" /* Parameter signature */
"glGetDebugLogLengthMESA\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3fARB_names[] =
+static const char VertexAttrib3fARB_names[] =
"ifff\0" /* Parameter signature */
"glVertexAttrib3f\0"
"glVertexAttrib3fARB\0"
@@ -264,7 +264,7 @@ static const char VertexAttrib3fARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char GetQueryivARB_names[] =
+static const char GetQueryivARB_names[] =
"iip\0" /* Parameter signature */
"glGetQueryiv\0"
"glGetQueryivARB\0"
@@ -272,7 +272,7 @@ static const char GetQueryivARB_names[] =
#endif
#if defined(need_GL_EXT_texture3D)
-static const char TexImage3D_names[] =
+static const char TexImage3D_names[] =
"iiiiiiiiip\0" /* Parameter signature */
"glTexImage3D\0"
"glTexImage3DEXT\0"
@@ -280,14 +280,14 @@ static const char TexImage3D_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiVertex3fvSUN_names[] =
+static const char ReplacementCodeuiVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
"glReplacementCodeuiVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char GetQueryObjectivARB_names[] =
+static const char GetQueryObjectivARB_names[] =
"iip\0" /* Parameter signature */
"glGetQueryObjectiv\0"
"glGetQueryObjectivARB\0"
@@ -295,14 +295,14 @@ static const char GetQueryObjectivARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexSubImage2DARB_names[] =
+static const char CompressedTexSubImage2DARB_names[] =
"iiiiiiiip\0" /* Parameter signature */
"glCompressedTexSubImage2D\0"
"glCompressedTexSubImage2DARB\0"
@@ -310,14 +310,21 @@ static const char CompressedTexSubImage2DARB_names[] =
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerOutputNV_names[] =
+static const char CombinerOutputNV_names[] =
"iiiiiiiiii\0" /* Parameter signature */
"glCombinerOutputNV\0"
"";
#endif
+#if defined(need_GL_NV_vertex_program)
+static const char VertexAttribs3fvNV_names[] =
+ "iip\0" /* Parameter signature */
+ "glVertexAttribs3fvNV\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform2fARB_names[] =
+static const char Uniform2fARB_names[] =
"iff\0" /* Parameter signature */
"glUniform2f\0"
"glUniform2fARB\0"
@@ -325,7 +332,7 @@ static const char Uniform2fARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1svARB_names[] =
+static const char VertexAttrib1svARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1sv\0"
"glVertexAttrib1svARB\0"
@@ -333,14 +340,14 @@ static const char VertexAttrib1svARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs1dvNV_names[] =
+static const char VertexAttribs1dvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs1dvNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform2ivARB_names[] =
+static const char Uniform2ivARB_names[] =
"iip\0" /* Parameter signature */
"glUniform2iv\0"
"glUniform2ivARB\0"
@@ -348,28 +355,28 @@ static const char Uniform2ivARB_names[] =
#endif
#if defined(need_GL_HP_image_transform)
-static const char GetImageTransformParameterfvHP_names[] =
+static const char GetImageTransformParameterfvHP_names[] =
"iip\0" /* Parameter signature */
"glGetImageTransformParameterfvHP\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightubvARB_names[] =
+static const char WeightubvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightubvARB\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1fvNV_names[] =
+static const char VertexAttrib1fvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1fvNV\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char CopyConvolutionFilter1D_names[] =
+static const char CopyConvolutionFilter1D_names[] =
"iiiii\0" /* Parameter signature */
"glCopyConvolutionFilter1D\0"
"glCopyConvolutionFilter1DEXT\0"
@@ -377,21 +384,28 @@ static const char CopyConvolutionFilter1D_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiNormal3fVertex3fSUN_names[] =
+static const char ReplacementCodeuiNormal3fVertex3fSUN_names[] =
"iffffff\0" /* Parameter signature */
"glReplacementCodeuiNormal3fVertex3fSUN\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char DeleteSync_names[] =
+ "i\0" /* Parameter signature */
+ "glDeleteSync\0"
+ "";
+#endif
+
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentMaterialfvSGIX_names[] =
+static const char FragmentMaterialfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glFragmentMaterialfvSGIX\0"
"";
#endif
#if defined(need_GL_EXT_blend_color)
-static const char BlendColor_names[] =
+static const char BlendColor_names[] =
"ffff\0" /* Parameter signature */
"glBlendColor\0"
"glBlendColorEXT\0"
@@ -399,7 +413,7 @@ static const char BlendColor_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char UniformMatrix4fvARB_names[] =
+static const char UniformMatrix4fvARB_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix4fv\0"
"glUniformMatrix4fvARB\0"
@@ -407,7 +421,7 @@ static const char UniformMatrix4fvARB_names[] =
#endif
#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object)
-static const char DeleteVertexArraysAPPLE_names[] =
+static const char DeleteVertexArraysAPPLE_names[] =
"ip\0" /* Parameter signature */
"glDeleteVertexArrays\0"
"glDeleteVertexArraysAPPLE\0"
@@ -415,28 +429,28 @@ static const char DeleteVertexArraysAPPLE_names[] =
#endif
#if defined(need_GL_SGIX_instruments)
-static const char ReadInstrumentsSGIX_names[] =
+static const char ReadInstrumentsSGIX_names[] =
"i\0" /* Parameter signature */
"glReadInstrumentsSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix2x4fv_names[] =
+static const char UniformMatrix2x4fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix2x4fv\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4ubVertex3fvSUN_names[] =
+static const char Color4ubVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
"glColor4ubVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_texture_array)
-static const char FramebufferTextureLayerEXT_names[] =
+static const char FramebufferTextureLayerEXT_names[] =
"iiiii\0" /* Parameter signature */
"glFramebufferTextureLayer\0"
"glFramebufferTextureLayerEXT\0"
@@ -444,14 +458,14 @@ static const char FramebufferTextureLayerEXT_names[] =
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char GetListParameterfvSGIX_names[] =
+static const char GetListParameterfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetListParameterfvSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NusvARB_names[] =
+static const char VertexAttrib4NusvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Nusv\0"
"glVertexAttrib4NusvARB\0"
@@ -459,35 +473,35 @@ static const char VertexAttrib4NusvARB_names[] =
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4svMESA_names[] =
+static const char WindowPos4svMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos4svMESA\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char CreateProgramObjectARB_names[] =
+static const char CreateProgramObjectARB_names[] =
"\0" /* Parameter signature */
"glCreateProgramObjectARB\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightModelivSGIX_names[] =
+static const char FragmentLightModelivSGIX_names[] =
"ip\0" /* Parameter signature */
"glFragmentLightModelivSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix4x3fv_names[] =
+static const char UniformMatrix4x3fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix4x3fv\0"
"";
#endif
#if defined(need_GL_EXT_texture_object)
-static const char PrioritizeTextures_names[] =
+static const char PrioritizeTextures_names[] =
"ipp\0" /* Parameter signature */
"glPrioritizeTextures\0"
"glPrioritizeTexturesEXT\0"
@@ -495,28 +509,28 @@ static const char PrioritizeTextures_names[] =
#endif
#if defined(need_GL_SGIX_async)
-static const char AsyncMarkerSGIX_names[] =
+static const char AsyncMarkerSGIX_names[] =
"i\0" /* Parameter signature */
"glAsyncMarkerSGIX\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactorubSUN_names[] =
+static const char GlobalAlphaFactorubSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactorubSUN\0"
"";
#endif
#if defined(need_GL_MESA_shader_debug)
-static const char ClearDebugLogMESA_names[] =
+static const char ClearDebugLogMESA_names[] =
"iii\0" /* Parameter signature */
"glClearDebugLogMESA\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char ResetHistogram_names[] =
+static const char ResetHistogram_names[] =
"i\0" /* Parameter signature */
"glResetHistogram\0"
"glResetHistogramEXT\0"
@@ -524,14 +538,14 @@ static const char ResetHistogram_names[] =
#endif
#if defined(need_GL_NV_fragment_program)
-static const char GetProgramNamedParameterfvNV_names[] =
+static const char GetProgramNamedParameterfvNV_names[] =
"iipp\0" /* Parameter signature */
"glGetProgramNamedParameterfvNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_point_parameters) || defined(need_GL_EXT_point_parameters) || defined(need_GL_SGIS_point_parameters)
-static const char PointParameterfEXT_names[] =
+static const char PointParameterfEXT_names[] =
"if\0" /* Parameter signature */
"glPointParameterf\0"
"glPointParameterfARB\0"
@@ -541,35 +555,42 @@ static const char PointParameterfEXT_names[] =
#endif
#if defined(need_GL_SGIX_polynomial_ffd)
-static const char LoadIdentityDeformationMapSGIX_names[] =
+static const char LoadIdentityDeformationMapSGIX_names[] =
"i\0" /* Parameter signature */
"glLoadIdentityDeformationMapSGIX\0"
"";
#endif
#if defined(need_GL_NV_fence)
-static const char GenFencesNV_names[] =
+static const char GenFencesNV_names[] =
"ip\0" /* Parameter signature */
"glGenFencesNV\0"
"";
#endif
#if defined(need_GL_HP_image_transform)
-static const char ImageTransformParameterfHP_names[] =
+static const char ImageTransformParameterfHP_names[] =
"iif\0" /* Parameter signature */
"glImageTransformParameterfHP\0"
"";
#endif
#if defined(need_GL_ARB_matrix_palette)
-static const char MatrixIndexusvARB_names[] =
+static const char MatrixIndexusvARB_names[] =
"ip\0" /* Parameter signature */
"glMatrixIndexusvARB\0"
"";
#endif
+#if defined(need_GL_ARB_draw_elements_base_vertex)
+static const char DrawElementsBaseVertex_names[] =
+ "iiipi\0" /* Parameter signature */
+ "glDrawElementsBaseVertex\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char DisableVertexAttribArrayARB_names[] =
+static const char DisableVertexAttribArrayARB_names[] =
"i\0" /* Parameter signature */
"glDisableVertexAttribArray\0"
"glDisableVertexAttribArrayARB\0"
@@ -577,21 +598,21 @@ static const char DisableVertexAttribArrayARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char StencilMaskSeparate_names[] =
+static const char StencilMaskSeparate_names[] =
"ii\0" /* Parameter signature */
"glStencilMaskSeparate\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char ProgramLocalParameter4dARB_names[] =
+static const char ProgramLocalParameter4dARB_names[] =
"iidddd\0" /* Parameter signature */
"glProgramLocalParameter4dARB\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexImage3DARB_names[] =
+static const char CompressedTexImage3DARB_names[] =
"iiiiiiiip\0" /* Parameter signature */
"glCompressedTexImage3D\0"
"glCompressedTexImage3DARB\0"
@@ -599,7 +620,7 @@ static const char CompressedTexImage3DARB_names[] =
#endif
#if defined(need_GL_EXT_convolution)
-static const char GetConvolutionParameteriv_names[] =
+static const char GetConvolutionParameteriv_names[] =
"iip\0" /* Parameter signature */
"glGetConvolutionParameteriv\0"
"glGetConvolutionParameterivEXT\0"
@@ -607,7 +628,7 @@ static const char GetConvolutionParameteriv_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1fARB_names[] =
+static const char VertexAttrib1fARB_names[] =
"if\0" /* Parameter signature */
"glVertexAttrib1f\0"
"glVertexAttrib1fARB\0"
@@ -615,14 +636,14 @@ static const char VertexAttrib1fARB_names[] =
#endif
#if defined(need_GL_NV_fence)
-static const char TestFenceNV_names[] =
+static const char TestFenceNV_names[] =
"i\0" /* Parameter signature */
"glTestFenceNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1fvARB_names[] =
+static const char MultiTexCoord1fvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord1fv\0"
"glMultiTexCoord1fvARB\0"
@@ -630,56 +651,56 @@ static const char MultiTexCoord1fvARB_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char ColorFragmentOp2ATI_names[] =
+static const char ColorFragmentOp2ATI_names[] =
"iiiiiiiiii\0" /* Parameter signature */
"glColorFragmentOp2ATI\0"
"";
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char SecondaryColorPointerListIBM_names[] =
+static const char SecondaryColorPointerListIBM_names[] =
"iiipi\0" /* Parameter signature */
"glSecondaryColorPointerListIBM\0"
"";
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char GetPixelTexGenParameterivSGIS_names[] =
+static const char GetPixelTexGenParameterivSGIS_names[] =
"ip\0" /* Parameter signature */
"glGetPixelTexGenParameterivSGIS\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4fNV_names[] =
+static const char VertexAttrib4fNV_names[] =
"iffff\0" /* Parameter signature */
"glVertexAttrib4fNV\0"
"";
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeubSUN_names[] =
+static const char ReplacementCodeubSUN_names[] =
"i\0" /* Parameter signature */
"glReplacementCodeubSUN\0"
"";
#endif
#if defined(need_GL_SGIX_async)
-static const char FinishAsyncSGIX_names[] =
+static const char FinishAsyncSGIX_names[] =
"p\0" /* Parameter signature */
"glFinishAsyncSGIX\0"
"";
#endif
#if defined(need_GL_MESA_shader_debug)
-static const char GetDebugLogMESA_names[] =
+static const char GetDebugLogMESA_names[] =
"iiiipp\0" /* Parameter signature */
"glGetDebugLogMESA\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
-static const char FogCoorddEXT_names[] =
+static const char FogCoorddEXT_names[] =
"d\0" /* Parameter signature */
"glFogCoordd\0"
"glFogCoorddEXT\0"
@@ -687,14 +708,14 @@ static const char FogCoorddEXT_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4ubVertex3fSUN_names[] =
+static const char Color4ubVertex3fSUN_names[] =
"iiiifff\0" /* Parameter signature */
"glColor4ubVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
-static const char FogCoordfEXT_names[] =
+static const char FogCoordfEXT_names[] =
"f\0" /* Parameter signature */
"glFogCoordf\0"
"glFogCoordfEXT\0"
@@ -702,35 +723,35 @@ static const char FogCoordfEXT_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fVertex3fSUN_names[] =
+static const char TexCoord2fVertex3fSUN_names[] =
"fffff\0" /* Parameter signature */
"glTexCoord2fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactoriSUN_names[] =
+static const char GlobalAlphaFactoriSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactoriSUN\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2dNV_names[] =
+static const char VertexAttrib2dNV_names[] =
"idd\0" /* Parameter signature */
"glVertexAttrib2dNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char GetProgramInfoLog_names[] =
+static const char GetProgramInfoLog_names[] =
"iipp\0" /* Parameter signature */
"glGetProgramInfoLog\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NbvARB_names[] =
+static const char VertexAttrib4NbvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Nbv\0"
"glVertexAttrib4NbvARB\0"
@@ -738,7 +759,7 @@ static const char VertexAttrib4NbvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
-static const char GetActiveAttribARB_names[] =
+static const char GetActiveAttribARB_names[] =
"iiipppp\0" /* Parameter signature */
"glGetActiveAttrib\0"
"glGetActiveAttribARB\0"
@@ -746,84 +767,91 @@ static const char GetActiveAttribARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4ubNV_names[] =
+static const char VertexAttrib4ubNV_names[] =
"iiiii\0" /* Parameter signature */
"glVertexAttrib4ubNV\0"
"";
#endif
+#if defined(need_GL_APPLE_texture_range)
+static const char TextureRangeAPPLE_names[] =
+ "iip\0" /* Parameter signature */
+ "glTextureRangeAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor4fNormal3fVertex3fSUN_names[] =
+static const char TexCoord2fColor4fNormal3fVertex3fSUN_names[] =
"ffffffffffff\0" /* Parameter signature */
"glTexCoord2fColor4fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerParameterfvNV_names[] =
+static const char CombinerParameterfvNV_names[] =
"ip\0" /* Parameter signature */
"glCombinerParameterfvNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs3dvNV_names[] =
+static const char VertexAttribs3dvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs3dvNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs4fvNV_names[] =
+static const char VertexAttribs4fvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs4fvNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_array_range)
-static const char VertexArrayRangeNV_names[] =
+static const char VertexArrayRangeNV_names[] =
"ip\0" /* Parameter signature */
"glVertexArrayRangeNV\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightiSGIX_names[] =
+static const char FragmentLightiSGIX_names[] =
"iii\0" /* Parameter signature */
"glFragmentLightiSGIX\0"
"";
#endif
#if defined(need_GL_EXT_polygon_offset)
-static const char PolygonOffsetEXT_names[] =
+static const char PolygonOffsetEXT_names[] =
"ff\0" /* Parameter signature */
"glPolygonOffsetEXT\0"
"";
#endif
#if defined(need_GL_SGIX_async)
-static const char PollAsyncSGIX_names[] =
+static const char PollAsyncSGIX_names[] =
"p\0" /* Parameter signature */
"glPollAsyncSGIX\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char DeleteFragmentShaderATI_names[] =
+static const char DeleteFragmentShaderATI_names[] =
"i\0" /* Parameter signature */
"glDeleteFragmentShaderATI\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fNormal3fVertex3fvSUN_names[] =
+static const char TexCoord2fNormal3fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glTexCoord2fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix)
-static const char MultTransposeMatrixdARB_names[] =
+static const char MultTransposeMatrixdARB_names[] =
"p\0" /* Parameter signature */
"glMultTransposeMatrixd\0"
"glMultTransposeMatrixdARB\0"
@@ -831,7 +859,7 @@ static const char MultTransposeMatrixdARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2svMESA_names[] =
+static const char WindowPos2svMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos2sv\0"
"glWindowPos2svARB\0"
@@ -840,7 +868,7 @@ static const char WindowPos2svMESA_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexImage1DARB_names[] =
+static const char CompressedTexImage1DARB_names[] =
"iiiiiip\0" /* Parameter signature */
"glCompressedTexImage1D\0"
"glCompressedTexImage1DARB\0"
@@ -848,35 +876,35 @@ static const char CompressedTexImage1DARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2sNV_names[] =
+static const char VertexAttrib2sNV_names[] =
"iii\0" /* Parameter signature */
"glVertexAttrib2sNV\0"
"";
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char NormalPointerListIBM_names[] =
+static const char NormalPointerListIBM_names[] =
"iipi\0" /* Parameter signature */
"glNormalPointerListIBM\0"
"";
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char IndexPointerEXT_names[] =
+static const char IndexPointerEXT_names[] =
"iiip\0" /* Parameter signature */
"glIndexPointerEXT\0"
"";
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char NormalPointerEXT_names[] =
+static const char NormalPointerEXT_names[] =
"iiip\0" /* Parameter signature */
"glNormalPointerEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3dARB_names[] =
+static const char MultiTexCoord3dARB_names[] =
"iddd\0" /* Parameter signature */
"glMultiTexCoord3d\0"
"glMultiTexCoord3dARB\0"
@@ -884,7 +912,7 @@ static const char MultiTexCoord3dARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2iARB_names[] =
+static const char MultiTexCoord2iARB_names[] =
"iii\0" /* Parameter signature */
"glMultiTexCoord2i\0"
"glMultiTexCoord2iARB\0"
@@ -892,14 +920,14 @@ static const char MultiTexCoord2iARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN_names[] =
"iffffffff\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2svARB_names[] =
+static const char MultiTexCoord2svARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord2sv\0"
"glMultiTexCoord2svARB\0"
@@ -907,14 +935,14 @@ static const char MultiTexCoord2svARB_names[] =
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeubvSUN_names[] =
+static const char ReplacementCodeubvSUN_names[] =
"p\0" /* Parameter signature */
"glReplacementCodeubvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform3iARB_names[] =
+static const char Uniform3iARB_names[] =
"iiii\0" /* Parameter signature */
"glUniform3i\0"
"glUniform3iARB\0"
@@ -922,49 +950,49 @@ static const char Uniform3iARB_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char GetFragmentMaterialfvSGIX_names[] =
+static const char GetFragmentMaterialfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetFragmentMaterialfvSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char GetShaderInfoLog_names[] =
+static const char GetShaderInfoLog_names[] =
"iipp\0" /* Parameter signature */
"glGetShaderInfoLog\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightivARB_names[] =
+static const char WeightivARB_names[] =
"ip\0" /* Parameter signature */
"glWeightivARB\0"
"";
#endif
#if defined(need_GL_SGIX_instruments)
-static const char PollInstrumentsSGIX_names[] =
+static const char PollInstrumentsSGIX_names[] =
"p\0" /* Parameter signature */
"glPollInstrumentsSGIX\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactordSUN_names[] =
+static const char GlobalAlphaFactordSUN_names[] =
"d\0" /* Parameter signature */
"glGlobalAlphaFactordSUN\0"
"";
#endif
-#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs3fvNV_names[] =
+#if defined(need_GL_NV_register_combiners)
+static const char GetFinalCombinerInputParameterfvNV_names[] =
"iip\0" /* Parameter signature */
- "glVertexAttribs3fvNV\0"
+ "glGetFinalCombinerInputParameterfvNV\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char GenerateMipmapEXT_names[] =
+static const char GenerateMipmapEXT_names[] =
"i\0" /* Parameter signature */
"glGenerateMipmap\0"
"glGenerateMipmapEXT\0"
@@ -972,35 +1000,35 @@ static const char GenerateMipmapEXT_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char SetFragmentShaderConstantATI_names[] =
+static const char SetFragmentShaderConstantATI_names[] =
"ip\0" /* Parameter signature */
"glSetFragmentShaderConstantATI\0"
"";
#endif
#if defined(need_GL_NV_evaluators)
-static const char GetMapAttribParameterivNV_names[] =
+static const char GetMapAttribParameterivNV_names[] =
"iiip\0" /* Parameter signature */
"glGetMapAttribParameterivNV\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char CreateShaderObjectARB_names[] =
+static const char CreateShaderObjectARB_names[] =
"i\0" /* Parameter signature */
"glCreateShaderObjectARB\0"
"";
#endif
#if defined(need_GL_SGIS_sharpen_texture)
-static const char GetSharpenTexFuncSGIS_names[] =
+static const char GetSharpenTexFuncSGIS_names[] =
"ip\0" /* Parameter signature */
"glGetSharpenTexFuncSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char BufferDataARB_names[] =
+static const char BufferDataARB_names[] =
"iipi\0" /* Parameter signature */
"glBufferData\0"
"glBufferDataARB\0"
@@ -1008,42 +1036,42 @@ static const char BufferDataARB_names[] =
#endif
#if defined(need_GL_NV_vertex_array_range)
-static const char FlushVertexArrayRangeNV_names[] =
+static const char FlushVertexArrayRangeNV_names[] =
"\0" /* Parameter signature */
"glFlushVertexArrayRangeNV\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char SampleMapATI_names[] =
+static const char SampleMapATI_names[] =
"iii\0" /* Parameter signature */
"glSampleMapATI\0"
"";
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char VertexPointerEXT_names[] =
+static const char VertexPointerEXT_names[] =
"iiiip\0" /* Parameter signature */
"glVertexPointerEXT\0"
"";
#endif
#if defined(need_GL_SGIS_texture_filter4)
-static const char GetTexFilterFuncSGIS_names[] =
+static const char GetTexFilterFuncSGIS_names[] =
"iip\0" /* Parameter signature */
"glGetTexFilterFuncSGIS\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char GetCombinerOutputParameterfvNV_names[] =
+static const char GetCombinerOutputParameterfvNV_names[] =
"iiip\0" /* Parameter signature */
"glGetCombinerOutputParameterfvNV\0"
"";
#endif
#if defined(need_GL_EXT_subtexture)
-static const char TexSubImage1D_names[] =
+static const char TexSubImage1D_names[] =
"iiiiiip\0" /* Parameter signature */
"glTexSubImage1D\0"
"glTexSubImage1DEXT\0"
@@ -1051,36 +1079,43 @@ static const char TexSubImage1D_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1sARB_names[] =
+static const char VertexAttrib1sARB_names[] =
"ii\0" /* Parameter signature */
"glVertexAttrib1s\0"
"glVertexAttrib1sARB\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char FenceSync_names[] =
+ "ii\0" /* Parameter signature */
+ "glFenceSync\0"
+ "";
+#endif
+
#if defined(need_GL_NV_register_combiners)
-static const char FinalCombinerInputNV_names[] =
+static const char FinalCombinerInputNV_names[] =
"iiii\0" /* Parameter signature */
"glFinalCombinerInputNV\0"
"";
#endif
#if defined(need_GL_SGIX_flush_raster)
-static const char FlushRasterSGIX_names[] =
+static const char FlushRasterSGIX_names[] =
"\0" /* Parameter signature */
"glFlushRasterSGIX\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fVertex3fSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fVertex3fSUN_names[] =
"ifffff\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform1fARB_names[] =
+static const char Uniform1fARB_names[] =
"if\0" /* Parameter signature */
"glUniform1f\0"
"glUniform1fARB\0"
@@ -1088,7 +1123,7 @@ static const char Uniform1fARB_names[] =
#endif
#if defined(need_GL_EXT_texture_object)
-static const char AreTexturesResident_names[] =
+static const char AreTexturesResident_names[] =
"ipp\0" /* Parameter signature */
"glAreTexturesResident\0"
"glAreTexturesResidentEXT\0"
@@ -1096,7 +1131,7 @@ static const char AreTexturesResident_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ATI_separate_stencil)
-static const char StencilOpSeparate_names[] =
+static const char StencilOpSeparate_names[] =
"iiii\0" /* Parameter signature */
"glStencilOpSeparate\0"
"glStencilOpSeparateATI\0"
@@ -1104,7 +1139,7 @@ static const char StencilOpSeparate_names[] =
#endif
#if defined(need_GL_SGI_color_table)
-static const char ColorTableParameteriv_names[] =
+static const char ColorTableParameteriv_names[] =
"iip\0" /* Parameter signature */
"glColorTableParameteriv\0"
"glColorTableParameterivSGI\0"
@@ -1112,14 +1147,14 @@ static const char ColorTableParameteriv_names[] =
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char FogCoordPointerListIBM_names[] =
+static const char FogCoordPointerListIBM_names[] =
"iipi\0" /* Parameter signature */
"glFogCoordPointerListIBM\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3dMESA_names[] =
+static const char WindowPos3dMESA_names[] =
"ddd\0" /* Parameter signature */
"glWindowPos3d\0"
"glWindowPos3dARB\0"
@@ -1128,7 +1163,7 @@ static const char WindowPos3dMESA_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_point_parameters) || defined(need_GL_EXT_point_parameters) || defined(need_GL_SGIS_point_parameters)
-static const char PointParameterfvEXT_names[] =
+static const char PointParameterfvEXT_names[] =
"ip\0" /* Parameter signature */
"glPointParameterfv\0"
"glPointParameterfvARB\0"
@@ -1138,7 +1173,7 @@ static const char PointParameterfvEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2fvMESA_names[] =
+static const char WindowPos2fvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos2fv\0"
"glWindowPos2fvARB\0"
@@ -1147,7 +1182,7 @@ static const char WindowPos2fvMESA_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3bvEXT_names[] =
+static const char SecondaryColor3bvEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3bv\0"
"glSecondaryColor3bvEXT\0"
@@ -1155,35 +1190,35 @@ static const char SecondaryColor3bvEXT_names[] =
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char VertexPointerListIBM_names[] =
+static const char VertexPointerListIBM_names[] =
"iiipi\0" /* Parameter signature */
"glVertexPointerListIBM\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramLocalParameterfvARB_names[] =
+static const char GetProgramLocalParameterfvARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramLocalParameterfvARB\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentMaterialfSGIX_names[] =
+static const char FragmentMaterialfSGIX_names[] =
"iif\0" /* Parameter signature */
"glFragmentMaterialfSGIX\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fNormal3fVertex3fSUN_names[] =
+static const char TexCoord2fNormal3fVertex3fSUN_names[] =
"ffffffff\0" /* Parameter signature */
"glTexCoord2fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char RenderbufferStorageEXT_names[] =
+static const char RenderbufferStorageEXT_names[] =
"iiii\0" /* Parameter signature */
"glRenderbufferStorage\0"
"glRenderbufferStorageEXT\0"
@@ -1191,28 +1226,28 @@ static const char RenderbufferStorageEXT_names[] =
#endif
#if defined(need_GL_NV_fence)
-static const char IsFenceNV_names[] =
+static const char IsFenceNV_names[] =
"i\0" /* Parameter signature */
"glIsFenceNV\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char AttachObjectARB_names[] =
+static const char AttachObjectARB_names[] =
"ii\0" /* Parameter signature */
"glAttachObjectARB\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char GetFragmentLightivSGIX_names[] =
+static const char GetFragmentLightivSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetFragmentLightivSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char UniformMatrix2fvARB_names[] =
+static const char UniformMatrix2fvARB_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix2fv\0"
"glUniformMatrix2fvARB\0"
@@ -1220,7 +1255,7 @@ static const char UniformMatrix2fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2fARB_names[] =
+static const char MultiTexCoord2fARB_names[] =
"iff\0" /* Parameter signature */
"glMultiTexCoord2f\0"
"glMultiTexCoord2fARB\0"
@@ -1228,7 +1263,7 @@ static const char MultiTexCoord2fARB_names[] =
#endif
#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture)
-static const char ColorTable_names[] =
+static const char ColorTable_names[] =
"iiiiip\0" /* Parameter signature */
"glColorTable\0"
"glColorTableSGI\0"
@@ -1237,14 +1272,14 @@ static const char ColorTable_names[] =
#endif
#if defined(need_GL_NV_evaluators)
-static const char MapControlPointsNV_names[] =
+static const char MapControlPointsNV_names[] =
"iiiiiiiip\0" /* Parameter signature */
"glMapControlPointsNV\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionFilter2D_names[] =
+static const char ConvolutionFilter2D_names[] =
"iiiiiip\0" /* Parameter signature */
"glConvolutionFilter2D\0"
"glConvolutionFilter2DEXT\0"
@@ -1252,14 +1287,14 @@ static const char ConvolutionFilter2D_names[] =
#endif
#if defined(need_GL_NV_evaluators)
-static const char MapParameterfvNV_names[] =
+static const char MapParameterfvNV_names[] =
"iip\0" /* Parameter signature */
"glMapParameterfvNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3dvARB_names[] =
+static const char VertexAttrib3dvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3dv\0"
"glVertexAttrib3dvARB\0"
@@ -1267,14 +1302,14 @@ static const char VertexAttrib3dvARB_names[] =
#endif
#if defined(need_GL_PGI_misc_hints)
-static const char HintPGI_names[] =
+static const char HintPGI_names[] =
"ii\0" /* Parameter signature */
"glHintPGI\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionParameteriv_names[] =
+static const char ConvolutionParameteriv_names[] =
"iip\0" /* Parameter signature */
"glConvolutionParameteriv\0"
"glConvolutionParameterivEXT\0"
@@ -1282,28 +1317,28 @@ static const char ConvolutionParameteriv_names[] =
#endif
#if defined(need_GL_EXT_cull_vertex)
-static const char CullParameterdvEXT_names[] =
+static const char CullParameterdvEXT_names[] =
"ip\0" /* Parameter signature */
"glCullParameterdvEXT\0"
"";
#endif
#if defined(need_GL_NV_fragment_program)
-static const char ProgramNamedParameter4fNV_names[] =
+static const char ProgramNamedParameter4fNV_names[] =
"iipffff\0" /* Parameter signature */
"glProgramNamedParameter4fNV\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color3fVertex3fSUN_names[] =
+static const char Color3fVertex3fSUN_names[] =
"ffffff\0" /* Parameter signature */
"glColor3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char ProgramEnvParameter4fvARB_names[] =
+static const char ProgramEnvParameter4fvARB_names[] =
"iip\0" /* Parameter signature */
"glProgramEnvParameter4fvARB\0"
"glProgramParameter4fvNV\0"
@@ -1311,14 +1346,14 @@ static const char ProgramEnvParameter4fvARB_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightModeliSGIX_names[] =
+static const char FragmentLightModeliSGIX_names[] =
"ii\0" /* Parameter signature */
"glFragmentLightModeliSGIX\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionParameterfv_names[] =
+static const char ConvolutionParameterfv_names[] =
"iip\0" /* Parameter signature */
"glConvolutionParameterfv\0"
"glConvolutionParameterfvEXT\0"
@@ -1326,35 +1361,42 @@ static const char ConvolutionParameterfv_names[] =
#endif
#if defined(need_GL_3DFX_tbuffer)
-static const char TbufferMask3DFX_names[] =
+static const char TbufferMask3DFX_names[] =
"i\0" /* Parameter signature */
"glTbufferMask3DFX\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char LoadProgramNV_names[] =
+static const char LoadProgramNV_names[] =
"iiip\0" /* Parameter signature */
"glLoadProgramNV\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char WaitSync_names[] =
+ "iii\0" /* Parameter signature */
+ "glWaitSync\0"
+ "";
+#endif
+
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4fvNV_names[] =
+static const char VertexAttrib4fvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4fvNV\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char GetAttachedObjectsARB_names[] =
+static const char GetAttachedObjectsARB_names[] =
"iipp\0" /* Parameter signature */
"glGetAttachedObjectsARB\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform3fvARB_names[] =
+static const char Uniform3fvARB_names[] =
"iip\0" /* Parameter signature */
"glUniform3fv\0"
"glUniform3fvARB\0"
@@ -1362,7 +1404,7 @@ static const char Uniform3fvARB_names[] =
#endif
#if defined(need_GL_EXT_draw_range_elements)
-static const char DrawRangeElements_names[] =
+static const char DrawRangeElements_names[] =
"iiiiip\0" /* Parameter signature */
"glDrawRangeElements\0"
"glDrawRangeElementsEXT\0"
@@ -1370,14 +1412,14 @@ static const char DrawRangeElements_names[] =
#endif
#if defined(need_GL_SGIX_sprite)
-static const char SpriteParameterfvSGIX_names[] =
+static const char SpriteParameterfvSGIX_names[] =
"ip\0" /* Parameter signature */
"glSpriteParameterfvSGIX\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char CheckFramebufferStatusEXT_names[] =
+static const char CheckFramebufferStatusEXT_names[] =
"i\0" /* Parameter signature */
"glCheckFramebufferStatus\0"
"glCheckFramebufferStatusEXT\0"
@@ -1385,21 +1427,21 @@ static const char CheckFramebufferStatusEXT_names[] =
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactoruiSUN_names[] =
+static const char GlobalAlphaFactoruiSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactoruiSUN\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char GetHandleARB_names[] =
+static const char GetHandleARB_names[] =
"i\0" /* Parameter signature */
"glGetHandleARB\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char GetVertexAttribivARB_names[] =
+static const char GetVertexAttribivARB_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribiv\0"
"glGetVertexAttribivARB\0"
@@ -1407,21 +1449,21 @@ static const char GetVertexAttribivARB_names[] =
#endif
#if defined(need_GL_NV_register_combiners)
-static const char GetCombinerInputParameterfvNV_names[] =
+static const char GetCombinerInputParameterfvNV_names[] =
"iiiip\0" /* Parameter signature */
"glGetCombinerInputParameterfvNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char CreateProgram_names[] =
+static const char CreateProgram_names[] =
"\0" /* Parameter signature */
"glCreateProgram\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix)
-static const char LoadTransposeMatrixdARB_names[] =
+static const char LoadTransposeMatrixdARB_names[] =
"p\0" /* Parameter signature */
"glLoadTransposeMatrixd\0"
"glLoadTransposeMatrixdARB\0"
@@ -1429,7 +1471,7 @@ static const char LoadTransposeMatrixdARB_names[] =
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetMinmax_names[] =
+static const char GetMinmax_names[] =
"iiiip\0" /* Parameter signature */
"glGetMinmax\0"
"glGetMinmaxEXT\0"
@@ -1437,14 +1479,14 @@ static const char GetMinmax_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char StencilFuncSeparate_names[] =
+static const char StencilFuncSeparate_names[] =
"iiii\0" /* Parameter signature */
"glStencilFuncSeparate\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3sEXT_names[] =
+static const char SecondaryColor3sEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3s\0"
"glSecondaryColor3sEXT\0"
@@ -1452,28 +1494,28 @@ static const char SecondaryColor3sEXT_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color3fVertex3fvSUN_names[] =
+static const char Color3fVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
"glColor3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactorbSUN_names[] =
+static const char GlobalAlphaFactorbSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactorbSUN\0"
"";
#endif
#if defined(need_GL_HP_image_transform)
-static const char ImageTransformParameterfvHP_names[] =
+static const char ImageTransformParameterfvHP_names[] =
"iip\0" /* Parameter signature */
"glImageTransformParameterfvHP\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4ivARB_names[] =
+static const char VertexAttrib4ivARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4iv\0"
"glVertexAttrib4ivARB\0"
@@ -1481,28 +1523,28 @@ static const char VertexAttrib4ivARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3fNV_names[] =
+static const char VertexAttrib3fNV_names[] =
"ifff\0" /* Parameter signature */
"glVertexAttrib3fNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs2dvNV_names[] =
+static const char VertexAttribs2dvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs2dvNV\0"
"";
#endif
#if defined(need_GL_EXT_timer_query)
-static const char GetQueryObjectui64vEXT_names[] =
+static const char GetQueryObjectui64vEXT_names[] =
"iip\0" /* Parameter signature */
"glGetQueryObjectui64vEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3fvARB_names[] =
+static const char MultiTexCoord3fvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord3fv\0"
"glMultiTexCoord3fvARB\0"
@@ -1510,7 +1552,7 @@ static const char MultiTexCoord3fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3dEXT_names[] =
+static const char SecondaryColor3dEXT_names[] =
"ddd\0" /* Parameter signature */
"glSecondaryColor3d\0"
"glSecondaryColor3dEXT\0"
@@ -1518,42 +1560,42 @@ static const char SecondaryColor3dEXT_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetProgramParameterfvNV_names[] =
+static const char GetProgramParameterfvNV_names[] =
"iiip\0" /* Parameter signature */
"glGetProgramParameterfvNV\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char TangentPointerEXT_names[] =
+static const char TangentPointerEXT_names[] =
"iip\0" /* Parameter signature */
"glTangentPointerEXT\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4fNormal3fVertex3fvSUN_names[] =
+static const char Color4fNormal3fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glColor4fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_SGIX_instruments)
-static const char GetInstrumentsSGIX_names[] =
+static const char GetInstrumentsSGIX_names[] =
"\0" /* Parameter signature */
"glGetInstrumentsSGIX\0"
"";
#endif
#if defined(need_GL_NV_evaluators)
-static const char EvalMapsNV_names[] =
+static const char EvalMapsNV_names[] =
"ii\0" /* Parameter signature */
"glEvalMapsNV\0"
"";
#endif
#if defined(need_GL_EXT_subtexture)
-static const char TexSubImage2D_names[] =
+static const char TexSubImage2D_names[] =
"iiiiiiiip\0" /* Parameter signature */
"glTexSubImage2D\0"
"glTexSubImage2DEXT\0"
@@ -1561,21 +1603,28 @@ static const char TexSubImage2D_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightivSGIX_names[] =
+static const char FragmentLightivSGIX_names[] =
"iip\0" /* Parameter signature */
"glFragmentLightivSGIX\0"
"";
#endif
+#if defined(need_GL_APPLE_texture_range)
+static const char GetTexParameterPointervAPPLE_names[] =
+ "iip\0" /* Parameter signature */
+ "glGetTexParameterPointervAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_pixel_transform)
-static const char PixelTransformParameterfvEXT_names[] =
+static const char PixelTransformParameterfvEXT_names[] =
"iip\0" /* Parameter signature */
"glPixelTransformParameterfvEXT\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4bvARB_names[] =
+static const char VertexAttrib4bvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4bv\0"
"glVertexAttrib4bvARB\0"
@@ -1583,14 +1632,14 @@ static const char VertexAttrib4bvARB_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char AlphaFragmentOp2ATI_names[] =
+static const char AlphaFragmentOp2ATI_names[] =
"iiiiiiiii\0" /* Parameter signature */
"glAlphaFragmentOp2ATI\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4sARB_names[] =
+static const char MultiTexCoord4sARB_names[] =
"iiiii\0" /* Parameter signature */
"glMultiTexCoord4s\0"
"glMultiTexCoord4sARB\0"
@@ -1598,28 +1647,28 @@ static const char MultiTexCoord4sARB_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char GetFragmentMaterialivSGIX_names[] =
+static const char GetFragmentMaterialivSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetFragmentMaterialivSGIX\0"
"";
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4dMESA_names[] =
+static const char WindowPos4dMESA_names[] =
"dddd\0" /* Parameter signature */
"glWindowPos4dMESA\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightPointerARB_names[] =
+static const char WeightPointerARB_names[] =
"iiip\0" /* Parameter signature */
"glWeightPointerARB\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2dMESA_names[] =
+static const char WindowPos2dMESA_names[] =
"dd\0" /* Parameter signature */
"glWindowPos2d\0"
"glWindowPos2dARB\0"
@@ -1628,7 +1677,7 @@ static const char WindowPos2dMESA_names[] =
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char FramebufferTexture3DEXT_names[] =
+static const char FramebufferTexture3DEXT_names[] =
"iiiiii\0" /* Parameter signature */
"glFramebufferTexture3D\0"
"glFramebufferTexture3DEXT\0"
@@ -1636,7 +1685,7 @@ static const char FramebufferTexture3DEXT_names[] =
#endif
#if defined(need_GL_EXT_blend_minmax)
-static const char BlendEquation_names[] =
+static const char BlendEquation_names[] =
"i\0" /* Parameter signature */
"glBlendEquation\0"
"glBlendEquationEXT\0"
@@ -1644,14 +1693,14 @@ static const char BlendEquation_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3dNV_names[] =
+static const char VertexAttrib3dNV_names[] =
"iddd\0" /* Parameter signature */
"glVertexAttrib3dNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3dARB_names[] =
+static const char VertexAttrib3dARB_names[] =
"iddd\0" /* Parameter signature */
"glVertexAttrib3d\0"
"glVertexAttrib3dARB\0"
@@ -1659,14 +1708,14 @@ static const char VertexAttrib3dARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
"ppppp\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4fARB_names[] =
+static const char VertexAttrib4fARB_names[] =
"iffff\0" /* Parameter signature */
"glVertexAttrib4f\0"
"glVertexAttrib4fARB\0"
@@ -1674,14 +1723,14 @@ static const char VertexAttrib4fARB_names[] =
#endif
#if defined(need_GL_EXT_index_func)
-static const char IndexFuncEXT_names[] =
+static const char IndexFuncEXT_names[] =
"if\0" /* Parameter signature */
"glIndexFuncEXT\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char FramebufferTexture2DEXT_names[] =
+static const char FramebufferTexture2DEXT_names[] =
"iiiii\0" /* Parameter signature */
"glFramebufferTexture2D\0"
"glFramebufferTexture2DEXT\0"
@@ -1689,7 +1738,7 @@ static const char FramebufferTexture2DEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2dvARB_names[] =
+static const char MultiTexCoord2dvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord2dv\0"
"glMultiTexCoord2dvARB\0"
@@ -1697,21 +1746,21 @@ static const char MultiTexCoord2dvARB_names[] =
#endif
#if defined(need_GL_EXT_cull_vertex)
-static const char CullParameterfvEXT_names[] =
+static const char CullParameterfvEXT_names[] =
"ip\0" /* Parameter signature */
"glCullParameterfvEXT\0"
"";
#endif
#if defined(need_GL_NV_fragment_program)
-static const char ProgramNamedParameter4fvNV_names[] =
+static const char ProgramNamedParameter4fvNV_names[] =
"iipp\0" /* Parameter signature */
"glProgramNamedParameter4fvNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColorPointerEXT_names[] =
+static const char SecondaryColorPointerEXT_names[] =
"iiip\0" /* Parameter signature */
"glSecondaryColorPointer\0"
"glSecondaryColorPointerEXT\0"
@@ -1719,7 +1768,7 @@ static const char SecondaryColorPointerEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4fvARB_names[] =
+static const char VertexAttrib4fvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4fv\0"
"glVertexAttrib4fvARB\0"
@@ -1727,14 +1776,14 @@ static const char VertexAttrib4fvARB_names[] =
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char ColorPointerListIBM_names[] =
+static const char ColorPointerListIBM_names[] =
"iiipi\0" /* Parameter signature */
"glColorPointerListIBM\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char GetActiveUniformARB_names[] =
+static const char GetActiveUniformARB_names[] =
"iiipppp\0" /* Parameter signature */
"glGetActiveUniform\0"
"glGetActiveUniformARB\0"
@@ -1742,14 +1791,14 @@ static const char GetActiveUniformARB_names[] =
#endif
#if defined(need_GL_HP_image_transform)
-static const char ImageTransformParameteriHP_names[] =
+static const char ImageTransformParameteriHP_names[] =
"iii\0" /* Parameter signature */
"glImageTransformParameteriHP\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1svARB_names[] =
+static const char MultiTexCoord1svARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord1sv\0"
"glMultiTexCoord1svARB\0"
@@ -1757,7 +1806,7 @@ static const char MultiTexCoord1svARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char EndQueryARB_names[] =
+static const char EndQueryARB_names[] =
"i\0" /* Parameter signature */
"glEndQuery\0"
"glEndQueryARB\0"
@@ -1765,42 +1814,42 @@ static const char EndQueryARB_names[] =
#endif
#if defined(need_GL_NV_fence)
-static const char DeleteFencesNV_names[] =
+static const char DeleteFencesNV_names[] =
"ip\0" /* Parameter signature */
"glDeleteFencesNV\0"
"";
#endif
#if defined(need_GL_SGIX_polynomial_ffd)
-static const char DeformationMap3dSGIX_names[] =
+static const char DeformationMap3dSGIX_names[] =
"iddiiddiiddiip\0" /* Parameter signature */
"glDeformationMap3dSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char IsShader_names[] =
+static const char IsShader_names[] =
"i\0" /* Parameter signature */
"glIsShader\0"
"";
#endif
#if defined(need_GL_HP_image_transform)
-static const char GetImageTransformParameterivHP_names[] =
+static const char GetImageTransformParameterivHP_names[] =
"iip\0" /* Parameter signature */
"glGetImageTransformParameterivHP\0"
"";
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4ivMESA_names[] =
+static const char WindowPos4ivMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos4ivMESA\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3svARB_names[] =
+static const char MultiTexCoord3svARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord3sv\0"
"glMultiTexCoord3svARB\0"
@@ -1808,7 +1857,7 @@ static const char MultiTexCoord3svARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4iARB_names[] =
+static const char MultiTexCoord4iARB_names[] =
"iiiii\0" /* Parameter signature */
"glMultiTexCoord4i\0"
"glMultiTexCoord4iARB\0"
@@ -1816,21 +1865,21 @@ static const char MultiTexCoord4iARB_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3ivEXT_names[] =
+static const char Binormal3ivEXT_names[] =
"p\0" /* Parameter signature */
"glBinormal3ivEXT\0"
"";
#endif
#if defined(need_GL_MESA_resize_buffers)
-static const char ResizeBuffersMESA_names[] =
+static const char ResizeBuffersMESA_names[] =
"\0" /* Parameter signature */
"glResizeBuffersMESA\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char GetUniformivARB_names[] =
+static const char GetUniformivARB_names[] =
"iip\0" /* Parameter signature */
"glGetUniformiv\0"
"glGetUniformivARB\0"
@@ -1838,28 +1887,28 @@ static const char GetUniformivARB_names[] =
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char PixelTexGenParameteriSGIS_names[] =
+static const char PixelTexGenParameteriSGIS_names[] =
"ii\0" /* Parameter signature */
"glPixelTexGenParameteriSGIS\0"
"";
#endif
#if defined(need_GL_INTEL_parallel_arrays)
-static const char VertexPointervINTEL_names[] =
+static const char VertexPointervINTEL_names[] =
"iip\0" /* Parameter signature */
"glVertexPointervINTEL\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor4fNormal3fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiColor4fNormal3fVertex3fvSUN_names[] =
"pppp\0" /* Parameter signature */
"glReplacementCodeuiColor4fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3uiEXT_names[] =
+static const char SecondaryColor3uiEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3ui\0"
"glSecondaryColor3uiEXT\0"
@@ -1867,14 +1916,14 @@ static const char SecondaryColor3uiEXT_names[] =
#endif
#if defined(need_GL_SGIX_instruments)
-static const char StartInstrumentsSGIX_names[] =
+static const char StartInstrumentsSGIX_names[] =
"\0" /* Parameter signature */
"glStartInstrumentsSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3usvEXT_names[] =
+static const char SecondaryColor3usvEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3usv\0"
"glSecondaryColor3usvEXT\0"
@@ -1882,49 +1931,49 @@ static const char SecondaryColor3usvEXT_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2fvNV_names[] =
+static const char VertexAttrib2fvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2fvNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char ProgramLocalParameter4dvARB_names[] =
+static const char ProgramLocalParameter4dvARB_names[] =
"iip\0" /* Parameter signature */
"glProgramLocalParameter4dvARB\0"
"";
#endif
#if defined(need_GL_ARB_matrix_palette)
-static const char MatrixIndexuivARB_names[] =
+static const char MatrixIndexuivARB_names[] =
"ip\0" /* Parameter signature */
"glMatrixIndexuivARB\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object)
-static const char RenderbufferStorageMultisample_names[] =
+static const char RenderbufferStorageMultisample_names[] =
"iiiii\0" /* Parameter signature */
"glRenderbufferStorageMultisample\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3sEXT_names[] =
+static const char Tangent3sEXT_names[] =
"iii\0" /* Parameter signature */
"glTangent3sEXT\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactorfSUN_names[] =
+static const char GlobalAlphaFactorfSUN_names[] =
"f\0" /* Parameter signature */
"glGlobalAlphaFactorfSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3iARB_names[] =
+static const char MultiTexCoord3iARB_names[] =
"iiii\0" /* Parameter signature */
"glMultiTexCoord3i\0"
"glMultiTexCoord3iARB\0"
@@ -1932,35 +1981,35 @@ static const char MultiTexCoord3iARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char IsProgram_names[] =
+static const char IsProgram_names[] =
"i\0" /* Parameter signature */
"glIsProgram\0"
"";
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char TexCoordPointerListIBM_names[] =
+static const char TexCoordPointerListIBM_names[] =
"iiipi\0" /* Parameter signature */
"glTexCoordPointerListIBM\0"
"";
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactorusSUN_names[] =
+static const char GlobalAlphaFactorusSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactorusSUN\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2dvNV_names[] =
+static const char VertexAttrib2dvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2dvNV\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char FramebufferRenderbufferEXT_names[] =
+static const char FramebufferRenderbufferEXT_names[] =
"iiii\0" /* Parameter signature */
"glFramebufferRenderbuffer\0"
"glFramebufferRenderbufferEXT\0"
@@ -1968,14 +2017,14 @@ static const char FramebufferRenderbufferEXT_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1dvNV_names[] =
+static const char VertexAttrib1dvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1dvNV\0"
"";
#endif
#if defined(need_GL_EXT_texture_object)
-static const char GenTextures_names[] =
+static const char GenTextures_names[] =
"ip\0" /* Parameter signature */
"glGenTextures\0"
"glGenTexturesEXT\0"
@@ -1983,14 +2032,14 @@ static const char GenTextures_names[] =
#endif
#if defined(need_GL_NV_fence)
-static const char SetFenceNV_names[] =
+static const char SetFenceNV_names[] =
"ii\0" /* Parameter signature */
"glSetFenceNV\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char FramebufferTexture1DEXT_names[] =
+static const char FramebufferTexture1DEXT_names[] =
"iiiii\0" /* Parameter signature */
"glFramebufferTexture1D\0"
"glFramebufferTexture1DEXT\0"
@@ -1998,49 +2047,49 @@ static const char FramebufferTexture1DEXT_names[] =
#endif
#if defined(need_GL_NV_register_combiners)
-static const char GetCombinerOutputParameterivNV_names[] =
+static const char GetCombinerOutputParameterivNV_names[] =
"iiip\0" /* Parameter signature */
"glGetCombinerOutputParameterivNV\0"
"";
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char PixelTexGenParameterivSGIS_names[] =
+static const char PixelTexGenParameterivSGIS_names[] =
"ip\0" /* Parameter signature */
"glPixelTexGenParameterivSGIS\0"
"";
#endif
#if defined(need_GL_EXT_texture_perturb_normal)
-static const char TextureNormalEXT_names[] =
+static const char TextureNormalEXT_names[] =
"i\0" /* Parameter signature */
"glTextureNormalEXT\0"
"";
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char IndexPointerListIBM_names[] =
+static const char IndexPointerListIBM_names[] =
"iipi\0" /* Parameter signature */
"glIndexPointerListIBM\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightfvARB_names[] =
+static const char WeightfvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightfvARB\0"
"";
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4fMESA_names[] =
+static const char WindowPos4fMESA_names[] =
"ffff\0" /* Parameter signature */
"glWindowPos4fMESA\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3dvMESA_names[] =
+static const char WindowPos3dvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos3dv\0"
"glWindowPos3dvARB\0"
@@ -2049,14 +2098,14 @@ static const char WindowPos3dvMESA_names[] =
#endif
#if defined(need_GL_EXT_timer_query)
-static const char GetQueryObjecti64vEXT_names[] =
+static const char GetQueryObjecti64vEXT_names[] =
"iip\0" /* Parameter signature */
"glGetQueryObjecti64vEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1dARB_names[] =
+static const char MultiTexCoord1dARB_names[] =
"id\0" /* Parameter signature */
"glMultiTexCoord1d\0"
"glMultiTexCoord1dARB\0"
@@ -2064,7 +2113,7 @@ static const char MultiTexCoord1dARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_NV_point_sprite)
-static const char PointParameterivNV_names[] =
+static const char PointParameterivNV_names[] =
"ip\0" /* Parameter signature */
"glPointParameteriv\0"
"glPointParameterivNV\0"
@@ -2072,15 +2121,22 @@ static const char PointParameterivNV_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform2fvARB_names[] =
+static const char Uniform2fvARB_names[] =
"iip\0" /* Parameter signature */
"glUniform2fv\0"
"glUniform2fvARB\0"
"";
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const char BufferParameteriAPPLE_names[] =
+ "iii\0" /* Parameter signature */
+ "glBufferParameteriAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3dvARB_names[] =
+static const char MultiTexCoord3dvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord3dv\0"
"glMultiTexCoord3dvARB\0"
@@ -2088,49 +2144,49 @@ static const char MultiTexCoord3dvARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN_names[] =
"pppp\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char DeleteObjectARB_names[] =
+static const char DeleteObjectARB_names[] =
"i\0" /* Parameter signature */
"glDeleteObjectARB\0"
"";
#endif
#if defined(need_GL_ARB_matrix_palette)
-static const char MatrixIndexPointerARB_names[] =
+static const char MatrixIndexPointerARB_names[] =
"iiip\0" /* Parameter signature */
"glMatrixIndexPointerARB\0"
"";
#endif
#if defined(need_GL_NV_fragment_program)
-static const char ProgramNamedParameter4dvNV_names[] =
+static const char ProgramNamedParameter4dvNV_names[] =
"iipp\0" /* Parameter signature */
"glProgramNamedParameter4dvNV\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3fvEXT_names[] =
+static const char Tangent3fvEXT_names[] =
"p\0" /* Parameter signature */
"glTangent3fvEXT\0"
"";
#endif
#if defined(need_GL_ARB_vertex_array_object)
-static const char GenVertexArrays_names[] =
+static const char GenVertexArrays_names[] =
"ip\0" /* Parameter signature */
"glGenVertexArrays\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char BindFramebufferEXT_names[] =
+static const char BindFramebufferEXT_names[] =
"ii\0" /* Parameter signature */
"glBindFramebuffer\0"
"glBindFramebufferEXT\0"
@@ -2138,14 +2194,14 @@ static const char BindFramebufferEXT_names[] =
#endif
#if defined(need_GL_SGIX_reference_plane)
-static const char ReferencePlaneSGIX_names[] =
+static const char ReferencePlaneSGIX_names[] =
"p\0" /* Parameter signature */
"glReferencePlaneSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char ValidateProgramARB_names[] =
+static const char ValidateProgramARB_names[] =
"i\0" /* Parameter signature */
"glValidateProgram\0"
"glValidateProgramARB\0"
@@ -2153,21 +2209,21 @@ static const char ValidateProgramARB_names[] =
#endif
#if defined(need_GL_EXT_compiled_vertex_array)
-static const char UnlockArraysEXT_names[] =
+static const char UnlockArraysEXT_names[] =
"\0" /* Parameter signature */
"glUnlockArraysEXT\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor3fVertex3fSUN_names[] =
+static const char TexCoord2fColor3fVertex3fSUN_names[] =
"ffffffff\0" /* Parameter signature */
"glTexCoord2fColor3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3fvMESA_names[] =
+static const char WindowPos3fvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos3fv\0"
"glWindowPos3fvARB\0"
@@ -2176,14 +2232,14 @@ static const char WindowPos3fvMESA_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1svNV_names[] =
+static const char VertexAttrib1svNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1svNV\0"
"";
#endif
#if defined(need_GL_EXT_copy_texture)
-static const char CopyTexSubImage3D_names[] =
+static const char CopyTexSubImage3D_names[] =
"iiiiiiiii\0" /* Parameter signature */
"glCopyTexSubImage3D\0"
"glCopyTexSubImage3DEXT\0"
@@ -2191,22 +2247,29 @@ static const char CopyTexSubImage3D_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2dARB_names[] =
+static const char VertexAttrib2dARB_names[] =
"idd\0" /* Parameter signature */
"glVertexAttrib2d\0"
"glVertexAttrib2dARB\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char GetInteger64v_names[] =
+ "ip\0" /* Parameter signature */
+ "glGetInteger64v\0"
+ "";
+#endif
+
#if defined(need_GL_SGIS_texture_color_mask)
-static const char TextureColorMaskSGIS_names[] =
+static const char TextureColorMaskSGIS_names[] =
"iiii\0" /* Parameter signature */
"glTextureColorMaskSGIS\0"
"";
#endif
#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture)
-static const char GetColorTable_names[] =
+static const char GetColorTable_names[] =
"iiip\0" /* Parameter signature */
"glGetColorTable\0"
"glGetColorTableSGI\0"
@@ -2215,7 +2278,7 @@ static const char GetColorTable_names[] =
#endif
#if defined(need_GL_SGI_color_table)
-static const char CopyColorTable_names[] =
+static const char CopyColorTable_names[] =
"iiiii\0" /* Parameter signature */
"glCopyColorTable\0"
"glCopyColorTableSGI\0"
@@ -2223,7 +2286,7 @@ static const char CopyColorTable_names[] =
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetHistogramParameterfv_names[] =
+static const char GetHistogramParameterfv_names[] =
"iip\0" /* Parameter signature */
"glGetHistogramParameterfv\0"
"glGetHistogramParameterfvEXT\0"
@@ -2231,21 +2294,21 @@ static const char GetHistogramParameterfv_names[] =
#endif
#if defined(need_GL_INTEL_parallel_arrays)
-static const char ColorPointervINTEL_names[] =
+static const char ColorPointervINTEL_names[] =
"iip\0" /* Parameter signature */
"glColorPointervINTEL\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char AlphaFragmentOp1ATI_names[] =
+static const char AlphaFragmentOp1ATI_names[] =
"iiiiii\0" /* Parameter signature */
"glAlphaFragmentOp1ATI\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3ivARB_names[] =
+static const char MultiTexCoord3ivARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord3iv\0"
"glMultiTexCoord3ivARB\0"
@@ -2253,7 +2316,7 @@ static const char MultiTexCoord3ivARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2sARB_names[] =
+static const char MultiTexCoord2sARB_names[] =
"iii\0" /* Parameter signature */
"glMultiTexCoord2s\0"
"glMultiTexCoord2sARB\0"
@@ -2261,7 +2324,7 @@ static const char MultiTexCoord2sARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1dvARB_names[] =
+static const char VertexAttrib1dvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1dv\0"
"glVertexAttrib1dvARB\0"
@@ -2269,7 +2332,7 @@ static const char VertexAttrib1dvARB_names[] =
#endif
#if defined(need_GL_EXT_texture_object)
-static const char DeleteTextures_names[] =
+static const char DeleteTextures_names[] =
"ip\0" /* Parameter signature */
"glDeleteTextures\0"
"glDeleteTexturesEXT\0"
@@ -2277,49 +2340,49 @@ static const char DeleteTextures_names[] =
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char TexCoordPointerEXT_names[] =
+static const char TexCoordPointerEXT_names[] =
"iiiip\0" /* Parameter signature */
"glTexCoordPointerEXT\0"
"";
#endif
#if defined(need_GL_SGIS_texture4D)
-static const char TexSubImage4DSGIS_names[] =
+static const char TexSubImage4DSGIS_names[] =
"iiiiiiiiiiiip\0" /* Parameter signature */
"glTexSubImage4DSGIS\0"
"";
#endif
#if defined(need_GL_NV_register_combiners2)
-static const char CombinerStageParameterfvNV_names[] =
+static const char CombinerStageParameterfvNV_names[] =
"iip\0" /* Parameter signature */
"glCombinerStageParameterfvNV\0"
"";
#endif
#if defined(need_GL_SGIX_instruments)
-static const char StopInstrumentsSGIX_names[] =
+static const char StopInstrumentsSGIX_names[] =
"i\0" /* Parameter signature */
"glStopInstrumentsSGIX\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord4fColor4fNormal3fVertex4fSUN_names[] =
+static const char TexCoord4fColor4fNormal3fVertex4fSUN_names[] =
"fffffffffffffff\0" /* Parameter signature */
"glTexCoord4fColor4fNormal3fVertex4fSUN\0"
"";
#endif
#if defined(need_GL_SGIX_polynomial_ffd)
-static const char DeformSGIX_names[] =
+static const char DeformSGIX_names[] =
"i\0" /* Parameter signature */
"glDeformSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char GetVertexAttribfvARB_names[] =
+static const char GetVertexAttribfvARB_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribfv\0"
"glGetVertexAttribfvARB\0"
@@ -2327,7 +2390,7 @@ static const char GetVertexAttribfvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3ivEXT_names[] =
+static const char SecondaryColor3ivEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3iv\0"
"glSecondaryColor3ivEXT\0"
@@ -2335,49 +2398,49 @@ static const char SecondaryColor3ivEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix4x2fv_names[] =
+static const char UniformMatrix4x2fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix4x2fv\0"
"";
#endif
#if defined(need_GL_SGIS_detail_texture)
-static const char GetDetailTexFuncSGIS_names[] =
+static const char GetDetailTexFuncSGIS_names[] =
"ip\0" /* Parameter signature */
"glGetDetailTexFuncSGIS\0"
"";
#endif
#if defined(need_GL_NV_register_combiners2)
-static const char GetCombinerStageParameterfvNV_names[] =
+static const char GetCombinerStageParameterfvNV_names[] =
"iip\0" /* Parameter signature */
"glGetCombinerStageParameterfvNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_array_object)
-static const char BindVertexArray_names[] =
+static const char BindVertexArray_names[] =
"i\0" /* Parameter signature */
"glBindVertexArray\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4ubVertex2fvSUN_names[] =
+static const char Color4ubVertex2fvSUN_names[] =
"pp\0" /* Parameter signature */
"glColor4ubVertex2fvSUN\0"
"";
#endif
#if defined(need_GL_SGIS_texture_filter4)
-static const char TexFilterFuncSGIS_names[] =
+static const char TexFilterFuncSGIS_names[] =
"iiip\0" /* Parameter signature */
"glTexFilterFuncSGIS\0"
"";
#endif
#if defined(need_GL_SGIS_multisample) || defined(need_GL_EXT_multisample)
-static const char SampleMaskSGIS_names[] =
+static const char SampleMaskSGIS_names[] =
"fi\0" /* Parameter signature */
"glSampleMaskSGIS\0"
"glSampleMaskEXT\0"
@@ -2385,7 +2448,7 @@ static const char SampleMaskSGIS_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
-static const char GetAttribLocationARB_names[] =
+static const char GetAttribLocationARB_names[] =
"ip\0" /* Parameter signature */
"glGetAttribLocation\0"
"glGetAttribLocationARB\0"
@@ -2393,7 +2456,7 @@ static const char GetAttribLocationARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4ubvARB_names[] =
+static const char VertexAttrib4ubvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4ubv\0"
"glVertexAttrib4ubvARB\0"
@@ -2401,21 +2464,21 @@ static const char VertexAttrib4ubvARB_names[] =
#endif
#if defined(need_GL_SGIS_detail_texture)
-static const char DetailTexFuncSGIS_names[] =
+static const char DetailTexFuncSGIS_names[] =
"iip\0" /* Parameter signature */
"glDetailTexFuncSGIS\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Normal3fVertex3fSUN_names[] =
+static const char Normal3fVertex3fSUN_names[] =
"ffffff\0" /* Parameter signature */
"glNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_EXT_copy_texture)
-static const char CopyTexImage2D_names[] =
+static const char CopyTexImage2D_names[] =
"iiiiiiii\0" /* Parameter signature */
"glCopyTexImage2D\0"
"glCopyTexImage2DEXT\0"
@@ -2423,7 +2486,7 @@ static const char CopyTexImage2D_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char GetBufferPointervARB_names[] =
+static const char GetBufferPointervARB_names[] =
"iip\0" /* Parameter signature */
"glGetBufferPointerv\0"
"glGetBufferPointervARB\0"
@@ -2431,7 +2494,7 @@ static const char GetBufferPointervARB_names[] =
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char ProgramEnvParameter4fARB_names[] =
+static const char ProgramEnvParameter4fARB_names[] =
"iiffff\0" /* Parameter signature */
"glProgramEnvParameter4fARB\0"
"glProgramParameter4fNV\0"
@@ -2439,7 +2502,7 @@ static const char ProgramEnvParameter4fARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform3ivARB_names[] =
+static const char Uniform3ivARB_names[] =
"iip\0" /* Parameter signature */
"glUniform3iv\0"
"glUniform3ivARB\0"
@@ -2447,21 +2510,21 @@ static const char Uniform3ivARB_names[] =
#endif
#if defined(need_GL_NV_fence)
-static const char GetFenceivNV_names[] =
+static const char GetFenceivNV_names[] =
"iip\0" /* Parameter signature */
"glGetFenceivNV\0"
"";
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4dvMESA_names[] =
+static const char WindowPos4dvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos4dvMESA\0"
"";
#endif
#if defined(need_GL_EXT_color_subtable)
-static const char ColorSubTable_names[] =
+static const char ColorSubTable_names[] =
"iiiiip\0" /* Parameter signature */
"glColorSubTable\0"
"glColorSubTableEXT\0"
@@ -2469,7 +2532,7 @@ static const char ColorSubTable_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4ivARB_names[] =
+static const char MultiTexCoord4ivARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord4iv\0"
"glMultiTexCoord4ivARB\0"
@@ -2477,21 +2540,21 @@ static const char MultiTexCoord4ivARB_names[] =
#endif
#if defined(need_GL_EXT_gpu_program_parameters)
-static const char ProgramLocalParameters4fvEXT_names[] =
+static const char ProgramLocalParameters4fvEXT_names[] =
"iiip\0" /* Parameter signature */
"glProgramLocalParameters4fvEXT\0"
"";
#endif
#if defined(need_GL_NV_evaluators)
-static const char GetMapAttribParameterfvNV_names[] =
+static const char GetMapAttribParameterfvNV_names[] =
"iiip\0" /* Parameter signature */
"glGetMapAttribParameterfvNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4sARB_names[] =
+static const char VertexAttrib4sARB_names[] =
"iiiii\0" /* Parameter signature */
"glVertexAttrib4s\0"
"glVertexAttrib4sARB\0"
@@ -2499,7 +2562,7 @@ static const char VertexAttrib4sARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char GetQueryObjectuivARB_names[] =
+static const char GetQueryObjectuivARB_names[] =
"iip\0" /* Parameter signature */
"glGetQueryObjectuiv\0"
"glGetQueryObjectuivARB\0"
@@ -2507,14 +2570,14 @@ static const char GetQueryObjectuivARB_names[] =
#endif
#if defined(need_GL_NV_evaluators)
-static const char MapParameterivNV_names[] =
+static const char MapParameterivNV_names[] =
"iip\0" /* Parameter signature */
"glMapParameterivNV\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char GenRenderbuffersEXT_names[] =
+static const char GenRenderbuffersEXT_names[] =
"ip\0" /* Parameter signature */
"glGenRenderbuffers\0"
"glGenRenderbuffersEXT\0"
@@ -2522,7 +2585,7 @@ static const char GenRenderbuffersEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2dvARB_names[] =
+static const char VertexAttrib2dvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2dv\0"
"glVertexAttrib2dvARB\0"
@@ -2530,28 +2593,28 @@ static const char VertexAttrib2dvARB_names[] =
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char EdgeFlagPointerEXT_names[] =
+static const char EdgeFlagPointerEXT_names[] =
"iip\0" /* Parameter signature */
"glEdgeFlagPointerEXT\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs2svNV_names[] =
+static const char VertexAttribs2svNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs2svNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightbvARB_names[] =
+static const char WeightbvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightbvARB\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2fvARB_names[] =
+static const char VertexAttrib2fvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2fv\0"
"glVertexAttrib2fvARB\0"
@@ -2559,7 +2622,7 @@ static const char VertexAttrib2fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char GetBufferParameterivARB_names[] =
+static const char GetBufferParameterivARB_names[] =
"iip\0" /* Parameter signature */
"glGetBufferParameteriv\0"
"glGetBufferParameterivARB\0"
@@ -2567,28 +2630,28 @@ static const char GetBufferParameterivARB_names[] =
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char ListParameteriSGIX_names[] =
+static const char ListParameteriSGIX_names[] =
"iii\0" /* Parameter signature */
"glListParameteriSGIX\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor4fNormal3fVertex3fSUN_names[] =
+static const char ReplacementCodeuiColor4fNormal3fVertex3fSUN_names[] =
"iffffffffff\0" /* Parameter signature */
"glReplacementCodeuiColor4fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_SGIX_instruments)
-static const char InstrumentsBufferSGIX_names[] =
+static const char InstrumentsBufferSGIX_names[] =
"ip\0" /* Parameter signature */
"glInstrumentsBufferSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NivARB_names[] =
+static const char VertexAttrib4NivARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Niv\0"
"glVertexAttrib4NivARB\0"
@@ -2596,35 +2659,35 @@ static const char VertexAttrib4NivARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char GetAttachedShaders_names[] =
+static const char GetAttachedShaders_names[] =
"iipp\0" /* Parameter signature */
"glGetAttachedShaders\0"
"";
#endif
#if defined(need_GL_APPLE_vertex_array_object)
-static const char GenVertexArraysAPPLE_names[] =
+static const char GenVertexArraysAPPLE_names[] =
"ip\0" /* Parameter signature */
"glGenVertexArraysAPPLE\0"
"";
#endif
#if defined(need_GL_EXT_gpu_program_parameters)
-static const char ProgramEnvParameters4fvEXT_names[] =
+static const char ProgramEnvParameters4fvEXT_names[] =
"iiip\0" /* Parameter signature */
"glProgramEnvParameters4fvEXT\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
+static const char TexCoord2fColor4fNormal3fVertex3fvSUN_names[] =
"pppp\0" /* Parameter signature */
"glTexCoord2fColor4fNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2iMESA_names[] =
+static const char WindowPos2iMESA_names[] =
"ii\0" /* Parameter signature */
"glWindowPos2i\0"
"glWindowPos2iARB\0"
@@ -2633,7 +2696,7 @@ static const char WindowPos2iMESA_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3fvEXT_names[] =
+static const char SecondaryColor3fvEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3fv\0"
"glSecondaryColor3fvEXT\0"
@@ -2641,7 +2704,7 @@ static const char SecondaryColor3fvEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexSubImage1DARB_names[] =
+static const char CompressedTexSubImage1DARB_names[] =
"iiiiiip\0" /* Parameter signature */
"glCompressedTexSubImage1D\0"
"glCompressedTexSubImage1DARB\0"
@@ -2649,28 +2712,28 @@ static const char CompressedTexSubImage1DARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetVertexAttribivNV_names[] =
+static const char GetVertexAttribivNV_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribivNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramStringARB_names[] =
+static const char GetProgramStringARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramStringARB\0"
"";
#endif
#if defined(need_GL_ATI_envmap_bumpmap)
-static const char TexBumpParameterfvATI_names[] =
+static const char TexBumpParameterfvATI_names[] =
"ip\0" /* Parameter signature */
"glTexBumpParameterfvATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char CompileShaderARB_names[] =
+static const char CompileShaderARB_names[] =
"i\0" /* Parameter signature */
"glCompileShader\0"
"glCompileShaderARB\0"
@@ -2678,14 +2741,14 @@ static const char CompileShaderARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0)
-static const char DeleteShader_names[] =
+static const char DeleteShader_names[] =
"i\0" /* Parameter signature */
"glDeleteShader\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform3fARB_names[] =
+static const char Uniform3fARB_names[] =
"ifff\0" /* Parameter signature */
"glUniform3f\0"
"glUniform3fARB\0"
@@ -2693,28 +2756,28 @@ static const char Uniform3fARB_names[] =
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char ListParameterfvSGIX_names[] =
+static const char ListParameterfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glListParameterfvSGIX\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3dvEXT_names[] =
+static const char Tangent3dvEXT_names[] =
"p\0" /* Parameter signature */
"glTangent3dvEXT\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetVertexAttribfvNV_names[] =
+static const char GetVertexAttribfvNV_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribfvNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3sMESA_names[] =
+static const char WindowPos3sMESA_names[] =
"iii\0" /* Parameter signature */
"glWindowPos3s\0"
"glWindowPos3sARB\0"
@@ -2723,35 +2786,35 @@ static const char WindowPos3sMESA_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2svNV_names[] =
+static const char VertexAttrib2svNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2svNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs1fvNV_names[] =
+static const char VertexAttribs1fvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs1fvNV\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fVertex3fvSUN_names[] =
+static const char TexCoord2fVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
"glTexCoord2fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4sMESA_names[] =
+static const char WindowPos4sMESA_names[] =
"iiii\0" /* Parameter signature */
"glWindowPos4sMESA\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NuivARB_names[] =
+static const char VertexAttrib4NuivARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Nuiv\0"
"glVertexAttrib4NuivARB\0"
@@ -2759,7 +2822,7 @@ static const char VertexAttrib4NuivARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char ClientActiveTextureARB_names[] =
+static const char ClientActiveTextureARB_names[] =
"i\0" /* Parameter signature */
"glClientActiveTexture\0"
"glClientActiveTextureARB\0"
@@ -2767,21 +2830,21 @@ static const char ClientActiveTextureARB_names[] =
#endif
#if defined(need_GL_SGIX_pixel_texture)
-static const char PixelTexGenSGIX_names[] =
+static const char PixelTexGenSGIX_names[] =
"i\0" /* Parameter signature */
"glPixelTexGenSGIX\0"
"";
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeusvSUN_names[] =
+static const char ReplacementCodeusvSUN_names[] =
"p\0" /* Parameter signature */
"glReplacementCodeusvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform4fARB_names[] =
+static const char Uniform4fARB_names[] =
"iffff\0" /* Parameter signature */
"glUniform4f\0"
"glUniform4fARB\0"
@@ -2789,29 +2852,36 @@ static const char Uniform4fARB_names[] =
#endif
#if defined(need_GL_ARB_map_buffer_range)
-static const char FlushMappedBufferRange_names[] =
+static const char FlushMappedBufferRange_names[] =
"iii\0" /* Parameter signature */
"glFlushMappedBufferRange\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char IsProgramNV_names[] =
+static const char IsProgramNV_names[] =
"i\0" /* Parameter signature */
"glIsProgramARB\0"
"glIsProgramNV\0"
"";
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const char FlushMappedBufferRangeAPPLE_names[] =
+ "iii\0" /* Parameter signature */
+ "glFlushMappedBufferRangeAPPLE\0"
+ "";
+#endif
+
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodePointerSUN_names[] =
+static const char ReplacementCodePointerSUN_names[] =
"iip\0" /* Parameter signature */
"glReplacementCodePointerSUN\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char ProgramEnvParameter4dARB_names[] =
+static const char ProgramEnvParameter4dARB_names[] =
"iidddd\0" /* Parameter signature */
"glProgramEnvParameter4dARB\0"
"glProgramParameter4dNV\0"
@@ -2819,7 +2889,7 @@ static const char ProgramEnvParameter4dARB_names[] =
#endif
#if defined(need_GL_SGI_color_table)
-static const char ColorTableParameterfv_names[] =
+static const char ColorTableParameterfv_names[] =
"iip\0" /* Parameter signature */
"glColorTableParameterfv\0"
"glColorTableParameterfvSGI\0"
@@ -2827,21 +2897,21 @@ static const char ColorTableParameterfv_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightModelfSGIX_names[] =
+static const char FragmentLightModelfSGIX_names[] =
"if\0" /* Parameter signature */
"glFragmentLightModelfSGIX\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3bvEXT_names[] =
+static const char Binormal3bvEXT_names[] =
"p\0" /* Parameter signature */
"glBinormal3bvEXT\0"
"";
#endif
#if defined(need_GL_EXT_texture_object)
-static const char IsTexture_names[] =
+static const char IsTexture_names[] =
"i\0" /* Parameter signature */
"glIsTexture\0"
"glIsTextureEXT\0"
@@ -2849,14 +2919,14 @@ static const char IsTexture_names[] =
#endif
#if defined(need_GL_EXT_vertex_weighting)
-static const char VertexWeightfvEXT_names[] =
+static const char VertexWeightfvEXT_names[] =
"p\0" /* Parameter signature */
"glVertexWeightfvEXT\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1dARB_names[] =
+static const char VertexAttrib1dARB_names[] =
"id\0" /* Parameter signature */
"glVertexAttrib1d\0"
"glVertexAttrib1dARB\0"
@@ -2864,14 +2934,14 @@ static const char VertexAttrib1dARB_names[] =
#endif
#if defined(need_GL_HP_image_transform)
-static const char ImageTransformParameterivHP_names[] =
+static const char ImageTransformParameterivHP_names[] =
"iip\0" /* Parameter signature */
"glImageTransformParameterivHP\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char DeleteQueriesARB_names[] =
+static const char DeleteQueriesARB_names[] =
"ip\0" /* Parameter signature */
"glDeleteQueries\0"
"glDeleteQueriesARB\0"
@@ -2879,28 +2949,28 @@ static const char DeleteQueriesARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4ubVertex2fSUN_names[] =
+static const char Color4ubVertex2fSUN_names[] =
"iiiiff\0" /* Parameter signature */
"glColor4ubVertex2fSUN\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentColorMaterialSGIX_names[] =
+static const char FragmentColorMaterialSGIX_names[] =
"ii\0" /* Parameter signature */
"glFragmentColorMaterialSGIX\0"
"";
#endif
#if defined(need_GL_ARB_matrix_palette)
-static const char CurrentPaletteMatrixARB_names[] =
+static const char CurrentPaletteMatrixARB_names[] =
"i\0" /* Parameter signature */
"glCurrentPaletteMatrixARB\0"
"";
#endif
#if defined(need_GL_SGIS_multisample) || defined(need_GL_EXT_multisample)
-static const char SamplePatternSGIS_names[] =
+static const char SamplePatternSGIS_names[] =
"i\0" /* Parameter signature */
"glSamplePatternSGIS\0"
"glSamplePatternEXT\0"
@@ -2908,7 +2978,7 @@ static const char SamplePatternSGIS_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char IsQueryARB_names[] =
+static const char IsQueryARB_names[] =
"i\0" /* Parameter signature */
"glIsQuery\0"
"glIsQueryARB\0"
@@ -2916,14 +2986,14 @@ static const char IsQueryARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor4ubVertex3fSUN_names[] =
+static const char ReplacementCodeuiColor4ubVertex3fSUN_names[] =
"iiiiifff\0" /* Parameter signature */
"glReplacementCodeuiColor4ubVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4usvARB_names[] =
+static const char VertexAttrib4usvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4usv\0"
"glVertexAttrib4usvARB\0"
@@ -2931,7 +3001,7 @@ static const char VertexAttrib4usvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char LinkProgramARB_names[] =
+static const char LinkProgramARB_names[] =
"i\0" /* Parameter signature */
"glLinkProgram\0"
"glLinkProgramARB\0"
@@ -2939,14 +3009,14 @@ static const char LinkProgramARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib2fNV_names[] =
+static const char VertexAttrib2fNV_names[] =
"iff\0" /* Parameter signature */
"glVertexAttrib2fNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char ShaderSourceARB_names[] =
+static const char ShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
"glShaderSource\0"
"glShaderSourceARB\0"
@@ -2954,14 +3024,14 @@ static const char ShaderSourceARB_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentMaterialiSGIX_names[] =
+static const char FragmentMaterialiSGIX_names[] =
"iii\0" /* Parameter signature */
"glFragmentMaterialiSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3svARB_names[] =
+static const char VertexAttrib3svARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3sv\0"
"glVertexAttrib3svARB\0"
@@ -2969,7 +3039,7 @@ static const char VertexAttrib3svARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexSubImage3DARB_names[] =
+static const char CompressedTexSubImage3DARB_names[] =
"iiiiiiiiiip\0" /* Parameter signature */
"glCompressedTexSubImage3D\0"
"glCompressedTexSubImage3DARB\0"
@@ -2977,7 +3047,7 @@ static const char CompressedTexSubImage3DARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2ivMESA_names[] =
+static const char WindowPos2ivMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos2iv\0"
"glWindowPos2ivARB\0"
@@ -2986,7 +3056,7 @@ static const char WindowPos2ivMESA_names[] =
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char IsFramebufferEXT_names[] =
+static const char IsFramebufferEXT_names[] =
"i\0" /* Parameter signature */
"glIsFramebuffer\0"
"glIsFramebufferEXT\0"
@@ -2994,7 +3064,7 @@ static const char IsFramebufferEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform4ivARB_names[] =
+static const char Uniform4ivARB_names[] =
"iip\0" /* Parameter signature */
"glUniform4iv\0"
"glUniform4ivARB\0"
@@ -3002,7 +3072,7 @@ static const char Uniform4ivARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char GetVertexAttribdvARB_names[] =
+static const char GetVertexAttribdvARB_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribdv\0"
"glGetVertexAttribdvARB\0"
@@ -3010,14 +3080,14 @@ static const char GetVertexAttribdvARB_names[] =
#endif
#if defined(need_GL_ATI_envmap_bumpmap)
-static const char TexBumpParameterivATI_names[] =
+static const char TexBumpParameterivATI_names[] =
"ip\0" /* Parameter signature */
"glTexBumpParameterivATI\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char GetSeparableFilter_names[] =
+static const char GetSeparableFilter_names[] =
"iiippp\0" /* Parameter signature */
"glGetSeparableFilter\0"
"glGetSeparableFilterEXT\0"
@@ -3025,49 +3095,49 @@ static const char GetSeparableFilter_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3dEXT_names[] =
+static const char Binormal3dEXT_names[] =
"ddd\0" /* Parameter signature */
"glBinormal3dEXT\0"
"";
#endif
#if defined(need_GL_SGIX_sprite)
-static const char SpriteParameteriSGIX_names[] =
+static const char SpriteParameteriSGIX_names[] =
"ii\0" /* Parameter signature */
"glSpriteParameteriSGIX\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char RequestResidentProgramsNV_names[] =
+static const char RequestResidentProgramsNV_names[] =
"ip\0" /* Parameter signature */
"glRequestResidentProgramsNV\0"
"";
#endif
#if defined(need_GL_SGIX_tag_sample_buffer)
-static const char TagSampleBufferSGIX_names[] =
+static const char TagSampleBufferSGIX_names[] =
"\0" /* Parameter signature */
"glTagSampleBufferSGIX\0"
"";
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeusSUN_names[] =
+static const char ReplacementCodeusSUN_names[] =
"i\0" /* Parameter signature */
"glReplacementCodeusSUN\0"
"";
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char ListParameterivSGIX_names[] =
+static const char ListParameterivSGIX_names[] =
"iip\0" /* Parameter signature */
"glListParameterivSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_multi_draw_arrays)
-static const char MultiDrawElementsEXT_names[] =
+static const char MultiDrawElementsEXT_names[] =
"ipipi\0" /* Parameter signature */
"glMultiDrawElements\0"
"glMultiDrawElementsEXT\0"
@@ -3075,7 +3145,7 @@ static const char MultiDrawElementsEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform1ivARB_names[] =
+static const char Uniform1ivARB_names[] =
"iip\0" /* Parameter signature */
"glUniform1iv\0"
"glUniform1ivARB\0"
@@ -3083,7 +3153,7 @@ static const char Uniform1ivARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2sMESA_names[] =
+static const char WindowPos2sMESA_names[] =
"ii\0" /* Parameter signature */
"glWindowPos2s\0"
"glWindowPos2sARB\0"
@@ -3092,14 +3162,14 @@ static const char WindowPos2sMESA_names[] =
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightusvARB_names[] =
+static const char WeightusvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightusvARB\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
-static const char FogCoordPointerEXT_names[] =
+static const char FogCoordPointerEXT_names[] =
"iip\0" /* Parameter signature */
"glFogCoordPointer\0"
"glFogCoordPointerEXT\0"
@@ -3107,14 +3177,14 @@ static const char FogCoordPointerEXT_names[] =
#endif
#if defined(need_GL_EXT_index_material)
-static const char IndexMaterialEXT_names[] =
+static const char IndexMaterialEXT_names[] =
"ii\0" /* Parameter signature */
"glIndexMaterialEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3ubvEXT_names[] =
+static const char SecondaryColor3ubvEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3ubv\0"
"glSecondaryColor3ubvEXT\0"
@@ -3122,7 +3192,7 @@ static const char SecondaryColor3ubvEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4dvARB_names[] =
+static const char VertexAttrib4dvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4dv\0"
"glVertexAttrib4dvARB\0"
@@ -3130,7 +3200,7 @@ static const char VertexAttrib4dvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_shader)
-static const char BindAttribLocationARB_names[] =
+static const char BindAttribLocationARB_names[] =
"iip\0" /* Parameter signature */
"glBindAttribLocation\0"
"glBindAttribLocationARB\0"
@@ -3138,7 +3208,7 @@ static const char BindAttribLocationARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2dARB_names[] =
+static const char MultiTexCoord2dARB_names[] =
"idd\0" /* Parameter signature */
"glMultiTexCoord2d\0"
"glMultiTexCoord2dARB\0"
@@ -3146,35 +3216,35 @@ static const char MultiTexCoord2dARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char ExecuteProgramNV_names[] =
+static const char ExecuteProgramNV_names[] =
"iip\0" /* Parameter signature */
"glExecuteProgramNV\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char LightEnviSGIX_names[] =
+static const char LightEnviSGIX_names[] =
"ii\0" /* Parameter signature */
"glLightEnviSGIX\0"
"";
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeuiSUN_names[] =
+static const char ReplacementCodeuiSUN_names[] =
"i\0" /* Parameter signature */
"glReplacementCodeuiSUN\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribPointerNV_names[] =
+static const char VertexAttribPointerNV_names[] =
"iiiip\0" /* Parameter signature */
"glVertexAttribPointerNV\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char GetFramebufferAttachmentParameterivEXT_names[] =
+static const char GetFramebufferAttachmentParameterivEXT_names[] =
"iiip\0" /* Parameter signature */
"glGetFramebufferAttachmentParameteriv\0"
"glGetFramebufferAttachmentParameterivEXT\0"
@@ -3182,14 +3252,14 @@ static const char GetFramebufferAttachmentParameterivEXT_names[] =
#endif
#if defined(need_GL_EXT_pixel_transform)
-static const char PixelTransformParameterfEXT_names[] =
+static const char PixelTransformParameterfEXT_names[] =
"iif\0" /* Parameter signature */
"glPixelTransformParameterfEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4dvARB_names[] =
+static const char MultiTexCoord4dvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord4dv\0"
"glMultiTexCoord4dvARB\0"
@@ -3197,21 +3267,21 @@ static const char MultiTexCoord4dvARB_names[] =
#endif
#if defined(need_GL_EXT_pixel_transform)
-static const char PixelTransformParameteriEXT_names[] =
+static const char PixelTransformParameteriEXT_names[] =
"iii\0" /* Parameter signature */
"glPixelTransformParameteriEXT\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor4ubVertex3fSUN_names[] =
+static const char TexCoord2fColor4ubVertex3fSUN_names[] =
"ffiiiifff\0" /* Parameter signature */
"glTexCoord2fColor4ubVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform1iARB_names[] =
+static const char Uniform1iARB_names[] =
"ii\0" /* Parameter signature */
"glUniform1i\0"
"glUniform1iARB\0"
@@ -3219,7 +3289,7 @@ static const char Uniform1iARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttribPointerARB_names[] =
+static const char VertexAttribPointerARB_names[] =
"iiiiip\0" /* Parameter signature */
"glVertexAttribPointer\0"
"glVertexAttribPointerARB\0"
@@ -3227,14 +3297,14 @@ static const char VertexAttribPointerARB_names[] =
#endif
#if defined(need_GL_SGIS_sharpen_texture)
-static const char SharpenTexFuncSGIS_names[] =
+static const char SharpenTexFuncSGIS_names[] =
"iip\0" /* Parameter signature */
"glSharpenTexFuncSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4fvARB_names[] =
+static const char MultiTexCoord4fvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord4fv\0"
"glMultiTexCoord4fvARB\0"
@@ -3242,56 +3312,56 @@ static const char MultiTexCoord4fvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix2x3fv_names[] =
+static const char UniformMatrix2x3fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix2x3fv\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char TrackMatrixNV_names[] =
+static const char TrackMatrixNV_names[] =
"iiii\0" /* Parameter signature */
"glTrackMatrixNV\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerParameteriNV_names[] =
+static const char CombinerParameteriNV_names[] =
"ii\0" /* Parameter signature */
"glCombinerParameteriNV\0"
"";
#endif
#if defined(need_GL_SGIX_async)
-static const char DeleteAsyncMarkersSGIX_names[] =
+static const char DeleteAsyncMarkersSGIX_names[] =
"ii\0" /* Parameter signature */
"glDeleteAsyncMarkersSGIX\0"
"";
#endif
#if defined(need_GL_SGIX_async)
-static const char IsAsyncMarkerSGIX_names[] =
+static const char IsAsyncMarkerSGIX_names[] =
"i\0" /* Parameter signature */
"glIsAsyncMarkerSGIX\0"
"";
#endif
#if defined(need_GL_SGIX_framezoom)
-static const char FrameZoomSGIX_names[] =
+static const char FrameZoomSGIX_names[] =
"i\0" /* Parameter signature */
"glFrameZoomSGIX\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Normal3fVertex3fvSUN_names[] =
+static const char Normal3fVertex3fvSUN_names[] =
"pp\0" /* Parameter signature */
"glNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NsvARB_names[] =
+static const char VertexAttrib4NsvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Nsv\0"
"glVertexAttrib4NsvARB\0"
@@ -3299,15 +3369,22 @@ static const char VertexAttrib4NsvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3fvARB_names[] =
+static const char VertexAttrib3fvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3fv\0"
"glVertexAttrib3fvARB\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char GetSynciv_names[] =
+ "iiipp\0" /* Parameter signature */
+ "glGetSynciv\0"
+ "";
+#endif
+
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char DeleteFramebuffersEXT_names[] =
+static const char DeleteFramebuffersEXT_names[] =
"ip\0" /* Parameter signature */
"glDeleteFramebuffers\0"
"glDeleteFramebuffersEXT\0"
@@ -3315,14 +3392,14 @@ static const char DeleteFramebuffersEXT_names[] =
#endif
#if defined(need_GL_SUN_global_alpha)
-static const char GlobalAlphaFactorsSUN_names[] =
+static const char GlobalAlphaFactorsSUN_names[] =
"i\0" /* Parameter signature */
"glGlobalAlphaFactorsSUN\0"
"";
#endif
#if defined(need_GL_EXT_texture3D)
-static const char TexSubImage3D_names[] =
+static const char TexSubImage3D_names[] =
"iiiiiiiiiip\0" /* Parameter signature */
"glTexSubImage3D\0"
"glTexSubImage3DEXT\0"
@@ -3330,14 +3407,14 @@ static const char TexSubImage3D_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3fEXT_names[] =
+static const char Tangent3fEXT_names[] =
"fff\0" /* Parameter signature */
"glTangent3fEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3uivEXT_names[] =
+static const char SecondaryColor3uivEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3uiv\0"
"glSecondaryColor3uivEXT\0"
@@ -3345,35 +3422,35 @@ static const char SecondaryColor3uivEXT_names[] =
#endif
#if defined(need_GL_ARB_matrix_palette)
-static const char MatrixIndexubvARB_names[] =
+static const char MatrixIndexubvARB_names[] =
"ip\0" /* Parameter signature */
"glMatrixIndexubvARB\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char Color4fNormal3fVertex3fSUN_names[] =
+static const char Color4fNormal3fVertex3fSUN_names[] =
"ffffffffff\0" /* Parameter signature */
"glColor4fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char PixelTexGenParameterfSGIS_names[] =
+static const char PixelTexGenParameterfSGIS_names[] =
"if\0" /* Parameter signature */
"glPixelTexGenParameterfSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char CreateShader_names[] =
+static const char CreateShader_names[] =
"i\0" /* Parameter signature */
"glCreateShader\0"
"";
#endif
#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture)
-static const char GetColorTableParameterfv_names[] =
+static const char GetColorTableParameterfv_names[] =
"iip\0" /* Parameter signature */
"glGetColorTableParameterfv\0"
"glGetColorTableParameterfvSGI\0"
@@ -3382,14 +3459,14 @@ static const char GetColorTableParameterfv_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightModelfvSGIX_names[] =
+static const char FragmentLightModelfvSGIX_names[] =
"ip\0" /* Parameter signature */
"glFragmentLightModelfvSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord3fARB_names[] =
+static const char MultiTexCoord3fARB_names[] =
"ifff\0" /* Parameter signature */
"glMultiTexCoord3f\0"
"glMultiTexCoord3fARB\0"
@@ -3397,14 +3474,14 @@ static const char MultiTexCoord3fARB_names[] =
#endif
#if defined(need_GL_SGIS_pixel_texture)
-static const char GetPixelTexGenParameterfvSGIS_names[] =
+static const char GetPixelTexGenParameterfvSGIS_names[] =
"ip\0" /* Parameter signature */
"glGetPixelTexGenParameterfvSGIS\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char GenFramebuffersEXT_names[] =
+static const char GenFramebuffersEXT_names[] =
"ip\0" /* Parameter signature */
"glGenFramebuffers\0"
"glGenFramebuffersEXT\0"
@@ -3412,14 +3489,14 @@ static const char GenFramebuffersEXT_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetProgramParameterdvNV_names[] =
+static const char GetProgramParameterdvNV_names[] =
"iiip\0" /* Parameter signature */
"glGetProgramParameterdvNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_array_object) || defined(need_GL_APPLE_vertex_array_object)
-static const char IsVertexArrayAPPLE_names[] =
+static const char IsVertexArrayAPPLE_names[] =
"i\0" /* Parameter signature */
"glIsVertexArray\0"
"glIsVertexArrayAPPLE\0"
@@ -3427,21 +3504,21 @@ static const char IsVertexArrayAPPLE_names[] =
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightfvSGIX_names[] =
+static const char FragmentLightfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glFragmentLightfvSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char DetachShader_names[] =
+static const char DetachShader_names[] =
"ii\0" /* Parameter signature */
"glDetachShader\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NubARB_names[] =
+static const char VertexAttrib4NubARB_names[] =
"iiiii\0" /* Parameter signature */
"glVertexAttrib4Nub\0"
"glVertexAttrib4NubARB\0"
@@ -3449,28 +3526,28 @@ static const char VertexAttrib4NubARB_names[] =
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramEnvParameterfvARB_names[] =
+static const char GetProgramEnvParameterfvARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramEnvParameterfvARB\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetTrackMatrixivNV_names[] =
+static const char GetTrackMatrixivNV_names[] =
"iiip\0" /* Parameter signature */
"glGetTrackMatrixivNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3svNV_names[] =
+static const char VertexAttrib3svNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3svNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform4fvARB_names[] =
+static const char Uniform4fvARB_names[] =
"iip\0" /* Parameter signature */
"glUniform4fv\0"
"glUniform4fvARB\0"
@@ -3478,7 +3555,7 @@ static const char Uniform4fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix)
-static const char MultTransposeMatrixfARB_names[] =
+static const char MultTransposeMatrixfARB_names[] =
"p\0" /* Parameter signature */
"glMultTransposeMatrixf\0"
"glMultTransposeMatrixfARB\0"
@@ -3486,14 +3563,14 @@ static const char MultTransposeMatrixfARB_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char ColorFragmentOp1ATI_names[] =
+static const char ColorFragmentOp1ATI_names[] =
"iiiiiii\0" /* Parameter signature */
"glColorFragmentOp1ATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char GetUniformfvARB_names[] =
+static const char GetUniformfvARB_names[] =
"iip\0" /* Parameter signature */
"glGetUniformfv\0"
"glGetUniformfvARB\0"
@@ -3501,28 +3578,28 @@ static const char GetUniformfvARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_names[] =
+static const char ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN_names[] =
"iffffffffffff\0" /* Parameter signature */
"glReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char DetachObjectARB_names[] =
+static const char DetachObjectARB_names[] =
"ii\0" /* Parameter signature */
"glDetachObjectARB\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char VertexBlendARB_names[] =
+static const char VertexBlendARB_names[] =
"i\0" /* Parameter signature */
"glVertexBlendARB\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3iMESA_names[] =
+static const char WindowPos3iMESA_names[] =
"iii\0" /* Parameter signature */
"glWindowPos3i\0"
"glWindowPos3iARB\0"
@@ -3531,7 +3608,7 @@ static const char WindowPos3iMESA_names[] =
#endif
#if defined(need_GL_EXT_convolution)
-static const char SeparableFilter2D_names[] =
+static const char SeparableFilter2D_names[] =
"iiiiiipp\0" /* Parameter signature */
"glSeparableFilter2D\0"
"glSeparableFilter2DEXT\0"
@@ -3539,14 +3616,14 @@ static const char SeparableFilter2D_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor4ubVertex3fvSUN_names[] =
+static const char ReplacementCodeuiColor4ubVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glReplacementCodeuiColor4ubVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char CompressedTexImage2DARB_names[] =
+static const char CompressedTexImage2DARB_names[] =
"iiiiiiip\0" /* Parameter signature */
"glCompressedTexImage2D\0"
"glCompressedTexImage2DARB\0"
@@ -3554,7 +3631,7 @@ static const char CompressedTexImage2DARB_names[] =
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char ArrayElement_names[] =
+static const char ArrayElement_names[] =
"i\0" /* Parameter signature */
"glArrayElement\0"
"glArrayElementEXT\0"
@@ -3562,35 +3639,35 @@ static const char ArrayElement_names[] =
#endif
#if defined(need_GL_EXT_depth_bounds_test)
-static const char DepthBoundsEXT_names[] =
+static const char DepthBoundsEXT_names[] =
"dd\0" /* Parameter signature */
"glDepthBoundsEXT\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char ProgramParameters4fvNV_names[] =
+static const char ProgramParameters4fvNV_names[] =
"iiip\0" /* Parameter signature */
"glProgramParameters4fvNV\0"
"";
#endif
#if defined(need_GL_SGIX_polynomial_ffd)
-static const char DeformationMap3fSGIX_names[] =
+static const char DeformationMap3fSGIX_names[] =
"iffiiffiiffiip\0" /* Parameter signature */
"glDeformationMap3fSGIX\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetProgramivNV_names[] =
+static const char GetProgramivNV_names[] =
"iip\0" /* Parameter signature */
"glGetProgramivNV\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetMinmaxParameteriv_names[] =
+static const char GetMinmaxParameteriv_names[] =
"iip\0" /* Parameter signature */
"glGetMinmaxParameteriv\0"
"glGetMinmaxParameterivEXT\0"
@@ -3598,7 +3675,7 @@ static const char GetMinmaxParameteriv_names[] =
#endif
#if defined(need_GL_EXT_copy_texture)
-static const char CopyTexImage1D_names[] =
+static const char CopyTexImage1D_names[] =
"iiiiiii\0" /* Parameter signature */
"glCopyTexImage1D\0"
"glCopyTexImage1DEXT\0"
@@ -3606,42 +3683,42 @@ static const char CopyTexImage1D_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char AlphaFragmentOp3ATI_names[] =
+static const char AlphaFragmentOp3ATI_names[] =
"iiiiiiiiiiii\0" /* Parameter signature */
"glAlphaFragmentOp3ATI\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetVertexAttribdvNV_names[] =
+static const char GetVertexAttribdvNV_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribdvNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3fvNV_names[] =
+static const char VertexAttrib3fvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3fvNV\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char GetFinalCombinerInputParameterivNV_names[] =
+static const char GetFinalCombinerInputParameterivNV_names[] =
"iip\0" /* Parameter signature */
"glGetFinalCombinerInputParameterivNV\0"
"";
#endif
#if defined(need_GL_NV_evaluators)
-static const char GetMapParameterivNV_names[] =
+static const char GetMapParameterivNV_names[] =
"iip\0" /* Parameter signature */
"glGetMapParameterivNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform4iARB_names[] =
+static const char Uniform4iARB_names[] =
"iiiii\0" /* Parameter signature */
"glUniform4i\0"
"glUniform4iARB\0"
@@ -3649,7 +3726,7 @@ static const char Uniform4iARB_names[] =
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionParameteri_names[] =
+static const char ConvolutionParameteri_names[] =
"iii\0" /* Parameter signature */
"glConvolutionParameteri\0"
"glConvolutionParameteriEXT\0"
@@ -3657,14 +3734,14 @@ static const char ConvolutionParameteri_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3sEXT_names[] =
+static const char Binormal3sEXT_names[] =
"iii\0" /* Parameter signature */
"glBinormal3sEXT\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char ConvolutionParameterf_names[] =
+static const char ConvolutionParameterf_names[] =
"iif\0" /* Parameter signature */
"glConvolutionParameterf\0"
"glConvolutionParameterfEXT\0"
@@ -3672,7 +3749,7 @@ static const char ConvolutionParameterf_names[] =
#endif
#if defined(need_GL_SGI_color_table) || defined(need_GL_EXT_paletted_texture)
-static const char GetColorTableParameteriv_names[] =
+static const char GetColorTableParameteriv_names[] =
"iip\0" /* Parameter signature */
"glGetColorTableParameteriv\0"
"glGetColorTableParameterivSGI\0"
@@ -3681,7 +3758,7 @@ static const char GetColorTableParameteriv_names[] =
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char ProgramEnvParameter4dvARB_names[] =
+static const char ProgramEnvParameter4dvARB_names[] =
"iip\0" /* Parameter signature */
"glProgramEnvParameter4dvARB\0"
"glProgramParameter4dvNV\0"
@@ -3689,14 +3766,14 @@ static const char ProgramEnvParameter4dvARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs2fvNV_names[] =
+static const char VertexAttribs2fvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs2fvNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char UseProgramObjectARB_names[] =
+static const char UseProgramObjectARB_names[] =
"i\0" /* Parameter signature */
"glUseProgram\0"
"glUseProgramObjectARB\0"
@@ -3704,42 +3781,42 @@ static const char UseProgramObjectARB_names[] =
#endif
#if defined(need_GL_NV_evaluators)
-static const char GetMapParameterfvNV_names[] =
+static const char GetMapParameterfvNV_names[] =
"iip\0" /* Parameter signature */
"glGetMapParameterfvNV\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char PassTexCoordATI_names[] =
+static const char PassTexCoordATI_names[] =
"iii\0" /* Parameter signature */
"glPassTexCoordATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char DeleteProgram_names[] =
+static const char DeleteProgram_names[] =
"i\0" /* Parameter signature */
"glDeleteProgram\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3ivEXT_names[] =
+static const char Tangent3ivEXT_names[] =
"p\0" /* Parameter signature */
"glTangent3ivEXT\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3dEXT_names[] =
+static const char Tangent3dEXT_names[] =
"ddd\0" /* Parameter signature */
"glTangent3dEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3dvEXT_names[] =
+static const char SecondaryColor3dvEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3dv\0"
"glSecondaryColor3dvEXT\0"
@@ -3747,7 +3824,7 @@ static const char SecondaryColor3dvEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_multi_draw_arrays)
-static const char MultiDrawArraysEXT_names[] =
+static const char MultiDrawArraysEXT_names[] =
"ippi\0" /* Parameter signature */
"glMultiDrawArrays\0"
"glMultiDrawArraysEXT\0"
@@ -3755,7 +3832,7 @@ static const char MultiDrawArraysEXT_names[] =
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char BindRenderbufferEXT_names[] =
+static const char BindRenderbufferEXT_names[] =
"ii\0" /* Parameter signature */
"glBindRenderbuffer\0"
"glBindRenderbufferEXT\0"
@@ -3763,7 +3840,7 @@ static const char BindRenderbufferEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4dARB_names[] =
+static const char MultiTexCoord4dARB_names[] =
"idddd\0" /* Parameter signature */
"glMultiTexCoord4d\0"
"glMultiTexCoord4dARB\0"
@@ -3771,7 +3848,7 @@ static const char MultiTexCoord4dARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3usEXT_names[] =
+static const char SecondaryColor3usEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3us\0"
"glSecondaryColor3usEXT\0"
@@ -3779,14 +3856,14 @@ static const char SecondaryColor3usEXT_names[] =
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char ProgramLocalParameter4fvARB_names[] =
+static const char ProgramLocalParameter4fvARB_names[] =
"iip\0" /* Parameter signature */
"glProgramLocalParameter4fvARB\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char DeleteProgramsNV_names[] =
+static const char DeleteProgramsNV_names[] =
"ip\0" /* Parameter signature */
"glDeleteProgramsARB\0"
"glDeleteProgramsNV\0"
@@ -3794,7 +3871,7 @@ static const char DeleteProgramsNV_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1sARB_names[] =
+static const char MultiTexCoord1sARB_names[] =
"ii\0" /* Parameter signature */
"glMultiTexCoord1s\0"
"glMultiTexCoord1sARB\0"
@@ -3802,14 +3879,14 @@ static const char MultiTexCoord1sARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiColor3fVertex3fSUN_names[] =
+static const char ReplacementCodeuiColor3fVertex3fSUN_names[] =
"iffffff\0" /* Parameter signature */
"glReplacementCodeuiColor3fVertex3fSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char GetVertexAttribPointervNV_names[] =
+static const char GetVertexAttribPointervNV_names[] =
"iip\0" /* Parameter signature */
"glGetVertexAttribPointerv\0"
"glGetVertexAttribPointervARB\0"
@@ -3818,7 +3895,7 @@ static const char GetVertexAttribPointervNV_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1dvARB_names[] =
+static const char MultiTexCoord1dvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord1dv\0"
"glMultiTexCoord1dvARB\0"
@@ -3826,7 +3903,7 @@ static const char MultiTexCoord1dvARB_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform2iARB_names[] =
+static const char Uniform2iARB_names[] =
"iii\0" /* Parameter signature */
"glUniform2i\0"
"glUniform2iARB\0"
@@ -3834,57 +3911,64 @@ static const char Uniform2iARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char GetProgramStringNV_names[] =
+static const char GetProgramStringNV_names[] =
"iip\0" /* Parameter signature */
"glGetProgramStringNV\0"
"";
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char ColorPointerEXT_names[] =
+static const char ColorPointerEXT_names[] =
"iiiip\0" /* Parameter signature */
"glColorPointerEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char MapBufferARB_names[] =
+static const char MapBufferARB_names[] =
"ii\0" /* Parameter signature */
"glMapBuffer\0"
"glMapBufferARB\0"
"";
#endif
+#if defined(need_GL_ARB_draw_elements_base_vertex)
+static const char MultiDrawElementsBaseVertex_names[] =
+ "ipipip\0" /* Parameter signature */
+ "glMultiDrawElementsBaseVertex\0"
+ "";
+#endif
+
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3svEXT_names[] =
+static const char Binormal3svEXT_names[] =
"p\0" /* Parameter signature */
"glBinormal3svEXT\0"
"";
#endif
#if defined(need_GL_EXT_light_texture)
-static const char ApplyTextureEXT_names[] =
+static const char ApplyTextureEXT_names[] =
"i\0" /* Parameter signature */
"glApplyTextureEXT\0"
"";
#endif
#if defined(need_GL_EXT_light_texture)
-static const char TextureMaterialEXT_names[] =
+static const char TextureMaterialEXT_names[] =
"ii\0" /* Parameter signature */
"glTextureMaterialEXT\0"
"";
#endif
#if defined(need_GL_EXT_light_texture)
-static const char TextureLightEXT_names[] =
+static const char TextureLightEXT_names[] =
"i\0" /* Parameter signature */
"glTextureLightEXT\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char ResetMinmax_names[] =
+static const char ResetMinmax_names[] =
"i\0" /* Parameter signature */
"glResetMinmax\0"
"glResetMinmaxEXT\0"
@@ -3892,21 +3976,21 @@ static const char ResetMinmax_names[] =
#endif
#if defined(need_GL_SGIX_sprite)
-static const char SpriteParameterfSGIX_names[] =
+static const char SpriteParameterfSGIX_names[] =
"if\0" /* Parameter signature */
"glSpriteParameterfSGIX\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4sNV_names[] =
+static const char VertexAttrib4sNV_names[] =
"iiiii\0" /* Parameter signature */
"glVertexAttrib4sNV\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char GetConvolutionParameterfv_names[] =
+static const char GetConvolutionParameterfv_names[] =
"iip\0" /* Parameter signature */
"glGetConvolutionParameterfv\0"
"glGetConvolutionParameterfvEXT\0"
@@ -3914,21 +3998,21 @@ static const char GetConvolutionParameterfv_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs4dvNV_names[] =
+static const char VertexAttribs4dvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs4dvNV\0"
"";
#endif
#if defined(need_GL_IBM_multimode_draw_arrays)
-static const char MultiModeDrawArraysIBM_names[] =
+static const char MultiModeDrawArraysIBM_names[] =
"pppii\0" /* Parameter signature */
"glMultiModeDrawArraysIBM\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4dARB_names[] =
+static const char VertexAttrib4dARB_names[] =
"idddd\0" /* Parameter signature */
"glVertexAttrib4d\0"
"glVertexAttrib4dARB\0"
@@ -3936,35 +4020,35 @@ static const char VertexAttrib4dARB_names[] =
#endif
#if defined(need_GL_ATI_envmap_bumpmap)
-static const char GetTexBumpParameterfvATI_names[] =
+static const char GetTexBumpParameterfvATI_names[] =
"ip\0" /* Parameter signature */
"glGetTexBumpParameterfvATI\0"
"";
#endif
#if defined(need_GL_NV_fragment_program)
-static const char ProgramNamedParameter4dNV_names[] =
+static const char ProgramNamedParameter4dNV_names[] =
"iipdddd\0" /* Parameter signature */
"glProgramNamedParameter4dNV\0"
"";
#endif
#if defined(need_GL_EXT_vertex_weighting)
-static const char VertexWeightfEXT_names[] =
+static const char VertexWeightfEXT_names[] =
"f\0" /* Parameter signature */
"glVertexWeightfEXT\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3fEXT_names[] =
+static const char Binormal3fEXT_names[] =
"fff\0" /* Parameter signature */
"glBinormal3fEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
-static const char FogCoordfvEXT_names[] =
+static const char FogCoordfvEXT_names[] =
"p\0" /* Parameter signature */
"glFogCoordfv\0"
"glFogCoordfvEXT\0"
@@ -3972,7 +4056,7 @@ static const char FogCoordfvEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1ivARB_names[] =
+static const char MultiTexCoord1ivARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord1iv\0"
"glMultiTexCoord1ivARB\0"
@@ -3980,7 +4064,7 @@ static const char MultiTexCoord1ivARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3ubEXT_names[] =
+static const char SecondaryColor3ubEXT_names[] =
"iii\0" /* Parameter signature */
"glSecondaryColor3ub\0"
"glSecondaryColor3ubEXT\0"
@@ -3988,7 +4072,7 @@ static const char SecondaryColor3ubEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2ivARB_names[] =
+static const char MultiTexCoord2ivARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord2iv\0"
"glMultiTexCoord2ivARB\0"
@@ -3996,14 +4080,14 @@ static const char MultiTexCoord2ivARB_names[] =
#endif
#if defined(need_GL_SGIS_fog_function)
-static const char FogFuncSGIS_names[] =
+static const char FogFuncSGIS_names[] =
"ip\0" /* Parameter signature */
"glFogFuncSGIS\0"
"";
#endif
#if defined(need_GL_EXT_copy_texture)
-static const char CopyTexSubImage2D_names[] =
+static const char CopyTexSubImage2D_names[] =
"iiiiiiii\0" /* Parameter signature */
"glCopyTexSubImage2D\0"
"glCopyTexSubImage2DEXT\0"
@@ -4011,35 +4095,35 @@ static const char CopyTexSubImage2D_names[] =
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char GetObjectParameterivARB_names[] =
+static const char GetObjectParameterivARB_names[] =
"iip\0" /* Parameter signature */
"glGetObjectParameterivARB\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord4fVertex4fSUN_names[] =
+static const char TexCoord4fVertex4fSUN_names[] =
"ffffffff\0" /* Parameter signature */
"glTexCoord4fVertex4fSUN\0"
"";
#endif
#if defined(need_GL_APPLE_vertex_array_object)
-static const char BindVertexArrayAPPLE_names[] =
+static const char BindVertexArrayAPPLE_names[] =
"i\0" /* Parameter signature */
"glBindVertexArrayAPPLE\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramLocalParameterdvARB_names[] =
+static const char GetProgramLocalParameterdvARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramLocalParameterdvARB\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetHistogramParameteriv_names[] =
+static const char GetHistogramParameteriv_names[] =
"iip\0" /* Parameter signature */
"glGetHistogramParameteriv\0"
"glGetHistogramParameterivEXT\0"
@@ -4047,7 +4131,7 @@ static const char GetHistogramParameteriv_names[] =
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1iARB_names[] =
+static const char MultiTexCoord1iARB_names[] =
"ii\0" /* Parameter signature */
"glMultiTexCoord1i\0"
"glMultiTexCoord1iARB\0"
@@ -4055,7 +4139,7 @@ static const char MultiTexCoord1iARB_names[] =
#endif
#if defined(need_GL_EXT_convolution)
-static const char GetConvolutionFilter_names[] =
+static const char GetConvolutionFilter_names[] =
"iiip\0" /* Parameter signature */
"glGetConvolutionFilter\0"
"glGetConvolutionFilterEXT\0"
@@ -4063,14 +4147,14 @@ static const char GetConvolutionFilter_names[] =
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramivARB_names[] =
+static const char GetProgramivARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramivARB\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_blend_func_separate) || defined(need_GL_INGR_blend_func_separate)
-static const char BlendFuncSeparateEXT_names[] =
+static const char BlendFuncSeparateEXT_names[] =
"iiii\0" /* Parameter signature */
"glBlendFuncSeparate\0"
"glBlendFuncSeparateEXT\0"
@@ -4079,49 +4163,49 @@ static const char BlendFuncSeparateEXT_names[] =
#endif
#if defined(need_GL_ARB_map_buffer_range)
-static const char MapBufferRange_names[] =
+static const char MapBufferRange_names[] =
"iiii\0" /* Parameter signature */
"glMapBufferRange\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char ProgramParameters4dvNV_names[] =
+static const char ProgramParameters4dvNV_names[] =
"iiip\0" /* Parameter signature */
"glProgramParameters4dvNV\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord2fColor3fVertex3fvSUN_names[] =
+static const char TexCoord2fColor3fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glTexCoord2fColor3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3dvEXT_names[] =
+static const char Binormal3dvEXT_names[] =
"p\0" /* Parameter signature */
"glBinormal3dvEXT\0"
"";
#endif
#if defined(need_GL_NV_fence)
-static const char FinishFenceNV_names[] =
+static const char FinishFenceNV_names[] =
"i\0" /* Parameter signature */
"glFinishFenceNV\0"
"";
#endif
#if defined(need_GL_SGIS_fog_function)
-static const char GetFogFuncSGIS_names[] =
+static const char GetFogFuncSGIS_names[] =
"p\0" /* Parameter signature */
"glGetFogFuncSGIS\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char GetUniformLocationARB_names[] =
+static const char GetUniformLocationARB_names[] =
"ip\0" /* Parameter signature */
"glGetUniformLocation\0"
"glGetUniformLocationARB\0"
@@ -4129,7 +4213,7 @@ static const char GetUniformLocationARB_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3fEXT_names[] =
+static const char SecondaryColor3fEXT_names[] =
"fff\0" /* Parameter signature */
"glSecondaryColor3f\0"
"glSecondaryColor3fEXT\0"
@@ -4137,14 +4221,14 @@ static const char SecondaryColor3fEXT_names[] =
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerInputNV_names[] =
+static const char CombinerInputNV_names[] =
"iiiiii\0" /* Parameter signature */
"glCombinerInputNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib3sARB_names[] =
+static const char VertexAttrib3sARB_names[] =
"iiii\0" /* Parameter signature */
"glVertexAttrib3s\0"
"glVertexAttrib3sARB\0"
@@ -4152,49 +4236,49 @@ static const char VertexAttrib3sARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiNormal3fVertex3fvSUN_names[] =
+static const char ReplacementCodeuiNormal3fVertex3fvSUN_names[] =
"ppp\0" /* Parameter signature */
"glReplacementCodeuiNormal3fVertex3fvSUN\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char ProgramStringARB_names[] =
+static const char ProgramStringARB_names[] =
"iiip\0" /* Parameter signature */
"glProgramStringARB\0"
"";
#endif
#if defined(need_GL_SUN_vertex)
-static const char TexCoord4fVertex4fvSUN_names[] =
+static const char TexCoord4fVertex4fvSUN_names[] =
"pp\0" /* Parameter signature */
"glTexCoord4fVertex4fvSUN\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3sNV_names[] =
+static const char VertexAttrib3sNV_names[] =
"iiii\0" /* Parameter signature */
"glVertexAttrib3sNV\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1fNV_names[] =
+static const char VertexAttrib1fNV_names[] =
"if\0" /* Parameter signature */
"glVertexAttrib1fNV\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentLightfSGIX_names[] =
+static const char FragmentLightfSGIX_names[] =
"iif\0" /* Parameter signature */
"glFragmentLightfSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_texture_compression)
-static const char GetCompressedTexImageARB_names[] =
+static const char GetCompressedTexImageARB_names[] =
"iip\0" /* Parameter signature */
"glGetCompressedTexImage\0"
"glGetCompressedTexImageARB\0"
@@ -4202,14 +4286,14 @@ static const char GetCompressedTexImageARB_names[] =
#endif
#if defined(need_GL_EXT_vertex_weighting)
-static const char VertexWeightPointerEXT_names[] =
+static const char VertexWeightPointerEXT_names[] =
"iiip\0" /* Parameter signature */
"glVertexWeightPointerEXT\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetHistogram_names[] =
+static const char GetHistogram_names[] =
"iiiip\0" /* Parameter signature */
"glGetHistogram\0"
"glGetHistogramEXT\0"
@@ -4217,21 +4301,21 @@ static const char GetHistogram_names[] =
#endif
#if defined(need_GL_EXT_stencil_two_side)
-static const char ActiveStencilFaceEXT_names[] =
+static const char ActiveStencilFaceEXT_names[] =
"i\0" /* Parameter signature */
"glActiveStencilFaceEXT\0"
"";
#endif
#if defined(need_GL_ATI_separate_stencil)
-static const char StencilFuncSeparateATI_names[] =
+static const char StencilFuncSeparateATI_names[] =
"iiii\0" /* Parameter signature */
"glStencilFuncSeparateATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char GetShaderSourceARB_names[] =
+static const char GetShaderSourceARB_names[] =
"iipp\0" /* Parameter signature */
"glGetShaderSource\0"
"glGetShaderSourceARB\0"
@@ -4239,28 +4323,28 @@ static const char GetShaderSourceARB_names[] =
#endif
#if defined(need_GL_SGIX_igloo_interface)
-static const char IglooInterfaceSGIX_names[] =
+static const char IglooInterfaceSGIX_names[] =
"ip\0" /* Parameter signature */
"glIglooInterfaceSGIX\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4dNV_names[] =
+static const char VertexAttrib4dNV_names[] =
"idddd\0" /* Parameter signature */
"glVertexAttrib4dNV\0"
"";
#endif
#if defined(need_GL_IBM_multimode_draw_arrays)
-static const char MultiModeDrawElementsIBM_names[] =
+static const char MultiModeDrawElementsIBM_names[] =
"ppipii\0" /* Parameter signature */
"glMultiModeDrawElementsIBM\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4svARB_names[] =
+static const char MultiTexCoord4svARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord4sv\0"
"glMultiTexCoord4svARB\0"
@@ -4268,7 +4352,7 @@ static const char MultiTexCoord4svARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_occlusion_query)
-static const char GenQueriesARB_names[] =
+static const char GenQueriesARB_names[] =
"ip\0" /* Parameter signature */
"glGenQueries\0"
"glGenQueriesARB\0"
@@ -4276,35 +4360,42 @@ static const char GenQueriesARB_names[] =
#endif
#if defined(need_GL_SUN_vertex)
-static const char ReplacementCodeuiVertex3fSUN_names[] =
+static const char ReplacementCodeuiVertex3fSUN_names[] =
"ifff\0" /* Parameter signature */
"glReplacementCodeuiVertex3fSUN\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3iEXT_names[] =
+static const char Tangent3iEXT_names[] =
"iii\0" /* Parameter signature */
"glTangent3iEXT\0"
"";
#endif
#if defined(need_GL_SUN_mesh_array)
-static const char DrawMeshArraysSUN_names[] =
+static const char DrawMeshArraysSUN_names[] =
"iiii\0" /* Parameter signature */
"glDrawMeshArraysSUN\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char IsSync_names[] =
+ "i\0" /* Parameter signature */
+ "glIsSync\0"
+ "";
+#endif
+
#if defined(need_GL_NV_evaluators)
-static const char GetMapControlPointsNV_names[] =
+static const char GetMapControlPointsNV_names[] =
"iiiiiip\0" /* Parameter signature */
"glGetMapControlPointsNV\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_draw_buffers) || defined(need_GL_ATI_draw_buffers)
-static const char DrawBuffersARB_names[] =
+static const char DrawBuffersARB_names[] =
"ip\0" /* Parameter signature */
"glDrawBuffers\0"
"glDrawBuffersARB\0"
@@ -4313,28 +4404,29 @@ static const char DrawBuffersARB_names[] =
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char ProgramLocalParameter4fARB_names[] =
+static const char ProgramLocalParameter4fARB_names[] =
"iiffff\0" /* Parameter signature */
"glProgramLocalParameter4fARB\0"
"";
#endif
#if defined(need_GL_SGIX_sprite)
-static const char SpriteParameterivSGIX_names[] =
+static const char SpriteParameterivSGIX_names[] =
"ip\0" /* Parameter signature */
"glSpriteParameterivSGIX\0"
"";
#endif
-#if defined(need_GL_EXT_provoking_vertex)
-static const char ProvokingVertexEXT_names[] =
+#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
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord1fARB_names[] =
+static const char MultiTexCoord1fARB_names[] =
"if\0" /* Parameter signature */
"glMultiTexCoord1f\0"
"glMultiTexCoord1fARB\0"
@@ -4342,21 +4434,21 @@ static const char MultiTexCoord1fARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs4ubvNV_names[] =
+static const char VertexAttribs4ubvNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs4ubvNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightsvARB_names[] =
+static const char WeightsvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightsvARB\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_shader_objects)
-static const char Uniform1fvARB_names[] =
+static const char Uniform1fvARB_names[] =
"iip\0" /* Parameter signature */
"glUniform1fv\0"
"glUniform1fvARB\0"
@@ -4364,7 +4456,7 @@ static const char Uniform1fvARB_names[] =
#endif
#if defined(need_GL_EXT_copy_texture)
-static const char CopyTexSubImage1D_names[] =
+static const char CopyTexSubImage1D_names[] =
"iiiiii\0" /* Parameter signature */
"glCopyTexSubImage1D\0"
"glCopyTexSubImage1DEXT\0"
@@ -4372,7 +4464,7 @@ static const char CopyTexSubImage1D_names[] =
#endif
#if defined(need_GL_EXT_texture_object)
-static const char BindTexture_names[] =
+static const char BindTexture_names[] =
"ii\0" /* Parameter signature */
"glBindTexture\0"
"glBindTextureEXT\0"
@@ -4380,14 +4472,14 @@ static const char BindTexture_names[] =
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char BeginFragmentShaderATI_names[] =
+static const char BeginFragmentShaderATI_names[] =
"\0" /* Parameter signature */
"glBeginFragmentShaderATI\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord4fARB_names[] =
+static const char MultiTexCoord4fARB_names[] =
"iffff\0" /* Parameter signature */
"glMultiTexCoord4f\0"
"glMultiTexCoord4fARB\0"
@@ -4395,21 +4487,21 @@ static const char MultiTexCoord4fARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs3svNV_names[] =
+static const char VertexAttribs3svNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs3svNV\0"
"";
#endif
#if defined(need_GL_SUN_triangle_list)
-static const char ReplacementCodeuivSUN_names[] =
+static const char ReplacementCodeuivSUN_names[] =
"p\0" /* Parameter signature */
"glReplacementCodeuivSUN\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char EnableVertexAttribArrayARB_names[] =
+static const char EnableVertexAttribArrayARB_names[] =
"i\0" /* Parameter signature */
"glEnableVertexAttribArray\0"
"glEnableVertexAttribArrayARB\0"
@@ -4417,14 +4509,14 @@ static const char EnableVertexAttribArrayARB_names[] =
#endif
#if defined(need_GL_INTEL_parallel_arrays)
-static const char NormalPointervINTEL_names[] =
+static const char NormalPointervINTEL_names[] =
"ip\0" /* Parameter signature */
"glNormalPointervINTEL\0"
"";
#endif
#if defined(need_GL_EXT_convolution)
-static const char CopyConvolutionFilter2D_names[] =
+static const char CopyConvolutionFilter2D_names[] =
"iiiiii\0" /* Parameter signature */
"glCopyConvolutionFilter2D\0"
"glCopyConvolutionFilter2DEXT\0"
@@ -4432,7 +4524,7 @@ static const char CopyConvolutionFilter2D_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3ivMESA_names[] =
+static const char WindowPos3ivMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos3iv\0"
"glWindowPos3ivARB\0"
@@ -4441,14 +4533,14 @@ static const char WindowPos3ivMESA_names[] =
#endif
#if defined(need_GL_ARB_copy_buffer)
-static const char CopyBufferSubData_names[] =
+static const char CopyBufferSubData_names[] =
"iiiii\0" /* Parameter signature */
"glCopyBufferSubData\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char IsBufferARB_names[] =
+static const char IsBufferARB_names[] =
"i\0" /* Parameter signature */
"glIsBuffer\0"
"glIsBufferARB\0"
@@ -4456,14 +4548,14 @@ static const char IsBufferARB_names[] =
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4iMESA_names[] =
+static const char WindowPos4iMESA_names[] =
"iiii\0" /* Parameter signature */
"glWindowPos4iMESA\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4uivARB_names[] =
+static const char VertexAttrib4uivARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4uiv\0"
"glVertexAttrib4uivARB\0"
@@ -4471,35 +4563,35 @@ static const char VertexAttrib4uivARB_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3bvEXT_names[] =
+static const char Tangent3bvEXT_names[] =
"p\0" /* Parameter signature */
"glTangent3bvEXT\0"
"";
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix3x4fv_names[] =
+static const char UniformMatrix3x4fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix3x4fv\0"
"";
#endif
-#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3fvEXT_names[] =
- "p\0" /* Parameter signature */
- "glBinormal3fvEXT\0"
+#if defined(need_GL_ARB_draw_elements_base_vertex)
+static const char DrawRangeElementsBaseVertex_names[] =
+ "iiiiipi\0" /* Parameter signature */
+ "glDrawRangeElementsBaseVertex\0"
"";
#endif
#if defined(need_GL_INTEL_parallel_arrays)
-static const char TexCoordPointervINTEL_names[] =
+static const char TexCoordPointervINTEL_names[] =
"iip\0" /* Parameter signature */
"glTexCoordPointervINTEL\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char DeleteBuffersARB_names[] =
+static const char DeleteBuffersARB_names[] =
"ip\0" /* Parameter signature */
"glDeleteBuffers\0"
"glDeleteBuffersARB\0"
@@ -4507,21 +4599,21 @@ static const char DeleteBuffersARB_names[] =
#endif
#if defined(need_GL_MESA_window_pos)
-static const char WindowPos4fvMESA_names[] =
+static const char WindowPos4fvMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos4fvMESA\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1sNV_names[] =
+static const char VertexAttrib1sNV_names[] =
"ii\0" /* Parameter signature */
"glVertexAttrib1sNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_secondary_color)
-static const char SecondaryColor3svEXT_names[] =
+static const char SecondaryColor3svEXT_names[] =
"p\0" /* Parameter signature */
"glSecondaryColor3sv\0"
"glSecondaryColor3svEXT\0"
@@ -4529,7 +4621,7 @@ static const char SecondaryColor3svEXT_names[] =
#endif
#if defined(need_GL_VERSION_1_3) || defined(need_GL_ARB_transpose_matrix)
-static const char LoadTransposeMatrixfARB_names[] =
+static const char LoadTransposeMatrixfARB_names[] =
"p\0" /* Parameter signature */
"glLoadTransposeMatrixf\0"
"glLoadTransposeMatrixfARB\0"
@@ -4537,7 +4629,7 @@ static const char LoadTransposeMatrixfARB_names[] =
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char GetPointerv_names[] =
+static const char GetPointerv_names[] =
"ip\0" /* Parameter signature */
"glGetPointerv\0"
"glGetPointervEXT\0"
@@ -4545,21 +4637,21 @@ static const char GetPointerv_names[] =
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3bEXT_names[] =
+static const char Tangent3bEXT_names[] =
"iii\0" /* Parameter signature */
"glTangent3bEXT\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerParameterfNV_names[] =
+static const char CombinerParameterfNV_names[] =
"if\0" /* Parameter signature */
"glCombinerParameterfNV\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char BindProgramNV_names[] =
+static const char BindProgramNV_names[] =
"ii\0" /* Parameter signature */
"glBindProgramARB\0"
"glBindProgramNV\0"
@@ -4567,7 +4659,7 @@ static const char BindProgramNV_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4svARB_names[] =
+static const char VertexAttrib4svARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4sv\0"
"glVertexAttrib4svARB\0"
@@ -4575,28 +4667,35 @@ static const char VertexAttrib4svARB_names[] =
#endif
#if defined(need_GL_MESA_shader_debug)
-static const char CreateDebugObjectMESA_names[] =
+static const char CreateDebugObjectMESA_names[] =
"\0" /* Parameter signature */
"glCreateDebugObjectMESA\0"
"";
#endif
#if defined(need_GL_VERSION_2_0)
-static const char GetShaderiv_names[] =
+static const char GetShaderiv_names[] =
"iip\0" /* Parameter signature */
"glGetShaderiv\0"
"";
#endif
+#if defined(need_GL_ARB_sync)
+static const char ClientWaitSync_names[] =
+ "iii\0" /* Parameter signature */
+ "glClientWaitSync\0"
+ "";
+#endif
+
#if defined(need_GL_ATI_fragment_shader)
-static const char BindFragmentShaderATI_names[] =
+static const char BindFragmentShaderATI_names[] =
"i\0" /* Parameter signature */
"glBindFragmentShaderATI\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char UnmapBufferARB_names[] =
+static const char UnmapBufferARB_names[] =
"i\0" /* Parameter signature */
"glUnmapBuffer\0"
"glUnmapBufferARB\0"
@@ -4604,7 +4703,7 @@ static const char UnmapBufferARB_names[] =
#endif
#if defined(need_GL_EXT_histogram)
-static const char Minmax_names[] =
+static const char Minmax_names[] =
"iii\0" /* Parameter signature */
"glMinmax\0"
"glMinmaxEXT\0"
@@ -4612,7 +4711,7 @@ static const char Minmax_names[] =
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_EXT_fog_coord)
-static const char FogCoorddvEXT_names[] =
+static const char FogCoorddvEXT_names[] =
"p\0" /* Parameter signature */
"glFogCoorddv\0"
"glFogCoorddvEXT\0"
@@ -4620,35 +4719,35 @@ static const char FogCoorddvEXT_names[] =
#endif
#if defined(need_GL_SUNX_constant_data)
-static const char FinishTextureSUNX_names[] =
+static const char FinishTextureSUNX_names[] =
"\0" /* Parameter signature */
"glFinishTextureSUNX\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char GetFragmentLightfvSGIX_names[] =
+static const char GetFragmentLightfvSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetFragmentLightfvSGIX\0"
"";
#endif
-#if defined(need_GL_NV_register_combiners)
-static const char GetFinalCombinerInputParameterfvNV_names[] =
- "iip\0" /* Parameter signature */
- "glGetFinalCombinerInputParameterfvNV\0"
+#if defined(need_GL_EXT_coordinate_frame)
+static const char Binormal3fvEXT_names[] =
+ "p\0" /* Parameter signature */
+ "glBinormal3fvEXT\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char ColorFragmentOp3ATI_names[] =
+static const char ColorFragmentOp3ATI_names[] =
"iiiiiiiiiiiii\0" /* Parameter signature */
"glColorFragmentOp3ATI\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2svARB_names[] =
+static const char VertexAttrib2svARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib2sv\0"
"glVertexAttrib2svARB\0"
@@ -4656,14 +4755,14 @@ static const char VertexAttrib2svARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char AreProgramsResidentNV_names[] =
+static const char AreProgramsResidentNV_names[] =
"ipp\0" /* Parameter signature */
"glAreProgramsResidentNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos3svMESA_names[] =
+static const char WindowPos3svMESA_names[] =
"p\0" /* Parameter signature */
"glWindowPos3sv\0"
"glWindowPos3svARB\0"
@@ -4672,7 +4771,7 @@ static const char WindowPos3svMESA_names[] =
#endif
#if defined(need_GL_EXT_color_subtable)
-static const char CopyColorSubTable_names[] =
+static const char CopyColorSubTable_names[] =
"iiiii\0" /* Parameter signature */
"glCopyColorSubTable\0"
"glCopyColorSubTableEXT\0"
@@ -4680,14 +4779,14 @@ static const char CopyColorSubTable_names[] =
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightdvARB_names[] =
+static const char WeightdvARB_names[] =
"ip\0" /* Parameter signature */
"glWeightdvARB\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char DeleteRenderbuffersEXT_names[] =
+static const char DeleteRenderbuffersEXT_names[] =
"ip\0" /* Parameter signature */
"glDeleteRenderbuffers\0"
"glDeleteRenderbuffersEXT\0"
@@ -4695,7 +4794,7 @@ static const char DeleteRenderbuffersEXT_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib4NubvARB_names[] =
+static const char VertexAttrib4NubvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4Nubv\0"
"glVertexAttrib4NubvARB\0"
@@ -4703,63 +4802,63 @@ static const char VertexAttrib4NubvARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib3dvNV_names[] =
+static const char VertexAttrib3dvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib3dvNV\0"
"";
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char GetObjectParameterfvARB_names[] =
+static const char GetObjectParameterfvARB_names[] =
"iip\0" /* Parameter signature */
"glGetObjectParameterfvARB\0"
"";
#endif
#if defined(need_GL_ARB_vertex_program)
-static const char GetProgramEnvParameterdvARB_names[] =
+static const char GetProgramEnvParameterdvARB_names[] =
"iip\0" /* Parameter signature */
"glGetProgramEnvParameterdvARB\0"
"";
#endif
#if defined(need_GL_EXT_compiled_vertex_array)
-static const char LockArraysEXT_names[] =
+static const char LockArraysEXT_names[] =
"ii\0" /* Parameter signature */
"glLockArraysEXT\0"
"";
#endif
#if defined(need_GL_EXT_pixel_transform)
-static const char PixelTransformParameterivEXT_names[] =
+static const char PixelTransformParameterivEXT_names[] =
"iip\0" /* Parameter signature */
"glPixelTransformParameterivEXT\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char BinormalPointerEXT_names[] =
+static const char BinormalPointerEXT_names[] =
"iip\0" /* Parameter signature */
"glBinormalPointerEXT\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib1dNV_names[] =
+static const char VertexAttrib1dNV_names[] =
"id\0" /* Parameter signature */
"glVertexAttrib1dNV\0"
"";
#endif
#if defined(need_GL_NV_register_combiners)
-static const char GetCombinerInputParameterivNV_names[] =
+static const char GetCombinerInputParameterivNV_names[] =
"iiiip\0" /* Parameter signature */
"glGetCombinerInputParameterivNV\0"
"";
#endif
#if defined(need_GL_VERSION_1_3)
-static const char MultiTexCoord2fvARB_names[] =
+static const char MultiTexCoord2fvARB_names[] =
"ip\0" /* Parameter signature */
"glMultiTexCoord2fv\0"
"glMultiTexCoord2fvARB\0"
@@ -4767,7 +4866,7 @@ static const char MultiTexCoord2fvARB_names[] =
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char GetRenderbufferParameterivEXT_names[] =
+static const char GetRenderbufferParameterivEXT_names[] =
"iip\0" /* Parameter signature */
"glGetRenderbufferParameteriv\0"
"glGetRenderbufferParameterivEXT\0"
@@ -4775,21 +4874,21 @@ static const char GetRenderbufferParameterivEXT_names[] =
#endif
#if defined(need_GL_NV_register_combiners)
-static const char CombinerParameterivNV_names[] =
+static const char CombinerParameterivNV_names[] =
"ip\0" /* Parameter signature */
"glCombinerParameterivNV\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char GenFragmentShadersATI_names[] =
+static const char GenFragmentShadersATI_names[] =
"i\0" /* Parameter signature */
"glGenFragmentShadersATI\0"
"";
#endif
#if defined(need_GL_EXT_vertex_array)
-static const char DrawArrays_names[] =
+static const char DrawArrays_names[] =
"iii\0" /* Parameter signature */
"glDrawArrays\0"
"glDrawArraysEXT\0"
@@ -4797,14 +4896,14 @@ static const char DrawArrays_names[] =
#endif
#if defined(need_GL_ARB_vertex_blend)
-static const char WeightuivARB_names[] =
+static const char WeightuivARB_names[] =
"ip\0" /* Parameter signature */
"glWeightuivARB\0"
"";
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib2sARB_names[] =
+static const char VertexAttrib2sARB_names[] =
"iii\0" /* Parameter signature */
"glVertexAttrib2s\0"
"glVertexAttrib2sARB\0"
@@ -4812,28 +4911,28 @@ static const char VertexAttrib2sARB_names[] =
#endif
#if defined(need_GL_SGIX_async)
-static const char GenAsyncMarkersSGIX_names[] =
+static const char GenAsyncMarkersSGIX_names[] =
"i\0" /* Parameter signature */
"glGenAsyncMarkersSGIX\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Tangent3svEXT_names[] =
+static const char Tangent3svEXT_names[] =
"p\0" /* Parameter signature */
"glTangent3svEXT\0"
"";
#endif
#if defined(need_GL_SGIX_list_priority)
-static const char GetListParameterivSGIX_names[] =
+static const char GetListParameterivSGIX_names[] =
"iip\0" /* Parameter signature */
"glGetListParameterivSGIX\0"
"";
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char BindBufferARB_names[] =
+static const char BindBufferARB_names[] =
"ii\0" /* Parameter signature */
"glBindBuffer\0"
"glBindBufferARB\0"
@@ -4841,35 +4940,35 @@ static const char BindBufferARB_names[] =
#endif
#if defined(need_GL_ARB_shader_objects)
-static const char GetInfoLogARB_names[] =
+static const char GetInfoLogARB_names[] =
"iipp\0" /* Parameter signature */
"glGetInfoLogARB\0"
"";
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs4svNV_names[] =
+static const char VertexAttribs4svNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs4svNV\0"
"";
#endif
#if defined(need_GL_IBM_vertex_array_lists)
-static const char EdgeFlagPointerListIBM_names[] =
+static const char EdgeFlagPointerListIBM_names[] =
"ipi\0" /* Parameter signature */
"glEdgeFlagPointerListIBM\0"
"";
#endif
#if defined(need_GL_VERSION_2_1)
-static const char UniformMatrix3x2fv_names[] =
+static const char UniformMatrix3x2fv_names[] =
"iiip\0" /* Parameter signature */
"glUniformMatrix3x2fv\0"
"";
#endif
#if defined(need_GL_EXT_histogram)
-static const char GetMinmaxParameterfv_names[] =
+static const char GetMinmaxParameterfv_names[] =
"iip\0" /* Parameter signature */
"glGetMinmaxParameterfv\0"
"glGetMinmaxParameterfvEXT\0"
@@ -4877,7 +4976,7 @@ static const char GetMinmaxParameterfv_names[] =
#endif
#if defined(need_GL_VERSION_2_0) || defined(need_GL_ARB_vertex_program)
-static const char VertexAttrib1fvARB_names[] =
+static const char VertexAttrib1fvARB_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib1fv\0"
"glVertexAttrib1fvARB\0"
@@ -4885,7 +4984,7 @@ static const char VertexAttrib1fvARB_names[] =
#endif
#if defined(need_GL_VERSION_1_5) || defined(need_GL_ARB_vertex_buffer_object)
-static const char GenBuffersARB_names[] =
+static const char GenBuffersARB_names[] =
"ip\0" /* Parameter signature */
"glGenBuffers\0"
"glGenBuffersARB\0"
@@ -4893,35 +4992,35 @@ static const char GenBuffersARB_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttribs1svNV_names[] =
+static const char VertexAttribs1svNV_names[] =
"iip\0" /* Parameter signature */
"glVertexAttribs1svNV\0"
"";
#endif
#if defined(need_GL_ATI_envmap_bumpmap)
-static const char GetTexBumpParameterivATI_names[] =
+static const char GetTexBumpParameterivATI_names[] =
"ip\0" /* Parameter signature */
"glGetTexBumpParameterivATI\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3bEXT_names[] =
+static const char Binormal3bEXT_names[] =
"iii\0" /* Parameter signature */
"glBinormal3bEXT\0"
"";
#endif
#if defined(need_GL_SGIX_fragment_lighting)
-static const char FragmentMaterialivSGIX_names[] =
+static const char FragmentMaterialivSGIX_names[] =
"iip\0" /* Parameter signature */
"glFragmentMaterialivSGIX\0"
"";
#endif
#if defined(need_GL_ARB_framebuffer_object) || defined(need_GL_EXT_framebuffer_object)
-static const char IsRenderbufferEXT_names[] =
+static const char IsRenderbufferEXT_names[] =
"i\0" /* Parameter signature */
"glIsRenderbuffer\0"
"glIsRenderbufferEXT\0"
@@ -4929,7 +5028,7 @@ static const char IsRenderbufferEXT_names[] =
#endif
#if defined(need_GL_ARB_vertex_program) || defined(need_GL_NV_vertex_program)
-static const char GenProgramsNV_names[] =
+static const char GenProgramsNV_names[] =
"ip\0" /* Parameter signature */
"glGenProgramsARB\0"
"glGenProgramsNV\0"
@@ -4937,28 +5036,28 @@ static const char GenProgramsNV_names[] =
#endif
#if defined(need_GL_NV_vertex_program)
-static const char VertexAttrib4dvNV_names[] =
+static const char VertexAttrib4dvNV_names[] =
"ip\0" /* Parameter signature */
"glVertexAttrib4dvNV\0"
"";
#endif
#if defined(need_GL_ATI_fragment_shader)
-static const char EndFragmentShaderATI_names[] =
+static const char EndFragmentShaderATI_names[] =
"\0" /* Parameter signature */
"glEndFragmentShaderATI\0"
"";
#endif
#if defined(need_GL_EXT_coordinate_frame)
-static const char Binormal3iEXT_names[] =
+static const char Binormal3iEXT_names[] =
"iii\0" /* Parameter signature */
"glBinormal3iEXT\0"
"";
#endif
#if defined(need_GL_VERSION_1_4) || defined(need_GL_ARB_window_pos) || defined(need_GL_MESA_window_pos)
-static const char WindowPos2fMESA_names[] =
+static const char WindowPos2fMESA_names[] =
"ff\0" /* Parameter signature */
"glWindowPos2f\0"
"glWindowPos2fARB\0"
@@ -4973,6 +5072,22 @@ static const struct dri_extension_function GL_3DFX_tbuffer_functions[] = {
};
#endif
+#if defined(need_GL_APPLE_flush_buffer_range)
+static const struct dri_extension_function GL_APPLE_flush_buffer_range_functions[] = {
+ { BufferParameteriAPPLE_names, BufferParameteriAPPLE_remap_index, -1 },
+ { FlushMappedBufferRangeAPPLE_names, FlushMappedBufferRangeAPPLE_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
+#if defined(need_GL_APPLE_texture_range)
+static const struct dri_extension_function GL_APPLE_texture_range_functions[] = {
+ { TextureRangeAPPLE_names, TextureRangeAPPLE_remap_index, -1 },
+ { GetTexParameterPointervAPPLE_names, GetTexParameterPointervAPPLE_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_APPLE_vertex_array_object)
static const struct dri_extension_function GL_APPLE_vertex_array_object_functions[] = {
{ DeleteVertexArraysAPPLE_names, DeleteVertexArraysAPPLE_remap_index, -1 },
@@ -4997,6 +5112,15 @@ static const struct dri_extension_function GL_ARB_draw_buffers_functions[] = {
};
#endif
+#if defined(need_GL_ARB_draw_elements_base_vertex)
+static const struct dri_extension_function GL_ARB_draw_elements_base_vertex_functions[] = {
+ { DrawElementsBaseVertex_names, DrawElementsBaseVertex_remap_index, -1 },
+ { MultiDrawElementsBaseVertex_names, MultiDrawElementsBaseVertex_remap_index, -1 },
+ { DrawRangeElementsBaseVertex_names, DrawRangeElementsBaseVertex_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_framebuffer_object)
static const struct dri_extension_function GL_ARB_framebuffer_object_functions[] = {
{ BlitFramebufferEXT_names, BlitFramebufferEXT_remap_index, -1 },
@@ -5071,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 },
@@ -5116,6 +5247,19 @@ static const struct dri_extension_function GL_ARB_shader_objects_functions[] = {
};
#endif
+#if defined(need_GL_ARB_sync)
+static const struct dri_extension_function GL_ARB_sync_functions[] = {
+ { DeleteSync_names, DeleteSync_remap_index, -1 },
+ { FenceSync_names, FenceSync_remap_index, -1 },
+ { WaitSync_names, WaitSync_remap_index, -1 },
+ { GetInteger64v_names, GetInteger64v_remap_index, -1 },
+ { GetSynciv_names, GetSynciv_remap_index, -1 },
+ { IsSync_names, IsSync_remap_index, -1 },
+ { ClientWaitSync_names, ClientWaitSync_remap_index, -1 },
+ { NULL, 0, 0 }
+};
+#endif
+
#if defined(need_GL_ARB_texture_compression)
static const struct dri_extension_function GL_ARB_texture_compression_functions[] = {
{ CompressedTexSubImage2DARB_names, CompressedTexSubImage2DARB_remap_index, -1 },
@@ -5414,8 +5558,8 @@ static const struct dri_extension_function GL_EXT_coordinate_frame_functions[] =
{ Binormal3dvEXT_names, Binormal3dvEXT_remap_index, -1 },
{ Tangent3iEXT_names, Tangent3iEXT_remap_index, -1 },
{ Tangent3bvEXT_names, Tangent3bvEXT_remap_index, -1 },
- { Binormal3fvEXT_names, Binormal3fvEXT_remap_index, -1 },
{ Tangent3bEXT_names, Tangent3bEXT_remap_index, -1 },
+ { Binormal3fvEXT_names, Binormal3fvEXT_remap_index, -1 },
{ BinormalPointerEXT_names, BinormalPointerEXT_remap_index, -1 },
{ Tangent3svEXT_names, Tangent3svEXT_remap_index, -1 },
{ Binormal3bEXT_names, Binormal3bEXT_remap_index, -1 },
@@ -5857,6 +6001,7 @@ static const struct dri_extension_function GL_NV_point_sprite_functions[] = {
static const struct dri_extension_function GL_NV_register_combiners_functions[] = {
{ CombinerOutputNV_names, CombinerOutputNV_remap_index, -1 },
{ CombinerParameterfvNV_names, CombinerParameterfvNV_remap_index, -1 },
+ { GetFinalCombinerInputParameterfvNV_names, GetFinalCombinerInputParameterfvNV_remap_index, -1 },
{ GetCombinerOutputParameterfvNV_names, GetCombinerOutputParameterfvNV_remap_index, -1 },
{ FinalCombinerInputNV_names, FinalCombinerInputNV_remap_index, -1 },
{ GetCombinerInputParameterfvNV_names, GetCombinerInputParameterfvNV_remap_index, -1 },
@@ -5865,7 +6010,6 @@ static const struct dri_extension_function GL_NV_register_combiners_functions[]
{ GetFinalCombinerInputParameterivNV_names, GetFinalCombinerInputParameterivNV_remap_index, -1 },
{ CombinerInputNV_names, CombinerInputNV_remap_index, -1 },
{ CombinerParameterfNV_names, CombinerParameterfNV_remap_index, -1 },
- { GetFinalCombinerInputParameterfvNV_names, GetFinalCombinerInputParameterfvNV_remap_index, -1 },
{ GetCombinerInputParameterivNV_names, GetCombinerInputParameterivNV_remap_index, -1 },
{ CombinerParameterivNV_names, CombinerParameterivNV_remap_index, -1 },
{ NULL, 0, 0 }
@@ -5892,6 +6036,7 @@ static const struct dri_extension_function GL_NV_vertex_array_range_functions[]
static const struct dri_extension_function GL_NV_vertex_program_functions[] = {
{ VertexAttrib4ubvNV_names, VertexAttrib4ubvNV_remap_index, -1 },
{ VertexAttrib4svNV_names, VertexAttrib4svNV_remap_index, -1 },
+ { VertexAttribs3fvNV_names, VertexAttribs3fvNV_remap_index, -1 },
{ VertexAttribs1dvNV_names, VertexAttribs1dvNV_remap_index, -1 },
{ VertexAttrib1fvNV_names, VertexAttrib1fvNV_remap_index, -1 },
{ VertexAttrib4fNV_names, VertexAttrib4fNV_remap_index, -1 },
@@ -5900,7 +6045,6 @@ static const struct dri_extension_function GL_NV_vertex_program_functions[] = {
{ VertexAttribs3dvNV_names, VertexAttribs3dvNV_remap_index, -1 },
{ VertexAttribs4fvNV_names, VertexAttribs4fvNV_remap_index, -1 },
{ VertexAttrib2sNV_names, VertexAttrib2sNV_remap_index, -1 },
- { VertexAttribs3fvNV_names, VertexAttribs3fvNV_remap_index, -1 },
{ ProgramEnvParameter4fvARB_names, ProgramEnvParameter4fvARB_remap_index, -1 },
{ LoadProgramNV_names, LoadProgramNV_remap_index, -1 },
{ VertexAttrib4fvNV_names, VertexAttrib4fvNV_remap_index, -1 },
diff --git a/src/mesa/drivers/dri/fb/fb_egl.c b/src/mesa/drivers/dri/fb/fb_egl.c
index dee67feb5a..4e41860d8c 100644
--- a/src/mesa/drivers/dri/fb/fb_egl.c
+++ b/src/mesa/drivers/dri/fb/fb_egl.c
@@ -605,7 +605,7 @@ fbDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
{
fbSurface *fs = Lookup_fbSurface(surface);
_eglUnlinkSurface(&fs->Base);
- if (!fs->Base.IsBound)
+ if (!_eglIsSurfaceBound(&fs->Base))
free(fs);
return EGL_TRUE;
}
@@ -616,7 +616,7 @@ fbDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext context)
{
fbContext *fc = Lookup_fbContext(context);
_eglUnlinkContext(&fc->Base);
- if (!fc->Base.IsBound)
+ if (!_eglIsContextBound(&fc->Base))
free(fc);
return EGL_TRUE;
}
diff --git a/src/mesa/drivers/dri/ffb/ffb_tex.c b/src/mesa/drivers/dri/ffb/ffb_tex.c
index 69d30aedba..95058e9069 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/i915/Makefile b/src/mesa/drivers/dri/i915/Makefile
index beaf9a4b12..9d049dea8f 100644
--- a/src/mesa/drivers/dri/i915/Makefile
+++ b/src/mesa/drivers/dri/i915/Makefile
@@ -51,6 +51,7 @@ DRIVER_SOURCES = \
intel_screen.c \
intel_span.c \
intel_state.c \
+ intel_syncobj.c \
intel_tris.c \
intel_fbo.c
diff --git a/src/mesa/drivers/dri/i915/i830_context.h b/src/mesa/drivers/dri/i915/i830_context.h
index 1bdb32049d..f73cbbf88b 100644
--- a/src/mesa/drivers/dri/i915/i830_context.h
+++ b/src/mesa/drivers/dri/i915/i830_context.h
@@ -40,6 +40,7 @@
#define I830_UPLOAD_BUFFERS 0x2
#define I830_UPLOAD_STIPPLE 0x4
#define I830_UPLOAD_INVARIENT 0x8
+#define I830_UPLOAD_RASTER_RULES 0x10
#define I830_UPLOAD_TEX(i) (0x10<<(i))
#define I830_UPLOAD_TEXBLEND(i) (0x100<<(i))
#define I830_UPLOAD_TEX_ALL (0x0f0)
@@ -99,6 +100,11 @@
#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
+enum {
+ I830_RASTER_RULES,
+ I830_RASTER_RULES_SIZE
+};
+
struct i830_texture_object
{
struct intel_texture_object intel;
@@ -112,6 +118,7 @@ struct i830_hw_state
GLuint Ctx[I830_CTX_SETUP_SIZE];
GLuint Buffer[I830_DEST_SETUP_SIZE];
GLuint Stipple[I830_STP_SETUP_SIZE];
+ GLuint RasterRules[I830_RASTER_RULES_SIZE];
GLuint Tex[I830_TEX_UNITS][I830_TEX_SETUP_SIZE];
GLuint TexBlend[I830_TEX_UNITS][I830_TEXBLEND_SIZE];
GLuint TexBlendWordsUsed[I830_TEX_UNITS];
@@ -197,6 +204,7 @@ extern void i830InitStateFuncs(struct dd_function_table *functions);
extern void i830EmitState(struct i830_context *i830);
extern void i830InitState(struct i830_context *i830);
+extern void i830_update_provoking_vertex(GLcontext *ctx);
/* i830_metaops.c
*/
diff --git a/src/mesa/drivers/dri/i915/i830_reg.h b/src/mesa/drivers/dri/i915/i830_reg.h
index db16871001..ae1317029a 100644
--- a/src/mesa/drivers/dri/i915/i830_reg.h
+++ b/src/mesa/drivers/dri/i915/i830_reg.h
@@ -420,8 +420,11 @@
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
#define ENABLE_TRI_STRIP_PROVOKE_VRTX (1<<2)
+#define LINE_STRIP_PROVOKE_VRTX_MASK (3<<6)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK (3<<3)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
+#define TRI_STRIP_PROVOKE_VRTX_MASK (3<<0)
#define TRI_STRIP_PROVOKE_VRTX(x) (x)
/* _3DSTATE_SCISSOR_ENABLE, p200 */
diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c
index 8ef6c9144f..645ebe3057 100644
--- a/src/mesa/drivers/dri/i915/i830_state.c
+++ b/src/mesa/drivers/dri/i915/i830_state.c
@@ -1047,6 +1047,16 @@ i830_init_packets(struct i830_context *i830)
TEXBIND_SET1(TEXCOORDSRC_VTXSET_1) |
TEXBIND_SET0(TEXCOORDSRC_VTXSET_0));
+ i830->state.RasterRules[I830_RASTER_RULES] = (_3DSTATE_RASTER_RULES_CMD |
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ ENABLE_TRI_STRIP_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ TRI_STRIP_PROVOKE_VRTX(2));
+
i830->state.Stipple[I830_STPREG_ST0] = _3DSTATE_STIPPLE;
@@ -1058,6 +1068,27 @@ i830_init_packets(struct i830_context *i830)
i830->state.Buffer[I830_DESTREG_SR2] = 0;
}
+void
+i830_update_provoking_vertex(GLcontext * ctx)
+{
+ struct i830_context *i830 = i830_context(ctx);
+
+ I830_STATECHANGE(i830, I830_UPLOAD_RASTER_RULES);
+ i830->state.RasterRules[I830_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+ TRI_FAN_PROVOKE_VRTX_MASK |
+ TRI_STRIP_PROVOKE_VRTX_MASK);
+
+ /* _NEW_LIGHT */
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+ i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) |
+ TRI_STRIP_PROVOKE_VRTX(2));
+ } else {
+ i830->state.RasterRules[I830_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+ TRI_FAN_PROVOKE_VRTX(1) |
+ TRI_STRIP_PROVOKE_VRTX(0));
+ }
+}
void
i830InitStateFuncs(struct dd_function_table *functions)
@@ -1101,6 +1132,7 @@ i830InitState(struct i830_context *i830)
i830->current = &i830->state;
i830->state.emitted = 0;
i830->state.active = (I830_UPLOAD_INVARIENT |
+ I830_UPLOAD_RASTER_RULES |
I830_UPLOAD_TEXBLEND(0) |
I830_UPLOAD_STIPPLE |
I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS);
diff --git a/src/mesa/drivers/dri/i915/i830_vtbl.c b/src/mesa/drivers/dri/i915/i830_vtbl.c
index 9c6f891dd3..983f6724c9 100644
--- a/src/mesa/drivers/dri/i915/i830_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i830_vtbl.c
@@ -299,7 +299,7 @@ i830_emit_invarient_state(struct intel_context *intel)
{
BATCH_LOCALS;
- BEGIN_BATCH(30, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(29, IGNORE_CLIPRECTS);
OUT_BATCH(_3DSTATE_DFLT_DIFFUSE_CMD);
OUT_BATCH(0);
@@ -351,15 +351,6 @@ i830_emit_invarient_state(struct intel_context *intel)
OUT_BATCH(_3DSTATE_MAP_COORD_TRANSFORM);
OUT_BATCH(DISABLE_TEX_TRANSFORM | TEXTURE_SET(3));
- OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- ENABLE_TRI_STRIP_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | TRI_STRIP_PROVOKE_VRTX(2));
-
OUT_BATCH(_3DSTATE_VERTEX_TRANSFORM);
OUT_BATCH(DISABLE_VIEWPORT_TRANSFORM | DISABLE_PERSPECTIVE_DIVIDE);
@@ -394,6 +385,9 @@ get_state_size(struct i830_hw_state *state)
if (dirty & I830_UPLOAD_INVARIENT)
sz += 40 * sizeof(int);
+ if (dirty & I830_UPLOAD_RASTER_RULES)
+ sz += sizeof(state->RasterRules);
+
if (dirty & I830_UPLOAD_CTX)
sz += sizeof(state->Ctx);
@@ -486,6 +480,11 @@ i830_emit_state(struct intel_context *intel)
i830_emit_invarient_state(intel);
}
+ if (dirty & I830_UPLOAD_RASTER_RULES) {
+ DBG("I830_UPLOAD_RASTER_RULES:\n");
+ emit(intel, state->RasterRules, sizeof(state->RasterRules));
+ }
+
if (dirty & I830_UPLOAD_CTX) {
DBG("I830_UPLOAD_CTX:\n");
emit(intel, state->Ctx, sizeof(state->Ctx));
@@ -737,6 +736,13 @@ i830_assert_not_dirty( struct intel_context *intel )
assert(!get_dirty(state));
}
+static void
+i830_invalidate_state(struct intel_context *intel, GLuint new_state)
+{
+ if (new_state & _NEW_LIGHT)
+ i830_update_provoking_vertex(&intel->ctx);
+}
+
void
i830InitVtbl(struct i830_context *i830)
{
@@ -752,4 +758,5 @@ i830InitVtbl(struct i830_context *i830)
i830->intel.vtbl.render_prevalidate = i830_render_prevalidate;
i830->intel.vtbl.assert_not_dirty = i830_assert_not_dirty;
i830->intel.vtbl.finish_batch = intel_finish_vb;
+ i830->intel.vtbl.invalidate_state = i830_invalidate_state;
}
diff --git a/src/mesa/drivers/dri/i915/i915_context.c b/src/mesa/drivers/dri/i915/i915_context.c
index 367d2a3b64..3ab7d682ee 100644
--- a/src/mesa/drivers/dri/i915/i915_context.c
+++ b/src/mesa/drivers/dri/i915/i915_context.c
@@ -27,6 +27,7 @@
#include "i915_context.h"
#include "main/imports.h"
+#include "main/macros.h"
#include "intel_tex.h"
#include "intel_tris.h"
#include "tnl/t_context.h"
@@ -75,6 +76,10 @@ i915InvalidateState(GLcontext * ctx, GLuint new_state)
if (new_state & (_NEW_FOG | _NEW_HINT | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS))
i915_update_fog(ctx);
+ if (new_state & (_NEW_STENCIL | _NEW_BUFFERS | _NEW_POLYGON))
+ i915_update_stencil(ctx);
+ if (new_state & (_NEW_LIGHT))
+ i915_update_provoking_vertex(ctx);
}
@@ -162,6 +167,9 @@ i915CreateContext(const __GLcontextModes * mesaVis,
ctx->Const.FragmentProgram.MaxNativeTexIndirections =
I915_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0; /* I don't think we have one */
+ ctx->Const.FragmentProgram.MaxEnvParams =
+ MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
+ ctx->Const.FragmentProgram.MaxEnvParams);
ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
diff --git a/src/mesa/drivers/dri/i915/i915_context.h b/src/mesa/drivers/dri/i915/i915_context.h
index 87bbf5f927..8de4a9d0d3 100644
--- a/src/mesa/drivers/dri/i915/i915_context.h
+++ b/src/mesa/drivers/dri/i915/i915_context.h
@@ -48,6 +48,7 @@
#define I915_UPLOAD_FOG 0x20
#define I915_UPLOAD_INVARIENT 0x40
#define I915_UPLOAD_DEFAULTS 0x80
+#define I915_UPLOAD_RASTER_RULES 0x100
#define I915_UPLOAD_TEX(i) (0x00010000<<(i))
#define I915_UPLOAD_TEX_ALL (0x00ff0000)
#define I915_UPLOAD_TEX_0_SHIFT 16
@@ -82,7 +83,9 @@
#define I915_CTXREG_IAB 6
#define I915_CTXREG_BLENDCOLOR0 7
#define I915_CTXREG_BLENDCOLOR1 8
-#define I915_CTX_SETUP_SIZE 9
+#define I915_CTXREG_BF_STENCIL_OPS 9
+#define I915_CTXREG_BF_STENCIL_MASKS 10
+#define I915_CTX_SETUP_SIZE 11
#define I915_FOGREG_COLOR 0
#define I915_FOGREG_MODE0 1
@@ -110,6 +113,10 @@
#define I915_DEFREG_Z1 5
#define I915_DEF_SETUP_SIZE 6
+enum {
+ I915_RASTER_RULES,
+ I915_RASTER_RULES_SETUP_SIZE,
+};
#define I915_MAX_CONSTANT 32
#define I915_CONSTANT_SIZE (2+(4*I915_MAX_CONSTANT))
@@ -206,6 +213,7 @@ struct i915_hw_state
GLuint Stipple[I915_STP_SETUP_SIZE];
GLuint Fog[I915_FOG_SETUP_SIZE];
GLuint Defaults[I915_DEF_SETUP_SIZE];
+ GLuint RasterRules[I915_RASTER_RULES_SETUP_SIZE];
GLuint Tex[I915_TEX_UNITS][I915_TEX_SETUP_SIZE];
GLuint Constant[I915_CONSTANT_SIZE];
GLuint ConstantSize;
@@ -321,6 +329,8 @@ extern void i915_print_ureg(const char *msg, GLuint ureg);
extern void i915InitStateFunctions(struct dd_function_table *functions);
extern void i915InitState(struct i915_context *i915);
extern void i915_update_fog(GLcontext * ctx);
+extern void i915_update_stencil(GLcontext * ctx);
+extern void i915_update_provoking_vertex(GLcontext *ctx);
/*======================================================================
diff --git a/src/mesa/drivers/dri/i915/i915_reg.h b/src/mesa/drivers/dri/i915/i915_reg.h
index 84db58ea95..b5fa7fddb9 100644
--- a/src/mesa/drivers/dri/i915/i915_reg.h
+++ b/src/mesa/drivers/dri/i915/i915_reg.h
@@ -86,8 +86,10 @@
#define BFM_ENABLE_STENCIL_WRITE_MASK (1<<16)
#define BFM_STENCIL_TEST_MASK_SHIFT 8
#define BFM_STENCIL_TEST_MASK_MASK (0xff<<8)
+#define BFM_STENCIL_TEST_MASK(x) (((x)&0xff) << 8)
#define BFM_STENCIL_WRITE_MASK_SHIFT 0
#define BFM_STENCIL_WRITE_MASK_MASK (0xff<<0)
+#define BFM_STENCIL_WRITE_MASK(x) ((x)&0xff)
@@ -295,7 +297,9 @@
#define TEXKILL_4D (1<<9)
#define ENABLE_LINE_STRIP_PROVOKE_VRTX (1<<8)
#define ENABLE_TRI_FAN_PROVOKE_VRTX (1<<5)
+#define LINE_STRIP_PROVOKE_VRTX_MASK (3 << 6)
#define LINE_STRIP_PROVOKE_VRTX(x) ((x)<<6)
+#define TRI_FAN_PROVOKE_VRTX_MASK (3 << 3)
#define TRI_FAN_PROVOKE_VRTX(x) ((x)<<3)
/* _3DSTATE_SCISSOR_ENABLE, p256 */
diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c
index 814fb59fd3..b60efea75b 100644
--- a/src/mesa/drivers/dri/i915/i915_state.c
+++ b/src/mesa/drivers/dri/i915/i915_state.c
@@ -48,73 +48,119 @@
#define FILE_DEBUG_FLAG DEBUG_STATE
-static void
-i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
- GLuint mask)
+void
+i915_update_stencil(GLcontext * ctx)
{
struct i915_context *i915 = I915_CONTEXT(ctx);
- int test = intel_translate_compare_func(func);
+ GLuint front_ref, front_writemask, front_mask;
+ GLenum front_func, front_fail, front_pass_z_fail, front_pass_z_pass;
+ GLuint back_ref, back_writemask, back_mask;
+ GLenum back_func, back_fail, back_pass_z_fail, back_pass_z_pass;
- mask = mask & 0xff;
-
- DBG("%s : func: %s, ref : 0x%x, mask: 0x%x\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(func), ref, mask);
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+ /* The 915 considers CW to be "front" for two-sided stencil, so choose
+ * appropriately.
+ */
+ /* _NEW_POLYGON | _NEW_STENCIL */
+ if (ctx->Polygon.FrontFace == GL_CW) {
+ front_ref = ctx->Stencil.Ref[0];
+ front_mask = ctx->Stencil.ValueMask[0];
+ front_writemask = ctx->Stencil.WriteMask[0];
+ front_func = ctx->Stencil.Function[0];
+ front_fail = ctx->Stencil.FailFunc[0];
+ front_pass_z_fail = ctx->Stencil.ZFailFunc[0];
+ front_pass_z_pass = ctx->Stencil.ZPassFunc[0];
+ back_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace];
+ back_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace];
+ back_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace];
+ back_func = ctx->Stencil.Function[ctx->Stencil._BackFace];
+ back_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace];
+ back_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace];
+ back_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace];
+ } else {
+ front_ref = ctx->Stencil.Ref[ctx->Stencil._BackFace];
+ front_mask = ctx->Stencil.ValueMask[ctx->Stencil._BackFace];
+ front_writemask = ctx->Stencil.WriteMask[ctx->Stencil._BackFace];
+ front_func = ctx->Stencil.Function[ctx->Stencil._BackFace];
+ front_fail = ctx->Stencil.FailFunc[ctx->Stencil._BackFace];
+ front_pass_z_fail = ctx->Stencil.ZFailFunc[ctx->Stencil._BackFace];
+ front_pass_z_pass = ctx->Stencil.ZPassFunc[ctx->Stencil._BackFace];
+ back_ref = ctx->Stencil.Ref[0];
+ back_mask = ctx->Stencil.ValueMask[0];
+ back_writemask = ctx->Stencil.WriteMask[0];
+ back_func = ctx->Stencil.Function[0];
+ back_fail = ctx->Stencil.FailFunc[0];
+ back_pass_z_fail = ctx->Stencil.ZFailFunc[0];
+ back_pass_z_pass = ctx->Stencil.ZPassFunc[0];
+ }
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_TEST_MASK;
+ /* Set front state. */
+ i915->state.Ctx[I915_CTXREG_STATE4] &= ~(MODE4_ENABLE_STENCIL_TEST_MASK |
+ MODE4_ENABLE_STENCIL_WRITE_MASK);
i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_TEST_MASK |
- STENCIL_TEST_MASK(mask));
+ ENABLE_STENCIL_WRITE_MASK |
+ STENCIL_TEST_MASK(front_mask) |
+ STENCIL_WRITE_MASK(front_writemask));
i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_REF_MASK |
- S5_STENCIL_TEST_FUNC_MASK);
+ S5_STENCIL_TEST_FUNC_MASK |
+ S5_STENCIL_FAIL_MASK |
+ S5_STENCIL_PASS_Z_FAIL_MASK |
+ S5_STENCIL_PASS_Z_PASS_MASK);
+
+ i915->state.Ctx[I915_CTXREG_LIS5] |=
+ (front_ref << S5_STENCIL_REF_SHIFT) |
+ (intel_translate_compare_func(front_func) << S5_STENCIL_TEST_FUNC_SHIFT) |
+ (intel_translate_stencil_op(front_fail) << S5_STENCIL_FAIL_SHIFT) |
+ (intel_translate_stencil_op(front_pass_z_fail) <<
+ S5_STENCIL_PASS_Z_FAIL_SHIFT) |
+ (intel_translate_stencil_op(front_pass_z_pass) <<
+ S5_STENCIL_PASS_Z_PASS_SHIFT);
+
+ /* Set back state if different from front. */
+ if (ctx->Stencil._TestTwoSide) {
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &=
+ ~(BFO_STENCIL_REF_MASK |
+ BFO_STENCIL_TEST_MASK |
+ BFO_STENCIL_FAIL_MASK |
+ BFO_STENCIL_PASS_Z_FAIL_MASK |
+ BFO_STENCIL_PASS_Z_PASS_MASK);
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] |= BFO_STENCIL_TWO_SIDE |
+ (back_ref << BFO_STENCIL_REF_SHIFT) |
+ (intel_translate_compare_func(back_func) << BFO_STENCIL_TEST_SHIFT) |
+ (intel_translate_stencil_op(back_fail) << BFO_STENCIL_FAIL_SHIFT) |
+ (intel_translate_stencil_op(back_pass_z_fail) <<
+ BFO_STENCIL_PASS_Z_FAIL_SHIFT) |
+ (intel_translate_stencil_op(back_pass_z_pass) <<
+ BFO_STENCIL_PASS_Z_PASS_SHIFT);
+
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] &=
+ ~(BFM_STENCIL_TEST_MASK_MASK |
+ BFM_STENCIL_WRITE_MASK_MASK);
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] |=
+ BFM_STENCIL_TEST_MASK(back_mask) |
+ BFM_STENCIL_WRITE_MASK(back_writemask);
+ } else {
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] &= ~BFO_STENCIL_TWO_SIDE;
+ }
+}
- i915->state.Ctx[I915_CTXREG_LIS5] |= ((ref << S5_STENCIL_REF_SHIFT) |
- (test <<
- S5_STENCIL_TEST_FUNC_SHIFT));
+static void
+i915StencilFuncSeparate(GLcontext * ctx, GLenum face, GLenum func, GLint ref,
+ GLuint mask)
+{
}
static void
i915StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
-
- DBG("%s : mask 0x%x\n", __FUNCTION__, mask);
-
- mask = mask & 0xff;
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
- i915->state.Ctx[I915_CTXREG_STATE4] &= ~MODE4_ENABLE_STENCIL_WRITE_MASK;
- i915->state.Ctx[I915_CTXREG_STATE4] |= (ENABLE_STENCIL_WRITE_MASK |
- STENCIL_WRITE_MASK(mask));
}
-
static void
i915StencilOpSeparate(GLcontext * ctx, GLenum face, GLenum fail, GLenum zfail,
GLenum zpass)
{
- struct i915_context *i915 = I915_CONTEXT(ctx);
- int fop = intel_translate_stencil_op(fail);
- int dfop = intel_translate_stencil_op(zfail);
- int dpop = intel_translate_stencil_op(zpass);
-
-
- DBG("%s: fail : %s, zfail: %s, zpass : %s\n", __FUNCTION__,
- _mesa_lookup_enum_by_nr(fail),
- _mesa_lookup_enum_by_nr(zfail), _mesa_lookup_enum_by_nr(zpass));
-
- I915_STATECHANGE(i915, I915_UPLOAD_CTX);
-
- i915->state.Ctx[I915_CTXREG_LIS5] &= ~(S5_STENCIL_FAIL_MASK |
- S5_STENCIL_PASS_Z_FAIL_MASK |
- S5_STENCIL_PASS_Z_PASS_MASK);
-
- i915->state.Ctx[I915_CTXREG_LIS5] |= ((fop << S5_STENCIL_FAIL_SHIFT) |
- (dfop <<
- S5_STENCIL_PASS_Z_FAIL_SHIFT) |
- (dpop <<
- S5_STENCIL_PASS_Z_PASS_SHIFT));
}
static void
@@ -945,6 +991,17 @@ i915_init_packets(struct i915_context *i915)
_3DSTATE_CONST_BLEND_COLOR_CMD;
i915->state.Ctx[I915_CTXREG_BLENDCOLOR1] = 0;
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_MASKS] =
+ _3DSTATE_BACKFACE_STENCIL_MASKS |
+ BFM_ENABLE_STENCIL_TEST_MASK |
+ BFM_ENABLE_STENCIL_WRITE_MASK |
+ (0xff << BFM_STENCIL_WRITE_MASK_SHIFT) |
+ (0xff << BFM_STENCIL_TEST_MASK_SHIFT);
+ i915->state.Ctx[I915_CTXREG_BF_STENCIL_OPS] =
+ _3DSTATE_BACKFACE_STENCIL_OPS |
+ BFO_ENABLE_STENCIL_REF |
+ BFO_ENABLE_STENCIL_FUNCS |
+ BFO_ENABLE_STENCIL_TWO_SIDE;
}
{
@@ -976,6 +1033,13 @@ i915_init_packets(struct i915_context *i915)
i915->state.Buffer[I915_DESTREG_SR2] = 0;
}
+ i915->state.RasterRules[I915_RASTER_RULES] = _3DSTATE_RASTER_RULES_CMD |
+ ENABLE_POINT_RASTER_RULE |
+ OGL_POINT_RASTER_RULE |
+ ENABLE_LINE_STRIP_PROVOKE_VRTX |
+ ENABLE_TRI_FAN_PROVOKE_VRTX |
+ LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D;
#if 0
{
@@ -996,7 +1060,33 @@ i915_init_packets(struct i915_context *i915)
i915->state.active = (I915_UPLOAD_PROGRAM |
I915_UPLOAD_STIPPLE |
I915_UPLOAD_CTX |
- I915_UPLOAD_BUFFERS | I915_UPLOAD_INVARIENT);
+ I915_UPLOAD_BUFFERS |
+ I915_UPLOAD_INVARIENT |
+ I915_UPLOAD_RASTER_RULES);
+}
+
+void
+i915_update_provoking_vertex(GLcontext * ctx)
+{
+ struct i915_context *i915 = I915_CONTEXT(ctx);
+
+ I915_STATECHANGE(i915, I915_UPLOAD_CTX);
+ i915->state.Ctx[I915_CTXREG_LIS6] &= ~(S6_TRISTRIP_PV_MASK);
+
+ I915_STATECHANGE(i915, I915_UPLOAD_RASTER_RULES);
+ i915->state.RasterRules[I915_RASTER_RULES] &= ~(LINE_STRIP_PROVOKE_VRTX_MASK |
+ TRI_FAN_PROVOKE_VRTX_MASK);
+
+ /* _NEW_LIGHT */
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION) {
+ i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(1) |
+ TRI_FAN_PROVOKE_VRTX(2));
+ i915->state.Ctx[I915_CTXREG_LIS6] |= (2 << S6_TRISTRIP_PV_SHIFT);
+ } else {
+ i915->state.RasterRules[I915_RASTER_RULES] |= (LINE_STRIP_PROVOKE_VRTX(0) |
+ TRI_FAN_PROVOKE_VRTX(1));
+ i915->state.Ctx[I915_CTXREG_LIS6] |= (0 << S6_TRISTRIP_PV_SHIFT);
+ }
}
void
diff --git a/src/mesa/drivers/dri/i915/i915_vtbl.c b/src/mesa/drivers/dri/i915/i915_vtbl.c
index fe1be93a6d..9a723d3cd7 100644
--- a/src/mesa/drivers/dri/i915/i915_vtbl.c
+++ b/src/mesa/drivers/dri/i915/i915_vtbl.c
@@ -176,7 +176,7 @@ i915_emit_invarient_state(struct intel_context *intel)
{
BATCH_LOCALS;
- BEGIN_BATCH(20, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(17, IGNORE_CLIPRECTS);
OUT_BATCH(_3DSTATE_AA_CMD |
AA_LINE_ECAAR_WIDTH_ENABLE |
@@ -200,14 +200,6 @@ i915_emit_invarient_state(struct intel_context *intel)
CSB_TCB(3, 3) |
CSB_TCB(4, 4) | CSB_TCB(5, 5) | CSB_TCB(6, 6) | CSB_TCB(7, 7));
- OUT_BATCH(_3DSTATE_RASTER_RULES_CMD |
- ENABLE_POINT_RASTER_RULE |
- OGL_POINT_RASTER_RULE |
- ENABLE_LINE_STRIP_PROVOKE_VRTX |
- ENABLE_TRI_FAN_PROVOKE_VRTX |
- LINE_STRIP_PROVOKE_VRTX(1) |
- TRI_FAN_PROVOKE_VRTX(2) | ENABLE_TEXKILL_3D_4D | TEXKILL_4D);
-
/* Need to initialize this to zero.
*/
OUT_BATCH(_3DSTATE_LOAD_STATE_IMMEDIATE_1 | I1_LOAD_S(3) | (0));
@@ -225,11 +217,6 @@ i915_emit_invarient_state(struct intel_context *intel)
OUT_BATCH(_3DSTATE_LOAD_INDIRECT | 0); /* disable indirect state */
OUT_BATCH(0);
-
- /* Don't support twosided stencil yet */
- OUT_BATCH(_3DSTATE_BACKFACE_STENCIL_OPS | BFO_ENABLE_STENCIL_TWO_SIDE | 0);
- OUT_BATCH(0);
-
ADVANCE_BATCH();
}
@@ -263,6 +250,9 @@ get_state_size(struct i915_hw_state *state)
if (dirty & I915_UPLOAD_INVARIENT)
sz += 30 * 4;
+ if (dirty & I915_UPLOAD_RASTER_RULES)
+ sz += sizeof(state->RasterRules);
+
if (dirty & I915_UPLOAD_CTX)
sz += sizeof(state->Ctx);
@@ -371,6 +361,12 @@ i915_emit_state(struct intel_context *intel)
i915_emit_invarient_state(intel);
}
+ if (dirty & I915_UPLOAD_RASTER_RULES) {
+ if (INTEL_DEBUG & DEBUG_STATE)
+ fprintf(stderr, "I915_UPLOAD_RASTER_RULES:\n");
+ emit(intel, state->RasterRules, sizeof(state->RasterRules));
+ }
+
if (dirty & I915_UPLOAD_CTX) {
if (INTEL_DEBUG & DEBUG_STATE)
fprintf(stderr, "I915_UPLOAD_CTX:\n");
diff --git a/src/mesa/drivers/dri/i915/intel_syncobj.c b/src/mesa/drivers/dri/i915/intel_syncobj.c
new file mode 120000
index 0000000000..0b2e56ab24
--- /dev/null
+++ b/src/mesa/drivers/dri/i915/intel_syncobj.c
@@ -0,0 +1 @@
+../intel/intel_syncobj.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/i965/Makefile b/src/mesa/drivers/dri/i965/Makefile
index 00a42111da..6e9a9a29a3 100644
--- a/src/mesa/drivers/dri/i965/Makefile
+++ b/src/mesa/drivers/dri/i965/Makefile
@@ -26,6 +26,7 @@ DRIVER_SOURCES = \
intel_pixel_read.c \
intel_state.c \
intel_swapbuffers.c \
+ intel_syncobj.c \
intel_tex.c \
intel_tex_copy.c \
intel_tex_format.c \
@@ -43,6 +44,7 @@ DRIVER_SOURCES = \
brw_clip_util.c \
brw_context.c \
brw_curbe.c \
+ brw_disasm.c \
brw_draw.c \
brw_draw_upload.c \
brw_eu.c \
diff --git a/src/mesa/drivers/dri/i965/brw_cc.c b/src/mesa/drivers/dri/i965/brw_cc.c
index c724218cf5..1088a7a607 100644
--- a/src/mesa/drivers/dri/i965/brw_cc.c
+++ b/src/mesa/drivers/dri/i965/brw_cc.c
@@ -39,12 +39,14 @@
static void prepare_cc_vp( struct brw_context *brw )
{
+ GLcontext *ctx = &brw->intel.ctx;
struct brw_cc_viewport ccv;
memset(&ccv, 0, sizeof(ccv));
- ccv.min_depth = 0.0;
- ccv.max_depth = 1.0;
+ /* _NEW_VIEWPORT */
+ ccv.min_depth = ctx->Viewport.Near;
+ ccv.max_depth = ctx->Viewport.Far;
dri_bo_unreference(brw->cc.vp_bo);
brw->cc.vp_bo = brw_cache_data( &brw->cache, BRW_CC_VP, &ccv, NULL, 0 );
@@ -52,7 +54,7 @@ static void prepare_cc_vp( struct brw_context *brw )
const struct brw_tracked_state brw_cc_vp = {
.dirty = {
- .mesa = 0,
+ .mesa = _NEW_VIEWPORT,
.brw = BRW_NEW_CONTEXT,
.cache = 0
},
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index 12e8548df1..957df441ab 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -100,6 +100,8 @@ struct brw_clip_compile {
struct brw_reg fixed_planes;
struct brw_reg plane_equation;
+
+ struct brw_reg ff_sync;
} reg;
/* 3 different ways of expressing vertex size:
@@ -173,4 +175,5 @@ struct brw_reg get_tmp( struct brw_clip_compile *c );
void brw_clip_project_position(struct brw_clip_compile *c,
struct brw_reg pos );
void brw_clip_ff_sync(struct brw_clip_compile *c);
+void brw_clip_init_ff_sync(struct brw_clip_compile *c);
#endif
diff --git a/src/mesa/drivers/dri/i965/brw_clip_line.c b/src/mesa/drivers/dri/i965/brw_clip_line.c
index 9abd0642aa..048ca620fa 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_line.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_line.c
@@ -85,6 +85,10 @@ static void brw_clip_line_alloc_regs( struct brw_clip_compile *c )
i++;
}
+ if (c->need_ff_sync) {
+ c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+ i++;
+ }
c->first_tmp = i;
c->last_tmp = i;
@@ -246,8 +250,6 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
brw_ADD(p, c->reg.t, c->reg.t0, c->reg.t1);
brw_CMP(p, vec1(brw_null_reg()), BRW_CONDITIONAL_L, c->reg.t, brw_imm_f(1.0));
- if (c->need_ff_sync)
- brw_clip_ff_sync(c);
not_culled = brw_IF(p, BRW_EXECUTE_1);
{
brw_clip_interp_vertex(c, newvtx0, vtx0, vtx1, c->reg.t0, GL_FALSE);
@@ -265,6 +267,7 @@ static void clip_and_emit_line( struct brw_clip_compile *c )
void brw_emit_line_clip( struct brw_clip_compile *c )
{
brw_clip_line_alloc_regs(c);
+ brw_clip_init_ff_sync(c);
if (c->key.do_flat_shading)
brw_clip_copy_colors(c, 0, 1);
diff --git a/src/mesa/drivers/dri/i965/brw_clip_point.c b/src/mesa/drivers/dri/i965/brw_clip_point.c
index 9738299168..8458f61c5a 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_point.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_point.c
@@ -50,7 +50,7 @@ void brw_emit_point_clip( struct brw_clip_compile *c )
/* Send an empty message to kill the thread:
*/
brw_clip_tri_alloc_regs(c, 0);
- if (c->need_ff_sync)
- brw_clip_ff_sync(c);
+ brw_clip_init_ff_sync(c);
+
brw_clip_kill_thread(c);
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_state.c b/src/mesa/drivers/dri/i965/brw_clip_state.c
index 5762c9577c..234b3744bf 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_state.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_state.c
@@ -43,11 +43,14 @@ struct brw_clip_unit_key {
unsigned int curbe_offset;
unsigned int nr_urb_entries, urb_size;
+
+ GLboolean depth_clamp;
};
static void
clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key)
{
+ GLcontext *ctx = &brw->intel.ctx;
memset(key, 0, sizeof(*key));
/* CACHE_NEW_CLIP_PROG */
@@ -62,6 +65,9 @@ clip_unit_populate_key(struct brw_context *brw, struct brw_clip_unit_key *key)
/* BRW_NEW_URB_FENCE */
key->nr_urb_entries = brw->urb.nr_clip_entries;
key->urb_size = brw->urb.vsize;
+
+ /* _NEW_TRANSOFORM */
+ key->depth_clamp = ctx->Transform.DepthClamp;
}
static dri_bo *
@@ -117,7 +123,8 @@ clip_unit_create_from_key(struct brw_context *brw,
clip.clip5.userclip_enable_flags = 0x7f;
clip.clip5.userclip_must_clip = 1;
clip.clip5.guard_band_enable = 0;
- clip.clip5.viewport_z_clip_enable = 1;
+ if (!key->depth_clamp)
+ clip.clip5.viewport_z_clip_enable = 1;
clip.clip5.viewport_xy_clip_enable = 1;
clip.clip5.vertex_position_space = BRW_CLIP_NDCSPACE;
clip.clip5.api_mode = BRW_CLIP_API_OGL;
@@ -168,7 +175,7 @@ static void upload_clip_unit( struct brw_context *brw )
const struct brw_tracked_state brw_clip_unit = {
.dirty = {
- .mesa = 0,
+ .mesa = _NEW_TRANSFORM,
.brw = (BRW_NEW_CURBE_OFFSETS |
BRW_NEW_URB_FENCE),
.cache = CACHE_NEW_CLIP_PROG
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index 4c2d655fb1..0efd77225e 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -119,6 +119,11 @@ void brw_clip_tri_alloc_regs( struct brw_clip_compile *c,
i++;
}
+ if (c->need_ff_sync) {
+ c->reg.ff_sync = retype(brw_vec1_grf(i, 0), BRW_REGISTER_TYPE_UD);
+ i++;
+ }
+
c->first_tmp = i;
c->last_tmp = i;
@@ -563,6 +568,7 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
brw_clip_tri_init_vertices(c);
brw_clip_init_clipmask(c);
+ brw_clip_init_ff_sync(c);
/* if -ve rhw workaround bit is set,
do cliptest */
@@ -589,8 +595,6 @@ void brw_emit_tri_clip( struct brw_clip_compile *c )
else
maybe_do_clip_tri(c);
- if (c->need_ff_sync)
- brw_clip_ff_sync(c);
brw_clip_tri_emit_polygon(c);
/* Send an empty message to kill the thread:
diff --git a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
index 26950383c1..ad1bfa435f 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_unfilled.c
@@ -453,6 +453,7 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
brw_clip_tri_alloc_regs(c, 3 + c->key.nr_userclip + 6);
brw_clip_tri_init_vertices(c);
+ brw_clip_init_ff_sync(c);
assert(c->offset[VERT_RESULT_EDGE]);
@@ -496,8 +497,6 @@ void brw_emit_unfilled_clip( struct brw_clip_compile *c )
}
brw_ENDIF(p, do_clip);
- if (c->need_ff_sync)
- brw_clip_ff_sync(c);
emit_unfilled_primitives(c);
brw_clip_kill_thread(c);
}
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index e09efc07ed..5a73abdfee 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -213,6 +213,8 @@ void brw_clip_emit_vue(struct brw_clip_compile *c,
struct brw_compile *p = &c->func;
GLuint start = c->last_mrf;
+ brw_clip_ff_sync(c);
+
assert(!(allocate && eot));
/* Cycle through mrf regs - probably futile as we have to wait for
@@ -263,6 +265,7 @@ void brw_clip_kill_thread(struct brw_clip_compile *c)
{
struct brw_compile *p = &c->func;
+ brw_clip_ff_sync(c);
/* Send an empty message to kill the thread and release any
* allocated urb entry:
*/
@@ -356,17 +359,38 @@ void brw_clip_init_clipmask( struct brw_clip_compile *c )
void brw_clip_ff_sync(struct brw_clip_compile *c)
{
+ if (c->need_ff_sync) {
+ struct brw_compile *p = &c->func;
+ struct brw_instruction *need_ff_sync;
+
+ brw_set_conditionalmod(p, BRW_CONDITIONAL_Z);
+ brw_AND(p, brw_null_reg(), c->reg.ff_sync, brw_imm_ud(0x1));
+ need_ff_sync = brw_IF(p, BRW_EXECUTE_1);
+ {
+ brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
+ brw_ff_sync(p,
+ c->reg.R0,
+ 0,
+ c->reg.R0,
+ 1,
+ 1, /* used */
+ 1, /* msg length */
+ 1, /* response length */
+ 0, /* eot */
+ 1, /* write compelete */
+ 0, /* urb offset */
+ BRW_URB_SWIZZLE_NONE);
+ }
+ brw_ENDIF(p, need_ff_sync);
+ brw_set_predicate_control(p, BRW_PREDICATE_NONE);
+ }
+}
+
+void brw_clip_init_ff_sync(struct brw_clip_compile *c)
+{
+ if (c->need_ff_sync) {
struct brw_compile *p = &c->func;
- brw_ff_sync(p,
- c->reg.R0,
- 0,
- c->reg.R0,
- 1,
- 1, /* used */
- 1, /* msg length */
- 1, /* response length */
- 0, /* eot */
- 1, /* write compelete */
- 0, /* urb offset */
- BRW_URB_SWIZZLE_NONE);
+
+ brw_MOV(p, c->reg.ff_sync, brw_imm_ud(0));
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 4dbe551d83..3c5b848319 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -126,7 +126,32 @@ GLboolean brwCreateContext( const __GLcontextModes *mesaVis,
/* We want the GLSL compiler to emit code that uses condition codes */
ctx->Shader.EmitCondCodes = GL_TRUE;
-/* ctx->Const.MaxNativeVertexProgramTemps = 32; */
+ ctx->Const.VertexProgram.MaxNativeInstructions = (16 * 1024);
+ ctx->Const.VertexProgram.MaxAluInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexInstructions = 0;
+ ctx->Const.VertexProgram.MaxTexIndirections = 0;
+ ctx->Const.VertexProgram.MaxNativeAluInstructions = 0;
+ ctx->Const.VertexProgram.MaxNativeTexInstructions = 0;
+ ctx->Const.VertexProgram.MaxNativeTexIndirections = 0;
+ ctx->Const.VertexProgram.MaxNativeAttribs = 16;
+ ctx->Const.VertexProgram.MaxNativeTemps = 256;
+ ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
+ ctx->Const.VertexProgram.MaxNativeParameters = 1024;
+ ctx->Const.VertexProgram.MaxEnvParams =
+ MIN2(ctx->Const.VertexProgram.MaxNativeParameters,
+ ctx->Const.VertexProgram.MaxEnvParams);
+
+ ctx->Const.FragmentProgram.MaxNativeInstructions = (16 * 1024);
+ ctx->Const.FragmentProgram.MaxNativeAluInstructions = (16 * 1024);
+ ctx->Const.FragmentProgram.MaxNativeTexInstructions = (16 * 1024);
+ ctx->Const.FragmentProgram.MaxNativeTexIndirections = (16 * 1024);
+ ctx->Const.FragmentProgram.MaxNativeAttribs = 12;
+ ctx->Const.FragmentProgram.MaxNativeTemps = 256;
+ ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
+ ctx->Const.FragmentProgram.MaxNativeParameters = 1024;
+ ctx->Const.FragmentProgram.MaxEnvParams =
+ MIN2(ctx->Const.FragmentProgram.MaxNativeParameters,
+ ctx->Const.FragmentProgram.MaxEnvParams);
brw_init_state( brw );
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 57ddf75413..a5209ac41b 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -143,6 +143,7 @@ struct brw_context;
#define BRW_NEW_DEPTH_BUFFER 0x20000
#define BRW_NEW_NR_WM_SURFACES 0x40000
#define BRW_NEW_NR_VS_SURFACES 0x80000
+#define BRW_NEW_INDEX_BUFFER 0x100000
struct brw_state_flags {
/** State update flags signalled by mesa internals */
@@ -173,6 +174,9 @@ struct brw_fragment_program {
dri_bo *const_buffer; /** Program constant buffer/surface */
GLboolean use_const_buffer;
+
+ /** for debugging, which texture units are referenced */
+ GLbitfield tex_units_used;
};
@@ -386,6 +390,8 @@ struct brw_cached_batch_item {
struct brw_vertex_element {
const struct gl_client_array *glarray;
+ /** The corresponding Mesa vertex attribute */
+ gl_vert_attrib attrib;
/** Size of a complete element */
GLuint element_size;
/** Number of uploaded elements for this input. */
@@ -438,9 +444,13 @@ struct brw_query_object {
unsigned int count;
};
+
+/**
+ * brw_context is derived from intel_context.
+ */
struct brw_context
{
- struct intel_context intel;
+ struct intel_context intel; /**< base class, must be first field */
GLuint primitive;
GLboolean emit_state_always;
@@ -475,6 +485,9 @@ struct brw_context
struct {
struct brw_vertex_element inputs[VERT_ATTRIB_MAX];
+ struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
+ GLuint nr_enabled;
+
#define BRW_NR_UPLOAD_BUFS 17
#define BRW_UPLOAD_INIT_SIZE (128*1024)
@@ -498,8 +511,15 @@ struct brw_context
*/
const struct _mesa_index_buffer *ib;
+ /* Updates to these fields are signaled by BRW_NEW_INDEX_BUFFER. */
dri_bo *bo;
unsigned int offset;
+ unsigned int size;
+ /* Offset to index buffer index to use in CMD_3D_PRIM so that we can
+ * avoid re-uploading the IB packet over and over if we're actually
+ * referencing the same index buffer.
+ */
+ unsigned int start_vertex_offset;
} ib;
/* Active vertex program:
@@ -706,6 +726,8 @@ void brw_upload_urb_fence(struct brw_context *brw);
*/
void brw_upload_cs_urb_state(struct brw_context *brw);
+/* brw_disasm.c */
+int brw_disasm (FILE *file, struct brw_instruction *inst);
/*======================================================================
* Inline conversion functions. These are better-typed than the
diff --git a/src/mesa/drivers/dri/i965/brw_curbe.c b/src/mesa/drivers/dri/i965/brw_curbe.c
index a1a6c53d0e..0b0e6931a0 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;
+ /* Updates the ParamaterValues[i] pointers for all parameters of the
+ * basic type of PROGRAM_STATE_VAR.
+ */
_mesa_load_state_parameters(ctx, vp->program.Base.Parameters);
/* XXX just use a memcpy here */
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index d166250b4f..78d457ad2b 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -471,8 +471,9 @@
#define BRW_CONDITIONAL_GE 4
#define BRW_CONDITIONAL_L 5
#define BRW_CONDITIONAL_LE 6
-#define BRW_CONDITIONAL_C 7
+#define BRW_CONDITIONAL_R 7
#define BRW_CONDITIONAL_O 8
+#define BRW_CONDITIONAL_U 9
#define BRW_DEBUG_NONE 0
#define BRW_DEBUG_BREAKPOINT 1
@@ -512,6 +513,7 @@
#define BRW_OPCODE_RSL 11
#define BRW_OPCODE_ASR 12
#define BRW_OPCODE_CMP 16
+#define BRW_OPCODE_CMPN 17
#define BRW_OPCODE_JMPI 32
#define BRW_OPCODE_IF 34
#define BRW_OPCODE_IFF 35
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
new file mode 100644
index 0000000000..9fef230507
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -0,0 +1,903 @@
+/*
+ * Copyright © 2008 Keith Packard
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that copyright
+ * notice and this permission notice appear in supporting documentation, and
+ * that the name of the copyright holders not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make no representations
+ * about the suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+ * OF THIS SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <stdarg.h>
+
+#include "main/mtypes.h"
+
+#include "brw_context.h"
+#include "brw_defines.h"
+
+struct {
+ char *name;
+ int nsrc;
+ int ndst;
+} opcode[128] = {
+ [BRW_OPCODE_MOV] = { .name = "mov", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_FRC] = { .name = "frc", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDU] = { .name = "rndu", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDD] = { .name = "rndd", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDE] = { .name = "rnde", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_RNDZ] = { .name = "rndz", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_NOT] = { .name = "not", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_LZD] = { .name = "lzd", .nsrc = 1, .ndst = 1 },
+
+ [BRW_OPCODE_MUL] = { .name = "mul", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_MAC] = { .name = "mac", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_MACH] = { .name = "mach", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_LINE] = { .name = "line", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SAD2] = { .name = "sad2", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SADA2] = { .name = "sada2", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP4] = { .name = "dp4", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DPH] = { .name = "dph", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP3] = { .name = "dp3", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_DP2] = { .name = "dp2", .nsrc = 2, .ndst = 1 },
+
+ [BRW_OPCODE_AVG] = { .name = "avg", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_ADD] = { .name = "add", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SEL] = { .name = "sel", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_AND] = { .name = "and", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_OR] = { .name = "or", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_XOR] = { .name = "xor", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SHR] = { .name = "shr", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_SHL] = { .name = "shl", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_ASR] = { .name = "asr", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_CMP] = { .name = "cmp", .nsrc = 2, .ndst = 1 },
+ [BRW_OPCODE_CMPN] = { .name = "cmpn", .nsrc = 2, .ndst = 1 },
+
+ [BRW_OPCODE_SEND] = { .name = "send", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_NOP] = { .name = "nop", .nsrc = 0, .ndst = 0 },
+ [BRW_OPCODE_JMPI] = { .name = "jmpi", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_IF] = { .name = "if", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_IFF] = { .name = "iff", .nsrc = 1, .ndst = 01 },
+ [BRW_OPCODE_WHILE] = { .name = "while", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_ELSE] = { .name = "else", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_BREAK] = { .name = "break", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_CONTINUE] = { .name = "cont", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_HALT] = { .name = "halt", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_MSAVE] = { .name = "msave", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_PUSH] = { .name = "push", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_MRESTORE] = { .name = "mrest", .nsrc = 1, .ndst = 1 },
+ [BRW_OPCODE_POP] = { .name = "pop", .nsrc = 2, .ndst = 0 },
+ [BRW_OPCODE_WAIT] = { .name = "wait", .nsrc = 1, .ndst = 0 },
+ [BRW_OPCODE_DO] = { .name = "do", .nsrc = 0, .ndst = 0 },
+ [BRW_OPCODE_ENDIF] = { .name = "endif", .nsrc = 2, .ndst = 0 },
+};
+
+char *conditional_modifier[16] = {
+ [BRW_CONDITIONAL_NONE] = "",
+ [BRW_CONDITIONAL_Z] = ".e",
+ [BRW_CONDITIONAL_NZ] = ".ne",
+ [BRW_CONDITIONAL_G] = ".g",
+ [BRW_CONDITIONAL_GE] = ".ge",
+ [BRW_CONDITIONAL_L] = ".l",
+ [BRW_CONDITIONAL_LE] = ".le",
+ [BRW_CONDITIONAL_R] = ".r",
+ [BRW_CONDITIONAL_O] = ".o",
+ [BRW_CONDITIONAL_U] = ".u",
+};
+
+char *negate[2] = {
+ [0] = "",
+ [1] = "-",
+};
+
+char *_abs[2] = {
+ [0] = "",
+ [1] = "(abs)",
+};
+
+char *vert_stride[16] = {
+ [0] = "0",
+ [1] = "1",
+ [2] = "2",
+ [3] = "4",
+ [4] = "8",
+ [5] = "16",
+ [6] = "32",
+ [15] = "VxH",
+};
+
+char *width[8] = {
+ [0] = "1",
+ [1] = "2",
+ [2] = "4",
+ [3] = "8",
+ [4] = "16",
+};
+
+char *horiz_stride[4] = {
+ [0] = "0",
+ [1] = "1",
+ [2] = "2",
+ [3] = "4"
+};
+
+char *chan_sel[4] = {
+ [0] = "x",
+ [1] = "y",
+ [2] = "z",
+ [3] = "w",
+};
+
+char *dest_condmod[16] = {
+};
+
+char *debug_ctrl[2] = {
+ [0] = "",
+ [1] = ".breakpoint"
+};
+
+char *saturate[2] = {
+ [0] = "",
+ [1] = ".sat"
+};
+
+char *exec_size[8] = {
+ [0] = "1",
+ [1] = "2",
+ [2] = "4",
+ [3] = "8",
+ [4] = "16",
+ [5] = "32"
+};
+
+char *pred_inv[2] = {
+ [0] = "+",
+ [1] = "-"
+};
+
+char *pred_ctrl_align16[16] = {
+ [1] = "",
+ [2] = ".x",
+ [3] = ".y",
+ [4] = ".z",
+ [5] = ".w",
+ [6] = ".any4h",
+ [7] = ".all4h",
+};
+
+char *pred_ctrl_align1[16] = {
+ [1] = "",
+ [2] = ".anyv",
+ [3] = ".allv",
+ [4] = ".any2h",
+ [5] = ".all2h",
+ [6] = ".any4h",
+ [7] = ".all4h",
+ [8] = ".any8h",
+ [9] = ".all8h",
+ [10] = ".any16h",
+ [11] = ".all16h",
+};
+
+char *thread_ctrl[4] = {
+ [0] = "",
+ [2] = "switch"
+};
+
+char *compr_ctrl[4] = {
+ [0] = "",
+ [1] = "sechalf",
+ [2] = "compr",
+};
+
+char *dep_ctrl[4] = {
+ [0] = "",
+ [1] = "NoDDClr",
+ [2] = "NoDDChk",
+ [3] = "NoDDClr,NoDDChk",
+};
+
+char *mask_ctrl[4] = {
+ [0] = "",
+ [1] = "nomask",
+};
+
+char *access_mode[2] = {
+ [0] = "align1",
+ [1] = "align16",
+};
+
+char *reg_encoding[8] = {
+ [0] = "UD",
+ [1] = "D",
+ [2] = "UW",
+ [3] = "W",
+ [4] = "UB",
+ [5] = "B",
+ [7] = "F"
+};
+
+char *imm_encoding[8] = {
+ [0] = "UD",
+ [1] = "D",
+ [2] = "UW",
+ [3] = "W",
+ [5] = "VF",
+ [5] = "V",
+ [7] = "F"
+};
+
+char *reg_file[4] = {
+ [0] = "A",
+ [1] = "g",
+ [2] = "m",
+ [3] = "imm",
+};
+
+char *writemask[16] = {
+ [0x0] = ".",
+ [0x1] = ".x",
+ [0x2] = ".y",
+ [0x3] = ".xy",
+ [0x4] = ".z",
+ [0x5] = ".xz",
+ [0x6] = ".yz",
+ [0x7] = ".xyz",
+ [0x8] = ".w",
+ [0x9] = ".xw",
+ [0xa] = ".yw",
+ [0xb] = ".xyw",
+ [0xc] = ".zw",
+ [0xd] = ".xzw",
+ [0xe] = ".yzw",
+ [0xf] = "",
+};
+
+char *end_of_thread[2] = {
+ [0] = "",
+ [1] = "EOT"
+};
+
+char *target_function[16] = {
+ [BRW_MESSAGE_TARGET_NULL] = "null",
+ [BRW_MESSAGE_TARGET_MATH] = "math",
+ [BRW_MESSAGE_TARGET_SAMPLER] = "sampler",
+ [BRW_MESSAGE_TARGET_GATEWAY] = "gateway",
+ [BRW_MESSAGE_TARGET_DATAPORT_READ] = "read",
+ [BRW_MESSAGE_TARGET_DATAPORT_WRITE] = "write",
+ [BRW_MESSAGE_TARGET_URB] = "urb",
+ [BRW_MESSAGE_TARGET_THREAD_SPAWNER] = "thread_spawner"
+};
+
+char *math_function[16] = {
+ [BRW_MATH_FUNCTION_INV] = "inv",
+ [BRW_MATH_FUNCTION_LOG] = "log",
+ [BRW_MATH_FUNCTION_EXP] = "exp",
+ [BRW_MATH_FUNCTION_SQRT] = "sqrt",
+ [BRW_MATH_FUNCTION_RSQ] = "rsq",
+ [BRW_MATH_FUNCTION_SIN] = "sin",
+ [BRW_MATH_FUNCTION_COS] = "cos",
+ [BRW_MATH_FUNCTION_SINCOS] = "sincos",
+ [BRW_MATH_FUNCTION_TAN] = "tan",
+ [BRW_MATH_FUNCTION_POW] = "pow",
+ [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT_AND_REMAINDER] = "intdivmod",
+ [BRW_MATH_FUNCTION_INT_DIV_QUOTIENT] = "intmod",
+ [BRW_MATH_FUNCTION_INT_DIV_REMAINDER] = "intdiv",
+};
+
+char *math_saturate[2] = {
+ [0] = "",
+ [1] = "sat"
+};
+
+char *math_signed[2] = {
+ [0] = "",
+ [1] = "signed"
+};
+
+char *math_scalar[2] = {
+ [0] = "",
+ [1] = "scalar"
+};
+
+char *math_precision[2] = {
+ [0] = "",
+ [1] = "partial_precision"
+};
+
+char *urb_swizzle[4] = {
+ [BRW_URB_SWIZZLE_NONE] = "",
+ [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
+ [BRW_URB_SWIZZLE_TRANSPOSE] = "transpose",
+};
+
+char *urb_allocate[2] = {
+ [0] = "",
+ [1] = "allocate"
+};
+
+char *urb_used[2] = {
+ [0] = "",
+ [1] = "used"
+};
+
+char *urb_complete[2] = {
+ [0] = "",
+ [1] = "complete"
+};
+
+char *sampler_target_format[4] = {
+ [0] = "F",
+ [2] = "UD",
+ [3] = "D"
+};
+
+
+static int column;
+
+static int string (FILE *file, char *string)
+{
+ fputs (string, file);
+ column += strlen (string);
+ return 0;
+}
+
+static int format (FILE *f, char *format, ...)
+{
+ char buf[1024];
+ va_list args;
+ va_start (args, format);
+
+ vsnprintf (buf, sizeof (buf) - 1, format, args);
+ string (f, buf);
+ return 0;
+}
+
+static int newline (FILE *f)
+{
+ putc ('\n', f);
+ column = 0;
+ return 0;
+}
+
+static int pad (FILE *f, int c)
+{
+ do
+ string (f, " ");
+ while (column < c);
+ return 0;
+}
+
+static int control (FILE *file, char *name, char *ctrl[], GLuint id, int *space)
+{
+ if (!ctrl[id]) {
+ fprintf (file, "*** invalid %s value %d ",
+ name, id);
+ return 1;
+ }
+ if (ctrl[id][0])
+ {
+ if (space && *space)
+ string (file, " ");
+ string (file, ctrl[id]);
+ if (space)
+ *space = 1;
+ }
+ return 0;
+}
+
+static int print_opcode (FILE *file, int id)
+{
+ if (!opcode[id].name) {
+ format (file, "*** invalid opcode value %d ", id);
+ return 1;
+ }
+ string (file, opcode[id].name);
+ return 0;
+}
+
+static int reg (FILE *file, GLuint _reg_file, GLuint _reg_nr)
+{
+ int err = 0;
+ if (_reg_file == BRW_ARCHITECTURE_REGISTER_FILE) {
+ switch (_reg_nr & 0xf0) {
+ case BRW_ARF_NULL:
+ string (file, "null");
+ return -1;
+ case BRW_ARF_ADDRESS:
+ format (file, "a%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_ACCUMULATOR:
+ format (file, "acc%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_MASK:
+ format (file, "mask%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_MASK_STACK:
+ format (file, "msd%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_STATE:
+ format (file, "sr%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_CONTROL:
+ format (file, "cr%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_NOTIFICATION_COUNT:
+ format (file, "n%d", _reg_nr & 0x0f);
+ break;
+ case BRW_ARF_IP:
+ string (file, "ip");
+ return -1;
+ break;
+ default:
+ format (file, "ARF%d", _reg_nr);
+ break;
+ }
+ } else {
+ err |= control (file, "src reg file", reg_file, _reg_file, NULL);
+ format (file, "%d", _reg_nr);
+ }
+ return err;
+}
+
+static int dest (FILE *file, struct brw_instruction *inst)
+{
+ int err = 0;
+
+ if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits1.da1.dest_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ err |= reg (file, inst->bits1.da1.dest_reg_file, inst->bits1.da1.dest_reg_nr);
+ if (err == -1)
+ return 0;
+ if (inst->bits1.da1.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.da1.dest_subreg_nr);
+ format (file, "<%d>", inst->bits1.da1.dest_horiz_stride);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da1.dest_reg_type, NULL);
+ }
+ else
+ {
+ string (file, "g[a0");
+ if (inst->bits1.ia1.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.ia1.dest_subreg_nr);
+ if (inst->bits1.ia1.dest_indirect_offset)
+ format (file, " %d", inst->bits1.ia1.dest_indirect_offset);
+ string (file, "]");
+ format (file, "<%d>", inst->bits1.ia1.dest_horiz_stride);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.ia1.dest_reg_type, NULL);
+ }
+ }
+ else
+ {
+ if (inst->bits1.da16.dest_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ err |= reg (file, inst->bits1.da16.dest_reg_file, inst->bits1.da16.dest_reg_nr);
+ if (err == -1)
+ return 0;
+ if (inst->bits1.da16.dest_subreg_nr)
+ format (file, ".%d", inst->bits1.da16.dest_subreg_nr);
+ string (file, "<1>");
+ err |= control (file, "writemask", writemask, inst->bits1.da16.dest_writemask, NULL);
+ err |= control (file, "dest reg encoding", reg_encoding, inst->bits1.da16.dest_reg_type, NULL);
+ }
+ else
+ {
+ err = 1;
+ string (file, "Indirect align16 address mode not supported");
+ }
+ }
+
+ return 0;
+}
+
+static int src_align1_region (FILE *file,
+ GLuint _vert_stride, GLuint _width, GLuint _horiz_stride)
+{
+ int err = 0;
+ string (file, "<");
+ err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+ string (file, ",");
+ err |= control (file, "width", width, _width, NULL);
+ string (file, ",");
+ err |= control (file, "horiz_stride", horiz_stride, _horiz_stride, NULL);
+ string (file, ">");
+ return err;
+}
+
+static int src_da1 (FILE *file, GLuint type, GLuint _reg_file,
+ GLuint _vert_stride, GLuint _width, GLuint _horiz_stride,
+ GLuint reg_num, GLuint sub_reg_num, GLuint __abs, GLuint _negate)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ err |= reg (file, _reg_file, reg_num);
+ if (err == -1)
+ return 0;
+ if (sub_reg_num)
+ format (file, ".%d", sub_reg_num);
+ src_align1_region (file, _vert_stride, _width, _horiz_stride);
+ err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+ return err;
+}
+
+static int src_ia1 (FILE *file,
+ GLuint type,
+ GLuint _reg_file,
+ GLint _addr_imm,
+ GLuint _addr_subreg_nr,
+ GLuint _negate,
+ GLuint __abs,
+ GLuint _addr_mode,
+ GLuint _horiz_stride,
+ GLuint _width,
+ GLuint _vert_stride)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ string (file, "g[a0");
+ if (_addr_subreg_nr)
+ format (file, ".%d", _addr_subreg_nr);
+ if (_addr_imm)
+ format (file, " %d", _addr_imm);
+ string (file, "]");
+ src_align1_region (file, _vert_stride, _width, _horiz_stride);
+ err |= control (file, "src reg encoding", reg_encoding, type, NULL);
+ return err;
+}
+
+static int src_da16 (FILE *file,
+ GLuint _reg_type,
+ GLuint _reg_file,
+ GLuint _vert_stride,
+ GLuint _reg_nr,
+ GLuint _subreg_nr,
+ GLuint __abs,
+ GLuint _negate,
+ GLuint swz_x,
+ GLuint swz_y,
+ GLuint swz_z,
+ GLuint swz_w)
+{
+ int err = 0;
+ err |= control (file, "negate", negate, _negate, NULL);
+ err |= control (file, "abs", _abs, __abs, NULL);
+
+ err |= reg (file, _reg_file, _reg_nr);
+ if (err == -1)
+ return 0;
+ if (_subreg_nr)
+ format (file, ".%d", _subreg_nr);
+ string (file, "<");
+ err |= control (file, "vert stride", vert_stride, _vert_stride, NULL);
+ string (file, ",1,1>");
+ err |= control (file, "src da16 reg type", reg_encoding, _reg_type, NULL);
+ /*
+ * Three kinds of swizzle display:
+ * identity - nothing printed
+ * 1->all - print the single channel
+ * 1->1 - print the mapping
+ */
+ if (swz_x == BRW_CHANNEL_X &&
+ swz_y == BRW_CHANNEL_Y &&
+ swz_z == BRW_CHANNEL_Z &&
+ swz_w == BRW_CHANNEL_W)
+ {
+ ;
+ }
+ else if (swz_x == swz_y && swz_x == swz_z && swz_x == swz_w)
+ {
+ string (file, ".");
+ err |= control (file, "channel select", chan_sel, swz_x, NULL);
+ }
+ else
+ {
+ string (file, ".");
+ err |= control (file, "channel select", chan_sel, swz_x, NULL);
+ err |= control (file, "channel select", chan_sel, swz_y, NULL);
+ err |= control (file, "channel select", chan_sel, swz_z, NULL);
+ err |= control (file, "channel select", chan_sel, swz_w, NULL);
+ }
+ return err;
+}
+
+
+static int imm (FILE *file, GLuint type, struct brw_instruction *inst) {
+ switch (type) {
+ case BRW_REGISTER_TYPE_UD:
+ format (file, "0x%08xUD", inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_D:
+ format (file, "%dD", inst->bits3.d);
+ break;
+ case BRW_REGISTER_TYPE_UW:
+ format (file, "0x%04xUW", (uint16_t) inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_W:
+ format (file, "%dW", (int16_t) inst->bits3.d);
+ break;
+ case BRW_REGISTER_TYPE_UB:
+ format (file, "0x%02xUB", (int8_t) inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_VF:
+ format (file, "Vector Float");
+ break;
+ case BRW_REGISTER_TYPE_V:
+ format (file, "0x%08xV", inst->bits3.ud);
+ break;
+ case BRW_REGISTER_TYPE_F:
+ format (file, "%-gF", inst->bits3.f);
+ }
+ return 0;
+}
+
+static int src0 (FILE *file, struct brw_instruction *inst)
+{
+ if (inst->bits1.da1.src0_reg_file == BRW_IMMEDIATE_VALUE)
+ return imm (file, inst->bits1.da1.src0_reg_type,
+ inst);
+ else if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits2.da1.src0_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da1 (file,
+ inst->bits1.da1.src0_reg_type,
+ inst->bits1.da1.src0_reg_file,
+ inst->bits2.da1.src0_vert_stride,
+ inst->bits2.da1.src0_width,
+ inst->bits2.da1.src0_horiz_stride,
+ inst->bits2.da1.src0_reg_nr,
+ inst->bits2.da1.src0_subreg_nr,
+ inst->bits2.da1.src0_abs,
+ inst->bits2.da1.src0_negate);
+ }
+ else
+ {
+ return src_ia1 (file,
+ inst->bits1.ia1.src0_reg_type,
+ inst->bits1.ia1.src0_reg_file,
+ inst->bits2.ia1.src0_indirect_offset,
+ inst->bits2.ia1.src0_subreg_nr,
+ inst->bits2.ia1.src0_negate,
+ inst->bits2.ia1.src0_abs,
+ inst->bits2.ia1.src0_address_mode,
+ inst->bits2.ia1.src0_horiz_stride,
+ inst->bits2.ia1.src0_width,
+ inst->bits2.ia1.src0_vert_stride);
+ }
+ }
+ else
+ {
+ if (inst->bits2.da16.src0_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da16 (file,
+ inst->bits1.da16.src0_reg_type,
+ inst->bits1.da16.src0_reg_file,
+ inst->bits2.da16.src0_vert_stride,
+ inst->bits2.da16.src0_reg_nr,
+ inst->bits2.da16.src0_subreg_nr,
+ inst->bits2.da16.src0_abs,
+ inst->bits2.da16.src0_negate,
+ inst->bits2.da16.src0_swz_x,
+ inst->bits2.da16.src0_swz_y,
+ inst->bits2.da16.src0_swz_z,
+ inst->bits2.da16.src0_swz_w);
+ }
+ else
+ {
+ string (file, "Indirect align16 address mode not supported");
+ return 1;
+ }
+ }
+}
+
+static int src1 (FILE *file, struct brw_instruction *inst)
+{
+ if (inst->bits1.da1.src1_reg_file == BRW_IMMEDIATE_VALUE)
+ return imm (file, inst->bits1.da1.src1_reg_type,
+ inst);
+ else if (inst->header.access_mode == BRW_ALIGN_1)
+ {
+ if (inst->bits3.da1.src1_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da1 (file,
+ inst->bits1.da1.src1_reg_type,
+ inst->bits1.da1.src1_reg_file,
+ inst->bits3.da1.src1_vert_stride,
+ inst->bits3.da1.src1_width,
+ inst->bits3.da1.src1_horiz_stride,
+ inst->bits3.da1.src1_reg_nr,
+ inst->bits3.da1.src1_subreg_nr,
+ inst->bits3.da1.src1_abs,
+ inst->bits3.da1.src1_negate);
+ }
+ else
+ {
+ return src_ia1 (file,
+ inst->bits1.ia1.src1_reg_type,
+ inst->bits1.ia1.src1_reg_file,
+ inst->bits3.ia1.src1_indirect_offset,
+ inst->bits3.ia1.src1_subreg_nr,
+ inst->bits3.ia1.src1_negate,
+ inst->bits3.ia1.src1_abs,
+ inst->bits3.ia1.src1_address_mode,
+ inst->bits3.ia1.src1_horiz_stride,
+ inst->bits3.ia1.src1_width,
+ inst->bits3.ia1.src1_vert_stride);
+ }
+ }
+ else
+ {
+ if (inst->bits3.da16.src1_address_mode == BRW_ADDRESS_DIRECT)
+ {
+ return src_da16 (file,
+ inst->bits1.da16.src1_reg_type,
+ inst->bits1.da16.src1_reg_file,
+ inst->bits3.da16.src1_vert_stride,
+ inst->bits3.da16.src1_reg_nr,
+ inst->bits3.da16.src1_subreg_nr,
+ inst->bits3.da16.src1_abs,
+ inst->bits3.da16.src1_negate,
+ inst->bits3.da16.src1_swz_x,
+ inst->bits3.da16.src1_swz_y,
+ inst->bits3.da16.src1_swz_z,
+ inst->bits3.da16.src1_swz_w);
+ }
+ else
+ {
+ string (file, "Indirect align16 address mode not supported");
+ return 1;
+ }
+ }
+}
+
+int brw_disasm (FILE *file, struct brw_instruction *inst)
+{
+ int err = 0;
+ int space = 0;
+
+ if (inst->header.predicate_control) {
+ string (file, "(");
+ err |= control (file, "predicate inverse", pred_inv, inst->header.predicate_inverse, NULL);
+ string (file, "f0");
+ if (inst->bits2.da1.flag_reg_nr)
+ format (file, ".%d", inst->bits2.da1.flag_reg_nr);
+ if (inst->header.access_mode == BRW_ALIGN_1)
+ err |= control (file, "predicate control align1", pred_ctrl_align1,
+ inst->header.predicate_control, NULL);
+ else
+ err |= control (file, "predicate control align16", pred_ctrl_align16,
+ inst->header.predicate_control, NULL);
+ string (file, ") ");
+ }
+
+ err |= print_opcode (file, inst->header.opcode);
+ err |= control (file, "saturate", saturate, inst->header.saturate, NULL);
+ err |= control (file, "debug control", debug_ctrl, inst->header.debug_control, NULL);
+
+ if (inst->header.opcode != BRW_OPCODE_SEND)
+ err |= control (file, "conditional modifier", conditional_modifier,
+ inst->header.destreg__conditionalmod, NULL);
+
+ if (inst->header.opcode != BRW_OPCODE_NOP) {
+ string (file, "(");
+ err |= control (file, "execution size", exec_size, inst->header.execution_size, NULL);
+ string (file, ")");
+ }
+
+ if (inst->header.opcode == BRW_OPCODE_SEND)
+ format (file, " %d", inst->header.destreg__conditionalmod);
+
+ if (opcode[inst->header.opcode].ndst > 0) {
+ pad (file, 16);
+ err |= dest (file, inst);
+ }
+ if (opcode[inst->header.opcode].nsrc > 0) {
+ pad (file, 32);
+ err |= src0 (file, inst);
+ }
+ if (opcode[inst->header.opcode].nsrc > 1) {
+ pad (file, 48);
+ err |= src1 (file, inst);
+ }
+
+ if (inst->header.opcode == BRW_OPCODE_SEND) {
+ newline (file);
+ pad (file, 16);
+ space = 0;
+ err |= control (file, "target function", target_function,
+ inst->bits3.generic.msg_target, &space);
+ switch (inst->bits3.generic.msg_target) {
+ case BRW_MESSAGE_TARGET_MATH:
+ err |= control (file, "math function", math_function,
+ inst->bits3.math.function, &space);
+ err |= control (file, "math saturate", math_saturate,
+ inst->bits3.math.saturate, &space);
+ err |= control (file, "math signed", math_signed,
+ inst->bits3.math.int_type, &space);
+ err |= control (file, "math scalar", math_scalar,
+ inst->bits3.math.data_type, &space);
+ err |= control (file, "math precision", math_precision,
+ inst->bits3.math.precision, &space);
+ break;
+ case BRW_MESSAGE_TARGET_SAMPLER:
+ format (file, " (%d, %d, ",
+ inst->bits3.sampler.binding_table_index,
+ inst->bits3.sampler.sampler);
+ err |= control (file, "sampler target format", sampler_target_format,
+ inst->bits3.sampler.return_format, NULL);
+ string (file, ")");
+ break;
+ case BRW_MESSAGE_TARGET_DATAPORT_WRITE:
+ format (file, " (%d, %d, %d, %d)",
+ inst->bits3.dp_write.binding_table_index,
+ (inst->bits3.dp_write.pixel_scoreboard_clear << 3) |
+ inst->bits3.dp_write.msg_control,
+ inst->bits3.dp_write.msg_type,
+ inst->bits3.dp_write.send_commit_msg);
+ break;
+ case BRW_MESSAGE_TARGET_URB:
+ format (file, " %d", inst->bits3.urb.offset);
+ space = 1;
+ err |= control (file, "urb swizzle", urb_swizzle,
+ inst->bits3.urb.swizzle_control, &space);
+ err |= control (file, "urb allocate", urb_allocate,
+ inst->bits3.urb.allocate, &space);
+ err |= control (file, "urb used", urb_used,
+ inst->bits3.urb.used, &space);
+ err |= control (file, "urb complete", urb_complete,
+ inst->bits3.urb.complete, &space);
+ break;
+ case BRW_MESSAGE_TARGET_THREAD_SPAWNER:
+ break;
+ default:
+ format (file, "unsupported target %d", inst->bits3.generic.msg_target);
+ break;
+ }
+ if (space)
+ string (file, " ");
+ format (file, "mlen %d",
+ inst->bits3.generic.msg_length);
+ format (file, " rlen %d",
+ inst->bits3.generic.response_length);
+ }
+ pad (file, 64);
+ if (inst->header.opcode != BRW_OPCODE_NOP) {
+ string (file, "{");
+ space = 1;
+ err |= control(file, "access mode", access_mode, inst->header.access_mode, &space);
+ err |= control (file, "mask control", mask_ctrl, inst->header.mask_control, &space);
+ err |= control (file, "dependency control", dep_ctrl, inst->header.dependency_control, &space);
+ err |= control (file, "compression control", compr_ctrl, inst->header.compression_control, &space);
+ err |= control (file, "thread control", thread_ctrl, inst->header.thread_control, &space);
+ if (inst->header.opcode == BRW_OPCODE_SEND)
+ err |= control (file, "end of thread", end_of_thread,
+ inst->bits3.generic.end_of_thread, &space);
+ if (space)
+ string (file, " ");
+ string (file, "}");
+ }
+ string (file, ";");
+ newline (file);
+ return err;
+}
diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c
index 5152c3f3a5..44bb7bd588 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.c
+++ b/src/mesa/drivers/dri/i965/brw_draw.c
@@ -25,13 +25,15 @@
*
**************************************************************************/
-#include <stdlib.h>
#include "main/glheader.h"
#include "main/context.h"
#include "main/state.h"
-#include "main/api_validate.h"
#include "main/enums.h"
+#include "tnl/tnl.h"
+#include "vbo/vbo_context.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
#include "brw_draw.h"
#include "brw_defines.h"
@@ -42,11 +44,6 @@
#include "intel_batchbuffer.h"
#include "intel_buffer_objects.h"
-#include "tnl/tnl.h"
-#include "vbo/vbo_context.h"
-#include "swrast/swrast.h"
-#include "swrast_setup/swrast_setup.h"
-
#define FILE_DEBUG_FLAG DEBUG_BATCH
static GLuint prim_to_hw_prim[GL_POLYGON+1] = {
@@ -141,9 +138,11 @@ static void brw_emit_prim(struct brw_context *brw,
prim_packet.verts_per_instance = trim(prim->mode, prim->count);
prim_packet.start_vert_location = prim->start;
+ if (prim->indexed)
+ prim_packet.start_vert_location += brw->ib.start_vertex_offset;
prim_packet.instance_count = 1;
prim_packet.start_instance_location = 0;
- prim_packet.base_vert_location = 0;
+ prim_packet.base_vert_location = prim->basevertex;
/* Can't wrap here, since we rely on the validated state. */
brw->no_batch_wrap = GL_TRUE;
@@ -185,6 +184,7 @@ static void brw_merge_inputs( struct brw_context *brw,
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
brw->vb.inputs[i].glarray = arrays[i];
+ brw->vb.inputs[i].attrib = (gl_vert_attrib) i;
if (arrays[i]->StrideB != 0)
brw->vb.info.sizes[i/16] |= (brw->vb.inputs[i].glarray->Size - 1) <<
@@ -422,54 +422,31 @@ static GLboolean brw_try_draw_prims( GLcontext *ctx,
return retval;
}
-static GLboolean brw_need_rebase( GLcontext *ctx,
- const struct gl_client_array *arrays[],
- const struct _mesa_index_buffer *ib,
- GLuint min_index )
-{
- if (min_index == 0)
- return GL_FALSE;
-
- if (ib) {
- if (!vbo_all_varyings_in_vbos(arrays))
- return GL_TRUE;
- else
- return GL_FALSE;
- }
- else {
- /* Hmm. This isn't quite what I wanted. BRW can actually
- * handle the mixed case well enough that we shouldn't need to
- * rebase. However, it's probably not very common, nor hugely
- * expensive to do it this way:
- */
- if (!vbo_all_varyings_in_vbos(arrays))
- return GL_TRUE;
- else
- return GL_FALSE;
- }
-}
-
-
void brw_draw_prims( GLcontext *ctx,
const struct gl_client_array *arrays[],
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index )
{
GLboolean retval;
- /* Decide if we want to rebase. If so we end up recursing once
- * only into this function.
- */
- if (brw_need_rebase( ctx, arrays, ib, min_index )) {
- vbo_rebase_prims( ctx, arrays,
- prim, nr_prims,
- ib, min_index, max_index,
- brw_draw_prims );
-
- return;
+ if (!vbo_all_varyings_in_vbos(arrays)) {
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ /* Decide if we want to rebase. If so we end up recursing once
+ * only into this function.
+ */
+ if (min_index != 0) {
+ vbo_rebase_prims(ctx, arrays,
+ prim, nr_prims,
+ ib, min_index, max_index,
+ brw_draw_prims );
+ return;
+ }
}
/* Make a first attempt at drawing:
diff --git a/src/mesa/drivers/dri/i965/brw_draw.h b/src/mesa/drivers/dri/i965/brw_draw.h
index 9aebbdb1b8..2a14db217f 100644
--- a/src/mesa/drivers/dri/i965/brw_draw.h
+++ b/src/mesa/drivers/dri/i965/brw_draw.h
@@ -39,6 +39,7 @@ void brw_draw_prims( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index c29f1dd5c0..765ae5a2fe 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -25,9 +25,9 @@
*
**************************************************************************/
-#include <stdlib.h>
#include "main/glheader.h"
+#include "main/bufferobj.h"
#include "main/context.h"
#include "main/state.h"
#include "main/api_validate.h"
@@ -350,9 +350,6 @@ static void brw_prepare_vertices(struct brw_context *brw)
unsigned int min_index = brw->vb.min_index;
unsigned int max_index = brw->vb.max_index;
- struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
- GLuint nr_enabled = 0;
-
struct brw_vertex_element *upload[VERT_ATTRIB_MAX];
GLuint nr_uploads = 0;
@@ -362,12 +359,13 @@ static void brw_prepare_vertices(struct brw_context *brw)
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
/* Accumulate the list of enabled arrays. */
+ brw->vb.nr_enabled = 0;
while (vs_inputs) {
GLuint i = _mesa_ffsll(vs_inputs) - 1;
struct brw_vertex_element *input = &brw->vb.inputs[i];
vs_inputs &= ~(1 << i);
- enabled[nr_enabled++] = input;
+ brw->vb.enabled[brw->vb.nr_enabled++] = input;
}
/* XXX: In the rare cases where this happens we fallback all
@@ -376,18 +374,17 @@ static void brw_prepare_vertices(struct brw_context *brw)
* cases with > 17 vertex attributes enabled, so it probably
* isn't an issue at this point.
*/
- if (nr_enabled >= BRW_VEP_MAX) {
+ if (brw->vb.nr_enabled >= BRW_VEP_MAX) {
intel->Fallback = 1;
return;
}
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
input->element_size = get_size(input->glarray->Type) * input->glarray->Size;
- input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
- if (input->glarray->BufferObj->Name != 0) {
+ if (_mesa_is_bufferobj(input->glarray->BufferObj)) {
struct intel_buffer_object *intel_buffer =
intel_buffer_object(input->glarray->BufferObj);
@@ -398,7 +395,23 @@ static void brw_prepare_vertices(struct brw_context *brw)
dri_bo_reference(input->bo);
input->offset = (unsigned long)input->glarray->Ptr;
input->stride = input->glarray->StrideB;
+ input->count = input->glarray->_MaxElement;
+
+ /* This is a common place to reach if the user mistakenly supplies
+ * a pointer in place of a VBO offset. If we just let it go through,
+ * we may end up dereferencing a pointer beyond the bounds of the
+ * GTT. We would hope that the VBO's max_index would save us, but
+ * Mesa appears to hand us min/max values not clipped to the
+ * array object's _MaxElement, and _MaxElement frequently appears
+ * to be wrong anyway.
+ *
+ * The VBO spec allows application termination in this case, and it's
+ * probably a service to the poor programmer to do so rather than
+ * trying to just not render.
+ */
+ assert(input->offset < input->bo->size);
} else {
+ input->count = input->glarray->StrideB ? max_index + 1 - min_index : 1;
if (input->bo != NULL) {
/* Already-uploaded vertex data is present from a previous
* prepare_vertices, but we had to re-validate state due to
@@ -410,7 +423,7 @@ static void brw_prepare_vertices(struct brw_context *brw)
/* Queue the buffer object up to be uploaded in the next pass,
* when we've decided if we're doing interleaved or not.
*/
- if (i == 0) {
+ if (input->attrib == VERT_ATTRIB_POS) {
/* Position array not properly enabled:
*/
if (input->glarray->StrideB == 0) {
@@ -466,8 +479,8 @@ static void brw_prepare_vertices(struct brw_context *brw)
brw_prepare_query_begin(brw);
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
brw_add_validated_bo(brw, input->bo);
}
@@ -477,34 +490,44 @@ static void brw_emit_vertices(struct brw_context *brw)
{
GLcontext *ctx = &brw->intel.ctx;
struct intel_context *intel = intel_context(ctx);
- GLbitfield vs_inputs = brw->vs.prog_data->inputs_read;
- struct brw_vertex_element *enabled[VERT_ATTRIB_MAX];
GLuint i;
- GLuint nr_enabled = 0;
- /* Accumulate the list of enabled arrays. */
- while (vs_inputs) {
- i = _mesa_ffsll(vs_inputs) - 1;
- struct brw_vertex_element *input = &brw->vb.inputs[i];
+ brw_emit_query_begin(brw);
- vs_inputs &= ~(1 << i);
- enabled[nr_enabled++] = input;
+ /* If the VS doesn't read any inputs (calculating vertex position from
+ * a state variable for some reason, for example), emit a single pad
+ * VERTEX_ELEMENT struct and bail.
+ *
+ * The stale VB state stays in place, but they don't do anything unless
+ * a VE loads from them.
+ */
+ if (brw->vb.nr_enabled == 0) {
+ BEGIN_BATCH(3, IGNORE_CLIPRECTS);
+ OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | 1);
+ OUT_BATCH((0 << BRW_VE0_INDEX_SHIFT) |
+ BRW_VE0_VALID |
+ (BRW_SURFACEFORMAT_R32G32B32A32_FLOAT << BRW_VE0_FORMAT_SHIFT) |
+ (0 << BRW_VE0_SRC_OFFSET_SHIFT));
+ OUT_BATCH((BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_0_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_1_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_0 << BRW_VE1_COMPONENT_2_SHIFT) |
+ (BRW_VE1_COMPONENT_STORE_1_FLT << BRW_VE1_COMPONENT_3_SHIFT));
+ ADVANCE_BATCH();
+ return;
}
- brw_emit_query_begin(brw);
-
/* Now emit VB and VEP state packets.
*
* This still defines a hardware VB for each input, even if they
* are interleaved or from the same VBO. TBD if this makes a
* performance difference.
*/
- BEGIN_BATCH(1 + nr_enabled * 4, IGNORE_CLIPRECTS);
+ BEGIN_BATCH(1 + brw->vb.nr_enabled * 4, IGNORE_CLIPRECTS);
OUT_BATCH((CMD_VERTEX_BUFFER << 16) |
- ((1 + nr_enabled * 4) - 2));
+ ((1 + brw->vb.nr_enabled * 4) - 2));
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
OUT_BATCH((i << BRW_VB0_INDEX_SHIFT) |
BRW_VB0_ACCESS_VERTEXDATA |
@@ -524,15 +547,15 @@ static void brw_emit_vertices(struct brw_context *brw)
input->offset + input->element_size);
}
} else
- OUT_BATCH(brw->vb.max_index);
+ OUT_BATCH(input->stride ? input->count : 0);
OUT_BATCH(0); /* Instance data step rate */
}
ADVANCE_BATCH();
- BEGIN_BATCH(1 + nr_enabled * 2, IGNORE_CLIPRECTS);
- OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + nr_enabled * 2) - 2));
- for (i = 0; i < nr_enabled; i++) {
- struct brw_vertex_element *input = enabled[i];
+ BEGIN_BATCH(1 + brw->vb.nr_enabled * 2, IGNORE_CLIPRECTS);
+ OUT_BATCH((CMD_VERTEX_ELEMENT << 16) | ((1 + brw->vb.nr_enabled * 2) - 2));
+ for (i = 0; i < brw->vb.nr_enabled; i++) {
+ struct brw_vertex_element *input = brw->vb.enabled[i];
uint32_t format = get_surface_type(input->glarray->Type,
input->glarray->Size,
input->glarray->Format,
@@ -589,17 +612,20 @@ static void brw_prepare_indices(struct brw_context *brw)
dri_bo *bo = NULL;
struct gl_buffer_object *bufferobj;
GLuint offset;
+ GLuint ib_type_size;
if (index_buffer == NULL)
return;
- ib_size = get_size(index_buffer->type) * index_buffer->count;
+ ib_type_size = get_size(index_buffer->type);
+ ib_size = ib_type_size * index_buffer->count;
bufferobj = index_buffer->obj;;
/* Turn into a proper VBO:
*/
- if (!bufferobj->Name) {
-
+ if (!_mesa_is_bufferobj(bufferobj)) {
+ brw->ib.start_vertex_offset = 0;
+
/* Get new bufferobj, offset:
*/
get_space(brw, ib_size, &bo, &offset);
@@ -615,6 +641,7 @@ static void brw_prepare_indices(struct brw_context *brw)
}
} else {
offset = (GLuint) (unsigned long) index_buffer->ptr;
+ brw->ib.start_vertex_offset = 0;
/* If the index buffer isn't aligned to its element size, we have to
* rebase it into a temporary.
@@ -635,39 +662,62 @@ static void brw_prepare_indices(struct brw_context *brw)
bo = intel_bufferobj_buffer(intel, intel_buffer_object(bufferobj),
INTEL_READ);
dri_bo_reference(bo);
+
+ /* Use CMD_3D_PRIM's start_vertex_offset to avoid re-uploading
+ * the index buffer state when we're just moving the start index
+ * of our drawing.
+ */
+ brw->ib.start_vertex_offset = offset / ib_type_size;
+ offset = 0;
+ ib_size = bo->size;
}
}
- dri_bo_unreference(brw->ib.bo);
- brw->ib.bo = bo;
- brw->ib.offset = offset;
+ if (brw->ib.bo != bo ||
+ brw->ib.offset != offset ||
+ brw->ib.size != ib_size)
+ {
+ drm_intel_bo_unreference(brw->ib.bo);
+ brw->ib.bo = bo;
+ brw->ib.offset = offset;
+ brw->ib.size = ib_size;
+
+ brw->state.dirty.brw |= BRW_NEW_INDEX_BUFFER;
+ } else {
+ drm_intel_bo_unreference(bo);
+ }
brw_add_validated_bo(brw, brw->ib.bo);
}
-static void brw_emit_indices(struct brw_context *brw)
+const struct brw_tracked_state brw_indices = {
+ .dirty = {
+ .mesa = 0,
+ .brw = BRW_NEW_INDICES,
+ .cache = 0,
+ },
+ .prepare = brw_prepare_indices,
+};
+
+static void brw_emit_index_buffer(struct brw_context *brw)
{
struct intel_context *intel = &brw->intel;
const struct _mesa_index_buffer *index_buffer = brw->ib.ib;
- GLuint ib_size;
if (index_buffer == NULL)
return;
- ib_size = get_size(index_buffer->type) * index_buffer->count - 1;
-
/* Emit the indexbuffer packet:
*/
{
struct brw_indexbuffer ib;
memset(&ib, 0, sizeof(ib));
-
+
ib.header.bits.opcode = CMD_INDEX_BUFFER;
ib.header.bits.length = sizeof(ib)/4 - 2;
ib.header.bits.index_format = get_index_type(index_buffer->type);
ib.header.bits.cut_index_enable = 0;
-
BEGIN_BATCH(4, IGNORE_CLIPRECTS);
OUT_BATCH( ib.header.dword );
@@ -676,18 +726,17 @@ static void brw_emit_indices(struct brw_context *brw)
brw->ib.offset);
OUT_RELOC(brw->ib.bo,
I915_GEM_DOMAIN_VERTEX, 0,
- brw->ib.offset + ib_size);
+ brw->ib.offset + brw->ib.size);
OUT_BATCH( 0 );
ADVANCE_BATCH();
}
}
-const struct brw_tracked_state brw_indices = {
+const struct brw_tracked_state brw_index_buffer = {
.dirty = {
.mesa = 0,
- .brw = BRW_NEW_BATCH | BRW_NEW_INDICES,
+ .brw = BRW_NEW_BATCH | BRW_NEW_INDEX_BUFFER,
.cache = 0,
},
- .prepare = brw_prepare_indices,
- .emit = brw_emit_indices,
+ .emit = brw_emit_index_buffer,
};
diff --git a/src/mesa/drivers/dri/i965/brw_eu.c b/src/mesa/drivers/dri/i965/brw_eu.c
index c53efba599..1df561386e 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.c
+++ b/src/mesa/drivers/dri/i965/brw_eu.c
@@ -62,7 +62,7 @@ void brw_set_predicate_control( struct brw_compile *p, GLuint pc )
void brw_set_conditionalmod( struct brw_compile *p, GLuint conditional )
{
- p->current->header.destreg__conditonalmod = conditional;
+ p->current->header.destreg__conditionalmod = conditional;
}
void brw_set_access_mode( struct brw_compile *p, GLuint access_mode )
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 2412014248..241cdc33f8 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -481,8 +481,8 @@ static struct brw_instruction *next_insn( struct brw_compile *p,
/* Reset this one-shot flag:
*/
- if (p->current->header.destreg__conditonalmod) {
- p->current->header.destreg__conditonalmod = 0;
+ if (p->current->header.destreg__conditionalmod) {
+ p->current->header.destreg__conditionalmod = 0;
p->current->header.predicate_control = BRW_PREDICATE_NORMAL;
}
@@ -679,7 +679,7 @@ struct brw_instruction *brw_ELSE(struct brw_compile *p,
assert(if_insn->header.opcode == BRW_OPCODE_IF);
if_insn->bits3.if_else.jump_count = br * (insn - if_insn);
- if_insn->bits3.if_else.pop_count = 1;
+ if_insn->bits3.if_else.pop_count = 0;
if_insn->bits3.if_else.pad0 = 0;
}
@@ -871,7 +871,7 @@ void brw_CMP(struct brw_compile *p,
{
struct brw_instruction *insn = next_insn(p, BRW_OPCODE_CMP);
- insn->header.destreg__conditonalmod = conditional;
+ insn->header.destreg__conditionalmod = conditional;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
brw_set_src1(insn, src1);
@@ -915,7 +915,7 @@ void brw_math( struct brw_compile *p,
* instructions.
*/
insn->header.predicate_control = 0;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -952,7 +952,7 @@ void brw_math_16( struct brw_compile *p,
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
insn = next_insn(p, BRW_OPCODE_SEND);
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -969,7 +969,7 @@ void brw_math_16( struct brw_compile *p,
*/
insn = next_insn(p, BRW_OPCODE_SEND);
insn->header.compression_control = BRW_COMPRESSION_2NDHALF;
- insn->header.destreg__conditonalmod = msg_reg_nr+1;
+ insn->header.destreg__conditionalmod = msg_reg_nr+1;
brw_set_dest(insn, offset(dest,1));
brw_set_src0(insn, src);
@@ -1016,7 +1016,7 @@ void brw_dp_WRITE_16( struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src);
@@ -1062,7 +1062,7 @@ void brw_dp_READ_16( struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest); /* UW? */
brw_set_src0(insn, retype(brw_vec8_grf(0, 0), BRW_REGISTER_TYPE_UW));
@@ -1116,7 +1116,7 @@ void brw_dp_READ_4( struct brw_compile *p,
insn->header.predicate_control = BRW_PREDICATE_NONE;
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
insn->header.mask_control = BRW_MASK_DISABLE;
/* cast dest to a uword[8] vector */
@@ -1190,7 +1190,7 @@ void brw_dp_READ_4_vs(struct brw_compile *p,
insn->header.predicate_control = BRW_PREDICATE_NONE;
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
insn->header.mask_control = BRW_MASK_DISABLE;
/*insn->header.access_mode = BRW_ALIGN_16;*/
@@ -1224,7 +1224,7 @@ void brw_fb_WRITE(struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
@@ -1322,7 +1322,7 @@ void brw_SAMPLE(struct brw_compile *p,
insn->header.predicate_control = 0; /* XXX */
insn->header.compression_control = BRW_COMPRESSION_NONE;
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_dest(insn, dest);
brw_set_src0(insn, src0);
@@ -1375,7 +1375,7 @@ void brw_urb_WRITE(struct brw_compile *p,
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_urb_message(p->brw,
insn,
@@ -1410,7 +1410,7 @@ void brw_ff_sync(struct brw_compile *p,
brw_set_src0(insn, src0);
brw_set_src1(insn, brw_imm_d(0));
- insn->header.destreg__conditonalmod = msg_reg_nr;
+ insn->header.destreg__conditionalmod = msg_reg_nr;
brw_set_ff_sync_message(p->brw,
insn,
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index 980eac7646..a9b2aa2eac 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -101,7 +101,7 @@ static void brw_gs_emit_vue(struct brw_gs_compile *c,
BRW_URB_SWIZZLE_NONE);
}
-void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
+static void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
{
struct brw_compile *p = &c->func;
brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
diff --git a/src/mesa/drivers/dri/i965/brw_gs_state.c b/src/mesa/drivers/dri/i965/brw_gs_state.c
index a761c03153..ed9d2ffe60 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_state.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_state.c
@@ -93,7 +93,10 @@ gs_unit_create_from_key(struct brw_context *brw, struct brw_gs_unit_key *key)
gs.thread4.nr_urb_entries = key->nr_urb_entries;
gs.thread4.urb_entry_allocation_size = key->urb_size - 1;
- gs.thread4.max_threads = 0; /* Hardware requirement */
+ if (key->nr_urb_entries >= 8)
+ gs.thread4.max_threads = 1;
+ else
+ gs.thread4.max_threads = 0;
if (BRW_IS_IGDNG(brw))
gs.thread4.rendering_enable = 1;
diff --git a/src/mesa/drivers/dri/i965/brw_misc_state.c b/src/mesa/drivers/dri/i965/brw_misc_state.c
index 85a7706404..ea71857548 100644
--- a/src/mesa/drivers/dri/i965/brw_misc_state.c
+++ b/src/mesa/drivers/dri/i965/brw_misc_state.c
@@ -172,6 +172,7 @@ static void prepare_psp_urb_cbs(struct brw_context *brw)
brw_add_validated_bo(brw, brw->vs.state_bo);
brw_add_validated_bo(brw, brw->gs.state_bo);
brw_add_validated_bo(brw, brw->clip.state_bo);
+ brw_add_validated_bo(brw, brw->sf.state_bo);
brw_add_validated_bo(brw, brw->wm.state_bo);
brw_add_validated_bo(brw, brw->cc.state_bo);
}
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index cb9169e2ee..a195bc32b0 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -146,17 +146,12 @@ static void brw_wait_query(GLcontext *ctx, struct gl_query_object *q)
static void brw_check_query(GLcontext *ctx, struct gl_query_object *q)
{
- /* XXX: Need to expose dri_bo_is_idle from bufmgr. */
-#if 0
struct brw_query_object *query = (struct brw_query_object *)q;
- if (dri_bo_is_idle(query->bo)) {
+ if (query->bo == NULL || !drm_intel_bo_busy(query->bo)) {
brw_queryobj_get_results(query);
query->Base.Ready = GL_TRUE;
}
-#else
- brw_wait_query(ctx, q);
-#endif
}
/** Called to set up the query BO and account for its aperture space */
diff --git a/src/mesa/drivers/dri/i965/brw_sf_state.c b/src/mesa/drivers/dri/i965/brw_sf_state.c
index b5f6371c82..bc0f076073 100644
--- a/src/mesa/drivers/dri/i965/brw_sf_state.c
+++ b/src/mesa/drivers/dri/i965/brw_sf_state.c
@@ -113,7 +113,7 @@ struct brw_sf_unit_key {
unsigned int nr_urb_entries, urb_size, sfsize;
- GLenum front_face, cull_face;
+ GLenum front_face, cull_face, provoking_vertex;
unsigned scissor:1;
unsigned line_smooth:1;
unsigned point_sprite:1;
@@ -153,6 +153,9 @@ sf_unit_populate_key(struct brw_context *brw, struct brw_sf_unit_key *key)
key->point_size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize);
key->point_attenuated = ctx->Point._Attenuated;
+ /* _NEW_LIGHT */
+ key->provoking_vertex = ctx->Light.ProvokingVertex;
+
key->render_to_fbo = brw->intel.ctx.DrawBuffer->Name != 0;
}
@@ -284,9 +287,15 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
/* might be BRW_NEW_PRIMITIVE if we have to adjust pv for polygons:
*/
- sf.sf7.trifan_pv = 2;
- sf.sf7.linestrip_pv = 1;
- sf.sf7.tristrip_pv = 2;
+ if (key->provoking_vertex == GL_LAST_VERTEX_CONVENTION) {
+ sf.sf7.trifan_pv = 2;
+ sf.sf7.linestrip_pv = 1;
+ sf.sf7.tristrip_pv = 2;
+ } else {
+ sf.sf7.trifan_pv = 1;
+ sf.sf7.linestrip_pv = 0;
+ sf.sf7.tristrip_pv = 0;
+ }
sf.sf7.line_last_pixel_enable = 0;
/* Set bias for OpenGL rasterization rules:
@@ -300,6 +309,9 @@ sf_unit_create_from_key(struct brw_context *brw, struct brw_sf_unit_key *key,
&sf, sizeof(sf),
NULL, NULL);
+ /* STATE_PREFETCH command description describes this state as being
+ * something loaded through the GPE (L2 ISC), so it's INSTRUCTION domain.
+ */
/* Emit SF program relocation */
dri_bo_emit_reloc(bo,
I915_GEM_DOMAIN_INSTRUCTION, 0,
@@ -340,6 +352,7 @@ static void upload_sf_unit( struct brw_context *brw )
const struct brw_tracked_state brw_sf_unit = {
.dirty = {
.mesa = (_NEW_POLYGON |
+ _NEW_LIGHT |
_NEW_LINE |
_NEW_POINT |
_NEW_SCISSOR |
diff --git a/src/mesa/drivers/dri/i965/brw_state.h b/src/mesa/drivers/dri/i965/brw_state.h
index bf9f6cae55..78572356a3 100644
--- a/src/mesa/drivers/dri/i965/brw_state.h
+++ b/src/mesa/drivers/dri/i965/brw_state.h
@@ -92,6 +92,7 @@ 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;
+const struct brw_tracked_state brw_index_buffer;
/**
* Use same key for WM and VS surfaces.
diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c b/src/mesa/drivers/dri/i965/brw_state_upload.c
index 38d9dd8991..414620d0b3 100644
--- a/src/mesa/drivers/dri/i965/brw_state_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_state_upload.c
@@ -94,6 +94,7 @@ const struct brw_tracked_state *atoms[] =
&brw_drawing_rect,
&brw_indices,
+ &brw_index_buffer,
&brw_vertices,
&brw_constant_buffer
@@ -208,6 +209,7 @@ static struct dirty_bit_map brw_bits[] = {
DEFINE_BIT(BRW_NEW_PSP),
DEFINE_BIT(BRW_NEW_FENCE),
DEFINE_BIT(BRW_NEW_INDICES),
+ DEFINE_BIT(BRW_NEW_INDEX_BUFFER),
DEFINE_BIT(BRW_NEW_VERTICES),
DEFINE_BIT(BRW_NEW_BATCH),
DEFINE_BIT(BRW_NEW_DEPTH_BUFFER),
@@ -320,6 +322,19 @@ void brw_validate_state( struct brw_context *brw )
}
}
}
+
+ /* Make sure that the textures which are referenced by the current
+ * brw fragment program are actually present/valid.
+ * If this fails, we can experience GPU lock-ups.
+ */
+ {
+ const struct brw_fragment_program *fp;
+ fp = brw_fragment_program_const(brw->fragment_program);
+ if (fp) {
+ assert((fp->tex_units_used & ctx->Texture._EnabledUnits)
+ == fp->tex_units_used);
+ }
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_structs.h b/src/mesa/drivers/dri/i965/brw_structs.h
index 8ba7eb27b3..66d4127271 100644
--- a/src/mesa/drivers/dri/i965/brw_structs.h
+++ b/src/mesa/drivers/dri/i965/brw_structs.h
@@ -442,8 +442,8 @@ struct brw_urb_fence
{
GLuint sf_fence:10;
GLuint vf_fence:10;
- GLuint cs_fence:10;
- GLuint pad:2;
+ GLuint cs_fence:11;
+ GLuint pad:1;
} bits1;
};
@@ -1200,7 +1200,7 @@ struct brw_instruction
GLuint predicate_control:4;
GLuint predicate_inverse:1;
GLuint execution_size:3;
- GLuint destreg__conditonalmod:4; /* destreg - send, conditionalmod - others */
+ GLuint destreg__conditionalmod:4; /* destreg - send, conditionalmod - others */
GLuint pad0:2;
GLuint debug_control:1;
GLuint saturate:1;
@@ -1228,7 +1228,9 @@ struct brw_instruction
GLuint dest_reg_type:3;
GLuint src0_reg_file:2;
GLuint src0_reg_type:3;
- GLuint pad:6;
+ GLuint src1_reg_file:2; /* 0x00000c00 */
+ GLuint src1_reg_type:3; /* 0x00007000 */
+ GLuint pad:1;
GLint dest_indirect_offset:10; /* offset against the deref'd address reg */
GLuint dest_subreg_nr:3; /* subnr for the address reg a0.x */
GLuint dest_horiz_stride:2;
@@ -1243,7 +1245,7 @@ struct brw_instruction
GLuint src0_reg_type:3;
GLuint src1_reg_file:2;
GLuint src1_reg_type:3;
- GLuint pad0:1;
+ GLuint pad:1;
GLuint dest_writemask:4;
GLuint dest_subreg_nr:1;
GLuint dest_reg_nr:8;
@@ -1348,7 +1350,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad:1;
+ GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@@ -1363,7 +1365,7 @@ struct brw_instruction
GLuint src1_reg_nr:8;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad0:1;
+ GLuint src1_address_mode:1;
GLuint src1_swz_z:2;
GLuint src1_swz_w:2;
GLuint pad1:1;
@@ -1377,7 +1379,7 @@ struct brw_instruction
GLuint src1_subreg_nr:3;
GLuint src1_abs:1;
GLuint src1_negate:1;
- GLuint pad0:1;
+ GLuint src1_address_mode:1;
GLuint src1_horiz_stride:2;
GLuint src1_width:3;
GLuint src1_vert_stride:4;
@@ -1565,6 +1567,7 @@ struct brw_instruction
GLint d;
GLuint ud;
+ float f;
} bits3;
};
diff --git a/src/mesa/drivers/dri/i965/brw_tex_layout.c b/src/mesa/drivers/dri/i965/brw_tex_layout.c
index 7f9b253534..5986cbffad 100644
--- a/src/mesa/drivers/dri/i965/brw_tex_layout.c
+++ b/src/mesa/drivers/dri/i965/brw_tex_layout.c
@@ -65,11 +65,6 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
if (mt->compressed) {
mt->pitch = ALIGN(mt->width0, align_w);
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp;
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
- } else {
- qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp;
- mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
}
if (mt->first_level != mt->last_level) {
@@ -90,6 +85,14 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
mt->pitch = intel_miptree_pitch_align(intel, mt, tiling, mt->pitch);
+ if (mt->compressed) {
+ qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * mt->pitch * mt->cpp;
+ mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) / 4 * 6;
+ } else {
+ qpitch = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * mt->pitch * mt->cpp;
+ mt->total_height = (y_pitch + ALIGN(minify(y_pitch), align_h) + 11 * align_h) * 6;
+ }
+
for (level = mt->first_level; level <= mt->last_level; level++) {
GLuint img_height;
GLuint nr_images = 6;
@@ -191,6 +194,16 @@ GLboolean brw_miptree_layout(struct intel_context *intel,
}
}
+ /* The 965's sampler lays cachelines out according to how accesses
+ * in the texture surfaces run, so they may be "vertical" through
+ * memory. As a result, the docs say in Surface Padding Requirements:
+ * Sampling Engine Surfaces that two extra rows of padding are required.
+ * We don't know of similar requirements for pre-965, but given that
+ * those docs are silent on padding requirements in general, let's play
+ * it safe.
+ */
+ if (mt->target == GL_TEXTURE_CUBE_MAP)
+ mt->total_height += 2;
break;
}
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index 514f15d5e3..1638ef8111 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -68,6 +68,7 @@ static void release_tmps( struct brw_vs_compile *c )
static void brw_vs_alloc_regs( struct brw_vs_compile *c )
{
GLuint i, reg = 0, mrf;
+ int attributes_in_vue;
/* Determine whether to use a real constant buffer or use a block
* of GRF registers for constants. The later is faster but only
@@ -128,6 +129,11 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
reg++;
}
}
+ /* If there are no inputs, we'll still be reading one attribute's worth
+ * because it's required -- see urb_read_length setting.
+ */
+ if (c->nr_inputs == 0)
+ reg++;
/* Allocate outputs. The non-position outputs go straight into message regs.
*/
@@ -220,11 +226,22 @@ static void brw_vs_alloc_regs( struct brw_vs_compile *c )
* vertex urb, so is half the amount:
*/
c->prog_data.urb_read_length = (c->nr_inputs + 1) / 2;
+ /* Setting this field to 0 leads to undefined behavior according to the
+ * the VS_STATE docs. Our VUEs will always have at least one attribute
+ * sitting in them, even if it's padding.
+ */
+ if (c->prog_data.urb_read_length == 0)
+ c->prog_data.urb_read_length = 1;
+
+ /* The VS VUEs are shared by VF (outputting our inputs) and VS, so size
+ * them to fit the biggest thing they need to.
+ */
+ attributes_in_vue = MAX2(c->nr_outputs, c->nr_inputs);
if (BRW_IS_IGDNG(c->func.brw))
- c->prog_data.urb_entry_size = (c->nr_outputs + 6 + 3) / 4;
+ c->prog_data.urb_entry_size = (attributes_in_vue + 6 + 3) / 4;
else
- c->prog_data.urb_entry_size = (c->nr_outputs + 2 + 3) / 4;
+ c->prog_data.urb_entry_size = (attributes_in_vue + 2 + 3) / 4;
c->prog_data.total_grf = reg;
@@ -894,6 +911,7 @@ get_src_reg( struct brw_vs_compile *c,
case PROGRAM_STATE_VAR:
case PROGRAM_CONSTANT:
case PROGRAM_UNIFORM:
+ case PROGRAM_ENV_PARAM:
if (c->vp->use_const_buffer) {
return get_constant(c, inst, argIndex);
}
@@ -913,7 +931,6 @@ get_src_reg( struct brw_vs_compile *c,
return brw_null_reg();
case PROGRAM_LOCAL_PARAM:
- case PROGRAM_ENV_PARAM:
case PROGRAM_WRITE_ONLY:
default:
assert(0);
@@ -1191,7 +1208,7 @@ static void emit_vertex_write( struct brw_vs_compile *c)
MIN2(c->nr_outputs + 1 + len_vertext_header, (BRW_MAX_MRF-1)), /* msg len */
0, /* response len */
eot, /* eot */
- 1, /* writes complete */
+ eot, /* writes complete */
0, /* urb destination offset */
BRW_URB_SWIZZLE_INTERLEAVE);
@@ -1245,9 +1262,49 @@ post_vs_emit( struct brw_vs_compile *c,
/* patch up the END code to jump past subroutines, etc */
offset = last_inst - end_inst;
- brw_set_src1(end_inst, brw_imm_d(offset * 16));
+ if (offset > 1) {
+ brw_set_src1(end_inst, brw_imm_d(offset * 16));
+ } else {
+ end_inst->header.opcode = BRW_OPCODE_NOP;
+ }
}
+static uint32_t
+get_predicate(const struct prog_instruction *inst)
+{
+ 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:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_Y;
+ case SWIZZLE_ZZZZ:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_Z;
+ case SWIZZLE_WWWW:
+ return BRW_PREDICATE_ALIGN16_REPLICATE_W;
+ default:
+ _mesa_problem(NULL, "Unexpected predicate: 0x%08x\n",
+ inst->DstReg.CondMask);
+ return BRW_PREDICATE_NORMAL;
+ }
+}
/* Emit the vertex program instructions here.
*/
@@ -1256,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;
@@ -1266,7 +1324,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
GLuint file;
if (INTEL_DEBUG & DEBUG_VS) {
- _mesa_printf("vs-emit:\n");
+ _mesa_printf("vs-mesa:\n");
_mesa_print_program(&c->vp->program.Base);
_mesa_printf("\n");
}
@@ -1453,7 +1511,10 @@ void brw_vs_emit(struct brw_vs_compile *c )
break;
case OPCODE_IF:
assert(if_depth < MAX_IF_DEPTH);
- if_inst[if_depth++] = brw_IF(p, BRW_EXECUTE_8);
+ if_inst[if_depth] = brw_IF(p, BRW_EXECUTE_8);
+ /* 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:
if_inst[if_depth-1] = brw_ELSE(p, if_inst[if_depth-1]);
@@ -1462,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);
@@ -1541,6 +1605,19 @@ void brw_vs_emit(struct brw_vs_compile *c )
"unknown");
}
+ /* Set the predication update on the last instruction of the native
+ * instruction sequence.
+ *
+ * This would be problematic if it was set on a math instruction,
+ * but that shouldn't be the case with the current GLSL compiler.
+ */
+ if (inst->CondUpdate) {
+ struct brw_instruction *hw_insn = &p->store[p->nr_insn - 1];
+
+ assert(hw_insn->header.destreg__conditionalmod == 0);
+ hw_insn->header.destreg__conditionalmod = BRW_CONDITIONAL_NZ;
+ }
+
if ((inst->DstReg.File == PROGRAM_OUTPUT)
&& (inst->DstReg.Index != VERT_RESULT_HPOS)
&& c->output_regs[inst->DstReg.Index].used_in_src) {
@@ -1578,4 +1655,13 @@ void brw_vs_emit(struct brw_vs_compile *c )
emit_vertex_write(c);
post_vs_emit(c, end_inst, last_inst);
+
+ if (INTEL_DEBUG & DEBUG_VS) {
+ int i;
+
+ _mesa_printf("vs-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm.c b/src/mesa/drivers/dri/i965/brw_wm.c
index 14e05be4f6..2292de94c4 100644
--- a/src/mesa/drivers/dri/i965/brw_wm.c
+++ b/src/mesa/drivers/dri/i965/brw_wm.c
@@ -41,13 +41,13 @@ GLuint brw_wm_nr_args( GLuint opcode )
{
switch (opcode) {
case WM_FRONTFACING:
- return 0;
case WM_PIXELXY:
+ return 0;
case WM_CINTERP:
case WM_WPOSXY:
+ case WM_DELTAXY:
return 1;
case WM_LINTERP:
- case WM_DELTAXY:
case WM_PIXELW:
return 2;
case WM_FB_WRITE:
@@ -171,9 +171,11 @@ static void do_wm_prog( struct brw_context *brw,
* differently from "simple" shaders.
*/
if (fp->isGLSL) {
+ c->dispatch_width = 8;
brw_wm_glsl_emit(brw, c);
}
else {
+ c->dispatch_width = 16;
brw_wm_non_glsl_emit(brw, c);
}
@@ -202,6 +204,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
/* BRW_NEW_FRAGMENT_PROGRAM */
const struct brw_fragment_program *fp =
(struct brw_fragment_program *)brw->fragment_program;
+ GLboolean uses_depth = (fp->program.Base.InputsRead & (1 << FRAG_ATTRIB_WPOS)) != 0;
GLuint lookup = 0;
GLuint line_aa;
GLuint i;
@@ -263,6 +266,7 @@ static void brw_wm_populate_key( struct brw_context *brw,
brw_wm_lookup_iz(line_aa,
lookup,
+ uses_depth,
key);
diff --git a/src/mesa/drivers/dri/i965/brw_wm.h b/src/mesa/drivers/dri/i965/brw_wm.h
index ba497432c6..872b1f3ecf 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;
@@ -260,6 +261,7 @@ struct brw_wm_compile {
GLuint tmp_index;
GLuint tmp_max;
GLuint subroutines[BRW_WM_MAX_SUBROUTINE];
+ GLuint dispatch_width;
/** we may need up to 3 constants per instruction (if use_const_buffer) */
struct {
@@ -292,10 +294,16 @@ void brw_wm_print_program( struct brw_wm_compile *c,
void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
+ GLboolean ps_uses_depth,
struct brw_wm_prog_key *key );
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 9f82916c02..bf80a2942a 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.
*/
@@ -65,8 +63,7 @@ static INLINE struct brw_reg sechalf( struct brw_reg reg )
static void emit_pixel_xy(struct brw_compile *p,
const struct brw_reg *dst,
- GLuint mask,
- const struct brw_reg *arg0)
+ GLuint mask)
{
struct brw_reg r1 = brw_vec1_grf(1, 0);
struct brw_reg r1_uw = retype(r1, BRW_REGISTER_TYPE_UW);
@@ -98,8 +95,7 @@ static void emit_pixel_xy(struct brw_compile *p,
static void emit_delta_xy(struct brw_compile *p,
const struct brw_reg *dst,
GLuint mask,
- const struct brw_reg *arg0,
- const struct brw_reg *arg1)
+ const struct brw_reg *arg0)
{
struct brw_reg r1 = brw_vec1_grf(1, 0);
@@ -283,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,
@@ -545,16 +614,18 @@ static void emit_dp3( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
- brw_MAC(p, dst[0], arg0[2], arg1[2]);
+ brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
brw_set_saturate(p, 0);
}
@@ -565,17 +636,19 @@ static void emit_dp4( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
brw_MAC(p, brw_null_reg(), arg0[2], arg1[2]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
- brw_MAC(p, dst[0], arg0[3], arg1[3]);
+ brw_MAC(p, dst[dst_chan], arg0[3], arg1[3]);
brw_set_saturate(p, 0);
}
@@ -586,17 +659,19 @@ static void emit_dph( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1 )
{
+ const int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_MUL(p, brw_null_reg(), arg0[0], arg1[0]);
brw_MAC(p, brw_null_reg(), arg0[1], arg1[1]);
- brw_MAC(p, dst[0], arg0[2], arg1[2]);
+ brw_MAC(p, dst[dst_chan], arg0[2], arg1[2]);
brw_set_saturate(p, (mask & SATURATE) ? 1 : 0);
- brw_ADD(p, dst[0], dst[0], arg1[3]);
+ brw_ADD(p, dst[dst_chan], dst[dst_chan], arg1[3]);
brw_set_saturate(p, 0);
}
@@ -632,18 +707,19 @@ static void emit_math1( struct brw_compile *p,
GLuint mask,
const struct brw_reg *arg0 )
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- //assert((mask & WRITEMASK_XYZW) == WRITEMASK_X ||
- // function == BRW_MATH_FUNCTION_SINCOS);
-
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
brw_MOV(p, brw_message_reg(2), arg0[0]);
/* Send two messages to perform all 16 operations:
*/
brw_math_16(p,
- dst[0],
+ dst[dst_chan],
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
@@ -659,10 +735,12 @@ static void emit_math2( struct brw_compile *p,
const struct brw_reg *arg0,
const struct brw_reg *arg1)
{
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
if (!(mask & WRITEMASK_XYZW))
return; /* Do not emit dead code */
- assert((mask & WRITEMASK_XYZW) == WRITEMASK_X);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
brw_push_insn_state(p);
@@ -681,7 +759,7 @@ static void emit_math2( struct brw_compile *p,
*/
brw_set_compression_control(p, BRW_COMPRESSION_NONE);
brw_math(p,
- dst[0],
+ dst[dst_chan],
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
@@ -691,7 +769,7 @@ static void emit_math2( struct brw_compile *p,
brw_set_compression_control(p, BRW_COMPRESSION_2NDHALF);
brw_math(p,
- offset(dst[0],1),
+ offset(dst[dst_chan],1),
function,
(mask & SATURATE) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
4,
@@ -728,10 +806,14 @@ static void emit_tex( struct brw_wm_compile *c,
emit = WRITEMASK_XY;
nr = 2;
break;
- default:
+ case TEXTURE_3D_INDEX:
+ case TEXTURE_CUBE_INDEX:
emit = WRITEMASK_XYZ;
nr = 3;
break;
+ default:
+ /* unexpected target */
+ abort();
}
if (inst->tex_shadow) {
@@ -803,11 +885,15 @@ static void emit_txb( struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(4), arg[1]);
brw_MOV(p, brw_message_reg(6), brw_imm_f(0));
break;
- default:
+ case TEXTURE_3D_INDEX:
+ case TEXTURE_CUBE_INDEX:
brw_MOV(p, brw_message_reg(2), arg[0]);
brw_MOV(p, brw_message_reg(4), arg[1]);
brw_MOV(p, brw_message_reg(6), arg[2]);
break;
+ default:
+ /* unexpected target */
+ abort();
}
brw_MOV(p, brw_message_reg(8), arg[3]);
@@ -893,6 +979,20 @@ static void emit_kil( struct brw_wm_compile *c,
}
}
+/* KIL_NV kills the pixels that are currently executing, not based on a test
+ * of the arguments.
+ */
+static void emit_kil_nv( struct brw_wm_compile *c )
+{
+ struct brw_compile *p = &c->func;
+ struct brw_reg r0uw = retype(brw_vec1_grf(0, 0), BRW_REGISTER_TYPE_UW);
+
+ brw_push_insn_state(p);
+ brw_set_mask_control(p, BRW_MASK_DISABLE);
+ brw_NOT(p, c->emit_mask_reg, brw_mask_reg(1)); //IMASK
+ brw_AND(p, r0uw, c->emit_mask_reg, r0uw);
+ brw_pop_insn_state(p);
+}
static void fire_fb_write( struct brw_wm_compile *c,
GLuint base_reg,
@@ -1194,11 +1294,11 @@ void brw_wm_emit( struct brw_wm_compile *c )
/* Generated instructions for calculating triangle interpolants:
*/
case WM_PIXELXY:
- emit_pixel_xy(p, dst, dst_flags, args[0]);
+ emit_pixel_xy(p, dst, dst_flags);
break;
case WM_DELTAXY:
- emit_delta_xy(p, dst, dst_flags, args[0], args[1]);
+ emit_delta_xy(p, dst, dst_flags, args[0]);
break;
case WM_WPOSXY:
@@ -1243,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;
@@ -1372,6 +1480,10 @@ void brw_wm_emit( struct brw_wm_compile *c )
emit_kil(c, args[0]);
break;
+ case OPCODE_KIL_NV:
+ emit_kil_nv(c);
+ break;
+
default:
_mesa_printf("Unsupported opcode %i (%s) in fragment shader\n",
inst->opcode, inst->opcode < MAX_OPCODE ?
@@ -1385,4 +1497,13 @@ void brw_wm_emit( struct brw_wm_compile *c )
inst->dst[i]->hw_reg,
inst->dst[i]->spill_slot);
}
+
+ if (INTEL_DEBUG & DEBUG_WM) {
+ int i;
+
+ _mesa_printf("wm-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_fp.c b/src/mesa/drivers/dri/i965/brw_wm_fp.c
index b9e8dd2e96..4e3edfbbff 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_fp.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_fp.c
@@ -42,6 +42,12 @@
#include "shader/prog_statevars.h"
+/** An invalid texture target */
+#define TEX_TARGET_NONE NUM_TEXTURE_TARGETS
+
+/** An invalid texture unit */
+#define TEX_UNIT_NONE BRW_MAX_TEX_UNIT
+
#define FIRST_INTERNAL_TEMP MAX_NV_FRAGMENT_PROGRAM_TEMPS
#define X 0
@@ -199,6 +205,15 @@ static struct prog_instruction * emit_tex_op(struct brw_wm_compile *c,
{
struct prog_instruction *inst = get_fp_inst(c);
+ assert(tex_src_unit < BRW_MAX_TEX_UNIT ||
+ tex_src_unit == TEX_UNIT_NONE);
+ assert(tex_src_target < NUM_TEXTURE_TARGETS ||
+ tex_src_target == TEX_TARGET_NONE);
+
+ /* update mask of which texture units are referenced by this program */
+ if (tex_src_unit != TEX_UNIT_NONE)
+ c->fp->tex_units_used |= (1 << tex_src_unit);
+
memset(inst, 0, sizeof(*inst));
inst->Opcode = op;
@@ -223,12 +238,45 @@ static struct prog_instruction * emit_op(struct brw_wm_compile *c,
struct prog_src_register src2 )
{
return emit_tex_op(c, op, dest, saturate,
- 0, 0, 0, /* tex unit, target, shadow */
+ TEX_UNIT_NONE, TEX_TARGET_NONE, 0, /* unit, tgt, shadow */
src0, src1, src2);
}
-
+/* Many Mesa opcodes produce the same value across all the result channels.
+ * We'd rather not have to support that splatting in the opcode implementations,
+ * and brw_wm_pass*.c wants to optimize them out by shuffling references around
+ * anyway. We can easily get both by emitting the opcode to one channel, and
+ * then MOVing it to the others, which brw_wm_pass*.c already understands.
+ */
+static struct prog_instruction *emit_scalar_insn(struct brw_wm_compile *c,
+ const struct prog_instruction *inst0)
+{
+ struct prog_instruction *inst;
+ unsigned int dst_chan;
+ unsigned int other_channel_mask;
+
+ if (inst0->DstReg.WriteMask == 0)
+ return NULL;
+
+ dst_chan = _mesa_ffs(inst0->DstReg.WriteMask) - 1;
+ inst = get_fp_inst(c);
+ *inst = *inst0;
+ inst->DstReg.WriteMask = 1 << dst_chan;
+
+ other_channel_mask = inst0->DstReg.WriteMask & ~(1 << dst_chan);
+ if (other_channel_mask != 0) {
+ inst = emit_op(c,
+ OPCODE_MOV,
+ dst_mask(inst0->DstReg, other_channel_mask),
+ 0,
+ src_swizzle1(src_reg_from_dst(inst0->DstReg), dst_chan),
+ src_undef(),
+ src_undef());
+ }
+ return inst;
+}
+
/***********************************************************************
* Special instructions for interpolation and other tasks
@@ -376,14 +424,6 @@ static void emit_interp( struct brw_wm_compile *c,
}
break;
case FRAG_ATTRIB_FOGC:
- /* The FOGC input is really special. When a program uses glFogFragCoord,
- * the results returned are supposed to be (f,0,0,1). But for Mesa GLSL,
- * the glFrontFacing and glPointCoord values are also stashed in FOGC.
- * So, write the interpolated fog value to X, then either 0, 1, or the
- * stashed values to Y, Z, W. Note that this means that
- * glFogFragCoord.yzw can be wrong in those cases!
- */
-
/* Interpolate the fog coordinate */
emit_op(c,
WM_PINTERP,
@@ -393,26 +433,40 @@ static void emit_interp( struct brw_wm_compile *c,
deltas,
get_pixel_w(c));
- /* Move the front facing value into FOGC.y if it's needed. */
- if (c->fp->program.UsesFrontFacing) {
- emit_op(c,
- WM_FRONTFACING,
- dst_mask(dst, WRITEMASK_Y),
- 0,
- src_undef(),
- src_undef(),
- src_undef());
- } else {
- emit_op(c,
- OPCODE_MOV,
- dst_mask(dst, WRITEMASK_Y),
- 0,
- src_swizzle1(interp, SWIZZLE_ZERO),
- src_undef(),
- src_undef());
- }
+ emit_op(c,
+ OPCODE_MOV,
+ dst_mask(dst, WRITEMASK_YZW),
+ 0,
+ src_swizzle(interp,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ZERO,
+ SWIZZLE_ONE),
+ src_undef(),
+ src_undef());
+ break;
+
+ case FRAG_ATTRIB_FACE:
+ /* XXX review/test this case */
+ emit_op(c,
+ WM_FRONTFACING,
+ dst_mask(dst, WRITEMASK_X),
+ 0,
+ src_undef(),
+ src_undef(),
+ src_undef());
+ break;
+
+ case FRAG_ATTRIB_PNTC:
+ /* XXX review/test this case */
+ emit_op(c,
+ WM_PINTERP,
+ dst_mask(dst, WRITEMASK_XY),
+ 0,
+ interp,
+ deltas,
+ get_pixel_w(c));
- /* Should do the PointCoord thing here. */
emit_op(c,
OPCODE_MOV,
dst_mask(dst, WRITEMASK_ZW),
@@ -425,6 +479,7 @@ static void emit_interp( struct brw_wm_compile *c,
src_undef(),
src_undef());
break;
+
default:
emit_op(c,
WM_PINTERP,
@@ -439,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.
*/
@@ -643,6 +666,8 @@ static void precalc_tex( struct brw_wm_compile *c,
struct prog_dst_register tmpcoord;
const GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ assert(unit < BRW_MAX_TEX_UNIT);
+
if (inst->TexSrcTarget == TEXTURE_CUBE_INDEX) {
struct prog_instruction *out;
struct prog_dst_register tmp0 = get_temp(c);
@@ -683,7 +708,7 @@ static void precalc_tex( struct brw_wm_compile *c,
/* tmp0 = 1 / tmp1 */
emit_op(c, OPCODE_RCP,
- tmp0,
+ dst_mask(tmp0, WRITEMASK_X),
0,
tmp1src,
src_undef(),
@@ -694,7 +719,7 @@ static void precalc_tex( struct brw_wm_compile *c,
tmpcoord,
0,
src0,
- tmp0src,
+ src_swizzle1(tmp0src, SWIZZLE_X),
src_undef());
release_temp(c, tmp0);
@@ -717,7 +742,11 @@ static void precalc_tex( struct brw_wm_compile *c,
tmpcoord,
0,
inst->SrcReg[0],
- scale,
+ src_swizzle(scale,
+ SWIZZLE_X,
+ SWIZZLE_Y,
+ SWIZZLE_ONE,
+ SWIZZLE_ONE),
src_undef());
coord = src_reg_from_dst(tmpcoord);
@@ -1041,6 +1070,7 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
c->delta_xy = src_undef();
c->pixel_w = src_undef();
c->nr_fp_insns = 0;
+ c->fp->tex_units_used = 0x0;
/* Emit preamble instructions. This is where special instructions such as
* WM_CINTERP, WM_LINTERP, WM_PINTERP and WM_WPOSXY are emitted to
@@ -1108,6 +1138,7 @@ void brw_wm_pass_fp( struct brw_wm_compile *c )
case OPCODE_TXB:
out = emit_insn(c, inst);
out->TexSrcUnit = fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ assert(out->TexSrcUnit < BRW_MAX_TEX_UNIT);
break;
case OPCODE_XPD:
@@ -1123,20 +1154,16 @@ 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;
case OPCODE_PRINT:
break;
-
default:
- emit_insn(c, inst);
+ if (brw_wm_is_scalar_result(inst->Opcode))
+ emit_scalar_insn(c, inst);
+ else
+ emit_insn(c, inst);
break;
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 19f777fe32..c9fe1dd8ad 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -10,6 +10,9 @@ enum _subroutine {
SUB_NOISE1, SUB_NOISE2, SUB_NOISE3, SUB_NOISE4
};
+static struct brw_reg get_dst_reg(struct brw_wm_compile *c,
+ const struct prog_instruction *inst,
+ GLuint component);
/**
* Determine if the given fragment program uses GLSL features such
@@ -19,16 +22,16 @@ enum _subroutine {
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) {
+ case OPCODE_ARL:
case OPCODE_IF:
case OPCODE_ENDIF:
case OPCODE_CAL:
case OPCODE_BRK:
case OPCODE_RET:
- case OPCODE_DDX:
- case OPCODE_DDY:
case OPCODE_NOISE1:
case OPCODE_NOISE2:
case OPCODE_NOISE3:
@@ -130,19 +133,6 @@ static void set_reg(struct brw_wm_compile *c, int file, int index,
c->wm_regs[file][index][component].inited = GL_TRUE;
}
-/**
- * Examine instruction's write mask to find index of first component
- * enabled for writing.
- */
-static int get_scalar_dst_index(const struct prog_instruction *inst)
-{
- int i;
- for (i = 0; i < 4; i++)
- if (inst->DstReg.WriteMask & (1<<i))
- break;
- return i;
-}
-
static struct brw_reg alloc_tmp(struct brw_wm_compile *c)
{
struct brw_reg reg;
@@ -302,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));
@@ -402,6 +392,27 @@ static void prealloc_reg(struct brw_wm_compile *c)
prealloc_grf(c, 126);
prealloc_grf(c, 127);
+ for (i = 0; i < c->nr_fp_insns; i++) {
+ const struct prog_instruction *inst = &c->prog_instructions[i];
+ struct brw_reg dst[4];
+
+ switch (inst->Opcode) {
+ case OPCODE_TEX:
+ case OPCODE_TXB:
+ /* Allocate the channels of texture results contiguously,
+ * since they are written out that way by the sampler unit.
+ */
+ for (j = 0; j < 4; j++) {
+ dst[j] = get_dst_reg(c, inst, j);
+ if (j != 0)
+ assert(dst[j].nr == dst[j - 1].nr + 1);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
/* An instruction may reference up to three constants.
* They'll be found in these registers.
* XXX alloc these on demand!
@@ -639,23 +650,6 @@ static void invoke_subroutine( struct brw_wm_compile *c,
}
}
-static void emit_abs( struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- int i;
- struct brw_compile *p = &c->func;
- brw_set_saturate(p, inst->SaturateMode != SATURATE_OFF);
- for (i = 0; i < 4; i++) {
- if (inst->DstReg.WriteMask & (1<<i)) {
- struct brw_reg src, dst;
- dst = get_dst_reg(c, inst, i);
- src = get_src_reg(c, inst, 0, i);
- brw_MOV(p, dst, brw_abs(src));
- }
- }
- brw_set_saturate(p, 0);
-}
-
static void emit_trunc( struct brw_wm_compile *c,
const struct prog_instruction *inst)
{
@@ -1031,12 +1025,20 @@ static void emit_dp3(struct brw_wm_compile *c,
struct brw_reg src0[3], src1[3], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 3; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
@@ -1050,11 +1052,19 @@ static void emit_dp4(struct brw_wm_compile *c,
struct brw_reg src0[4], src1[4], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 4; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_MAC(p, brw_null_reg(), src0[2], src1[2]);
@@ -1069,11 +1079,19 @@ static void emit_dph(struct brw_wm_compile *c,
struct brw_reg src0[4], src1[4], dst;
int i;
struct brw_compile *p = &c->func;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
for (i = 0; i < 4; i++) {
src0[i] = get_src_reg(c, inst, 0, i);
src1[i] = get_src_reg_imm(c, inst, 1, i);
}
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ dst = get_dst_reg(c, inst, dst_chan);
brw_MUL(p, brw_null_reg(), src0[0], src1[0]);
brw_MAC(p, brw_null_reg(), src0[1], src1[1]);
brw_MAC(p, dst, src0[2], src1[2]);
@@ -1091,37 +1109,28 @@ static void emit_math1(struct brw_wm_compile *c,
const struct prog_instruction *inst, GLuint func)
{
struct brw_compile *p = &c->func;
- struct brw_reg src0, dst, tmp;
- const int mark = mark_tmps( c );
- int i;
+ struct brw_reg src0, dst;
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
- tmp = alloc_tmp(c);
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
/* Get first component of source register */
+ dst = get_dst_reg(c, inst, dst_chan);
src0 = get_src_reg(c, inst, 0, 0);
- /* tmp = func(src0) */
brw_MOV(p, brw_message_reg(2), src0);
brw_math(p,
- tmp,
+ dst,
func,
(inst->SaturateMode != SATURATE_OFF) ? BRW_MATH_SATURATE_SATURATE : BRW_MATH_SATURATE_NONE,
2,
brw_null_reg(),
BRW_MATH_DATA_VECTOR,
BRW_MATH_PRECISION_FULL);
-
- /*tmp.dw1.bits.swizzle = SWIZZLE_XXXX;*/
-
- /* replicate tmp value across enabled dest channels */
- for (i = 0; i < 4; i++) {
- if (inst->DstReg.WriteMask & (1 << i)) {
- dst = get_dst_reg(c, inst, i);
- brw_MOV(p, dst, tmp);
- }
- }
-
- release_tmps(c, mark);
}
static void emit_rcp(struct brw_wm_compile *c,
@@ -1192,24 +1201,6 @@ static void emit_arl(struct brw_wm_compile *c,
brw_set_saturate(p, 0);
}
-static void emit_sub(struct brw_wm_compile *c,
- const struct prog_instruction *inst)
-{
- struct brw_compile *p = &c->func;
- struct brw_reg src0, src1, dst;
- GLuint mask = inst->DstReg.WriteMask;
- int i;
- brw_set_saturate(p, (inst->SaturateMode != SATURATE_OFF) ? 1 : 0);
- for (i = 0 ; i < 4; i++) {
- if (mask & (1<<i)) {
- dst = get_dst_reg(c, inst, i);
- src0 = get_src_reg(c, inst, 0, i);
- src1 = get_src_reg_imm(c, inst, 1, i);
- brw_ADD(p, dst, src0, negate(src1));
- }
- }
- brw_set_saturate(p, 0);
-}
static void emit_mul(struct brw_wm_compile *c,
const struct prog_instruction *inst)
@@ -1321,7 +1312,15 @@ static void emit_pow(struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
struct brw_reg dst, src0, src1;
- dst = get_dst_reg(c, inst, get_scalar_dst_index(inst));
+ GLuint mask = inst->DstReg.WriteMask;
+ int dst_chan = _mesa_ffs(mask & WRITEMASK_XYZW) - 1;
+
+ if (!(mask & WRITEMASK_XYZW))
+ return;
+
+ assert(is_power_of_two(mask & WRITEMASK_XYZW));
+
+ dst = get_dst_reg(c, inst, dst_chan);
src0 = get_src_reg_imm(c, inst, 0, 0);
src1 = get_src_reg_imm(c, inst, 1, 0);
@@ -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 ),
@@ -2623,10 +2567,13 @@ static void emit_txb(struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
struct brw_reg dst[4], src[4], payload_reg;
- GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ /* Note: TexSrcUnit was already looked up through SamplerTextures[] */
+ const GLuint unit = inst->TexSrcUnit;
GLuint i;
GLuint msg_type;
+ assert(unit < BRW_MAX_TEX_UNIT);
+
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
for (i = 0; i < 4; i++)
@@ -2646,11 +2593,15 @@ static void emit_txb(struct brw_wm_compile *c,
brw_MOV(p, brw_message_reg(3), src[1]);
brw_MOV(p, brw_message_reg(4), brw_imm_f(0));
break;
- default:
+ case TEXTURE_3D_INDEX:
+ case TEXTURE_CUBE_INDEX:
brw_MOV(p, brw_message_reg(2), src[0]);
brw_MOV(p, brw_message_reg(3), src[1]);
brw_MOV(p, brw_message_reg(4), src[2]);
break;
+ default:
+ /* invalid target */
+ abort();
}
brw_MOV(p, brw_message_reg(5), src[3]); /* bias */
brw_MOV(p, brw_message_reg(6), brw_imm_f(0)); /* ref (unused?) */
@@ -2683,13 +2634,16 @@ static void emit_tex(struct brw_wm_compile *c,
{
struct brw_compile *p = &c->func;
struct brw_reg dst[4], src[4], payload_reg;
- GLuint unit = c->fp->program.Base.SamplerUnits[inst->TexSrcUnit];
+ /* Note: TexSrcUnit was already looked up through SamplerTextures[] */
+ const GLuint unit = inst->TexSrcUnit;
GLuint msg_len;
GLuint i, nr;
GLuint emit;
GLboolean shadow = (c->key.shadowtex_mask & (1<<unit)) ? 1 : 0;
GLuint msg_type;
+ assert(unit < BRW_MAX_TEX_UNIT);
+
payload_reg = get_reg(c, PROGRAM_PAYLOAD, PAYLOAD_DEPTH, 0, 1, 0, 0);
for (i = 0; i < 4; i++)
@@ -2707,10 +2661,14 @@ static void emit_tex(struct brw_wm_compile *c,
emit = WRITEMASK_XY;
nr = 2;
break;
- default:
+ case TEXTURE_3D_INDEX:
+ case TEXTURE_CUBE_INDEX:
emit = WRITEMASK_XYZ;
nr = 3;
break;
+ default:
+ /* invalid target */
+ abort();
}
msg_len = 1;
@@ -2766,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
@@ -2783,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;
@@ -2800,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);
@@ -2828,18 +2808,12 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
case WM_FRONTFACING:
emit_frontfacing(c, inst);
break;
- case OPCODE_ABS:
- emit_abs(c, inst);
- break;
case OPCODE_ADD:
emit_add(c, inst);
break;
case OPCODE_ARL:
emit_arl(c, inst);
break;
- case OPCODE_SUB:
- emit_sub(c, inst);
- break;
case OPCODE_FRC:
emit_frc(c, inst);
break;
@@ -2891,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);
@@ -3007,7 +2987,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
loop_depth--;
inst0 = inst1 = brw_WHILE(p, loop_inst[loop_depth]);
- /* patch all the BREAK/CONT instructions from last BEGINLOOP */
+ /* patch all the BREAK/CONT instructions from last BGNLOOP */
while (inst0 > loop_inst[loop_depth]) {
inst0--;
if (inst0->header.opcode == BRW_OPCODE_BREAK) {
@@ -3032,8 +3012,14 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
brw_set_predicate_control(p, BRW_PREDICATE_NONE);
}
post_wm_emit(c);
-}
+ if (INTEL_DEBUG & DEBUG_WM) {
+ _mesa_printf("wm-native:\n");
+ for (i = 0; i < p->nr_insn; i++)
+ brw_disasm(stderr, &p->store[i]);
+ _mesa_printf("\n");
+ }
+}
/**
* Do GPU code generation for shaders that use GLSL features such as
diff --git a/src/mesa/drivers/dri/i965/brw_wm_iz.c b/src/mesa/drivers/dri/i965/brw_wm_iz.c
index 8fd067abe7..5e399ac62a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_iz.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_iz.c
@@ -122,6 +122,7 @@ const struct {
*/
void brw_wm_lookup_iz( GLuint line_aa,
GLuint lookup,
+ GLboolean ps_uses_depth,
struct brw_wm_prog_key *key )
{
GLuint reg = 2;
@@ -131,7 +132,7 @@ void brw_wm_lookup_iz( GLuint line_aa,
if (lookup & IZ_PS_COMPUTES_DEPTH_BIT)
key->computes_depth = 1;
- if (wm_iz_table[lookup].sd_present) {
+ if (wm_iz_table[lookup].sd_present || ps_uses_depth) {
key->source_depth_reg = reg;
reg += 2;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass0.c b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
index 92142764f5..6279258339 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_pass0.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_pass0.c
@@ -257,34 +257,6 @@ static void pass0_set_dst( struct brw_wm_compile *c,
}
-static void pass0_set_dst_scalar( struct brw_wm_compile *c,
- struct brw_wm_instruction *out,
- const struct prog_instruction *inst,
- GLuint writemask )
-{
- if (writemask) {
- const struct prog_dst_register *dst = &inst->DstReg;
- GLuint i;
-
- /* Compute only the first (X) value:
- */
- out->writemask = WRITEMASK_X;
- out->dst[0] = get_value(c);
-
- /* Update our tracking register file for all the components in
- * writemask:
- */
- for (i = 0; i < 4; i++) {
- if (writemask & (1<<i)) {
- pass0_set_fpreg_value(c, dst->File, dst->Index, i, out->dst[0]);
- }
- }
- }
- else
- out->writemask = 0;
-}
-
-
static const struct brw_wm_ref *get_fp_src_reg_ref( struct brw_wm_compile *c,
struct prog_src_register src,
GLuint i )
@@ -363,10 +335,7 @@ translate_insn(struct brw_wm_compile *c,
/* Dst:
*/
- if (brw_wm_is_scalar_result(out->opcode))
- pass0_set_dst_scalar(c, out, inst, writemask);
- else
- pass0_set_dst(c, out, inst, writemask);
+ pass0_set_dst(c, out, inst, writemask);
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_pass1.c b/src/mesa/drivers/dri/i965/brw_wm_pass1.c
index 3436a24717..b449394029 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:
@@ -270,6 +275,7 @@ void brw_wm_pass1( struct brw_wm_compile *c )
case OPCODE_DST:
case WM_FRONTFACING:
+ case OPCODE_KIL_NV:
default:
break;
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
index 3fc18ff1f3..dff466587a 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_sampler_state.c
@@ -103,6 +103,10 @@ struct wm_sampler_key {
GLenum minfilter, magfilter;
GLenum comparemode, comparefunc;
dri_bo *sdc_bo;
+
+ /** If target is cubemap, take context setting.
+ */
+ GLboolean seamless_cube_map;
} sampler[BRW_MAX_TEX_UNIT];
};
@@ -169,30 +173,33 @@ static void brw_update_sampler_state(struct wm_sampler_entry *key,
}
}
- if (key->tex_target == GL_TEXTURE_CUBE_MAP &&
- (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) {
- /* If we're using anything but nearest sampling for a cube map, we
- * need to set this wrap mode to avoid GPU lock-ups.
- */
- sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
- }
- else if (key->tex_target == GL_TEXTURE_1D) {
+ sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
+ sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
+ sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);
+
+ /* Cube-maps on 965 and later must use the same wrap mode for all 3
+ * coordinate dimensions. Futher, only CUBE and CLAMP are valid.
+ */
+ if (key->tex_target == GL_TEXTURE_CUBE_MAP) {
+ if (key->seamless_cube_map &&
+ (key->minfilter != GL_NEAREST || key->magfilter != GL_NEAREST)) {
+ sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CUBE;
+ } else {
+ sampler->ss1.r_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ sampler->ss1.s_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_CLAMP;
+ }
+ } else if (key->tex_target == GL_TEXTURE_1D) {
/* There's a bug in 1D texture sampling - it actually pays
* attention to the wrap_t value, though it should not.
* Override the wrap_t value here to GL_REPEAT to keep
* any nonexistent border pixels from floating in.
*/
- sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
- sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
sampler->ss1.t_wrap_mode = BRW_TEXCOORDMODE_WRAP;
}
- else {
- sampler->ss1.r_wrap_mode = translate_wrap_mode(key->wrap_r);
- sampler->ss1.s_wrap_mode = translate_wrap_mode(key->wrap_s);
- sampler->ss1.t_wrap_mode = translate_wrap_mode(key->wrap_t);
- }
+
/* Set shadow function:
*/
@@ -249,6 +256,9 @@ brw_wm_sampler_populate_key(struct brw_context *brw,
entry->tex_target = texObj->Target;
+ entry->seamless_cube_map = (texObj->Target == GL_TEXTURE_CUBE_MAP)
+ ? ctx->Texture.CubeMapSeamless : GL_FALSE;
+
entry->wrap_r = texObj->WrapR;
entry->wrap_s = texObj->WrapS;
entry->wrap_t = texObj->WrapT;
diff --git a/src/mesa/drivers/dri/i965/brw_wm_state.c b/src/mesa/drivers/dri/i965/brw_wm_state.c
index 39f8c6d522..361f91292b 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_state.c
@@ -107,6 +107,12 @@ wm_unit_populate_key(struct brw_context *brw, struct brw_wm_unit_key *key)
/* as far as we can tell */
key->computes_depth =
(fp->Base.OutputsWritten & (1 << FRAG_RESULT_DEPTH)) != 0;
+ /* BRW_NEW_DEPTH_BUFFER
+ * Override for NULL depthbuffer case, required by the Pixel Shader Computed
+ * Depth field.
+ */
+ if (brw->state.depth_region == NULL)
+ key->computes_depth = 0;
/* _NEW_COLOR */
key->uses_kill = fp->UsesKill || ctx->Color.AlphaEnabled;
@@ -300,6 +306,7 @@ const struct brw_tracked_state brw_wm_unit = {
.brw = (BRW_NEW_FRAGMENT_PROGRAM |
BRW_NEW_CURBE_OFFSETS |
+ BRW_NEW_DEPTH_BUFFER |
BRW_NEW_NR_WM_SURFACES),
.cache = (CACHE_NEW_WM_PROG |
diff --git a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
index 096f74394e..51539ac1e7 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_surface_state.c
@@ -545,15 +545,20 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
irb->texformat->MesaFormat);
}
key.tiling = region->tiling;
- key.width = region->width;
- key.height = region->height;
+ if (brw->intel.intelScreen->driScrnPriv->dri2.enabled) {
+ key.width = rb->Width;
+ key.height = rb->Height;
+ } else {
+ key.width = region->width;
+ key.height = region->height;
+ }
key.pitch = region->pitch;
key.cpp = region->cpp;
key.draw_offset = region->draw_offset; /* cur 3d or cube face offset */
} else {
key.surface_type = BRW_SURFACE_NULL;
key.surface_format = BRW_SURFACEFORMAT_B8G8R8A8_UNORM;
- key.tiling = 0;
+ key.tiling = I915_TILING_X;
key.width = 1;
key.height = 1;
key.cpp = 4;
@@ -629,7 +634,7 @@ brw_update_renderbuffer_surface(struct brw_context *brw,
drm_intel_bo_emit_reloc(brw->wm.surf_bo[unit],
offsetof(struct brw_surface_state, ss1),
region_bo,
- surf.ss1.base_addr,
+ surf.ss1.base_addr - region_bo->offset,
I915_GEM_DOMAIN_RENDER,
I915_GEM_DOMAIN_RENDER);
}
diff --git a/src/mesa/drivers/dri/i965/intel_syncobj.c b/src/mesa/drivers/dri/i965/intel_syncobj.c
new file mode 120000
index 0000000000..0b2e56ab24
--- /dev/null
+++ b/src/mesa/drivers/dri/i965/intel_syncobj.c
@@ -0,0 +1 @@
+../intel/intel_syncobj.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 0f87fc46a4..6aa36d10b1 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -196,6 +196,16 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
struct intel_context *intel = batch->intel;
GLuint used = batch->ptr - batch->map;
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
+ if (intel->first_post_swapbuffers_batch == NULL) {
+ intel->first_post_swapbuffers_batch = intel->batch->buf;
+ drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
+ }
+
if (used == 0) {
batch->cliprect_mode = IGNORE_CLIPRECTS;
return;
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 2e95bd1013..43141c509c 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -26,9 +26,6 @@
**************************************************************************/
-#include <stdio.h>
-#include <errno.h>
-
#include "main/mtypes.h"
#include "main/context.h"
#include "main/enums.h"
@@ -477,6 +474,8 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
BR13 |= BR13_565;
}
+ assert(irb->region->tiling != I915_TILING_Y);
+
#ifndef I915
if (irb->region->tiling != I915_TILING_NONE) {
CMD |= XY_DST_TILED;
@@ -571,6 +570,7 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
assert( logic_op - GL_CLEAR >= 0 );
assert( logic_op - GL_CLEAR < 0x10 );
+ assert(dst_pitch > 0);
if (w < 0 || h < 0)
return GL_TRUE;
@@ -633,3 +633,43 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
return GL_TRUE;
}
+
+/* We don't have a memmove-type blit like some other hardware, so we'll do a
+ * rectangular blit covering a large space, then emit 1-scanline blit at the
+ * end to cover the last if we need.
+ */
+void
+intel_emit_linear_blit(struct intel_context *intel,
+ drm_intel_bo *dst_bo,
+ unsigned int dst_offset,
+ drm_intel_bo *src_bo,
+ unsigned int src_offset,
+ unsigned int size)
+{
+ GLuint pitch, height;
+
+ /* The pitch is a signed value. */
+ pitch = MIN2(size, (1 << 15) - 1);
+ height = size / pitch;
+ intelEmitCopyBlit(intel, 1,
+ pitch, src_bo, src_offset, I915_TILING_NONE,
+ pitch, dst_bo, dst_offset, I915_TILING_NONE,
+ 0, 0, /* src x/y */
+ 0, 0, /* dst x/y */
+ pitch, height, /* w, h */
+ GL_COPY);
+
+ src_offset += pitch * height;
+ dst_offset += pitch * height;
+ size -= pitch * height;
+ assert (size < (1 << 15));
+ if (size != 0) {
+ intelEmitCopyBlit(intel, 1,
+ size, src_bo, src_offset, I915_TILING_NONE,
+ size, dst_bo, dst_offset, I915_TILING_NONE,
+ 0, 0, /* src x/y */
+ 0, 0, /* dst x/y */
+ size, 1, /* w, h */
+ GL_COPY);
+ }
+}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.h b/src/mesa/drivers/dri/intel/intel_blit.h
index 152fa3f17b..240cb7cd1b 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.h
+++ b/src/mesa/drivers/dri/intel/intel_blit.h
@@ -63,5 +63,11 @@ intelEmitImmediateColorExpandBlit(struct intel_context *intel,
GLshort x, GLshort y,
GLshort w, GLshort h,
GLenum logic_op);
+void intel_emit_linear_blit(struct intel_context *intel,
+ drm_intel_bo *dst_bo,
+ unsigned int dst_offset,
+ drm_intel_bo *src_bo,
+ unsigned int src_offset,
+ unsigned int size);
#endif
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.c b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
index 9600557f2c..c55c5c426e 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.c
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.c
@@ -28,9 +28,11 @@
#include "main/imports.h"
#include "main/mtypes.h"
+#include "main/macros.h"
#include "main/bufferobj.h"
#include "intel_context.h"
+#include "intel_blit.h"
#include "intel_buffer_objects.h"
#include "intel_batchbuffer.h"
#include "intel_regions.h"
@@ -128,9 +130,10 @@ intel_bufferobj_free(GLcontext * ctx, struct gl_buffer_object *obj)
* Allocate space for and store data in a buffer object. Any data that was
* previously stored in the buffer object is lost. If data is NULL,
* memory will be allocated, but no copy will occur.
- * Called via glBufferDataARB().
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
*/
-static void
+static GLboolean
intel_bufferobj_data(GLcontext * ctx,
GLenum target,
GLsizeiptrARB size,
@@ -165,15 +168,19 @@ intel_bufferobj_data(GLcontext * ctx,
if (intel_obj->sys_buffer != NULL) {
if (data != NULL)
memcpy(intel_obj->sys_buffer, data, size);
- return;
+ return GL_TRUE;
}
}
#endif
intel_bufferobj_alloc_buffer(intel, intel_obj);
+ if (!intel_obj->buffer)
+ return GL_FALSE;
if (data != NULL)
dri_bo_subdata(intel_obj->buffer, 0, size, data);
}
+
+ return GL_TRUE;
}
@@ -243,8 +250,10 @@ intel_bufferobj_map(GLcontext * ctx,
return obj->Pointer;
}
- if (!read_only)
- intelFlush(ctx);
+ /* Flush any existing batchbuffer that might have written to this
+ * buffer.
+ */
+ intelFlush(ctx);
if (intel_obj->region)
intel_bufferobj_cow(intel, intel_obj);
@@ -263,32 +272,205 @@ intel_bufferobj_map(GLcontext * ctx,
}
obj->Pointer = intel_obj->buffer->virtual;
+ obj->Length = obj->Size;
+ obj->Offset = 0;
+
return obj->Pointer;
}
+/**
+ * Called via glMapBufferRange().
+ *
+ * The goal of this extension is to allow apps to accumulate their rendering
+ * at the same time as they accumulate their buffer object. Without it,
+ * you'd end up blocking on execution of rendering every time you mapped
+ * the buffer to put new data in.
+ *
+ * We support it in 3 ways: If unsynchronized, then don't bother
+ * flushing the batchbuffer before mapping the buffer, which can save blocking
+ * in many cases. If we would still block, and they allow the whole buffer
+ * to be invalidated, then just allocate a new buffer to replace the old one.
+ * If not, and we'd block, and they allow the subrange of the buffer to be
+ * invalidated, then we can make a new little BO, let them write into that,
+ * and blit it into the real BO at unmap time.
+ */
+static void *
+intel_bufferobj_map_range(GLcontext * ctx,
+ GLenum target, GLintptr offset, GLsizeiptr length,
+ GLbitfield access, struct gl_buffer_object *obj)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+
+ assert(intel_obj);
+
+ /* _mesa_MapBufferRange (GL entrypoint) sets these, but the vbo module also
+ * internally uses our functions directly.
+ */
+ obj->Offset = offset;
+ obj->Length = length;
+ obj->AccessFlags = access;
+
+ if (intel_obj->sys_buffer) {
+ obj->Pointer = intel_obj->sys_buffer + offset;
+ return obj->Pointer;
+ }
+
+ if (intel_obj->region)
+ intel_bufferobj_cow(intel, intel_obj);
+
+ /* If the mapping is synchronized with other GL operations, flush
+ * the batchbuffer so that GEM knows about the buffer access for later
+ * syncing.
+ */
+ if (!(access & GL_MAP_UNSYNCHRONIZED_BIT))
+ intelFlush(ctx);
+
+ if (intel_obj->buffer == NULL) {
+ obj->Pointer = NULL;
+ return NULL;
+ }
+
+ /* If the user doesn't care about existing buffer contents and mapping
+ * would cause us to block, then throw out the old buffer.
+ */
+ if (!(access & GL_MAP_UNSYNCHRONIZED_BIT) &&
+ (access & GL_MAP_INVALIDATE_BUFFER_BIT) &&
+ drm_intel_bo_busy(intel_obj->buffer)) {
+ drm_intel_bo_unreference(intel_obj->buffer);
+ intel_obj->buffer = dri_bo_alloc(intel->bufmgr, "bufferobj",
+ intel_obj->Base.Size, 64);
+ }
+
+ /* If the user is mapping a range of an active buffer object but
+ * doesn't require the current contents of that range, make a new
+ * BO, and we'll copy what they put in there out at unmap or
+ * FlushRange time.
+ */
+ if ((access & GL_MAP_INVALIDATE_RANGE_BIT) &&
+ drm_intel_bo_busy(intel_obj->buffer)) {
+ if (access & GL_MAP_FLUSH_EXPLICIT_BIT) {
+ intel_obj->range_map_buffer = _mesa_malloc(length);
+ obj->Pointer = intel_obj->range_map_buffer;
+ } else {
+ intel_obj->range_map_bo = drm_intel_bo_alloc(intel->bufmgr,
+ "range map",
+ length, 64);
+ if (!(access & GL_MAP_READ_BIT) &&
+ intel->intelScreen->kernel_exec_fencing) {
+ drm_intel_gem_bo_map_gtt(intel_obj->range_map_bo);
+ intel_obj->mapped_gtt = GL_TRUE;
+ } else {
+ drm_intel_bo_map(intel_obj->range_map_bo,
+ (access & GL_MAP_WRITE_BIT) != 0);
+ intel_obj->mapped_gtt = GL_FALSE;
+ }
+ obj->Pointer = intel_obj->range_map_bo->virtual;
+ }
+ return obj->Pointer;
+ }
+
+ if (!(access & GL_MAP_READ_BIT) &&
+ intel->intelScreen->kernel_exec_fencing) {
+ drm_intel_gem_bo_map_gtt(intel_obj->buffer);
+ intel_obj->mapped_gtt = GL_TRUE;
+ } else {
+ drm_intel_bo_map(intel_obj->buffer, (access & GL_MAP_WRITE_BIT) != 0);
+ intel_obj->mapped_gtt = GL_FALSE;
+ }
+
+ obj->Pointer = intel_obj->buffer->virtual + offset;
+ return obj->Pointer;
+}
+
+/* Ideally we'd use a BO to avoid taking up cache space for the temporary
+ * data, but FlushMappedBufferRange may be followed by further writes to
+ * the pointer, so we would have to re-map after emitting our blit, which
+ * would defeat the point.
+ */
+static void
+intel_bufferobj_flush_mapped_range(GLcontext *ctx, GLenum target,
+ GLintptr offset, GLsizeiptr length,
+ struct gl_buffer_object *obj)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
+ drm_intel_bo *temp_bo;
+
+ /* Unless we're in the range map using a temporary system buffer,
+ * there's no work to do.
+ */
+ if (intel_obj->range_map_buffer == NULL)
+ return;
+
+ temp_bo = drm_intel_bo_alloc(intel->bufmgr, "range map flush", length, 64);
+
+ drm_intel_bo_subdata(temp_bo, 0, length, intel_obj->range_map_buffer);
+
+ intel_emit_linear_blit(intel,
+ intel_obj->buffer, obj->Offset + offset,
+ temp_bo, 0,
+ length);
+
+ drm_intel_bo_unreference(temp_bo);
+}
+
/**
- * Called via glMapBufferARB().
+ * Called via glUnmapBuffer().
*/
static GLboolean
intel_bufferobj_unmap(GLcontext * ctx,
GLenum target, struct gl_buffer_object *obj)
{
+ struct intel_context *intel = intel_context(ctx);
struct intel_buffer_object *intel_obj = intel_buffer_object(obj);
assert(intel_obj);
+ assert(obj->Pointer);
if (intel_obj->sys_buffer != NULL) {
- assert(obj->Pointer);
- obj->Pointer = NULL;
+ /* always keep the mapping around. */
+ } else if (intel_obj->range_map_buffer != NULL) {
+ /* Since we've emitted some blits to buffers that will (likely) be used
+ * in rendering operations in other cache domains in this batch, emit a
+ * flush. Once again, we wish for a domain tracker in libdrm to cover
+ * usage inside of a batchbuffer.
+ */
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+ free(intel_obj->range_map_buffer);
+ intel_obj->range_map_buffer = NULL;
+ } else if (intel_obj->range_map_bo != NULL) {
+ if (intel_obj->mapped_gtt) {
+ drm_intel_gem_bo_unmap_gtt(intel_obj->range_map_bo);
+ } else {
+ drm_intel_bo_unmap(intel_obj->range_map_bo);
+ }
+
+ intel_emit_linear_blit(intel,
+ intel_obj->buffer, obj->Offset,
+ intel_obj->range_map_bo, 0,
+ obj->Length);
+
+ /* Since we've emitted some blits to buffers that will (likely) be used
+ * in rendering operations in other cache domains in this batch, emit a
+ * flush. Once again, we wish for a domain tracker in libdrm to cover
+ * usage inside of a batchbuffer.
+ */
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+
+ drm_intel_bo_unreference(intel_obj->range_map_bo);
+ intel_obj->range_map_bo = NULL;
} else if (intel_obj->buffer != NULL) {
- assert(obj->Pointer);
if (intel_obj->mapped_gtt) {
drm_intel_gem_bo_unmap_gtt(intel_obj->buffer);
} else {
drm_intel_bo_unmap(intel_obj->buffer);
}
- obj->Pointer = NULL;
}
+ obj->Pointer = NULL;
+ obj->Offset = 0;
+ obj->Length = 0;
+
return GL_TRUE;
}
@@ -325,6 +507,64 @@ intel_bufferobj_buffer(struct intel_context *intel,
return intel_obj->buffer;
}
+static void
+intel_bufferobj_copy_subdata(GLcontext *ctx,
+ struct gl_buffer_object *src,
+ struct gl_buffer_object *dst,
+ GLintptr read_offset, GLintptr write_offset,
+ GLsizeiptr size)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_buffer_object *intel_src = intel_buffer_object(src);
+ struct intel_buffer_object *intel_dst = intel_buffer_object(dst);
+ drm_intel_bo *src_bo, *dst_bo;
+
+ if (size == 0)
+ return;
+
+ /* If we're in system memory, just map and memcpy. */
+ if (intel_src->sys_buffer || intel_dst->sys_buffer) {
+ /* The same buffer may be used, but note that regions copied may
+ * not overlap.
+ */
+ if (src == dst) {
+ char *ptr = intel_bufferobj_map(ctx, GL_COPY_WRITE_BUFFER,
+ GL_READ_WRITE, dst);
+ memcpy(ptr + write_offset, ptr + read_offset, size);
+ intel_bufferobj_unmap(ctx, GL_COPY_WRITE_BUFFER, dst);
+ } else {
+ const char *src_ptr;
+ char *dst_ptr;
+
+ src_ptr = intel_bufferobj_map(ctx, GL_COPY_READ_BUFFER,
+ GL_READ_ONLY, src);
+ dst_ptr = intel_bufferobj_map(ctx, GL_COPY_WRITE_BUFFER,
+ GL_WRITE_ONLY, dst);
+
+ memcpy(dst_ptr + write_offset, src_ptr + read_offset, size);
+
+ intel_bufferobj_unmap(ctx, GL_COPY_READ_BUFFER, src);
+ intel_bufferobj_unmap(ctx, GL_COPY_WRITE_BUFFER, dst);
+ }
+ }
+
+ /* Otherwise, we have real BOs, so blit them. */
+
+ dst_bo = intel_bufferobj_buffer(intel, intel_dst, INTEL_WRITE_PART);
+ src_bo = intel_bufferobj_buffer(intel, intel_src, INTEL_READ);
+
+ intel_emit_linear_blit(intel,
+ dst_bo, write_offset,
+ src_bo, read_offset, size);
+
+ /* Since we've emitted some blits to buffers that will (likely) be used
+ * in rendering operations in other cache domains in this batch, emit a
+ * flush. Once again, we wish for a domain tracker in libdrm to cover
+ * usage inside of a batchbuffer.
+ */
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+}
+
void
intelInitBufferObjectFuncs(struct dd_function_table *functions)
{
@@ -334,5 +574,8 @@ intelInitBufferObjectFuncs(struct dd_function_table *functions)
functions->BufferSubData = intel_bufferobj_subdata;
functions->GetBufferSubData = intel_bufferobj_get_subdata;
functions->MapBuffer = intel_bufferobj_map;
+ functions->MapBufferRange = intel_bufferobj_map_range;
+ functions->FlushMappedBufferRange = intel_bufferobj_flush_mapped_range;
functions->UnmapBuffer = intel_bufferobj_unmap;
+ functions->CopyBufferSubData = intel_bufferobj_copy_subdata;
}
diff --git a/src/mesa/drivers/dri/intel/intel_buffer_objects.h b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
index 8164407f07..bf3e08a320 100644
--- a/src/mesa/drivers/dri/intel/intel_buffer_objects.h
+++ b/src/mesa/drivers/dri/intel/intel_buffer_objects.h
@@ -48,6 +48,12 @@ struct intel_buffer_object
struct intel_region *region; /* Is there a zero-copy texture
associated with this (pixel)
buffer object? */
+
+ drm_intel_bo *range_map_bo;
+ void *range_map_buffer;
+ unsigned int range_map_offset;
+ GLsizei range_map_size;
+
GLboolean mapped_gtt;
};
diff --git a/src/mesa/drivers/dri/intel/intel_chipset.h b/src/mesa/drivers/dri/intel/intel_chipset.h
index 3c38f1676c..3dc8653a73 100644
--- a/src/mesa/drivers/dri/intel/intel_chipset.h
+++ b/src/mesa/drivers/dri/intel/intel_chipset.h
@@ -66,6 +66,7 @@
#define PCI_CHIP_Q45_G 0x2E12
#define PCI_CHIP_G45_G 0x2E22
#define PCI_CHIP_G41_G 0x2E32
+#define PCI_CHIP_B43_G 0x2E42
#define PCI_CHIP_ILD_G 0x0042
#define PCI_CHIP_ILM_G 0x0046
@@ -83,7 +84,8 @@
#define IS_G45(devid) (devid == PCI_CHIP_IGD_E_G || \
devid == PCI_CHIP_Q45_G || \
devid == PCI_CHIP_G45_G || \
- devid == PCI_CHIP_G41_G)
+ devid == PCI_CHIP_G41_G || \
+ devid == PCI_CHIP_B43_G)
#define IS_GM45(devid) (devid == PCI_CHIP_GM45_GM)
#define IS_G4X(devid) (IS_G45(devid) || IS_GM45(devid))
diff --git a/src/mesa/drivers/dri/intel/intel_clear.c b/src/mesa/drivers/dri/intel/intel_clear.c
index cfddabd318..fef977f465 100644
--- a/src/mesa/drivers/dri/intel/intel_clear.c
+++ b/src/mesa/drivers/dri/intel/intel_clear.c
@@ -27,25 +27,9 @@
**************************************************************************/
#include "main/glheader.h"
-#include "main/enums.h"
-#include "main/image.h"
#include "main/mtypes.h"
-#include "main/arrayobj.h"
-#include "main/attrib.h"
-#include "main/blend.h"
-#include "main/bufferobj.h"
-#include "main/buffers.h"
-#include "main/depth.h"
-#include "main/enable.h"
-#include "main/macros.h"
-#include "main/matrix.h"
-#include "main/polygon.h"
-#include "main/texstate.h"
-#include "main/shaders.h"
-#include "main/stencil.h"
-#include "main/varray.h"
-#include "glapi/dispatch.h"
#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
#include "intel_context.h"
#include "intel_blit.h"
@@ -54,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
@@ -140,7 +125,7 @@ intelClear(GLcontext *ctx, GLbitfield mask)
* buffer with it.
*/
if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) {
- int color_bit = _mesa_ffs(mask & TRI_CLEAR_COLOR_BITS);
+ int color_bit = _mesa_ffs(mask & BUFFER_BITS_COLOR);
if (color_bit != 0) {
tri_mask |= blit_mask & (1 << (color_bit - 1));
blit_mask &= ~(1 << (color_bit - 1));
@@ -150,14 +135,18 @@ intelClear(GLcontext *ctx, GLbitfield mask)
/* SW fallback clearing */
swrast_mask = mask & ~tri_mask & ~blit_mask;
- for (i = 0; i < BUFFER_COUNT; i++) {
- GLuint bufBit = 1 << i;
- if ((blit_mask | tri_mask) & bufBit) {
+ {
+ /* look for non-Intel renderbuffers (clear them with swrast) */
+ GLbitfield blit_or_tri = blit_mask | tri_mask;
+ while (blit_or_tri) {
+ GLuint i = _mesa_ffs(blit_or_tri) - 1;
+ GLbitfield bufBit = 1 << i;
if (!fb->Attachment[i].Renderbuffer->ClassID) {
blit_mask &= ~bufBit;
tri_mask &= ~bufBit;
swrast_mask |= bufBit;
}
+ blit_or_tri ^= bufBit;
}
}
@@ -182,7 +171,9 @@ intelClear(GLcontext *ctx, GLbitfield mask)
}
DBG("\n");
}
- meta_clear_tris(&intel->meta, tri_mask);
+
+ _mesa_meta_Clear(&intel->ctx, tri_mask);
+ intel_batchbuffer_flush(intel->batch);
}
if (swrast_mask) {
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 4abb525f78..d49d95768d 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -38,6 +38,7 @@
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
#include "i830_dri.h"
@@ -161,6 +162,9 @@ intelGetString(GLcontext * ctx, GLenum name)
case PCI_CHIP_G41_G:
chipset = "Intel(R) G41";
break;
+ case PCI_CHIP_B43_G:
+ chipset = "Intel(R) B43";
+ break;
case PCI_CHIP_ILD_G:
chipset = "Intel(R) IGDNG_D";
break;
@@ -503,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);
@@ -513,7 +518,7 @@ intel_flush(GLcontext *ctx, GLboolean needs_mi_flush)
* each of N places that do rendering. This has worse performances,
* but it is much easier to get correct.
*/
- if (intel->is_front_buffer_rendering) {
+ if (!intel->is_front_buffer_rendering) {
intel->front_buffer_dirty = GL_FALSE;
}
}
@@ -529,7 +534,27 @@ intelFlush(GLcontext * ctx)
static void
intel_glFlush(GLcontext *ctx)
{
+ struct intel_context *intel = intel_context(ctx);
+
intel_flush(ctx, GL_TRUE);
+
+ /* We're using glFlush as an indicator that a frame is done, which is
+ * what DRI2 does before calling SwapBuffers (and means we should catch
+ * people doing front-buffer rendering, as well)..
+ *
+ * Wait for the swapbuffers before the one we just emitted, so we don't
+ * get too many swaps outstanding for apps that are GPU-heavy but not
+ * CPU-heavy.
+ *
+ * Unfortunately, we don't have a handle to the batch containing the swap,
+ * and getting our hands on that doesn't seem worth it, so we just us the
+ * first batch we emitted after the last swap.
+ */
+ if (intel->first_post_swapbuffers_batch != NULL) {
+ drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+ drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
+ }
}
void
@@ -563,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);
@@ -577,6 +597,7 @@ intelInitDriverFunctions(struct dd_function_table *functions)
intelInitBufferFuncs(functions);
intelInitPixelFuncs(functions);
intelInitBufferObjectFuncs(functions);
+ intel_init_syncobj_functions(functions);
}
@@ -692,6 +713,8 @@ intelInitContext(struct intel_context *intel,
_swrast_allow_pixel_fog(ctx, GL_FALSE);
_swrast_allow_vertex_fog(ctx, GL_TRUE);
+ _mesa_meta_init(ctx);
+
intel->hw_stencil = mesaVis->stencilBits && mesaVis->depthBits == 24;
intel->hw_stipple = 1;
@@ -752,7 +775,7 @@ intelInitContext(struct intel_context *intel,
if (intel->use_texture_tiling &&
!intel->intelScreen->kernel_exec_fencing) {
fprintf(stderr, "No kernel support for execution fencing, "
- "disabling texture tiling");
+ "disabling texture tiling\n");
intel->use_texture_tiling = GL_FALSE;
}
intel->use_early_z = driQueryOptionb(&intel->optionCache, "early_z");
@@ -795,6 +818,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
INTEL_FIREVERTICES(intel);
+ _mesa_meta_free(&intel->ctx);
+
meta_destroy_metaops(&intel->meta);
intel->vtbl.destroy(intel);
@@ -814,6 +839,8 @@ intelDestroyContext(__DRIcontextPrivate * driContextPriv)
intel->prim.vb = NULL;
dri_bo_unreference(intel->prim.vb_bo);
intel->prim.vb_bo = NULL;
+ dri_bo_unreference(intel->first_post_swapbuffers_batch);
+ intel->first_post_swapbuffers_batch = NULL;
if (release_texture_heaps) {
/* Nothing is currently done here to free texture heaps;
@@ -891,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_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index 08bea88c95..03e7cf39d6 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -80,9 +80,19 @@ extern void intelFallback(struct intel_context *intel, GLuint bit,
#define INTEL_MAX_FIXUP 64
+struct intel_sync_object {
+ struct gl_sync_object Base;
+
+ /** Batch associated with this sync object */
+ drm_intel_bo *bo;
+};
+
+/**
+ * intel_context is derived from Mesa's context class: GLcontext.
+ */
struct intel_context
{
- GLcontext ctx; /* the parent class */
+ GLcontext ctx; /**< base class, must be first field */
struct
{
@@ -178,6 +188,7 @@ struct intel_context
GLboolean ttm;
struct intel_batchbuffer *batch;
+ drm_intel_bo *first_post_swapbuffers_batch;
GLboolean no_batch_wrap;
unsigned batch_id;
@@ -307,7 +318,7 @@ struct intel_context
__DRIdrawablePrivate *driReadDrawable;
__DRIscreenPrivate *driScreen;
intelScreenPrivate *intelScreen;
- volatile struct drm_i915_sarea *sarea;
+ volatile drm_i915_sarea_t *sarea;
GLuint lastStamp;
@@ -465,6 +476,8 @@ extern void intelFlush(GLcontext * ctx);
extern void intelInitDriverFunctions(struct dd_function_table *functions);
+void intel_init_syncobj_functions(struct dd_function_table *functions);
+
/* ================================================================
* intel_state.c:
diff --git a/src/mesa/drivers/dri/intel/intel_extensions.c b/src/mesa/drivers/dri/intel/intel_extensions.c
index 7742609d24..5431cf90a1 100644
--- a/src/mesa/drivers/dri/intel/intel_extensions.c
+++ b/src/mesa/drivers/dri/intel/intel_extensions.c
@@ -30,10 +30,14 @@
#include "intel_extensions.h"
+#define need_GL_ARB_copy_buffer
+#define need_GL_ARB_draw_elements_base_vertex
#define need_GL_ARB_framebuffer_object
+#define need_GL_ARB_map_buffer_range
#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
#define need_GL_ARB_shader_objects
+#define need_GL_ARB_sync
#define need_GL_ARB_vertex_array_object
#define need_GL_ARB_vertex_program
#define need_GL_ARB_vertex_shader
@@ -48,6 +52,7 @@
#define need_GL_EXT_framebuffer_blit
#define need_GL_EXT_gpu_program_parameters
#define need_GL_EXT_point_parameters
+#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
#define need_GL_APPLE_vertex_array_object
@@ -68,9 +73,14 @@
* i965_dri.
*/
static const struct dri_extension card_extensions[] = {
+ { "GL_ARB_copy_buffer", GL_ARB_copy_buffer_functions },
+ { "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions },
{ "GL_ARB_half_float_pixel", NULL },
+ { "GL_ARB_map_buffer_range", GL_ARB_map_buffer_range_functions },
{ "GL_ARB_multitexture", NULL },
{ "GL_ARB_point_parameters", GL_ARB_point_parameters_functions },
+ { "GL_ARB_point_sprite", NULL },
+ { "GL_ARB_sync", GL_ARB_sync_functions },
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_cube_map", NULL },
{ "GL_ARB_texture_env_add", NULL },
@@ -92,6 +102,7 @@ static const struct dri_extension card_extensions[] = {
{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{ "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
{ "GL_EXT_packed_depth_stencil", NULL },
+ { "GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions },
{ "GL_EXT_secondary_color", GL_EXT_secondary_color_functions },
{ "GL_EXT_stencil_wrap", NULL },
{ "GL_EXT_texture_edge_clamp", NULL },
@@ -119,8 +130,10 @@ static const struct dri_extension i915_extensions[] = {
{ "GL_ARB_fragment_program", NULL },
{ "GL_ARB_shadow", NULL },
{ "GL_ARB_texture_non_power_of_two", NULL },
+ { "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions },
{ "GL_ATI_texture_env_combine3", NULL },
{ "GL_EXT_shadow_funcs", NULL },
+ { "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions },
{ "GL_NV_texture_env_combine4", NULL },
{ NULL, NULL }
};
@@ -128,6 +141,7 @@ static const struct dri_extension i915_extensions[] = {
/** i965-only extensions */
static const struct dri_extension brw_extensions[] = {
+ { "GL_ARB_depth_clamp", NULL },
{ "GL_ARB_depth_texture", NULL },
{ "GL_ARB_fragment_program", NULL },
{ "GL_ARB_fragment_program_shadow", NULL },
@@ -135,6 +149,7 @@ static const struct dri_extension brw_extensions[] = {
{ "GL_ARB_framebuffer_object", GL_ARB_framebuffer_object_functions},
{ "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions },
{ "GL_ARB_point_sprite", NULL },
+ { "GL_ARB_seamless_cube_map", NULL },
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
{ "GL_ARB_shading_language_100", GL_VERSION_2_0_functions },
{ "GL_ARB_shading_language_120", GL_VERSION_2_1_functions },
diff --git a/src/mesa/drivers/dri/intel/intel_fbo.c b/src/mesa/drivers/dri/intel/intel_fbo.c
index 666893596e..8dfb24290d 100644
--- a/src/mesa/drivers/dri/intel/intel_fbo.c
+++ b/src/mesa/drivers/dri/intel/intel_fbo.c
@@ -35,6 +35,7 @@
#include "main/context.h"
#include "main/texformat.h"
#include "main/texrender.h"
+#include "drivers/common/meta.h"
#include "intel_context.h"
#include "intel_buffers.h"
@@ -700,74 +701,6 @@ intel_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
/**
- * Called from glBlitFramebuffer().
- * For now, we're doing an approximation with glCopyPixels().
- * XXX we need to bypass all the per-fragment operations, except scissor.
- */
-static void
-intel_blit_framebuffer(GLcontext *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
- const GLfloat xZoomSave = ctx->Pixel.ZoomX;
- const GLfloat yZoomSave = ctx->Pixel.ZoomY;
- GLsizei width, height;
- GLfloat xFlip = 1.0F, yFlip = 1.0F;
-
- if (srcX1 < srcX0) {
- GLint tmp = srcX1;
- srcX1 = srcX0;
- srcX0 = tmp;
- xFlip = -1.0F;
- }
-
- if (srcY1 < srcY0) {
- GLint tmp = srcY1;
- srcY1 = srcY0;
- srcY0 = tmp;
- yFlip = -1.0F;
- }
-
- width = srcX1 - srcX0;
- height = srcY1 - srcY0;
-
- ctx->Pixel.ZoomX = xFlip * (dstX1 - dstX0) / (srcX1 - srcY0);
- ctx->Pixel.ZoomY = yFlip * (dstY1 - dstY0) / (srcY1 - srcY0);
-
- if (ctx->Pixel.ZoomX < 0.0F) {
- dstX0 = MAX2(dstX0, dstX1);
- }
- else {
- dstX0 = MIN2(dstX0, dstX1);
- }
-
- if (ctx->Pixel.ZoomY < 0.0F) {
- dstY0 = MAX2(dstY0, dstY1);
- }
- else {
- dstY0 = MIN2(dstY0, dstY1);
- }
-
- if (mask & GL_COLOR_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_COLOR);
- }
- if (mask & GL_DEPTH_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_DEPTH);
- }
- if (mask & GL_STENCIL_BUFFER_BIT) {
- ctx->Driver.CopyPixels(ctx, srcX0, srcY0, width, height,
- dstX0, dstY0, GL_STENCIL);
- }
-
- ctx->Pixel.ZoomX = xZoomSave;
- ctx->Pixel.ZoomY = yZoomSave;
-}
-
-
-/**
* Do one-time context initializations related to GL_EXT_framebuffer_object.
* Hook in device driver functions.
*/
@@ -782,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 = intel_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 fe986092db..237754d469 100644
--- a/src/mesa/drivers/dri/intel/intel_generatemipmap.c
+++ b/src/mesa/drivers/dri/intel/intel_generatemipmap.c
@@ -223,10 +223,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_bitmap.c b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
index 540e7620a9..9a0bcc07a5 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_bitmap.c
@@ -93,19 +93,12 @@ static const GLubyte *map_pbo( GLcontext *ctx,
return ADD_POINTERS(buf, bitmap);
}
-static GLboolean test_bit( const GLubyte *src,
- GLuint bit )
+static GLboolean test_bit( const GLubyte *src, GLuint bit )
{
return (src[bit/8] & (1<<(bit % 8))) ? 1 : 0;
}
-static GLboolean test_msb_bit(const GLubyte *src, GLuint bit)
-{
- return (src[bit/8] & (1<<(7 - (bit % 8)))) ? 1 : 0;
-}
-
-static void set_bit( GLubyte *dest,
- GLuint bit )
+static void set_bit( GLubyte *dest, GLuint bit )
{
dest[bit/8] |= 1 << (bit % 8);
}
@@ -216,7 +209,7 @@ do_blit_bitmap( GLcontext *ctx,
if (!dst)
return GL_FALSE;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
bitmap = map_pbo(ctx, width, height, unpack, bitmap);
if (bitmap == NULL)
return GL_TRUE; /* even though this is an error, we're done */
@@ -336,7 +329,7 @@ out:
if (INTEL_DEBUG & DEBUG_SYNC)
intel_batchbuffer_flush(intel->batch);
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* done with PBO so unmap it now */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
@@ -365,9 +358,7 @@ intel_texture_bitmap(GLcontext * ctx,
GLuint texname;
GLfloat vertices[4][4];
GLint old_active_texture;
- GLubyte *unpacked_bitmap;
GLubyte *a8_bitmap;
- int x, y;
GLfloat dst_z;
/* We need a fragment program for the KIL effect */
@@ -427,23 +418,17 @@ intel_texture_bitmap(GLcontext * ctx,
return GL_FALSE;
}
- /* Convert the A1 bitmap to an A8 format suitable for glTexImage */
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
bitmap = map_pbo(ctx, width, height, unpack, bitmap);
if (bitmap == NULL)
return GL_TRUE; /* even though this is an error, we're done */
}
- unpacked_bitmap = _mesa_unpack_bitmap(width, height, bitmap,
- unpack);
+
+ /* Convert the A1 bitmap to an A8 format suitable for glTexImage */
a8_bitmap = _mesa_calloc(width * height);
- for (y = 0; y < height; y++) {
- for (x = 0; x < width; x++) {
- if (test_msb_bit(unpacked_bitmap, ALIGN(width, 8) * y + x))
- a8_bitmap[y * width + x] = 0xff;
- }
- }
- _mesa_free(unpacked_bitmap);
- if (unpack->BufferObj->Name) {
+ _mesa_expand_bitmap(width, height, unpack, bitmap, a8_bitmap, width, 0xff);
+
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* done with PBO so unmap it now */
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
diff --git a/src/mesa/drivers/dri/intel/intel_pixel_copy.c b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
index 5d52335dee..f058b3c8e4 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_copy.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_copy.c
@@ -26,18 +26,13 @@
**************************************************************************/
#include "main/glheader.h"
-#include "main/enums.h"
#include "main/image.h"
#include "main/state.h"
#include "main/mtypes.h"
-#include "main/macros.h"
-#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
-#include "intel_screen.h"
#include "intel_context.h"
-#include "intel_batchbuffer.h"
#include "intel_buffers.h"
-#include "intel_blit.h"
#include "intel_regions.h"
#include "intel_pixel.h"
@@ -97,162 +92,6 @@ intel_check_copypixel_blit_fragment_ops(GLcontext * ctx)
ctx->Color.BlendEnabled);
}
-#ifdef I915
-/* Doesn't work for overlapping regions. Could do a double copy or
- * just fallback.
- */
-static GLboolean
-do_texture_copypixels(GLcontext * ctx,
- GLint srcx, GLint srcy,
- GLsizei width, GLsizei height,
- GLint dstx, GLint dsty, GLenum type)
-{
- struct intel_context *intel = intel_context(ctx);
- struct intel_region *dst = intel_drawbuf_region(intel);
- struct intel_region *src = copypix_src_region(intel, type);
- GLenum src_format;
- GLenum src_type;
-
- DBG("%s %d,%d %dx%d --> %d,%d\n", __FUNCTION__,
- srcx, srcy, width, height, dstx, dsty);
-
- if (!src || !dst || type != GL_COLOR)
- return GL_FALSE;
-
- if (ctx->_ImageTransferState) {
- if (INTEL_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s: check_color failed\n", __FUNCTION__);
- return GL_FALSE;
- }
-
- /* Can't handle overlapping regions. Don't have sufficient control
- * over rasterization to pull it off in-place. Punt on these for
- * now.
- *
- * XXX: do a copy to a temporary.
- */
- if (src->buffer == dst->buffer) {
- drm_clip_rect_t srcbox;
- drm_clip_rect_t dstbox;
- drm_clip_rect_t tmp;
-
- srcbox.x1 = srcx;
- srcbox.y1 = srcy;
- srcbox.x2 = srcx + width;
- srcbox.y2 = srcy + height;
-
- if (ctx->Pixel.ZoomX > 0) {
- dstbox.x1 = dstx;
- dstbox.x2 = dstx + width * ctx->Pixel.ZoomX;
- } else {
- dstbox.x1 = dstx + width * ctx->Pixel.ZoomX;
- dstbox.x2 = dstx;
- }
- if (ctx->Pixel.ZoomY > 0) {
- dstbox.y1 = dsty;
- dstbox.y2 = dsty + height * ctx->Pixel.ZoomY;
- } else {
- dstbox.y1 = dsty + height * ctx->Pixel.ZoomY;
- dstbox.y2 = dsty;
- }
-
- DBG("src %d,%d %d,%d\n", srcbox.x1, srcbox.y1, srcbox.x2, srcbox.y2);
- DBG("dst %d,%d %d,%d (%dx%d) (%f,%f)\n", dstbox.x1, dstbox.y1, dstbox.x2, dstbox.y2,
- width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
-
- if (intel_intersect_cliprects(&tmp, &srcbox, &dstbox)) {
- DBG("%s: regions overlap\n", __FUNCTION__);
- return GL_FALSE;
- }
- }
-
- intelFlush(&intel->ctx);
-
- intel->vtbl.install_meta_state(intel);
-
- /* Is this true? Also will need to turn depth testing on according
- * to state:
- */
- intel->vtbl.meta_no_stencil_write(intel);
- intel->vtbl.meta_no_depth_write(intel);
-
- /* Set the 3d engine to draw into the destination region:
- */
- intel->vtbl.meta_draw_region(intel, dst, intel->depth_region);
-
- intel->vtbl.meta_import_pixel_state(intel);
-
- if (src->cpp == 2) {
- src_format = GL_RGB;
- src_type = GL_UNSIGNED_SHORT_5_6_5;
- }
- else {
- src_format = GL_BGRA;
- src_type = GL_UNSIGNED_BYTE;
- }
-
- /* Set the frontbuffer up as a large rectangular texture.
- */
- if (!intel->vtbl.meta_tex_rect_source(intel, src->buffer, 0,
- src->pitch,
- src->height, src_format, src_type)) {
- intel->vtbl.leave_meta_state(intel);
- return GL_FALSE;
- }
-
-
- intel->vtbl.meta_texture_blend_replace(intel);
-
- LOCK_HARDWARE(intel);
-
- if (intel->driDrawable->numClipRects) {
- __DRIdrawablePrivate *dPriv = intel->driDrawable;
-
-
- srcy = dPriv->h - srcy - height; /* convert from gl to hardware coords */
-
- srcx += dPriv->x;
- srcy += dPriv->y;
-
- /* Clip against the source region. This is the only source
- * clipping we do. XXX: Just set the texcord wrap mode to clamp
- * or similar.
- *
- */
- if (0) {
- GLint orig_x = srcx;
- GLint orig_y = srcy;
-
- if (!_mesa_clip_to_region(0, 0, src->pitch, src->height,
- &srcx, &srcy, &width, &height))
- goto out;
-
- dstx += srcx - orig_x;
- dsty += (srcy - orig_y) * ctx->Pixel.ZoomY;
- }
-
- /* Just use the regular cliprect mechanism... Does this need to
- * even hold the lock???
- */
- intel->vtbl.meta_draw_quad(intel,
- dstx,
- dstx + width * ctx->Pixel.ZoomX,
- dPriv->h - (dsty + height * ctx->Pixel.ZoomY),
- dPriv->h - (dsty), 0, /* XXX: what z value? */
- 0x00ff00ff,
- srcx, srcx + width, srcy, srcy + height);
-
- out:
- intel->vtbl.leave_meta_state(intel);
- intel_batchbuffer_emit_mi_flush(intel->batch);
- }
- UNLOCK_HARDWARE(intel);
-
- DBG("%s: success\n", __FUNCTION__);
- return GL_TRUE;
-}
-#endif /* I915 */
-
/**
* CopyPixels with the blitter. Don't support zooming, pixel transfer, etc.
@@ -400,12 +239,6 @@ intelCopyPixels(GLcontext * ctx,
if (do_blit_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
return;
-#ifdef I915
- if (do_texture_copypixels(ctx, srcx, srcy, width, height, destx, desty, type))
- return;
-#endif
-
- DBG("fallback to _swrast_CopyPixels\n");
-
- _swrast_CopyPixels(ctx, srcx, srcy, width, height, destx, desty, type);
+ /* this will use swrast if needed */
+ _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 a6b6824164..5ffa847fd4 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_draw.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_draw.c
@@ -29,8 +29,6 @@
#include "main/enums.h"
#include "main/image.h"
#include "main/mtypes.h"
-#include "main/macros.h"
-#include "main/bufferobj.h"
#include "main/teximage.h"
#include "main/texenv.h"
#include "main/texobj.h"
@@ -41,163 +39,22 @@
#include "main/enable.h"
#include "main/buffers.h"
#include "main/fbobject.h"
-#include "main/renderbuffer.h"
#include "main/depth.h"
#include "main/hash.h"
#include "main/blend.h"
-#include "main/viewport.h"
-#include "glapi/dispatch.h"
#include "swrast/swrast.h"
+#include "drivers/common/meta.h"
-#include "intel_screen.h"
#include "intel_context.h"
#include "intel_batchbuffer.h"
#include "intel_blit.h"
#include "intel_buffers.h"
#include "intel_regions.h"
#include "intel_pixel.h"
-#include "intel_buffer_objects.h"
#include "intel_fbo.h"
-static GLboolean
-intel_texture_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 intel_context *intel = intel_context(ctx);
- GLuint texname;
- GLfloat vertices[4][4];
- GLfloat z;
- GLint old_active_texture;
- GLenum internalFormat;
-
- /* We're going to mess with texturing with no regard to existing texture
- * state, so if there is some set up we have to bail.
- */
- if (ctx->Texture._EnabledUnits != 0) {
- if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "glDrawPixels() fallback: texturing enabled\n");
- return GL_FALSE;
- }
-
- /* Can't do textured DrawPixels with a fragment program, unless we were
- * to generate a new program that sampled our texture and put the results
- * in the fragment color before the user's program started.
- */
- if (ctx->FragmentProgram.Enabled) {
- if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "glDrawPixels() fallback: fragment program enabled\n");
- return GL_FALSE;
- }
-
- /* We don't have a way to generate fragments with stencil values which
- * will set the resulting stencil value.
- */
- if (format == GL_STENCIL_INDEX || format == GL_DEPTH_STENCIL)
- return GL_FALSE;
-
- /* Check that we can load in a texture this big. */
- if (width > (1 << (ctx->Const.MaxTextureLevels - 1)) ||
- height > (1 << (ctx->Const.MaxTextureLevels - 1))) {
- if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "glDrawPixels() fallback: bitmap too large (%dx%d)\n",
- width, height);
- return GL_FALSE;
- }
-
- /* To do DEPTH_COMPONENT, we would need to change our setup to not draw to
- * the color buffer, and sample the texture values into the fragment depth
- * in a program.
- */
- if (format == GL_DEPTH_COMPONENT) {
- if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr,
- "glDrawPixels() fallback: format == GL_DEPTH_COMPONENT\n");
- return GL_FALSE;
- }
-
- if (!ctx->Extensions.ARB_texture_non_power_of_two &&
- (!is_power_of_two(width) || !is_power_of_two(height))) {
- if (INTEL_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr,
- "glDrawPixels() fallback: NPOT texture\n");
- return GL_FALSE;
- }
-
- _mesa_PushAttrib(GL_ENABLE_BIT | GL_TEXTURE_BIT |
- GL_CURRENT_BIT | GL_VIEWPORT_BIT);
- _mesa_PushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT);
-
- /* XXX: pixel store stuff */
- _mesa_Disable(GL_POLYGON_STIPPLE);
-
- old_active_texture = ctx->Texture.CurrentUnit;
- _mesa_ActiveTextureARB(GL_TEXTURE0_ARB);
- _mesa_Enable(GL_TEXTURE_2D);
- _mesa_GenTextures(1, &texname);
- _mesa_BindTexture(GL_TEXTURE_2D, texname);
- _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- _mesa_TexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- _mesa_TexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
- if (type == GL_ALPHA)
- internalFormat = GL_ALPHA;
- else
- internalFormat = GL_RGBA;
- _mesa_TexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, format,
- type, pixels);
-
- meta_set_passthrough_transform(&intel->meta);
-
- /* convert rasterpos Z from [0,1] to NDC coord in [-1,1] */
- z = -1.0 + 2.0 * ctx->Current.RasterPos[2];
-
- /* RasterPos[2] already takes into account the DepthRange mapping. */
- _mesa_DepthRange(0.0, 1.0);
-
- /* Create the vertex buffer based on the current raster pos. The x and y
- * we're handed are ctx->Current.RasterPos[0,1] rounded to integers.
- * We also apply the depth. However, the W component is already multiplied
- * into ctx->Current.RasterPos[0,1,2] and we can ignore it at this point.
- */
- vertices[0][0] = x;
- vertices[0][1] = y;
- vertices[0][2] = z;
- vertices[0][3] = 1.0;
- vertices[1][0] = x + width * ctx->Pixel.ZoomX;
- vertices[1][1] = y;
- vertices[1][2] = z;
- vertices[1][3] = 1.0;
- vertices[2][0] = x + width * ctx->Pixel.ZoomX;
- vertices[2][1] = y + height * ctx->Pixel.ZoomY;
- vertices[2][2] = z;
- vertices[2][3] = 1.0;
- vertices[3][0] = x;
- vertices[3][1] = y + height * ctx->Pixel.ZoomY;
- vertices[3][2] = z;
- vertices[3][3] = 1.0;
-
- _mesa_VertexPointer(4, GL_FLOAT, 4 * sizeof(GLfloat), &vertices);
- _mesa_Enable(GL_VERTEX_ARRAY);
- meta_set_default_texrect(&intel->meta);
-
- _mesa_DrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
- meta_restore_texcoords(&intel->meta);
- meta_restore_transform(&intel->meta);
-
- _mesa_ActiveTextureARB(GL_TEXTURE0_ARB + old_active_texture);
- _mesa_PopClientAttrib();
- _mesa_PopAttrib();
-
- _mesa_DeleteTextures(1, &texname);
-
- return GL_TRUE;
-}
+/** XXX compare perf of this vs. _mesa_meta_DrawPixels(STENCIL) */
static GLboolean
intel_stencil_drawpixels(GLcontext * ctx,
GLint x, GLint y,
@@ -404,17 +261,25 @@ intelDrawPixels(GLcontext * ctx,
const struct gl_pixelstore_attrib *unpack,
const GLvoid * pixels)
{
- if (intel_texture_drawpixels(ctx, x, y, width, height, format, type,
- unpack, pixels))
- return;
-
+#if 0
+ /* 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_DrawPixels() approach
+ * isn't working because of an apparent stencil bug.
+ */
if (intel_stencil_drawpixels(ctx, x, y, width, height, format, type,
unpack, pixels))
return;
+#else
+ (void) intel_stencil_drawpixels; /* silence warning */
+ if (format == GL_STENCIL_INDEX) {
+ _swrast_DrawPixels(ctx, x, y, width, height, format, type,
+ unpack, pixels);
+ return;
+ }
+#endif
- if (INTEL_DEBUG & DEBUG_PIXEL)
- _mesa_printf("%s: fallback to swrast\n", __FUNCTION__);
-
- _swrast_DrawPixels(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_pixel_read.c b/src/mesa/drivers/dri/intel/intel_pixel_read.c
index 8713463ace..bc67f6242a 100644
--- a/src/mesa/drivers/dri/intel/intel_pixel_read.c
+++ b/src/mesa/drivers/dri/intel/intel_pixel_read.c
@@ -180,16 +180,7 @@ do_blit_readpixels(GLcontext * ctx,
if (!src)
return GL_FALSE;
- if (pack->BufferObj->Name) {
- /* XXX This validation should be done by core mesa:
- */
- if (!_mesa_validate_pbo_access(2, pack, width, height, 1,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawPixels");
- return GL_TRUE;
- }
- }
- else {
+ if (!_mesa_is_bufferobj(pack->BufferObj)) {
/* PBO only for now:
*/
if (INTEL_DEBUG & DEBUG_PIXEL)
diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c
index 7525cd9c4d..a86c66a844 100644
--- a/src/mesa/drivers/dri/intel/intel_regions.c
+++ b/src/mesa/drivers/dri/intel/intel_regions.c
@@ -181,6 +181,28 @@ intel_region_alloc(struct intel_context *intel,
dri_bo *buffer;
struct intel_region *region;
+ /* If we're tiled, our allocations are in 8 or 32-row blocks, so
+ * failure to align our height means that we won't allocate enough pages.
+ *
+ * If we're untiled, we still have to align to 2 rows high because the
+ * data port accesses 2x2 blocks even if the bottom row isn't to be
+ * rendered, so failure to align means we could walk off the end of the
+ * GTT and fault.
+ */
+ if (tiling == I915_TILING_X)
+ height = ALIGN(height, 8);
+ else if (tiling == I915_TILING_Y)
+ height = ALIGN(height, 32);
+ else
+ height = ALIGN(height, 2);
+
+ /* If we're untiled, we have to align to 2 rows high because the
+ * data port accesses 2x2 blocks even if the bottom row isn't to be
+ * rendered, so failure to align means we could walk off the end of the
+ * GTT and fault.
+ */
+ height = ALIGN(height, 2);
+
if (expect_accelerated_upload) {
buffer = drm_intel_bo_alloc_for_render(intel->bufmgr, "region",
pitch * cpp * height, 64);
@@ -452,6 +474,7 @@ void
intel_region_cow(struct intel_context *intel, struct intel_region *region)
{
struct intel_buffer_object *pbo = region->pbo;
+ GLboolean ok;
intel_region_release_pbo(intel, region);
@@ -463,13 +486,14 @@ intel_region_cow(struct intel_context *intel, struct intel_region *region)
*/
LOCK_HARDWARE(intel);
- assert(intelEmitCopyBlit(intel,
- region->cpp,
- region->pitch, pbo->buffer, 0, region->tiling,
- region->pitch, region->buffer, 0, region->tiling,
- 0, 0, 0, 0,
- region->pitch, region->height,
- GL_COPY));
+ ok = intelEmitCopyBlit(intel,
+ region->cpp,
+ region->pitch, pbo->buffer, 0, region->tiling,
+ region->pitch, region->buffer, 0, region->tiling,
+ 0, 0, 0, 0,
+ region->pitch, region->height,
+ GL_COPY);
+ assert(ok);
UNLOCK_HARDWARE(intel);
}
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 6bbc995c1e..1b8c56e68d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -69,7 +69,11 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_DESC_END
DRI_CONF_OPT_END
- DRI_CONF_TEXTURE_TILING(false)
+#ifdef I915
+ DRI_CONF_TEXTURE_TILING(false)
+#else
+ DRI_CONF_TEXTURE_TILING(true)
+#endif
DRI_CONF_OPT_BEGIN(early_z, bool, false)
DRI_CONF_DESC(en, "Enable early Z in classic mode (unstable, 945-only).")
@@ -628,10 +632,10 @@ intel_init_bufmgr(intelScreenPrivate *intelScreen)
/* Otherwise, use the classic buffer manager. */
if (intelScreen->bufmgr == NULL) {
if (gem_disable) {
- fprintf(stderr, "GEM disabled. Using classic.\n");
+ _mesa_warning(NULL, "GEM disabled. Using classic.");
} else {
- fprintf(stderr, "Failed to initialize GEM. "
- "Falling back to classic.\n");
+ _mesa_warning(NULL,
+ "Failed to initialize GEM. Falling back to classic.");
}
if (intelScreen->tex.size == 0) {
diff --git a/src/mesa/drivers/dri/intel/intel_span.c b/src/mesa/drivers/dri/intel/intel_span.c
index 34b78ebc1a..28eabbc005 100644
--- a/src/mesa/drivers/dri/intel/intel_span.c
+++ b/src/mesa/drivers/dri/intel/intel_span.c
@@ -444,23 +444,30 @@ intel_renderbuffer_unmap(struct intel_context *intel,
* _ColorReadBuffer, _DepthBuffer or _StencilBuffer fields.
*/
static void
-intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
+intel_map_unmap_framebuffer(struct intel_context *intel,
+ struct gl_framebuffer *fb,
+ GLboolean map)
{
- GLcontext *ctx = &intel->ctx;
- GLuint i, j;
+ GLuint i;
/* color draw buffers */
- for (j = 0; j < ctx->DrawBuffer->_NumColorDrawBuffers; j++) {
+ for (i = 0; i < fb->_NumColorDrawBuffers; i++) {
if (map)
- intel_renderbuffer_map(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
+ intel_renderbuffer_map(intel, fb->_ColorDrawBuffers[i]);
else
- intel_renderbuffer_unmap(intel, ctx->DrawBuffer->_ColorDrawBuffers[j]);
+ 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 =
- ctx->DrawBuffer->Attachment + i;
+ fb->Attachment + i;
struct gl_texture_object *tex = att->Texture;
if (tex) {
/* render to texture */
@@ -472,36 +479,25 @@ intel_map_unmap_buffers(struct intel_context *intel, GLboolean map)
}
}
- /* color read buffers */
- if (map)
- intel_renderbuffer_map(intel, ctx->ReadBuffer->_ColorReadBuffer);
- else
- intel_renderbuffer_unmap(intel, ctx->ReadBuffer->_ColorReadBuffer);
-
/* depth buffer (Note wrapper!) */
- if (ctx->DrawBuffer->_DepthBuffer) {
+ if (fb->_DepthBuffer) {
if (map)
- intel_renderbuffer_map(intel, ctx->DrawBuffer->_DepthBuffer->Wrapped);
+ intel_renderbuffer_map(intel, fb->_DepthBuffer->Wrapped);
else
- intel_renderbuffer_unmap(intel,
- ctx->DrawBuffer->_DepthBuffer->Wrapped);
+ intel_renderbuffer_unmap(intel, fb->_DepthBuffer->Wrapped);
}
/* stencil buffer (Note wrapper!) */
- if (ctx->DrawBuffer->_StencilBuffer) {
+ if (fb->_StencilBuffer) {
if (map)
- intel_renderbuffer_map(intel,
- ctx->DrawBuffer->_StencilBuffer->Wrapped);
+ intel_renderbuffer_map(intel, fb->_StencilBuffer->Wrapped);
else
- intel_renderbuffer_unmap(intel,
- ctx->DrawBuffer->_StencilBuffer->Wrapped);
+ intel_renderbuffer_unmap(intel, fb->_StencilBuffer->Wrapped);
}
}
-
-
/**
- * Prepare for softare rendering. Map current read/draw framebuffers'
+ * Prepare for software rendering. Map current read/draw framebuffers'
* renderbuffes and all currently bound texture objects.
*
* Old note: Moved locking out to get reasonable span performance.
@@ -522,11 +518,13 @@ intelSpanRenderStart(GLcontext * ctx)
}
}
- intel_map_unmap_buffers(intel, GL_TRUE);
+ intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_TRUE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_TRUE);
}
/**
- * Called when done softare rendering. Unmap the buffers we mapped in
+ * Called when done software rendering. Unmap the buffers we mapped in
* the above function.
*/
void
@@ -544,7 +542,9 @@ intelSpanRenderFinish(GLcontext * ctx)
}
}
- intel_map_unmap_buffers(intel, GL_FALSE);
+ intel_map_unmap_framebuffer(intel, ctx->DrawBuffer, GL_FALSE);
+ if (ctx->ReadBuffer != ctx->DrawBuffer)
+ intel_map_unmap_framebuffer(intel, ctx->ReadBuffer, GL_FALSE);
UNLOCK_HARDWARE(intel);
}
@@ -711,6 +711,9 @@ intel_set_span_functions(struct intel_context *intel,
intel_YTile_InitStencilPointers_z24_s8(rb);
break;
}
+ } else {
+ _mesa_problem(NULL,
+ "Unexpected ActualFormat in intelSetSpanFunctions");
}
break;
default:
diff --git a/src/mesa/drivers/dri/intel/intel_syncobj.c b/src/mesa/drivers/dri/intel/intel_syncobj.c
new file mode 100644
index 0000000000..1286fe929b
--- /dev/null
+++ b/src/mesa/drivers/dri/intel/intel_syncobj.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ *
+ */
+
+/** @file intel_syncobj.c
+ *
+ * Support for ARB_sync
+ *
+ * ARB_sync is implemented by flushing the current batchbuffer and keeping a
+ * reference on it. We can then check for completion or wait for compeltion
+ * using the normal buffer object mechanisms. This does mean that if an
+ * application is using many sync objects, it will emit small batchbuffers
+ * which may end up being a significant overhead. In other tests of removing
+ * gratuitous batchbuffer syncs in Mesa, it hasn't appeared to be a significant
+ * performance bottleneck, though.
+ */
+
+#include "main/simple_list.h"
+#include "main/imports.h"
+
+#include "intel_context.h"
+#include "intel_batchbuffer.h"
+#include "intel_reg.h"
+
+static struct gl_sync_object *
+intel_new_sync_object(GLcontext *ctx, GLuint id)
+{
+ struct intel_sync_object *sync;
+
+ sync = _mesa_calloc(sizeof(struct intel_sync_object));
+
+ return &sync->Base;
+}
+
+static void
+intel_delete_sync_object(GLcontext *ctx, struct gl_sync_object *s)
+{
+ struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+ drm_intel_bo_unreference(sync->bo);
+ _mesa_free(sync);
+}
+
+static void
+intel_fence_sync(GLcontext *ctx, struct gl_sync_object *s,
+ GLenum condition, GLbitfield flags)
+{
+ struct intel_context *intel = intel_context(ctx);
+ struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+ assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE);
+ intel_batchbuffer_emit_mi_flush(intel->batch);
+
+ sync->bo = intel->batch->buf;
+ drm_intel_bo_reference(sync->bo);
+
+ intelFlush(ctx);
+}
+
+/* We ignore the user-supplied timeout. This is weaselly -- we're allowed to
+ * round to an implementation-dependent accuracy, and right now our
+ * implementation "rounds" to the wait-forever value.
+ *
+ * The fix would be a new kernel function to do the GTT transition with a
+ * timeout.
+ */
+static void intel_client_wait_sync(GLcontext *ctx, struct gl_sync_object *s,
+ GLbitfield flags, GLuint64 timeout)
+{
+ struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+ if (sync->bo) {
+ drm_intel_bo_wait_rendering(sync->bo);
+ s->StatusFlag = 1;
+ drm_intel_bo_unreference(sync->bo);
+ sync->bo = NULL;
+ }
+}
+
+/* We have nothing to do for WaitSync. Our GL command stream is sequential,
+ * so given that the sync object has already flushed the batchbuffer,
+ * any batchbuffers coming after this waitsync will naturally not occur until
+ * the previous one is done.
+ */
+static void intel_server_wait_sync(GLcontext *ctx, struct gl_sync_object *s,
+ GLbitfield flags, GLuint64 timeout)
+{
+}
+
+static void intel_check_sync(GLcontext *ctx, struct gl_sync_object *s)
+{
+ struct intel_sync_object *sync = (struct intel_sync_object *)s;
+
+ if (sync->bo && drm_intel_bo_busy(sync->bo)) {
+ drm_intel_bo_unreference(sync->bo);
+ sync->bo = NULL;
+ s->StatusFlag = 1;
+ }
+}
+
+void intel_init_syncobj_functions(struct dd_function_table *functions)
+{
+ functions->NewSyncObject = intel_new_sync_object;
+ functions->DeleteSyncObject = intel_delete_sync_object;
+ functions->FenceSync = intel_fence_sync;
+ functions->CheckSync = intel_check_sync;
+ functions->ClientWaitSync = intel_client_wait_sync;
+ functions->ServerWaitSync = intel_server_wait_sync;
+}
diff --git a/src/mesa/drivers/dri/intel/intel_tex_copy.c b/src/mesa/drivers/dri/intel/intel_tex_copy.c
index 028b49c14d..ac557a9200 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 c5f5220837..66201b1f46 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_image.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_image.c
@@ -1,15 +1,11 @@
-#include <stdlib.h>
-#include <stdio.h>
-
#include "main/glheader.h"
#include "main/macros.h"
#include "main/mtypes.h"
#include "main/enums.h"
-#include "main/colortab.h"
+#include "main/bufferobj.h"
#include "main/convolve.h"
#include "main/context.h"
-#include "main/simple_list.h"
#include "main/texcompress.h"
#include "main/texformat.h"
#include "main/texgetimage.h"
@@ -206,7 +202,7 @@ try_pbo_upload(struct intel_context *intel,
GLuint src_offset, src_stride;
GLuint dst_offset, dst_stride;
- if (unpack->BufferObj->Name == 0 ||
+ if (!_mesa_is_bufferobj(unpack->BufferObj) ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
DBG("%s: failure 1\n", __FUNCTION__);
@@ -264,7 +260,7 @@ try_pbo_zcopy(struct intel_context *intel,
GLuint src_offset, src_stride;
GLuint dst_offset, dst_stride;
- if (unpack->BufferObj->Name == 0 ||
+ if (!_mesa_is_bufferobj(unpack->BufferObj) ||
intel->ctx._ImageTransferState ||
unpack->SkipPixels || unpack->SkipRows) {
DBG("%s: failure 1\n", __FUNCTION__);
@@ -427,7 +423,7 @@ intelTexImage(GLcontext * ctx,
*/
if (dims <= 2 &&
intelImage->mt &&
- unpack->BufferObj->Name != 0 &&
+ _mesa_is_bufferobj(unpack->BufferObj) &&
check_pbo_format(internalFormat, format,
type, intelImage->base.TexFormat)) {
@@ -550,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 1f27131dac..751ec2c98c 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_subimage.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_subimage.c
@@ -44,10 +44,12 @@ intelTexSubimage(GLcontext * ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint width, GLint height, GLint depth,
+ GLsizei imageSize,
GLenum format, GLenum type, const void *pixels,
const struct gl_pixelstore_attrib *packing,
struct gl_texture_object *texObj,
- struct gl_texture_image *texImage)
+ struct gl_texture_image *texImage,
+ GLboolean compressed)
{
struct intel_context *intel = intel_context(ctx);
struct intel_texture_image *intelImage = intel_texture_image(texImage);
@@ -59,9 +61,14 @@ intelTexSubimage(GLcontext * ctx,
intelFlush(ctx);
- pixels =
- _mesa_validate_pbo_teximage(ctx, dims, width, height, depth, format,
- type, pixels, packing, "glTexSubImage2D");
+ if (compressed)
+ pixels = _mesa_validate_pbo_compressed_teximage(ctx, imageSize,
+ pixels, packing,
+ "glCompressedTexImage");
+ else
+ pixels = _mesa_validate_pbo_teximage(ctx, dims, width, height, depth,
+ format, type, pixels, packing,
+ "glTexSubImage");
if (!pixels)
return;
@@ -90,15 +97,28 @@ intelTexSubimage(GLcontext * ctx,
assert(dstRowStride);
- if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
- texImage->TexFormat,
- texImage->Data,
- xoffset, yoffset, zoffset,
- dstRowStride,
- texImage->ImageOffsets,
- width, height, depth,
- format, type, pixels, packing)) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+ if (compressed) {
+ if (intelImage->mt) {
+ struct intel_region *dst = intelImage->mt->region;
+
+ _mesa_copy_rect(texImage->Data, dst->cpp, dst->pitch,
+ xoffset, yoffset / 4,
+ (width + 3) & ~3, (height + 3) / 4,
+ pixels, (width + 3) & ~3, 0, 0);
+ } else
+ memcpy(texImage->Data, pixels, imageSize);
+ }
+ else {
+ if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
+ texImage->TexFormat,
+ texImage->Data,
+ xoffset, yoffset, zoffset,
+ dstRowStride,
+ texImage->ImageOffsets,
+ width, height, depth,
+ format, type, pixels, packing)) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "intelTexSubImage");
+ }
}
_mesa_unmap_teximage_pbo(ctx, packing);
@@ -109,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);
- }
}
@@ -132,8 +147,8 @@ intelTexSubImage3D(GLcontext * ctx,
intelTexSubimage(ctx, 3,
target, level,
xoffset, yoffset, zoffset,
- width, height, depth,
- format, type, pixels, packing, texObj, texImage);
+ width, height, depth, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
@@ -152,8 +167,8 @@ intelTexSubImage2D(GLcontext * ctx,
intelTexSubimage(ctx, 2,
target, level,
xoffset, yoffset, 0,
- width, height, 1,
- format, type, pixels, packing, texObj, texImage);
+ width, height, 1, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
@@ -172,8 +187,8 @@ intelTexSubImage1D(GLcontext * ctx,
intelTexSubimage(ctx, 1,
target, level,
xoffset, 0, 0,
- width, 1, 1,
- format, type, pixels, packing, texObj, texImage);
+ width, 1, 1, 0,
+ format, type, pixels, packing, texObj, texImage, GL_FALSE);
}
static void
@@ -187,8 +202,11 @@ intelCompressedTexSubImage2D(GLcontext * ctx,
struct gl_texture_object *texObj,
struct gl_texture_image *texImage)
{
- fprintf(stderr, "stubbed CompressedTexSubImage2D: %dx%d@%dx%d\n",
- width, height, xoffset, yoffset);
+ intelTexSubimage(ctx, 2,
+ target, level,
+ xoffset, yoffset, 0,
+ width, height, 1, imageSize,
+ format, 0, pixels, &ctx->Unpack, texObj, texImage, GL_TRUE);
}
diff --git a/src/mesa/drivers/dri/r200/Makefile b/src/mesa/drivers/dri/r200/Makefile
index e81a1b38ac..fbce70c37b 100644
--- a/src/mesa/drivers/dri/r200/Makefile
+++ b/src/mesa/drivers/dri/r200/Makefile
@@ -18,16 +18,18 @@ CS_SOURCES = radeon_cs_space_drm.c
endif
RADEON_COMMON_SOURCES = \
- radeon_texture.c \
+ radeon_bo_legacy.c \
radeon_common_context.c \
radeon_common.c \
+ radeon_cs_legacy.c \
radeon_dma.c \
+ radeon_debug.c \
+ radeon_fbo.c \
radeon_lock.c \
- radeon_bo_legacy.c \
- radeon_cs_legacy.c \
radeon_mipmap_tree.c \
+ radeon_queryobj.c \
radeon_span.c \
- radeon_fbo.c
+ radeon_texture.c
DRIVER_SOURCES = r200_context.c \
@@ -53,7 +55,7 @@ C_SOURCES = $(COMMON_SOURCES) $(DRIVER_SOURCES)
X86_SOURCES =
-DRIVER_DEFINES = -DRADEON_COMMON=1 -DRADEON_COMMON_FOR_R200
+DRIVER_DEFINES = -DRADEON_R200 -Wall
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/r200/r200_cmdbuf.c b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
index d49f4fabe7..1d1bea6f5f 100644
--- a/src/mesa/drivers/dri/r200/r200_cmdbuf.c
+++ b/src/mesa/drivers/dri/r200/r200_cmdbuf.c
@@ -49,6 +49,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* The state atoms will be emitted in the order they appear in the atom list,
* so this step is important.
*/
+#define insert_at_tail_if(atom_list, atom) \
+ do { \
+ struct radeon_state_atom* __atom = (atom); \
+ if (__atom->check) \
+ insert_at_tail((atom_list), __atom); \
+ } while(0)
+
void r200SetUpAtomList( r200ContextPtr rmesa )
{
int i, mtu;
@@ -58,80 +65,52 @@ void r200SetUpAtomList( r200ContextPtr rmesa )
make_empty_list(&rmesa->radeon.hw.atomlist);
rmesa->radeon.hw.atomlist.name = "atom-list";
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ctx );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.set );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.lin );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msk );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpt );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vtx );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vap );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vte );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msc );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.cst );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.zbs );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcl );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.msl );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcg );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.grd );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.fog );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tam );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tf );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.atf );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ctx );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.set );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lin );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msk );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpt );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vtx );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vap );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vte );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msc );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cst );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.zbs );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcl );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.msl );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tcg );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.grd );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.fog );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tam );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tf );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.atf );
for (i = 0; i < mtu; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.tex[i] );
for (i = 0; i < mtu; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.cube[i] );
for (i = 0; i < 6; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pix[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[0] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.afs[1] );
for (i = 0; i < 8; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.lit[i] );
for (i = 0; i < 3 + mtu; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.eye );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.glt );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mat[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.eye );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.glt );
for (i = 0; i < 2; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.mtl[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.mtl[i] );
for (i = 0; i < 6; ++i)
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.spr );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.ptp );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.prf );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.pvs );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[0] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[1] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[0] );
- insert_at_tail( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[1] );
-}
-
-void r200EmitScissor(r200ContextPtr rmesa)
-{
- BATCH_LOCALS(&rmesa->radeon);
- if (!rmesa->radeon.radeonScreen->kernel_mm) {
- return;
- }
- if (rmesa->radeon.state.scissor.enabled) {
- BEGIN_BATCH(8);
- OUT_BATCH(CP_PACKET0(R200_RE_CNTL, 0));
- OUT_BATCH(R200_SCISSOR_ENABLE | rmesa->hw.set.cmd[SET_RE_CNTL]);
- OUT_BATCH(CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0));
- OUT_BATCH(R200_SCISSOR_ENABLE_0);
- OUT_BATCH(CP_PACKET0(R200_RE_SCISSOR_TL_0, 0));
- OUT_BATCH((rmesa->radeon.state.scissor.rect.y1 << 16) |
- rmesa->radeon.state.scissor.rect.x1);
- OUT_BATCH(CP_PACKET0(R200_RE_SCISSOR_BR_0, 0));
- OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2 - 1) << 16) |
- (rmesa->radeon.state.scissor.rect.x2 - 1));
- END_BATCH();
- } else {
- BEGIN_BATCH(4);
- OUT_BATCH(CP_PACKET0(R200_RE_CNTL, 0));
- OUT_BATCH(rmesa->hw.set.cmd[SET_RE_CNTL] & ~R200_SCISSOR_ENABLE);
- OUT_BATCH(CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0));
- OUT_BATCH(0);
- END_BATCH();
- }
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ucp[i] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.spr );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.ptp );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.prf );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.pvs );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[0] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpp[1] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[0] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.vpi[1] );
+ insert_at_tail_if( &rmesa->radeon.hw.atomlist, &rmesa->hw.sci );
}
/* Fire a section of the retained (indexed_verts) buffer as a regular
@@ -147,10 +126,9 @@ void r200EmitVbufPrim( r200ContextPtr rmesa,
radeonEmitState(&rmesa->radeon);
- if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
- fprintf(stderr, "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__,
- rmesa->store.cmd_used/4, primitive, vertex_nr);
- r200EmitScissor(rmesa);
+ radeon_print(RADEON_RENDER|RADEON_SWRENDER,RADEON_VERBOSE,
+ "%s cmd_used/4: %d prim %x nr %d\n", __FUNCTION__,
+ rmesa->store.cmd_used/4, primitive, vertex_nr);
BEGIN_BATCH(3);
OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_VBUF_2, 0);
@@ -164,7 +142,6 @@ static void r200FireEB(r200ContextPtr rmesa, int vertex_count, int type)
BATCH_LOCALS(&rmesa->radeon);
if (vertex_count > 0) {
- r200EmitScissor(rmesa);
BEGIN_BATCH(8+2);
OUT_BATCH_PACKET3_CLIP(R200_CP_CMD_3D_DRAW_INDX_2, 0);
OUT_BATCH(R200_VF_PRIM_WALK_IND |
@@ -198,8 +175,7 @@ void r200FlushElts(GLcontext *ctx)
r200ContextPtr rmesa = R200_CONTEXT(ctx);
int nr, elt_used = rmesa->tcl.elt_used;
- if (R200_DEBUG & (DEBUG_IOCTL|DEBUG_PRIMS))
- fprintf(stderr, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x %d\n", __FUNCTION__, rmesa->tcl.hw_primitive, elt_used);
assert( rmesa->radeon.dma.flush == r200FlushElts );
rmesa->radeon.dma.flush = NULL;
@@ -213,8 +189,11 @@ void r200FlushElts(GLcontext *ctx)
radeon_bo_unref(rmesa->radeon.tcl.elt_dma_bo);
rmesa->radeon.tcl.elt_dma_bo = NULL;
- if (R200_DEBUG & DEBUG_SYNC) {
- fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
+ if (R200_ELT_BUF_SZ > elt_used)
+ radeonReturnDmaRegion(&rmesa->radeon, R200_ELT_BUF_SZ - elt_used);
+
+ if (radeon_is_debug_enabled(RADEON_SYNC, RADEON_CRITICAL)) {
+ radeon_print(RADEON_SYNC, RADEON_NORMAL, "%s: Syncing\n", __FUNCTION__);
radeonFinish( rmesa->radeon.glCtx );
}
}
@@ -225,41 +204,20 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
GLuint min_nr )
{
GLushort *retval;
- int ret;
- if (R200_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
assert((primitive & R200_VF_PRIM_WALK_IND));
radeonEmitState(&rmesa->radeon);
-#ifdef RADEON_DEBUG_BO
- rmesa->radeon.tcl.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
- 0, R200_ELT_BUF_SZ, 4,
- RADEON_GEM_DOMAIN_GTT, 0, "ELT");
-#else
- rmesa->radeon.tcl.elt_dma_bo = radeon_bo_open(rmesa->radeon.radeonScreen->bom,
- 0, R200_ELT_BUF_SZ, 4,
- RADEON_GEM_DOMAIN_GTT, 0);
-#endif
- rmesa->radeon.tcl.elt_dma_offset = 0;
+ radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
+ &rmesa->radeon.tcl.elt_dma_offset, R200_ELT_BUF_SZ, 4);
rmesa->tcl.elt_used = min_nr * 2;
- ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.tcl.elt_dma_bo,
- RADEON_GEM_DOMAIN_GTT, 0);
- if (ret) {
- fprintf(stderr,"failure to revalidate BOs - badness\n");
- }
-
radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
retval = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
-
- if (R200_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s: header prim %x \n",
- __FUNCTION__, primitive);
-
assert(!rmesa->radeon.dma.flush);
rmesa->radeon.glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
rmesa->radeon.dma.flush = r200FlushElts;
@@ -267,7 +225,17 @@ GLushort *r200AllocEltsOpenEnded( r200ContextPtr rmesa,
return retval;
}
+void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count)
+{
+ BATCH_LOCALS(&rmesa->radeon);
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ OUT_BATCH(CP_PACKET0(R200_SE_VF_MAX_VTX_INDX, 0));
+ OUT_BATCH(count);
+ END_BATCH();
+ }
+}
void r200EmitVertexAOS( r200ContextPtr rmesa,
GLuint vertex_size,
@@ -276,8 +244,7 @@ void r200EmitVertexAOS( r200ContextPtr rmesa,
{
BATCH_LOCALS(&rmesa->radeon);
- if (R200_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
- fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s: vertex_size 0x%x offset 0x%x \n",
__FUNCTION__, vertex_size, offset);
@@ -296,9 +263,9 @@ void r200EmitAOS(r200ContextPtr rmesa, GLuint nr, GLuint offset)
int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
- offset);
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE,
+ "%s: nr=%d, ofs=0x%08x\n",
+ __FUNCTION__, nr, offset);
BEGIN_BATCH(sz+2+ (nr*2));
OUT_BATCH_PACKET3(R200_CP_CMD_3D_LOAD_VBPNTR, sz - 1);
diff --git a/src/mesa/drivers/dri/r200/r200_context.c b/src/mesa/drivers/dri/r200/r200_context.c
index 9a92a32079..3ddb5bf7d6 100644
--- a/src/mesa/drivers/dri/r200/r200_context.c
+++ b/src/mesa/drivers/dri/r200/r200_context.c
@@ -60,9 +60,11 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tcl.h"
#include "r200_maos.h"
#include "r200_vertprog.h"
+#include "radeon_queryobj.h"
#include "radeon_span.h"
+#define need_GL_ARB_occlusion_query
#define need_GL_ARB_vertex_program
#define need_GL_ATI_fragment_shader
#define need_GL_EXT_blend_minmax
@@ -116,6 +118,7 @@ static const GLubyte *r200GetString( GLcontext *ctx, GLenum name )
const struct dri_extension card_extensions[] =
{
{ "GL_ARB_multitexture", NULL },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_env_add", NULL },
{ "GL_ARB_texture_env_combine", NULL },
@@ -218,26 +221,6 @@ static void r200InitDriverFuncs( struct dd_function_table *functions )
functions->GetString = r200GetString;
}
-static const struct dri_debug_control debug_control[] =
-{
- { "fall", DEBUG_FALLBACKS },
- { "tex", DEBUG_TEXTURE },
- { "ioctl", DEBUG_IOCTL },
- { "prim", DEBUG_PRIMS },
- { "vert", DEBUG_VERTS },
- { "state", DEBUG_STATE },
- { "code", DEBUG_CODEGEN },
- { "vfmt", DEBUG_VFMT },
- { "vtxf", DEBUG_VFMT },
- { "verb", DEBUG_VERBOSE },
- { "dri", DEBUG_DRI },
- { "dma", DEBUG_DMA },
- { "san", DEBUG_SANITY },
- { "sync", DEBUG_SYNC },
- { "pix", DEBUG_PIXEL },
- { "mem", DEBUG_MEMORY },
- { NULL, 0 }
-};
static void r200_get_lock(radeonContextPtr radeon)
{
@@ -262,6 +245,19 @@ static void r200_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes
{
}
+static void r200_emit_query_finish(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ END_BATCH();
+ query->curr_offset += sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
static void r200_init_vtbl(radeonContextPtr radeon)
{
@@ -270,6 +266,8 @@ static void r200_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.emit_cs_header = r200_vtbl_emit_cs_header;
radeon->vtbl.swtcl_flush = r200_swtcl_flush;
radeon->vtbl.fallback = r200Fallback;
+ radeon->vtbl.update_scissor = r200_vtbl_update_scissor;
+ radeon->vtbl.emit_query_finish = r200_emit_query_finish;
}
@@ -309,7 +307,8 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
rmesa->radeon.initialMaxAnisotropy = driQueryOptionf(&rmesa->radeon.optionCache,
"def_max_anisotropy");
- if ( driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
+ if ( sPriv->drm_version.major == 1
+ && driQueryOptionb( &rmesa->radeon.optionCache, "hyperz" ) ) {
if ( sPriv->drm_version.minor < 13 )
fprintf( stderr, "DRM version 1.%d too old to support HyperZ, "
"disabling.\n", sPriv->drm_version.minor );
@@ -326,9 +325,10 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
_mesa_init_driver_functions(&functions);
r200InitDriverFuncs(&functions);
r200InitIoctlFuncs(&functions);
- r200InitStateFuncs(&functions);
+ r200InitStateFuncs(&functions, screen->kernel_mm);
r200InitTextureFuncs(&functions);
r200InitShaderFuncs(&functions);
+ radeonInitQueryObjFunctions(&functions);
if (!radeonInitContext(&rmesa->radeon, &functions,
glVisual, driContextPriv,
@@ -457,6 +457,9 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
driInitSingleExtension( ctx, ATI_fs_extension );
if (rmesa->radeon.radeonScreen->drmSupportsPointSprites)
driInitExtensions( ctx, point_extensions, GL_FALSE );
+
+ if (!rmesa->radeon.radeonScreen->kernel_mm)
+ _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
#if 0
r200InitDriverFuncs( ctx );
r200InitIoctlFuncs( ctx );
@@ -475,13 +478,6 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
rmesa->prefer_gart_client_texturing =
(getenv("R200_GART_CLIENT_TEXTURES") != 0);
-#if DO_DEBUG
- R200_DEBUG = driParseDebugString( getenv( "R200_DEBUG" ),
- debug_control );
- R200_DEBUG |= driParseDebugString( getenv( "RADEON_DEBUG" ),
- debug_control );
-#endif
-
tcl_mode = driQueryOptioni(&rmesa->radeon.optionCache, "tcl_mode");
if (driQueryOptionb(&rmesa->radeon.optionCache, "no_rast")) {
fprintf(stderr, "disabling 3D acceleration\n");
@@ -500,3 +496,15 @@ GLboolean r200CreateContext( const __GLcontextModes *glVisual,
}
+void r200DestroyContext( __DRIcontextPrivate *driContextPriv )
+{
+ int i;
+ r200ContextPtr rmesa = (r200ContextPtr)driContextPriv->driverPrivate;
+ if (rmesa)
+ {
+ for ( i = 0 ; i < R200_MAX_TEXTURE_UNITS ; i++ ) {
+ _math_matrix_dtr( &rmesa->TexGenMatrix[i] );
+ }
+ }
+ radeonDestroyContext(driContextPriv);
+}
diff --git a/src/mesa/drivers/dri/r200/r200_context.h b/src/mesa/drivers/dri/r200/r200_context.h
index 6267293817..246f98c6dc 100644
--- a/src/mesa/drivers/dri/r200/r200_context.h
+++ b/src/mesa/drivers/dri/r200/r200_context.h
@@ -467,6 +467,23 @@ struct r200_texture_state {
#define PRF_STATE_SIZE 3
+#define SCI_CMD_0 0
+#define SCI_RE_AUX 1
+#define SCI_CMD_1 2
+#define SCI_XY_1 3
+#define SCI_CMD_2 4
+#define SCI_XY_2 5
+#define SCI_STATE_SIZE 6
+
+#define R200_QUERYOBJ_CMD_0 0
+#define R200_QUERYOBJ_DATA_0 1
+#define R200_QUERYOBJ_CMDSIZE 2
+
+#define STP_CMD_0 0
+#define STP_DATA_0 1
+#define STP_CMD_1 2
+#define STP_STATE_SIZE 35
+
struct r200_hw_state {
/* Hardware state, stored as cmdbuf commands:
* -- Need to doublebuffer for
@@ -475,6 +492,7 @@ struct r200_hw_state {
*/
struct radeon_state_atom ctx;
struct radeon_state_atom set;
+ struct radeon_state_atom sci;
struct radeon_state_atom vte;
struct radeon_state_atom lin;
struct radeon_state_atom msk;
@@ -508,12 +526,12 @@ struct r200_hw_state {
struct radeon_state_atom atf;
struct radeon_state_atom spr;
struct radeon_state_atom ptp;
+ struct radeon_state_atom stp;
};
struct r200_state {
/* Derived state for internal purposes:
*/
- struct radeon_stipple_state stipple;
struct r200_texture_state texture;
GLuint envneeded;
};
@@ -526,8 +544,6 @@ struct r200_state {
struct r200_tcl_info {
GLuint hw_primitive;
- GLuint *Elts;
-
int elt_used;
};
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.c b/src/mesa/drivers/dri/r200/r200_ioctl.c
index 4dbda39eb9..b238adb972 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.c
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.c
@@ -190,7 +190,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
GLuint color_mask = 0;
GLuint orig_mask = mask;
- if ( R200_DEBUG & DEBUG_IOCTL ) {
+ if ( R200_DEBUG & RADEON_IOCTL ) {
if (rmesa->radeon.sarea)
fprintf( stderr, "r200Clear %x %d\n", mask, rmesa->radeon.sarea->pfCurrentPage);
else
@@ -229,7 +229,7 @@ static void r200Clear( GLcontext *ctx, GLbitfield mask )
}
if ( mask ) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
_swrast_Clear( ctx, mask );
}
@@ -274,7 +274,7 @@ void *r200AllocateMemoryMESA(__DRIscreen *screen, GLsizei size,
drm_radeon_mem_alloc_t alloc;
int ret;
- if (R200_DEBUG & DEBUG_IOCTL)
+ if (R200_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s sz %d %f/%f/%f\n", __FUNCTION__, size, readfreq,
writefreq, priority);
@@ -314,7 +314,7 @@ void r200FreeMemoryMESA(__DRIscreen *screen, GLvoid *pointer)
drm_radeon_mem_free_t memfree;
int ret;
- if (R200_DEBUG & DEBUG_IOCTL)
+ if (R200_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s %p\n", __FUNCTION__, pointer);
if (!ctx || !(rmesa = R200_CONTEXT(ctx)) || !rmesa->radeon.radeonScreen->gartTextures.map) {
@@ -370,7 +370,7 @@ GLboolean r200IsGartMemory( r200ContextPtr rmesa, const GLvoid *pointer,
offset >= 0 &&
offset + size < rmesa->radeon.radeonScreen->gartTextures.size);
- if (R200_DEBUG & DEBUG_IOCTL)
+ if (R200_DEBUG & RADEON_IOCTL)
fprintf(stderr, "r200IsGartMemory( %p ) : %d\n", pointer, valid );
return valid;
diff --git a/src/mesa/drivers/dri/r200/r200_ioctl.h b/src/mesa/drivers/dri/r200/r200_ioctl.h
index 2a4b8a11f4..8d51aefa04 100644
--- a/src/mesa/drivers/dri/r200/r200_ioctl.h
+++ b/src/mesa/drivers/dri/r200/r200_ioctl.h
@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "drm.h"
#include "radeon_drm.h"
+extern void r200EmitMaxVtxIndex(r200ContextPtr rmesa, int count);
extern void r200EmitVertexAOS( r200ContextPtr rmesa,
GLuint vertex_size,
struct radeon_bo *bo,
@@ -98,6 +99,16 @@ do { \
rmesa->radeon.hw.is_dirty = GL_TRUE; \
} while (0)
+#define R200_SET_STATE( rmesa, ATOM, index, newvalue ) \
+ do { \
+ uint32_t __index = (index); \
+ uint32_t __dword = (newvalue); \
+ if (__dword != (rmesa)->hw.ATOM.cmd[__index]) { \
+ R200_STATECHANGE( (rmesa), ATOM ); \
+ (rmesa)->hw.ATOM.cmd[__index] = __dword; \
+ } \
+ } while(0)
+
#define R200_DB_STATE( ATOM ) \
memcpy( rmesa->hw.ATOM.lastcmd, rmesa->hw.ATOM.cmd, \
rmesa->hw.ATOM.cmd_size * 4)
@@ -125,10 +136,12 @@ static INLINE int R200_DB_STATECHANGE(
* are available, you will also be adding an rmesa->state.max_state_size because
* r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
*/
-#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
-#define VERT_AOS_BUFSZ (5 * sizeof(int))
+#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2) + nr*2))
+#define VERT_AOS_BUFSZ (5)
#define ELTS_BUFSZ(nr) (12 + nr * 2)
-#define VBUF_BUFSZ (3 * sizeof(int))
+#define VBUF_BUFSZ (3)
+#define SCISSOR_BUFSZ (8)
+#define INDEX_BUFSZ (8+2)
static inline uint32_t cmdpacket3(int cmd_type)
{
diff --git a/src/mesa/drivers/dri/r200/r200_pixel.c b/src/mesa/drivers/dri/r200/r200_pixel.c
index 654f2c6ae9..95773871e0 100644
--- a/src/mesa/drivers/dri/r200/r200_pixel.c
+++ b/src/mesa/drivers/dri/r200/r200_pixel.c
@@ -53,14 +53,14 @@ check_color( const GLcontext *ctx, GLenum type, GLenum format,
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint cpp = rmesa->radeon.radeonScreen->cpp;
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if ( (pitch & 63) ||
ctx->_ImageTransferState ||
packing->SwapBytes ||
packing->LsbFirst) {
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: failed 1\n", __FUNCTION__);
return GL_FALSE;
}
@@ -68,12 +68,12 @@ check_color( const GLcontext *ctx, GLenum type, GLenum format,
if ( type == GL_UNSIGNED_INT_8_8_8_8_REV &&
cpp == 4 &&
format == GL_BGRA ) {
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: passed 2\n", __FUNCTION__);
return GL_TRUE;
}
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: failed\n", __FUNCTION__);
return GL_FALSE;
@@ -101,7 +101,7 @@ check_color_per_fragment_ops( const GLcontext *ctx )
}
-
+#if 0
static GLboolean
clip_pixelrect( const GLcontext *ctx,
const GLframebuffer *buffer,
@@ -142,6 +142,7 @@ clip_pixelrect( const GLcontext *ctx,
return GL_TRUE;
}
+#endif
static GLboolean
r200TryReadPixels( GLcontext *ctx,
@@ -150,22 +151,22 @@ r200TryReadPixels( GLcontext *ctx,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
+ return GL_FALSE;
+#if 0
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLint pitch = pack->RowLength ? pack->RowLength : width;
GLint blit_format;
GLuint cpp = rmesa->radeon.radeonScreen->cpp;
GLint size = width * height * cpp;
- return GL_FALSE;
-#if 0
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* Only accelerate reading to GART buffers.
*/
if ( !r200IsGartMemory(rmesa, pixels,
pitch * height * rmesa->radeon.radeonScreen->cpp ) ) {
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: dest not GART\n", __FUNCTION__);
}
@@ -173,7 +174,7 @@ r200TryReadPixels( GLcontext *ctx,
* blitter:
*/
if (!pack->Invert) {
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: MESA_PACK_INVERT not set\n", __FUNCTION__);
return GL_FALSE;
}
@@ -206,7 +207,7 @@ r200TryReadPixels( GLcontext *ctx,
if (!clip_pixelrect(ctx, ctx->ReadBuffer, &x, &y, &width, &height,
&size)) {
UNLOCK_HARDWARE( &rmesa->radeon );
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s totally clipped -- nothing to do\n",
__FUNCTION__);
return GL_TRUE;
@@ -231,7 +232,7 @@ r200TryReadPixels( GLcontext *ctx,
y += dPriv->y;
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "readpixel blit src_pitch %d dst_pitch %d\n",
src_pitch, dst_pitch);
@@ -274,7 +275,7 @@ r200ReadPixels( GLcontext *ctx,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!r200TryReadPixels( ctx, x, y, width, height, format, type, pack,
@@ -292,6 +293,10 @@ static void do_draw_pix( GLcontext *ctx,
const void *pixels,
GLuint planemask)
{
+ if (R200_DEBUG & RADEON_PIXEL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+#if 0
r200ContextPtr rmesa = R200_CONTEXT(ctx);
__DRIdrawablePrivate *dPriv = radeon_get_drawable(&rmesa->radeon);
drm_clip_rect_t *box = dPriv->pClipRects;
@@ -304,9 +309,6 @@ static void do_draw_pix( GLcontext *ctx,
int src_offset = r200GartOffsetFromVirtual( rmesa, pixels );
int src_pitch = pitch * rmesa->radeon.radeonScreen->cpp;
- if (R200_DEBUG & DEBUG_PIXEL)
- fprintf(stderr, "%s\n", __FUNCTION__);
-#if 0
switch ( rmesa->radeon.radeonScreen->cpp ) {
case 2:
blit_format = R200_CP_COLOR_FORMAT_RGB565;
@@ -386,7 +388,7 @@ r200TryDrawPixels( GLcontext *ctx,
GLuint cpp = rmesa->radeon.radeonScreen->cpp;
GLint size = height * pitch * cpp;
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
/* check that we're drawing to exactly one color buffer */
@@ -412,7 +414,7 @@ r200TryDrawPixels( GLcontext *ctx,
/* Can't do conversions on GART reads/draws.
*/
if ( !r200IsGartMemory( rmesa, pixels, size ) ) {
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s: not GART memory\n", __FUNCTION__);
return GL_FALSE;
}
@@ -455,7 +457,7 @@ r200DrawPixels( GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
- if (R200_DEBUG & DEBUG_PIXEL)
+ if (R200_DEBUG & RADEON_PIXEL)
fprintf(stderr, "%s\n", __FUNCTION__);
if (!r200TryDrawPixels( ctx, x, y, width, height, format, type,
diff --git a/src/mesa/drivers/dri/r200/r200_sanity.c b/src/mesa/drivers/dri/r200/r200_sanity.c
index 36530c224e..1241a926ba 100644
--- a/src/mesa/drivers/dri/r200/r200_sanity.c
+++ b/src/mesa/drivers/dri/r200/r200_sanity.c
@@ -48,11 +48,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MORE_VERBOSE 1
#if MORE_VERBOSE
-#define VERBOSE (R200_DEBUG & DEBUG_VERBOSE)
+#define VERBOSE (R200_DEBUG & RADEON_VERBOSE)
#define NORMAL (1)
#else
#define VERBOSE 0
-#define NORMAL (R200_DEBUG & DEBUG_VERBOSE)
+#define NORMAL (R200_DEBUG & RADEON_VERBOSE)
#endif
diff --git a/src/mesa/drivers/dri/r200/r200_state.c b/src/mesa/drivers/dri/r200/r200_state.c
index 5a6fd20d8c..76852e315c 100644
--- a/src/mesa/drivers/dri/r200/r200_state.c
+++ b/src/mesa/drivers/dri/r200/r200_state.c
@@ -764,31 +764,6 @@ static void r200PolygonOffset( GLcontext *ctx,
rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
}
-static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask )
-{
- r200ContextPtr rmesa = R200_CONTEXT(ctx);
- GLuint i;
- drm_radeon_stipple_t stipple;
-
- /* Must flip pattern upside down.
- */
- for ( i = 0 ; i < 32 ; i++ ) {
- rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
- }
-
- /* TODO: push this into cmd mechanism
- */
- radeon_firevertices(&rmesa->radeon);
- LOCK_HARDWARE( &rmesa->radeon );
-
- /* FIXME: Use window x,y offsets into stipple RAM.
- */
- stipple.mask = rmesa->state.stipple.mask;
- drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
- &stipple, sizeof(stipple) );
- UNLOCK_HARDWARE( &rmesa->radeon );
-}
-
static void r200PolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
@@ -1053,7 +1028,7 @@ void r200UpdateMaterial( GLcontext *ctx )
if (ctx->Light.ColorMaterialEnabled)
mask &= ~ctx->Light.ColorMaterialBitmask;
- if (R200_DEBUG & DEBUG_STATE)
+ if (R200_DEBUG & RADEON_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
if (mask & MAT_BIT_FRONT_EMISSION) {
@@ -1650,6 +1625,30 @@ void r200UpdateWindow( GLcontext *ctx )
rmesa->hw.vpt.cmd[VPT_SE_VPORT_ZOFFSET] = tz.ui32;
}
+void r200_vtbl_update_scissor( GLcontext *ctx )
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ unsigned x1, y1, x2, y2;
+ struct radeon_renderbuffer *rrb;
+
+ R200_SET_STATE(r200, set, SET_RE_CNTL, R200_SCISSOR_ENABLE | r200->hw.set.cmd[SET_RE_CNTL]);
+
+ if (r200->radeon.state.scissor.enabled) {
+ x1 = r200->radeon.state.scissor.rect.x1;
+ y1 = r200->radeon.state.scissor.rect.y1;
+ x2 = r200->radeon.state.scissor.rect.x2;
+ y2 = r200->radeon.state.scissor.rect.y2;
+ } else {
+ rrb = radeon_get_colorbuffer(&r200->radeon);
+ x1 = 0;
+ y1 = 0;
+ x2 = rrb->base.Width - 1;
+ y2 = rrb->base.Height - 1;
+ }
+
+ R200_SET_STATE(r200, sci, SCI_XY_1, x1 | (y1 << 16));
+ R200_SET_STATE(r200, sci, SCI_XY_2, x2 | (y2 << 16));
+}
static void r200Viewport( GLcontext *ctx, GLint x, GLint y,
@@ -1791,7 +1790,7 @@ static void r200Enable( GLcontext *ctx, GLenum cap, GLboolean state )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLuint p, flag;
- if ( R200_DEBUG & DEBUG_STATE )
+ if ( R200_DEBUG & RADEON_STATE )
fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr( cap ),
state ? "GL_TRUE" : "GL_FALSE" );
@@ -2175,7 +2174,7 @@ void r200LightingSpaceChange( GLcontext *ctx )
r200ContextPtr rmesa = R200_CONTEXT(ctx);
GLboolean tmp;
- if (R200_DEBUG & DEBUG_STATE)
+ if (R200_DEBUG & RADEON_STATE)
fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
@@ -2191,7 +2190,7 @@ void r200LightingSpaceChange( GLcontext *ctx )
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0] &= ~R200_RESCALE_NORMALS;
}
- if (R200_DEBUG & DEBUG_STATE)
+ if (R200_DEBUG & RADEON_STATE)
fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL_0]);
}
@@ -2234,7 +2233,7 @@ static void update_texturematrix( GLcontext *ctx )
GLuint compsel = rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL];
int unit;
- if (R200_DEBUG & DEBUG_STATE)
+ if (R200_DEBUG & RADEON_STATE)
fprintf(stderr, "%s before COMPSEL: %x\n", __FUNCTION__,
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_COMPSEL]);
@@ -2289,8 +2288,11 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
+ struct radeon_dma_bo *dma_bo;
int i, ret;
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
radeon_cs_space_reset_bos(rmesa->radeon.cmdbuf.cs);
rrb = radeon_get_colorbuffer(&rmesa->radeon);
@@ -2323,9 +2325,12 @@ static GLboolean r200ValidateBuffers(GLcontext *ctx)
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
- if (ret)
- return GL_FALSE;
+ dma_bo = first_elem(&rmesa->radeon.dma.reserved);
+ {
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, dma_bo->bo, RADEON_GEM_DOMAIN_GTT, 0);
+ if (ret)
+ return GL_FALSE;
+ }
return GL_TRUE;
}
@@ -2461,9 +2466,24 @@ static void r200WrapRunPipeline( GLcontext *ctx )
}
+static void r200PolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ GLint i;
+
+ radeon_firevertices(&r200->radeon);
+
+ R200_STATECHANGE(r200, stp);
+
+ /* Must flip pattern upside down.
+ */
+ for ( i = 31 ; i >= 0; i--) {
+ r200->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
+ }
+}
/* Initialize the driver's state functions.
*/
-void r200InitStateFuncs( struct dd_function_table *functions )
+void r200InitStateFuncs( struct dd_function_table *functions, GLboolean dri2 )
{
functions->UpdateState = r200InvalidateState;
functions->LightingSpaceChange = r200LightingSpaceChange;
@@ -2497,7 +2517,10 @@ void r200InitStateFuncs( struct dd_function_table *functions )
functions->LogicOpcode = r200LogicOpCode;
functions->PolygonMode = r200PolygonMode;
functions->PolygonOffset = r200PolygonOffset;
- functions->PolygonStipple = r200PolygonStipple;
+ if (dri2)
+ functions->PolygonStipple = r200PolygonStipple;
+ else
+ functions->PolygonStipple = radeonPolygonStipplePreKMS;
functions->PointParameterfv = r200PointParameter;
functions->PointSize = r200PointSize;
functions->RenderMode = r200RenderMode;
diff --git a/src/mesa/drivers/dri/r200/r200_state.h b/src/mesa/drivers/dri/r200/r200_state.h
index 23cf8aea66..9c62f0a644 100644
--- a/src/mesa/drivers/dri/r200/r200_state.h
+++ b/src/mesa/drivers/dri/r200/r200_state.h
@@ -38,7 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_context.h"
extern void r200InitState( r200ContextPtr rmesa );
-extern void r200InitStateFuncs( struct dd_function_table *functions );
+extern void r200InitStateFuncs( struct dd_function_table *functions, GLboolean dri2 );
extern void r200InitTnlFuncs( GLcontext *ctx );
extern void r200UpdateMaterial( GLcontext *ctx );
@@ -49,6 +49,8 @@ extern void r200UpdateDrawBuffer(GLcontext *ctx);
extern GLboolean r200ValidateState( GLcontext *ctx );
+extern void r200_vtbl_update_scissor( GLcontext *ctx );
+
extern void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode );
#define FALLBACK( rmesa, bit, mode ) do { \
if ( 0 ) fprintf( stderr, "FALLBACK in %s: #%d=%d\n", \
diff --git a/src/mesa/drivers/dri/r200/r200_state_init.c b/src/mesa/drivers/dri/r200/r200_state_init.c
index bc871d9904..7697306d88 100644
--- a/src/mesa/drivers/dri/r200/r200_state_init.c
+++ b/src/mesa/drivers/dri/r200/r200_state_init.c
@@ -51,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_tcl.h"
#include "r200_tex.h"
#include "r200_swtcl.h"
+#include "radeon_queryobj.h"
#include "xmlpool.h"
@@ -226,57 +227,73 @@ static int cmdscl2( int offset, int stride, int count )
return h.i;
}
-#define CHECK( NM, FLAG ) \
+/**
+ * Check functions are used to check if state is active.
+ * If it is active check function returns maximum emit size.
+ */
+#define CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom) \
{ \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
(void) rmesa; \
- return (FLAG) ? atom->cmd_size : 0; \
+ return (FLAG) ? atom->cmd_size + (ADD) : 0; \
}
-#define TCL_CHECK( NM, FLAG ) \
+#define TCL_CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom) \
{ \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- return (!rmesa->radeon.TclFallback && !ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size : 0; \
+ return (!rmesa->radeon.TclFallback && !ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size + (ADD) : 0; \
}
-#define TCL_OR_VP_CHECK( NM, FLAG ) \
+#define TCL_OR_VP_CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \
{ \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size : 0; \
+ return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size + (ADD) : 0; \
}
-#define VP_CHECK( NM, FLAG ) \
+#define VP_CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \
{ \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
(void) atom; \
- return (!rmesa->radeon.TclFallback && ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size : 0; \
+ return (!rmesa->radeon.TclFallback && ctx->VertexProgram._Enabled && (FLAG)) ? atom->cmd_size + (ADD) : 0; \
}
-CHECK( always, GL_TRUE )
-CHECK( never, GL_FALSE )
-CHECK( tex_any, ctx->Texture._EnabledUnits )
-CHECK( tf, (ctx->Texture._EnabledUnits && !ctx->ATIFragmentShader._Enabled) );
-CHECK( tex_pair, (rmesa->state.texture.unit[atom->idx].unitneeded | rmesa->state.texture.unit[atom->idx & ~1].unitneeded) )
-CHECK( tex, rmesa->state.texture.unit[atom->idx].unitneeded )
-CHECK( pix_zero, !ctx->ATIFragmentShader._Enabled )
- CHECK( texenv, (rmesa->state.envneeded & (1 << (atom->idx)) && !ctx->ATIFragmentShader._Enabled) )
-CHECK( afs_pass1, (ctx->ATIFragmentShader._Enabled && (ctx->ATIFragmentShader.Current->NumPasses > 1)) )
-CHECK( afs, ctx->ATIFragmentShader._Enabled )
-CHECK( tex_cube, rmesa->state.texture.unit[atom->idx].unitneeded & TEXTURE_CUBE_BIT )
-TCL_CHECK( tcl_fog, ctx->Fog.Enabled )
-TCL_CHECK( tcl, GL_TRUE )
-TCL_CHECK( tcl_tex, rmesa->state.texture.unit[atom->idx].unitneeded )
-TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
-TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[atom->idx].Enabled )
-TCL_OR_VP_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << (atom->idx))) )
-TCL_OR_VP_CHECK( tcl_or_vp, GL_TRUE )
-VP_CHECK( tcl_vp, GL_TRUE )
-VP_CHECK( tcl_vp_size, ctx->VertexProgram.Current->Base.NumNativeInstructions > 64 )
-VP_CHECK( tcl_vpp_size, ctx->VertexProgram.Current->Base.NumNativeParameters > 96 )
+CHECK( always, GL_TRUE, 0 )
+CHECK( always_add4, GL_TRUE, 4 )
+CHECK( never, GL_FALSE, 0 )
+CHECK( tex_any, ctx->Texture._EnabledUnits, 0 )
+CHECK( tf, (ctx->Texture._EnabledUnits && !ctx->ATIFragmentShader._Enabled), 0 );
+CHECK( pix_zero, !ctx->ATIFragmentShader._Enabled, 0 )
+ CHECK( texenv, (rmesa->state.envneeded & (1 << (atom->idx)) && !ctx->ATIFragmentShader._Enabled), 0 )
+CHECK( afs_pass1, (ctx->ATIFragmentShader._Enabled && (ctx->ATIFragmentShader.Current->NumPasses > 1)), 0 )
+CHECK( afs, ctx->ATIFragmentShader._Enabled, 0 )
+CHECK( tex_cube, rmesa->state.texture.unit[atom->idx].unitneeded & TEXTURE_CUBE_BIT, 3 + 3*5 - CUBE_STATE_SIZE )
+CHECK( tex_cube_cs, rmesa->state.texture.unit[atom->idx].unitneeded & TEXTURE_CUBE_BIT, 2 + 4*5 - CUBE_STATE_SIZE )
+TCL_CHECK( tcl_fog, ctx->Fog.Enabled, 0 )
+TCL_CHECK( tcl_fog_add4, ctx->Fog.Enabled, 4 )
+TCL_CHECK( tcl, GL_TRUE, 0 )
+TCL_CHECK( tcl_add8, GL_TRUE, 8 )
+TCL_CHECK( tcl_add4, GL_TRUE, 4 )
+TCL_CHECK( tcl_tex, rmesa->state.texture.unit[atom->idx].unitneeded, 0 )
+TCL_CHECK( tcl_lighting, ctx->Light.Enabled, 0 )
+TCL_CHECK( tcl_light, ctx->Light.Enabled && ctx->Light.Light[atom->idx].Enabled, 0 )
+TCL_CHECK( tcl_tex_add4, rmesa->state.texture.unit[atom->idx].unitneeded, 4 )
+TCL_CHECK( tcl_lighting_add4, ctx->Light.Enabled, 4 )
+TCL_CHECK( tcl_lighting_add6, ctx->Light.Enabled, 6 )
+TCL_CHECK( tcl_light_add8, ctx->Light.Enabled && ctx->Light.Light[atom->idx].Enabled, 8 )
+TCL_OR_VP_CHECK( tcl_ucp, (ctx->Transform.ClipPlanesEnabled & (1 << (atom->idx))), 0 )
+TCL_OR_VP_CHECK( tcl_ucp_add4, (ctx->Transform.ClipPlanesEnabled & (1 << (atom->idx))), 4 )
+TCL_OR_VP_CHECK( tcl_or_vp, GL_TRUE, 0 )
+TCL_OR_VP_CHECK( tcl_or_vp_add2, GL_TRUE, 2 )
+VP_CHECK( tcl_vp, GL_TRUE, 0 )
+VP_CHECK( tcl_vp_add4, GL_TRUE, 4 )
+VP_CHECK( tcl_vp_size, ctx->VertexProgram.Current->Base.NumNativeInstructions > 64, 0 )
+VP_CHECK( tcl_vpp_size, ctx->VertexProgram.Current->Base.NumNativeParameters > 96, 0 )
+VP_CHECK( tcl_vp_size_add4, ctx->VertexProgram.Current->Base.NumNativeInstructions > 64, 4 )
+VP_CHECK( tcl_vpp_size_add4, ctx->VertexProgram.Current->Base.NumNativeParameters > 96, 4 )
#define OUT_VEC(hdr, data) do { \
drm_radeon_cmd_header_t h; \
@@ -324,14 +341,22 @@ VP_CHECK( tcl_vpp_size, ctx->VertexProgram.Current->Base.NumNativeParameters > 9
OUT_BATCH(CP_PACKET0_ONE(R200_SE_TCL_SCALAR_DATA_REG, h.scalars.count - 1)); \
OUT_BATCH_TABLE((data), h.scalars.count); \
} while(0)
+static int check_rrb(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrb;
+ rrb = radeon_get_colorbuffer(&r200->radeon);
+ if (!rrb || !rrb->bo)
+ return 0;
+ return atom->cmd_size;
+}
static void mtl_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 6;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[MTL_CMD_0], (atom->cmd+1));
OUT_SCL2(atom->cmd[MTL_CMD_1], (atom->cmd + 18));
@@ -342,9 +367,8 @@ static void lit_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 8;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[LIT_CMD_0], atom->cmd+1);
OUT_VEC(atom->cmd[LIT_CMD_1], atom->cmd+LIT_CMD_1+1);
@@ -355,9 +379,8 @@ static void ptp_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 8;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[PTP_CMD_0], atom->cmd+1);
OUT_VEC(atom->cmd[PTP_CMD_1], atom->cmd+PTP_CMD_1+1);
@@ -368,9 +391,8 @@ static void veclinear_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 4;
OUT_VECLINEAR(atom->cmd[0], atom->cmd+1);
}
@@ -378,9 +400,8 @@ static void scl_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 2;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_SCL(atom->cmd[0], atom->cmd+1);
END_BATCH();
@@ -391,9 +412,8 @@ static void vec_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 4;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[0], atom->cmd+1);
END_BATCH();
@@ -406,10 +426,10 @@ static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom)
struct radeon_renderbuffer *rrb;
uint32_t cbpitch;
uint32_t zbpitch, depth_fmt;
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
/* output the first 7 bytes of context */
- BEGIN_BATCH_NO_AUTOSTATE(dwords+2+2);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH_TABLE(atom->cmd, 5);
rrb = radeon_get_depthbuffer(&r200->radeon);
@@ -466,6 +486,31 @@ static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom)
END_BATCH();
}
+static int check_always_ctx( GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrb, *drb;
+ uint32_t dwords;
+
+ rrb = radeon_get_colorbuffer(&r200->radeon);
+ if (!rrb || !rrb->bo) {
+ return 0;
+ }
+
+ drb = radeon_get_depthbuffer(&r200->radeon);
+
+ dwords = 10;
+ if (drb)
+ dwords += 6;
+ if (rrb)
+ dwords += 8;
+ if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM)
+ dwords += 4;
+
+
+ return dwords;
+}
+
static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
@@ -473,7 +518,7 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
struct radeon_renderbuffer *rrb, *drb;
uint32_t cbpitch = 0;
uint32_t zbpitch = 0;
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
uint32_t depth_fmt;
rrb = radeon_get_colorbuffer(&r200->radeon);
@@ -511,14 +556,6 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
atom->cmd[CTX_RB3D_ZSTENCILCNTL] |= depth_fmt;
}
- dwords = 10;
- if (drb)
- dwords += 6;
- if (rrb)
- dwords += 6;
- if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM)
- dwords += 4;
-
/* output the first 7 bytes of context */
BEGIN_BATCH_NO_AUTOSTATE(dwords);
@@ -546,7 +583,7 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
OUT_BATCH(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
- OUT_BATCH(cbpitch);
+ OUT_BATCH_RELOC(cbpitch, rrb->bo, cbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
}
if (atom->cmd_size == CTX_STATE_SIZE_NEWDRM) {
@@ -556,17 +593,46 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
END_BATCH();
}
+static int get_tex_size(GLcontext* ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ uint32_t dwords = atom->cmd_size + 2;
+ int i = atom->idx;
+ radeonTexObj *t = r200->state.texture.unit[i].texobj;
+ if (!(t && t->mt && !t->image_override))
+ dwords -= 2;
+
+ return dwords;
+}
+
+static int check_tex_pair(GLcontext* ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ /** XOR is bit flip operation so use it for finding pair */
+ if (!(r200->state.texture.unit[atom->idx].unitneeded | r200->state.texture.unit[atom->idx ^ 1].unitneeded))
+ return 0;
+
+ return get_tex_size(ctx, atom);
+}
+
+static int check_tex(GLcontext* ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ if (!(r200->state.texture.unit[atom->idx].unitneeded))
+ return 0;
+
+ return get_tex_size(ctx, atom);
+}
+
+
static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
int i = atom->idx;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
- radeon_mipmap_level *lvl;
- if (t && t->mt && !t->image_override)
- dwords += 2;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
/* is this ok even with drm older than 1.18? */
OUT_BATCH_TABLE(atom->cmd, 10);
@@ -584,18 +650,13 @@ static void tex_emit(GLcontext *ctx, struct radeon_state_atom *atom)
END_BATCH();
}
-static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
+static int get_tex_mm_size(GLcontext* ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
- BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->cmd_size + 2;
+ int hastexture = 1;
int i = atom->idx;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
- radeon_mipmap_level *lvl;
- int hastexture = 1;
-
- if (!r200->state.texture.unit[i].unitneeded)
- hastexture = 0;
if (!t)
hastexture = 0;
else {
@@ -603,16 +664,46 @@ static void tex_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
hastexture = 0;
}
- if (hastexture)
- dwords += 2;
- else
- dwords -= 2;
+ if (!hastexture)
+ dwords -= 4;
+ return dwords;
+}
+
+static int check_tex_pair_mm(GLcontext* ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ /** XOR is bit flip operation so use it for finding pair */
+ if (!(r200->state.texture.unit[atom->idx].unitneeded | r200->state.texture.unit[atom->idx ^ 1].unitneeded))
+ return 0;
+
+ return get_tex_mm_size(ctx, atom);
+}
+
+static int check_tex_mm(GLcontext* ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ if (!(r200->state.texture.unit[atom->idx].unitneeded))
+ return 0;
+
+ return get_tex_mm_size(ctx, atom);
+}
+
+
+static void tex_emit_mm(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r200ContextPtr r200 = R200_CONTEXT(ctx);
+ BATCH_LOCALS(&r200->radeon);
+ uint32_t dwords = atom->check(ctx, atom);
+ int i = atom->idx;
+ radeonTexObj *t = r200->state.texture.unit[i].texobj;
+ if (!r200->state.texture.unit[i].unitneeded)
+ dwords -= 4;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH(CP_PACKET0(R200_PP_TXFILTER_0 + (32 * i), 7));
OUT_BATCH_TABLE((atom->cmd + 1), 8);
- if (hastexture) {
+ if (dwords > atom->cmd_size) {
OUT_BATCH(CP_PACKET0(R200_PP_TXOFFSET_0 + (24 * i), 0));
if (t->mt && !t->image_override) {
OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
@@ -631,12 +722,15 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = 3;
+ uint32_t dwords = atom->check(ctx, atom);
int i = atom->idx, j;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
radeon_mipmap_level *lvl;
- BEGIN_BATCH_NO_AUTOSTATE(dwords + (3 * 5));
+ if (!(t && !t->image_override))
+ dwords = 2;
+
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
/* XXX that size won't really match with image_override... */
OUT_BATCH_TABLE(atom->cmd, 2);
@@ -655,12 +749,14 @@ static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
{
r200ContextPtr r200 = R200_CONTEXT(ctx);
BATCH_LOCALS(&r200->radeon);
- uint32_t dwords = 2;
+ uint32_t dwords = atom->check(ctx, atom);
int i = atom->idx, j;
radeonTexObj *t = r200->state.texture.unit[i].texobj;
radeon_mipmap_level *lvl;
+ if (!(t && !t->image_override))
+ dwords = 2;
- BEGIN_BATCH_NO_AUTOSTATE(dwords + (4 * 5));
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH_TABLE(atom->cmd, 2);
if (t && !t->image_override) {
@@ -668,7 +764,7 @@ static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
for (j = 1; j <= 5; j++) {
OUT_BATCH(CP_PACKET0(R200_PP_CUBIC_OFFSET_F1_0 + (24*i) + (4 * (j-1)), 0));
OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset,
- RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
}
END_BATCH();
@@ -706,23 +802,32 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.ATOM.lastcmd = (GLuint *)CALLOC(SZ * sizeof(int)); \
rmesa->hw.ATOM.name = NM; \
rmesa->hw.ATOM.idx = IDX; \
- rmesa->hw.ATOM.check = check_##CHK; \
+ if (check_##CHK != check_never) { \
+ rmesa->hw.ATOM.check = check_##CHK; \
+ rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \
+ } else { \
+ rmesa->hw.ATOM.check = NULL; \
+ } \
rmesa->hw.ATOM.dirty = GL_FALSE; \
- rmesa->radeon.hw.max_state_size += SZ * sizeof(int); \
} while (0)
/* Allocate state buffers:
*/
if (rmesa->radeon.radeonScreen->drmSupportsBlendColor)
- ALLOC_STATE( ctx, always, CTX_STATE_SIZE_NEWDRM, "CTX/context", 0 );
+ ALLOC_STATE( ctx, always_add4, CTX_STATE_SIZE_NEWDRM, "CTX/context", 0 );
else
- ALLOC_STATE( ctx, always, CTX_STATE_SIZE_OLDDRM, "CTX/context", 0 );
+ ALLOC_STATE( ctx, always_add4, CTX_STATE_SIZE_OLDDRM, "CTX/context", 0 );
if (rmesa->radeon.radeonScreen->kernel_mm)
+ {
rmesa->hw.ctx.emit = ctx_emit_cs;
+ rmesa->hw.ctx.check = check_always_ctx;
+ }
else
+ {
rmesa->hw.ctx.emit = ctx_emit;
+ }
ALLOC_STATE( set, always, SET_STATE_SIZE, "SET/setup", 0 );
ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 );
ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 );
@@ -734,49 +839,60 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( cst, always, CST_STATE_SIZE, "CST/constant", 0 );
ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 );
ALLOC_STATE( tf, tf, TF_STATE_SIZE, "TF/tfactor", 0 );
- if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
- if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
- /* make sure texture units 0/1 are emitted pair-wise for r200 t0 hang workaround */
- ALLOC_STATE( tex[0], tex_pair, TEX_STATE_SIZE_NEWDRM, "TEX/tex-0", 0 );
- ALLOC_STATE( tex[1], tex_pair, TEX_STATE_SIZE_NEWDRM, "TEX/tex-1", 1 );
- ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 );
+ {
+ int state_size = TEX_STATE_SIZE_NEWDRM;
+ if (!rmesa->radeon.radeonScreen->drmSupportsFragShader) {
+ state_size = TEX_STATE_SIZE_OLDDRM;
}
- else {
- ALLOC_STATE( tex[0], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-0", 0 );
- ALLOC_STATE( tex[1], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-1", 1 );
- ALLOC_STATE( tam, never, TAM_STATE_SIZE, "TAM/tam", 0 );
+ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
+ if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
+ /* make sure texture units 0/1 are emitted pair-wise for r200 t0 hang workaround */
+ ALLOC_STATE( tex[0], tex_pair_mm, state_size, "TEX/tex-0", 0 );
+ ALLOC_STATE( tex[1], tex_pair_mm, state_size, "TEX/tex-1", 1 );
+ ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 );
+ }
+ else {
+ ALLOC_STATE( tex[0], tex_mm, state_size, "TEX/tex-0", 0 );
+ ALLOC_STATE( tex[1], tex_mm, state_size, "TEX/tex-1", 1 );
+ ALLOC_STATE( tam, never, TAM_STATE_SIZE, "TAM/tam", 0 );
+ }
+ ALLOC_STATE( tex[2], tex_mm, state_size, "TEX/tex-2", 2 );
+ ALLOC_STATE( tex[3], tex_mm, state_size, "TEX/tex-3", 3 );
+ ALLOC_STATE( tex[4], tex_mm, state_size, "TEX/tex-4", 4 );
+ ALLOC_STATE( tex[5], tex_mm, state_size, "TEX/tex-5", 5 );
+ if (!rmesa->radeon.radeonScreen->kernel_mm)
+ {
+ if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
+ rmesa->hw.tex[0].check = check_tex_pair;
+ rmesa->hw.tex[1].check = check_tex_pair;
+ } else {
+ rmesa->hw.tex[0].check = check_tex;
+ rmesa->hw.tex[1].check = check_tex;
+ }
+ rmesa->hw.tex[2].check = check_tex;
+ rmesa->hw.tex[3].check = check_tex;
+ rmesa->hw.tex[4].check = check_tex;
+ rmesa->hw.tex[5].check = check_tex;
+ }
+ if (rmesa->radeon.radeonScreen->drmSupportsFragShader) {
+ ALLOC_STATE( atf, afs, ATF_STATE_SIZE, "ATF/tfactor", 0 );
+ ALLOC_STATE( afs[0], afs_pass1, AFS_STATE_SIZE, "AFS/afsinst-0", 0 );
+ ALLOC_STATE( afs[1], afs, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
+ } else {
+ ALLOC_STATE( atf, never, ATF_STATE_SIZE, "ATF/tfactor", 0 );
+ ALLOC_STATE( afs[0], never, AFS_STATE_SIZE, "AFS/afsinst-0", 0 );
+ ALLOC_STATE( afs[1], never, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
+ }
}
- ALLOC_STATE( tex[2], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-2", 2 );
- ALLOC_STATE( tex[3], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-3", 3 );
- ALLOC_STATE( tex[4], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-4", 4 );
- ALLOC_STATE( tex[5], tex, TEX_STATE_SIZE_NEWDRM, "TEX/tex-5", 5 );
- ALLOC_STATE( atf, afs, ATF_STATE_SIZE, "ATF/tfactor", 0 );
- ALLOC_STATE( afs[0], afs_pass1, AFS_STATE_SIZE, "AFS/afsinst-0", 0 );
- ALLOC_STATE( afs[1], afs, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
}
- else {
- if (rmesa->radeon.radeonScreen->chip_family == CHIP_FAMILY_R200) {
- ALLOC_STATE( tex[0], tex_pair, TEX_STATE_SIZE_OLDDRM, "TEX/tex-0", 0 );
- ALLOC_STATE( tex[1], tex_pair, TEX_STATE_SIZE_OLDDRM, "TEX/tex-1", 1 );
- ALLOC_STATE( tam, tex_any, TAM_STATE_SIZE, "TAM/tam", 0 );
- }
- else {
- ALLOC_STATE( tex[0], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-0", 0 );
- ALLOC_STATE( tex[1], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-1", 1 );
- ALLOC_STATE( tam, never, TAM_STATE_SIZE, "TAM/tam", 0 );
- }
- ALLOC_STATE( tex[2], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-2", 2 );
- ALLOC_STATE( tex[3], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-3", 3 );
- ALLOC_STATE( tex[4], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-4", 4 );
- ALLOC_STATE( tex[5], tex, TEX_STATE_SIZE_OLDDRM, "TEX/tex-5", 5 );
- ALLOC_STATE( atf, never, ATF_STATE_SIZE, "TF/tfactor", 0 );
- ALLOC_STATE( afs[0], never, AFS_STATE_SIZE, "AFS/afsinst-0", 0 );
- ALLOC_STATE( afs[1], never, AFS_STATE_SIZE, "AFS/afsinst-1", 1 );
+ /* polygon stipple is done with irq for non-kms */
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 );
}
- for (i = 0; i < 5; i++)
+ for (i = 0; i < 6; i++)
if (rmesa->radeon.radeonScreen->kernel_mm)
- rmesa->hw.tex[i].emit = tex_emit_cs;
+ rmesa->hw.tex[i].emit = tex_emit_mm;
else
rmesa->hw.tex[i].emit = tex_emit;
if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR200) {
@@ -786,10 +902,11 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( cube[3], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-3", 3 );
ALLOC_STATE( cube[4], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-4", 4 );
ALLOC_STATE( cube[5], tex_cube, CUBE_STATE_SIZE, "CUBE/tex-5", 5 );
- for (i = 0; i < 5; i++)
- if (rmesa->radeon.radeonScreen->kernel_mm)
+ for (i = 0; i < 6; i++)
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
rmesa->hw.cube[i].emit = cube_emit_cs;
- else
+ rmesa->hw.cube[i].check = check_tex_cube_cs;
+ } else
rmesa->hw.cube[i].emit = cube_emit;
}
else {
@@ -803,10 +920,17 @@ void r200InitState( r200ContextPtr rmesa )
if (rmesa->radeon.radeonScreen->drmSupportsVertexProgram) {
ALLOC_STATE( pvs, tcl_vp, PVS_STATE_SIZE, "PVS/pvscntl", 0 );
- ALLOC_STATE( vpi[0], tcl_vp, VPI_STATE_SIZE, "VP/vertexprog-0", 0 );
- ALLOC_STATE( vpi[1], tcl_vp_size, VPI_STATE_SIZE, "VP/vertexprog-1", 1 );
- ALLOC_STATE( vpp[0], tcl_vp, VPP_STATE_SIZE, "VPP/vertexparam-0", 0 );
- ALLOC_STATE( vpp[1], tcl_vpp_size, VPP_STATE_SIZE, "VPP/vertexparam-1", 1 );
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE( vpi[0], tcl_vp_add4, VPI_STATE_SIZE, "VP/vertexprog-0", 0 );
+ ALLOC_STATE( vpi[1], tcl_vp_size_add4, VPI_STATE_SIZE, "VP/vertexprog-1", 1 );
+ ALLOC_STATE( vpp[0], tcl_vp_add4, VPP_STATE_SIZE, "VPP/vertexparam-0", 0 );
+ ALLOC_STATE( vpp[1], tcl_vpp_size_add4, VPP_STATE_SIZE, "VPP/vertexparam-1", 1 );
+ } else {
+ ALLOC_STATE( vpi[0], tcl_vp, VPI_STATE_SIZE, "VP/vertexprog-0", 0 );
+ ALLOC_STATE( vpi[1], tcl_vp_size, VPI_STATE_SIZE, "VP/vertexprog-1", 1 );
+ ALLOC_STATE( vpp[0], tcl_vp, VPP_STATE_SIZE, "VPP/vertexparam-0", 0 );
+ ALLOC_STATE( vpp[1], tcl_vpp_size, VPP_STATE_SIZE, "VPP/vertexparam-1", 1 );
+ }
}
else {
ALLOC_STATE( pvs, never, PVS_STATE_SIZE, "PVS/pvscntl", 0 );
@@ -819,35 +943,69 @@ void r200InitState( r200ContextPtr rmesa )
ALLOC_STATE( tcl, tcl_or_vp, TCL_STATE_SIZE, "TCL/tcl", 0 );
ALLOC_STATE( msl, tcl, MSL_STATE_SIZE, "MSL/matrix-select", 0 );
ALLOC_STATE( tcg, tcl, TCG_STATE_SIZE, "TCG/texcoordgen", 0 );
- ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 );
- ALLOC_STATE( mtl[1], tcl_lighting, MTL_STATE_SIZE, "MTL1/material1", 1 );
- ALLOC_STATE( grd, tcl_or_vp, GRD_STATE_SIZE, "GRD/guard-band", 0 );
- ALLOC_STATE( fog, tcl_fog, FOG_STATE_SIZE, "FOG/fog", 0 );
- ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 );
- ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 );
- ALLOC_STATE( mat[R200_MTX_MV], tcl, MAT_STATE_SIZE, "MAT/modelview", 0 );
- ALLOC_STATE( mat[R200_MTX_IMV], tcl, MAT_STATE_SIZE, "MAT/it-modelview", 0 );
- ALLOC_STATE( mat[R200_MTX_MVP], tcl, MAT_STATE_SIZE, "MAT/modelproject", 0 );
- ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex, MAT_STATE_SIZE, "MAT/texmat0", 0 );
- ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex, MAT_STATE_SIZE, "MAT/texmat1", 1 );
- ALLOC_STATE( mat[R200_MTX_TEX2], tcl_tex, MAT_STATE_SIZE, "MAT/texmat2", 2 );
- ALLOC_STATE( mat[R200_MTX_TEX3], tcl_tex, MAT_STATE_SIZE, "MAT/texmat3", 3 );
- ALLOC_STATE( mat[R200_MTX_TEX4], tcl_tex, MAT_STATE_SIZE, "MAT/texmat4", 4 );
- ALLOC_STATE( mat[R200_MTX_TEX5], tcl_tex, MAT_STATE_SIZE, "MAT/texmat5", 5 );
- ALLOC_STATE( ucp[0], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-0", 0 );
- ALLOC_STATE( ucp[1], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
- ALLOC_STATE( ucp[2], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-2", 2 );
- ALLOC_STATE( ucp[3], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-3", 3 );
- ALLOC_STATE( ucp[4], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-4", 4 );
- ALLOC_STATE( ucp[5], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-5", 5 );
- ALLOC_STATE( lit[0], tcl_light, LIT_STATE_SIZE, "LIT/light-0", 0 );
- ALLOC_STATE( lit[1], tcl_light, LIT_STATE_SIZE, "LIT/light-1", 1 );
- ALLOC_STATE( lit[2], tcl_light, LIT_STATE_SIZE, "LIT/light-2", 2 );
- ALLOC_STATE( lit[3], tcl_light, LIT_STATE_SIZE, "LIT/light-3", 3 );
- ALLOC_STATE( lit[4], tcl_light, LIT_STATE_SIZE, "LIT/light-4", 4 );
- ALLOC_STATE( lit[5], tcl_light, LIT_STATE_SIZE, "LIT/light-5", 5 );
- ALLOC_STATE( lit[6], tcl_light, LIT_STATE_SIZE, "LIT/light-6", 6 );
- ALLOC_STATE( lit[7], tcl_light, LIT_STATE_SIZE, "LIT/light-7", 7 );
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE( mtl[0], tcl_lighting_add6, MTL_STATE_SIZE, "MTL0/material0", 0 );
+ ALLOC_STATE( mtl[1], tcl_lighting_add6, MTL_STATE_SIZE, "MTL1/material1", 1 );
+ ALLOC_STATE( grd, tcl_or_vp_add2, GRD_STATE_SIZE, "GRD/guard-band", 0 );
+ ALLOC_STATE( fog, tcl_fog_add4, FOG_STATE_SIZE, "FOG/fog", 0 );
+ ALLOC_STATE( glt, tcl_lighting_add4, GLT_STATE_SIZE, "GLT/light-global", 0 );
+ ALLOC_STATE( eye, tcl_lighting_add4, EYE_STATE_SIZE, "EYE/eye-vector", 0 );
+ ALLOC_STATE( mat[R200_MTX_MV], tcl_add4, MAT_STATE_SIZE, "MAT/modelview", 0 );
+ ALLOC_STATE( mat[R200_MTX_IMV], tcl_add4, MAT_STATE_SIZE, "MAT/it-modelview", 0 );
+ ALLOC_STATE( mat[R200_MTX_MVP], tcl_add4, MAT_STATE_SIZE, "MAT/modelproject", 0 );
+ ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat0", 0 );
+ ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat1", 1 );
+ ALLOC_STATE( mat[R200_MTX_TEX2], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat2", 2 );
+ ALLOC_STATE( mat[R200_MTX_TEX3], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat3", 3 );
+ ALLOC_STATE( mat[R200_MTX_TEX4], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat4", 4 );
+ ALLOC_STATE( mat[R200_MTX_TEX5], tcl_tex_add4, MAT_STATE_SIZE, "MAT/texmat5", 5 );
+ ALLOC_STATE( ucp[0], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-0", 0 );
+ ALLOC_STATE( ucp[1], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
+ ALLOC_STATE( ucp[2], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-2", 2 );
+ ALLOC_STATE( ucp[3], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-3", 3 );
+ ALLOC_STATE( ucp[4], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-4", 4 );
+ ALLOC_STATE( ucp[5], tcl_ucp_add4, UCP_STATE_SIZE, "UCP/userclip-5", 5 );
+ ALLOC_STATE( lit[0], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-0", 0 );
+ ALLOC_STATE( lit[1], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-1", 1 );
+ ALLOC_STATE( lit[2], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-2", 2 );
+ ALLOC_STATE( lit[3], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-3", 3 );
+ ALLOC_STATE( lit[4], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-4", 4 );
+ ALLOC_STATE( lit[5], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-5", 5 );
+ ALLOC_STATE( lit[6], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-6", 6 );
+ ALLOC_STATE( lit[7], tcl_light_add8, LIT_STATE_SIZE, "LIT/light-7", 7 );
+ ALLOC_STATE( sci, rrb, SCI_STATE_SIZE, "SCI/scissor", 0 );
+ } else {
+ ALLOC_STATE( mtl[0], tcl_lighting, MTL_STATE_SIZE, "MTL0/material0", 0 );
+ ALLOC_STATE( mtl[1], tcl_lighting, MTL_STATE_SIZE, "MTL1/material1", 1 );
+ ALLOC_STATE( grd, tcl_or_vp, GRD_STATE_SIZE, "GRD/guard-band", 0 );
+ ALLOC_STATE( fog, tcl_fog, FOG_STATE_SIZE, "FOG/fog", 0 );
+ ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 0 );
+ ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 0 );
+ ALLOC_STATE( mat[R200_MTX_MV], tcl, MAT_STATE_SIZE, "MAT/modelview", 0 );
+ ALLOC_STATE( mat[R200_MTX_IMV], tcl, MAT_STATE_SIZE, "MAT/it-modelview", 0 );
+ ALLOC_STATE( mat[R200_MTX_MVP], tcl, MAT_STATE_SIZE, "MAT/modelproject", 0 );
+ ALLOC_STATE( mat[R200_MTX_TEX0], tcl_tex, MAT_STATE_SIZE, "MAT/texmat0", 0 );
+ ALLOC_STATE( mat[R200_MTX_TEX1], tcl_tex, MAT_STATE_SIZE, "MAT/texmat1", 1 );
+ ALLOC_STATE( mat[R200_MTX_TEX2], tcl_tex, MAT_STATE_SIZE, "MAT/texmat2", 2 );
+ ALLOC_STATE( mat[R200_MTX_TEX3], tcl_tex, MAT_STATE_SIZE, "MAT/texmat3", 3 );
+ ALLOC_STATE( mat[R200_MTX_TEX4], tcl_tex, MAT_STATE_SIZE, "MAT/texmat4", 4 );
+ ALLOC_STATE( mat[R200_MTX_TEX5], tcl_tex, MAT_STATE_SIZE, "MAT/texmat5", 5 );
+ ALLOC_STATE( ucp[0], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-0", 0 );
+ ALLOC_STATE( ucp[1], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
+ ALLOC_STATE( ucp[2], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-2", 2 );
+ ALLOC_STATE( ucp[3], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-3", 3 );
+ ALLOC_STATE( ucp[4], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-4", 4 );
+ ALLOC_STATE( ucp[5], tcl_ucp, UCP_STATE_SIZE, "UCP/userclip-5", 5 );
+ ALLOC_STATE( lit[0], tcl_light, LIT_STATE_SIZE, "LIT/light-0", 0 );
+ ALLOC_STATE( lit[1], tcl_light, LIT_STATE_SIZE, "LIT/light-1", 1 );
+ ALLOC_STATE( lit[2], tcl_light, LIT_STATE_SIZE, "LIT/light-2", 2 );
+ ALLOC_STATE( lit[3], tcl_light, LIT_STATE_SIZE, "LIT/light-3", 3 );
+ ALLOC_STATE( lit[4], tcl_light, LIT_STATE_SIZE, "LIT/light-4", 4 );
+ ALLOC_STATE( lit[5], tcl_light, LIT_STATE_SIZE, "LIT/light-5", 5 );
+ ALLOC_STATE( lit[6], tcl_light, LIT_STATE_SIZE, "LIT/light-6", 6 );
+ ALLOC_STATE( lit[7], tcl_light, LIT_STATE_SIZE, "LIT/light-7", 7 );
+ ALLOC_STATE( sci, never, SCI_STATE_SIZE, "SCI/scissor", 0 );
+ }
ALLOC_STATE( pix[0], pix_zero, PIX_STATE_SIZE, "PIX/pixstage-0", 0 );
ALLOC_STATE( pix[1], texenv, PIX_STATE_SIZE, "PIX/pixstage-1", 1 );
ALLOC_STATE( pix[2], texenv, PIX_STATE_SIZE, "PIX/pixstage-2", 2 );
@@ -862,7 +1020,10 @@ void r200InitState( r200ContextPtr rmesa )
}
if (rmesa->radeon.radeonScreen->drmSupportsPointSprites) {
ALLOC_STATE( spr, always, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
- ALLOC_STATE( ptp, tcl, PTP_STATE_SIZE, "PTP/pointparams", 0 );
+ if (rmesa->radeon.radeonScreen->kernel_mm)
+ ALLOC_STATE( ptp, tcl_add8, PTP_STATE_SIZE, "PTP/pointparams", 0 );
+ else
+ ALLOC_STATE( ptp, tcl, PTP_STATE_SIZE, "PTP/pointparams", 0 );
}
else {
ALLOC_STATE (spr, never, SPR_STATE_SIZE, "SPR/pointsprite", 0 );
@@ -954,19 +1115,29 @@ void r200InitState( r200ContextPtr rmesa )
rmesa->hw.vte.cmd[VTE_CMD_0] = cmdpkt(rmesa, R200_EMIT_VTE_CNTL);
rmesa->hw.prf.cmd[PRF_CMD_0] = cmdpkt(rmesa, R200_EMIT_PP_TRI_PERF_CNTL);
rmesa->hw.spr.cmd[SPR_CMD_0] = cmdpkt(rmesa, R200_EMIT_TCL_POINT_SPRITE_CNTL);
+
+ rmesa->hw.sci.cmd[SCI_CMD_0] = CP_PACKET0(R200_RE_AUX_SCISSOR_CNTL, 0);
+ rmesa->hw.sci.cmd[SCI_CMD_1] = CP_PACKET0(R200_RE_TOP_LEFT, 0);
+ rmesa->hw.sci.cmd[SCI_CMD_2] = CP_PACKET0(R200_RE_WIDTH_HEIGHT, 0);
+
if (rmesa->radeon.radeonScreen->kernel_mm) {
- rmesa->hw.mtl[0].emit = mtl_emit;
- rmesa->hw.mtl[1].emit = mtl_emit;
- rmesa->hw.vpi[0].emit = veclinear_emit;
- rmesa->hw.vpi[1].emit = veclinear_emit;
- rmesa->hw.vpp[0].emit = veclinear_emit;
- rmesa->hw.vpp[1].emit = veclinear_emit;
+ rmesa->hw.stp.cmd[STP_CMD_0] = CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0);
+ rmesa->hw.stp.cmd[STP_DATA_0] = 0;
+ rmesa->hw.stp.cmd[STP_CMD_1] = CP_PACKET0_ONE(RADEON_RE_STIPPLE_DATA, 31);
+
+ rmesa->hw.mtl[0].emit = mtl_emit;
+ rmesa->hw.mtl[1].emit = mtl_emit;
+
+ rmesa->hw.vpi[0].emit = veclinear_emit;
+ rmesa->hw.vpi[1].emit = veclinear_emit;
+ rmesa->hw.vpp[0].emit = veclinear_emit;
+ rmesa->hw.vpp[1].emit = veclinear_emit;
- rmesa->hw.grd.emit = scl_emit;
- rmesa->hw.fog.emit = vec_emit;
- rmesa->hw.glt.emit = vec_emit;
- rmesa->hw.eye.emit = vec_emit;
+ rmesa->hw.grd.emit = scl_emit;
+ rmesa->hw.fog.emit = vec_emit;
+ rmesa->hw.glt.emit = vec_emit;
+ rmesa->hw.eye.emit = vec_emit;
for (i = R200_MTX_MV; i <= R200_MTX_TEX5; i++)
rmesa->hw.mat[i].emit = vec_emit;
@@ -1435,6 +1606,12 @@ void r200InitState( r200ContextPtr rmesa )
r200LightingSpaceChange( ctx );
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ radeon_init_query_stateobj(&rmesa->radeon, R200_QUERYOBJ_CMDSIZE);
+ rmesa->radeon.query.queryobj.cmd[R200_QUERYOBJ_CMD_0] = CP_PACKET0(RADEON_RB3D_ZPASS_DATA, 0);
+ rmesa->radeon.query.queryobj.cmd[R200_QUERYOBJ_DATA_0] = 0;
+ }
+
rmesa->radeon.hw.all_dirty = GL_TRUE;
rcommonInitCmdBuf(&rmesa->radeon);
diff --git a/src/mesa/drivers/dri/r200/r200_swtcl.c b/src/mesa/drivers/dri/r200/r200_swtcl.c
index 83e70b586d..240fb45078 100644
--- a/src/mesa/drivers/dri/r200/r200_swtcl.c
+++ b/src/mesa/drivers/dri/r200/r200_swtcl.c
@@ -39,6 +39,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/image.h"
#include "main/imports.h"
#include "main/macros.h"
+#include "main/simple_list.h"
#include "swrast/s_context.h"
#include "swrast/s_fog.h"
@@ -200,10 +201,32 @@ static void r200SetVertexFormat( GLcontext *ctx )
}
}
+static void r200_predict_emit_size( r200ContextPtr rmesa )
+{
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
+ const int vertex_array_size = 7;
+ const int prim_size = 3;
+ if (!rmesa->radeon.swtcl.emit_prediction) {
+ const int state_size = radeonCountStateEmitSize(&rmesa->radeon);
+ if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
+ state_size +
+ vertex_array_size + prim_size,
+ __FUNCTION__))
+ rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
+ else
+ rmesa->radeon.swtcl.emit_prediction = state_size;
+ rmesa->radeon.swtcl.emit_prediction += vertex_array_size + prim_size
+ + rmesa->radeon.cmdbuf.cs->cdw;
+ }
+}
+
static void r200RenderStart( GLcontext *ctx )
{
r200SetVertexFormat( ctx );
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
}
@@ -267,21 +290,26 @@ void r200ChooseVertexState( GLcontext *ctx )
void r200_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
{
r200ContextPtr rmesa = R200_CONTEXT(ctx);
- rcommonEnsureCmdBufSpace(&rmesa->radeon,
- rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
- __FUNCTION__);
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
radeonEmitState(&rmesa->radeon);
r200EmitVertexAOS( rmesa,
rmesa->radeon.swtcl.vertex_size,
- rmesa->radeon.dma.current,
+ first_elem(&rmesa->radeon.dma.reserved)->bo,
current_offset);
r200EmitVbufPrim( rmesa,
rmesa->radeon.swtcl.hw_primitive,
rmesa->radeon.swtcl.numverts);
+ if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n",
+ rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
+
+ rmesa->radeon.swtcl.emit_prediction = 0;
}
@@ -329,17 +357,27 @@ static void r200ResetLineStipple( GLcontext *ctx );
#define HAVE_POLYGONS 1
#define HAVE_ELTS 0
+static void* r200_alloc_verts( r200ContextPtr rmesa, GLuint n, GLuint size)
+{
+ void *rv;
+ do {
+ r200_predict_emit_size( rmesa );
+ rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
+ } while(!rv);
+ return rv;
+}
+
#undef LOCAL_VARS
#undef ALLOC_VERTS
#define CTX_ARG r200ContextPtr rmesa
#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
-#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
+#define ALLOC_VERTS( n, size ) r200_alloc_verts(rmesa, n, size)
#define LOCAL_VARS \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
const char *r200verts = (char *)rmesa->radeon.swtcl.verts;
#define VERT(x) (radeonVertex *)(r200verts + ((x) * vertsize * sizeof(int)))
#define VERTEX radeonVertex
-#define DO_DEBUG_VERTS (1 && (R200_DEBUG & DEBUG_VERTS))
+#define DO_DEBUG_VERTS (1 && (R200_DEBUG & RADEON_VERTS))
#undef TAG
#define TAG(x) r200_##x
@@ -443,7 +481,7 @@ do { \
#define LOCAL_VARS(n) \
r200ContextPtr rmesa = R200_CONTEXT(ctx); \
- GLuint color[n], spec[n]; \
+ GLuint color[n] = {0}, spec[n] = {0}; \
GLuint coloroffset = rmesa->swtcl.coloroffset; \
GLuint specoffset = rmesa->swtcl.specoffset; \
(void) color; (void) spec; (void) coloroffset; (void) specoffset;
@@ -650,7 +688,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
TCL_FALLBACK( ctx, R200_TCL_FALLBACK_RASTER, GL_TRUE );
_swsetup_Wakeup( ctx );
rmesa->radeon.swtcl.RenderIndex = ~0;
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "R200 begin rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
@@ -682,7 +720,7 @@ void r200Fallback( GLcontext *ctx, GLuint bit, GLboolean mode )
r200ChooseVertexState( ctx );
r200ChooseRenderState( ctx );
}
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "R200 end rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
@@ -889,6 +927,7 @@ void r200InitSwtcl( GLcontext *ctx )
init_rast_tab();
firsttime = 0;
}
+ rmesa->radeon.swtcl.emit_prediction = 0;
tnl->Driver.Render.Start = r200RenderStart;
tnl->Driver.Render.Finish = r200RenderFinish;
diff --git a/src/mesa/drivers/dri/r200/r200_tcl.c b/src/mesa/drivers/dri/r200/r200_tcl.c
index 580370933e..c702910ef2 100644
--- a/src/mesa/drivers/dri/r200/r200_tcl.c
+++ b/src/mesa/drivers/dri/r200/r200_tcl.c
@@ -51,6 +51,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r200_swtcl.h"
#include "r200_maos.h"
+#include "radeon_common_context.h"
+
#define HAVE_POINTS 1
@@ -109,7 +111,7 @@ static GLboolean discrete_prim[0x10] = {
#define ELT_INIT(prim, hw_prim) \
r200TclPrimitive( ctx, prim, hw_prim | R200_VF_PRIM_WALK_IND )
-#define GET_MESA_ELTS() rmesa->tcl.Elts
+#define GET_MESA_ELTS() TNL_CONTEXT(ctx)->vb.Elts
/* Don't really know how many elts will fit in what's left of cmdbuf,
@@ -146,7 +148,7 @@ static GLushort *r200AllocElts( r200ContextPtr rmesa, GLuint nr )
rmesa->tcl.elt_used + nr*2 < R200_ELT_BUF_SZ) {
GLushort *dest = (GLushort *)(rmesa->radeon.tcl.elt_dma_bo->ptr +
- rmesa->tcl.elt_used);
+ rmesa->radeon.tcl.elt_dma_offset + rmesa->tcl.elt_used);
rmesa->tcl.elt_used += nr*2;
@@ -156,11 +158,10 @@ static GLushort *r200AllocElts( r200ContextPtr rmesa, GLuint nr )
if (rmesa->radeon.dma.flush)
rmesa->radeon.dma.flush( rmesa->radeon.glCtx );
- rcommonEnsureCmdBufSpace(&rmesa->radeon, AOS_BUFSZ(rmesa->radeon.tcl.aos_count), __FUNCTION__);
-
r200EmitAOS( rmesa,
rmesa->radeon.tcl.aos_count, 0 );
+ r200EmitMaxVtxIndex(rmesa, rmesa->radeon.tcl.aos[0].count);
return r200AllocEltsOpenEnded( rmesa, rmesa->tcl.hw_primitive, nr );
}
}
@@ -187,9 +188,6 @@ static void r200EmitPrim( GLcontext *ctx,
r200TclPrimitive( ctx, prim, hwprim );
// fprintf(stderr,"Emit prim %d\n", rmesa->radeon.tcl.aos_count);
- rcommonEnsureCmdBufSpace( &rmesa->radeon,
- AOS_BUFSZ(rmesa->radeon.tcl.aos_count) +
- rmesa->radeon.hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ );
r200EmitAOS( rmesa,
rmesa->radeon.tcl.aos_count,
@@ -206,6 +204,7 @@ static void r200EmitPrim( GLcontext *ctx,
r200EmitPrim( ctx, prim, hwprim, start, count ); \
(void) rmesa; } while (0)
+#define MAX_CONVERSION_SIZE 40
/* Try & join small primitives
*/
#if 0
@@ -368,6 +367,66 @@ r200ComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord )
}
}
+/**
+ * Predict total emit size for next rendering operation so there is no flush in middle of rendering
+ * Prediction has to aim towards the best possible value that is worse than worst case scenario
+ */
+static GLuint r200EnsureEmitSize( GLcontext * ctx , GLubyte* vimap_rev )
+{
+ r200ContextPtr rmesa = R200_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint space_required;
+ GLuint state_size;
+ GLuint nr_aos = 0;
+ int i;
+ /* predict number of aos to emit */
+ for (i = 0; i < 15; ++i)
+ {
+ if (vimap_rev[i] != 255)
+ {
+ ++nr_aos;
+ }
+ }
+
+ {
+ /* count the prediction for state size */
+ space_required = 0;
+ state_size = radeonCountStateEmitSize( &rmesa->radeon );
+ /* vtx may be changed in r200EmitArrays so account for it if not dirty */
+ if (!rmesa->hw.vtx.dirty)
+ state_size += rmesa->hw.vtx.check(rmesa->radeon.glCtx, &rmesa->hw.vtx);
+ /* predict size for elements */
+ for (i = 0; i < VB->PrimitiveCount; ++i)
+ {
+ if (!VB->Primitive[i].count)
+ continue;
+ /* If primitive.count is less than MAX_CONVERSION_SIZE
+ rendering code may decide convert to elts.
+ In that case we have to make pessimistic prediction.
+ and use larger of 2 paths. */
+ const GLuint elts = ELTS_BUFSZ(nr_aos);
+ const GLuint index = INDEX_BUFSZ;
+ const GLuint vbuf = VBUF_BUFSZ;
+ if ( (!VB->Elts && VB->Primitive[i].count >= MAX_CONVERSION_SIZE)
+ || vbuf > index + elts)
+ space_required += vbuf;
+ else
+ space_required += index + elts;
+ space_required += AOS_BUFSZ(nr_aos);
+ }
+ }
+
+ radeon_print(RADEON_RENDER,RADEON_VERBOSE,
+ "%s space %u, aos %d\n",
+ __func__, space_required, AOS_BUFSZ(nr_aos) );
+ /* flush the buffer in case we need more than is left. */
+ if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required + state_size, __FUNCTION__))
+ return space_required + radeonCountStateEmitSize( &rmesa->radeon );
+ else
+ return space_required + state_size;
+}
+
/**********************************************************************/
/* Render pipeline stage */
@@ -396,8 +455,7 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
if (rmesa->radeon.TclFallback)
return GL_TRUE; /* fallback to software t&l */
- if (R200_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
+ radeon_print(RADEON_RENDER, RADEON_NORMAL, "%s\n", __FUNCTION__);
if (VB->Count == 0)
return GL_FALSE;
@@ -482,10 +540,10 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
/* Do the actual work:
*/
radeonReleaseArrays( ctx, ~0 /* stage->changed_inputs */ );
+ GLuint emit_end = r200EnsureEmitSize( ctx, vimap_rev )
+ + rmesa->radeon.cmdbuf.cs->cdw;
r200EmitArrays( ctx, vimap_rev );
- rmesa->tcl.Elts = VB->Elts;
-
for (i = 0 ; i < VB->PrimitiveCount ; i++)
{
GLuint prim = _tnl_translate_prim(&VB->Primitive[i]);
@@ -495,11 +553,14 @@ static GLboolean r200_run_tcl_render( GLcontext *ctx,
if (!length)
continue;
- if (rmesa->tcl.Elts)
+ if (VB->Elts)
r200EmitEltPrimitive( ctx, start, start+length, prim );
else
r200EmitPrimitive( ctx, start, start+length, prim );
}
+ if ( emit_end < rmesa->radeon.cmdbuf.cs->cdw )
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end);
return GL_FALSE; /* finished the pipe */
}
@@ -590,7 +651,7 @@ static void transition_to_hwtnl( GLcontext *ctx )
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] &= ~(R200_VTX_XY_FMT|R200_VTX_Z_FMT);
rmesa->hw.vte.cmd[VTE_SE_VTE_CNTL] |= R200_VTX_W0_FMT;
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 end tcl fallback\n");
}
@@ -632,7 +693,7 @@ void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
if (mode) {
rmesa->radeon.TclFallback |= bit;
if (oldfallback == 0) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 begin tcl fallback %s\n",
getFallbackString( bit ));
transition_to_swtnl( ctx );
@@ -641,7 +702,7 @@ void r200TclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
else {
rmesa->radeon.TclFallback &= ~bit;
if (oldfallback == bit) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "R200 end tcl fallback %s\n",
getFallbackString( bit ));
transition_to_hwtnl( ctx );
diff --git a/src/mesa/drivers/dri/r200/r200_tex.c b/src/mesa/drivers/dri/r200/r200_tex.c
index 9f79157915..36d9e37d87 100644
--- a/src/mesa/drivers/dri/r200/r200_tex.c
+++ b/src/mesa/drivers/dri/r200/r200_tex.c
@@ -287,7 +287,7 @@ static void r200TexEnv( GLcontext *ctx, GLenum target,
GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- if ( R200_DEBUG & DEBUG_STATE ) {
+ if ( R200_DEBUG & RADEON_STATE ) {
fprintf( stderr, "%s( %s )\n",
__FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
}
@@ -359,7 +359,7 @@ static void r200TexParameter( GLcontext *ctx, GLenum target,
{
radeonTexObj* t = radeon_tex_obj(texObj);
- if ( R200_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
+ if ( R200_DEBUG & (RADEON_STATE|RADEON_TEXTURE) ) {
fprintf( stderr, "%s( %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr( pname ) );
}
@@ -409,7 +409,7 @@ static void r200DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
r200ContextPtr rmesa = R200_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) {
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
(void *)texObj,
_mesa_lookup_enum_by_nr(texObj->Target));
@@ -470,7 +470,7 @@ static struct gl_texture_object *r200NewTextureObject(GLcontext * ctx,
radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) {
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
t, _mesa_lookup_enum_by_nr(target));
}
diff --git a/src/mesa/drivers/dri/r200/r200_texstate.c b/src/mesa/drivers/dri/r200/r200_texstate.c
index 4e53672aee..c94834752e 100644
--- a/src/mesa/drivers/dri/r200/r200_texstate.c
+++ b/src/mesa/drivers/dri/r200/r200_texstate.c
@@ -321,7 +321,7 @@ static GLboolean r200UpdateTextureEnv( GLcontext *ctx, int unit, int slot, GLuin
assert( (texUnit->_ReallyEnabled == 0)
|| (texUnit->_Current != NULL) );
- if ( R200_DEBUG & DEBUG_TEXTURE ) {
+ if ( R200_DEBUG & RADEON_TEXTURE ) {
fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
}
@@ -1084,6 +1084,8 @@ static void disable_tex_obj_state( r200ContextPtr rmesa,
R200_STATECHANGE( rmesa, vtx );
rmesa->hw.vtx.cmd[VTX_TCL_OUTPUT_VTXFMT_1] &= ~(7 << (unit * 3));
+ R200_STATECHANGE( rmesa, ctx );
+ rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= ~(R200_TEX_0_ENABLE << unit);
if (rmesa->radeon.TclFallback & (R200_TCL_FALLBACK_TEXGEN_0<<unit)) {
TCL_FALLBACK( rmesa->radeon.glCtx, (R200_TCL_FALLBACK_TEXGEN_0<<unit), GL_FALSE);
}
@@ -1276,7 +1278,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
}
if (mixed_fallback) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback mixed texgen, 0x%x (0x%x 0x%x 0x%x 0x%x)\n",
texUnit->TexGenEnabled, texUnit->GenS.Mode, texUnit->GenT.Mode,
texUnit->GenR.Mode, texUnit->GenQ.Mode);
@@ -1302,7 +1304,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
texUnit->GenR.ObjectPlane,
texUnit->GenQ.ObjectPlane );
if (needtgenable & (S_BIT | T_BIT)) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback mixed texgen / obj plane, 0x%x\n",
texUnit->TexGenEnabled);
return GL_FALSE;
@@ -1330,7 +1332,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
texUnit->GenR.EyePlane,
texUnit->GenQ.EyePlane );
if (needtgenable & (S_BIT | T_BIT)) {
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback mixed texgen / eye plane, 0x%x\n",
texUnit->TexGenEnabled);
return GL_FALSE;
@@ -1380,7 +1382,7 @@ static GLboolean r200_validate_texgen( GLcontext *ctx, GLuint unit )
default:
/* Unsupported mode, fallback:
*/
- if (R200_DEBUG & DEBUG_FALLBACKS)
+ if (R200_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback unsupported texgen, %d\n",
texUnit->GenS.Mode);
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/r200/r200_vertprog.c b/src/mesa/drivers/dri/r200/r200_vertprog.c
index 620f29b5c6..11405d7cae 100644
--- a/src/mesa/drivers/dri/r200/r200_vertprog.c
+++ b/src/mesa/drivers/dri/r200/r200_vertprog.c
@@ -423,7 +423,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
~(VERT_BIT_POS | VERT_BIT_NORMAL | VERT_BIT_COLOR0 | VERT_BIT_COLOR1 |
VERT_BIT_FOG | VERT_BIT_TEX0 | VERT_BIT_TEX1 | VERT_BIT_TEX2 |
VERT_BIT_TEX3 | VERT_BIT_TEX4 | VERT_BIT_TEX5)) != 0) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "can't handle vert prog inputs 0x%x\n",
mesa_vp->Base.InputsRead);
}
@@ -436,7 +436,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
(1 << VERT_RESULT_FOGC) | (1 << VERT_RESULT_TEX0) | (1 << VERT_RESULT_TEX1) |
(1 << VERT_RESULT_TEX2) | (1 << VERT_RESULT_TEX3) | (1 << VERT_RESULT_TEX4) |
(1 << VERT_RESULT_TEX5) | (1 << VERT_RESULT_PSIZ))) != 0) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "can't handle vert prog outputs 0x%x\n",
mesa_vp->Base.OutputsWritten);
}
@@ -551,7 +551,7 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
if (mesa_vp->Base.InputsRead & (1 << i)) {
array_count++;
if (array_count > 12) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "more than 12 attribs used in vert prog\n");
}
return GL_FALSE;
@@ -571,13 +571,13 @@ static GLboolean r200_translate_vertex_program(GLcontext *ctx, struct r200_verte
}
if (!(mesa_vp->Base.OutputsWritten & (1 << VERT_RESULT_HPOS))) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "can't handle vert prog without position output\n");
}
return GL_FALSE;
}
if (free_inputs & 1) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "can't handle vert prog without position input\n");
}
return GL_FALSE;
@@ -1070,7 +1070,7 @@ else {
mesa_vp->Base.NumTemporaries + u_temp_used;
}
if ((mesa_vp->Base.NumTemporaries + u_temp_used) > R200_VSF_MAX_TEMPS) {
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "Ran out of temps, num temps %d, us %d\n", mesa_vp->Base.NumTemporaries, u_temp_used);
}
return GL_FALSE;
@@ -1078,7 +1078,7 @@ else {
u_temp_i = R200_VSF_MAX_TEMPS - 1;
if(o_inst - vp->instr >= R200_VSF_MAX_INST) {
mesa_vp->Base.NumNativeInstructions = 129;
- if (R200_DEBUG & DEBUG_FALLBACKS) {
+ if (R200_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "more than 128 native instructions\n");
}
return GL_FALSE;
diff --git a/src/mesa/drivers/dri/r200/radeon_debug.c b/src/mesa/drivers/dri/r200/radeon_debug.c
new file mode 120000
index 0000000000..c98c2e074c
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_debug.c
@@ -0,0 +1 @@
+../radeon/radeon_debug.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_debug.h b/src/mesa/drivers/dri/r200/radeon_debug.h
new file mode 120000
index 0000000000..bd8aa28e89
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_debug.h
@@ -0,0 +1 @@
+../radeon/radeon_debug.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_queryobj.c b/src/mesa/drivers/dri/r200/radeon_queryobj.c
new file mode 120000
index 0000000000..1d6ebc1c48
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_queryobj.c
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r200/radeon_queryobj.h b/src/mesa/drivers/dri/r200/radeon_queryobj.h
new file mode 120000
index 0000000000..8f6f842b0a
--- /dev/null
+++ b/src/mesa/drivers/dri/r200/radeon_queryobj.h
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/Makefile b/src/mesa/drivers/dri/r300/Makefile
index 7460410ee6..fe775eac99 100644
--- a/src/mesa/drivers/dri/r300/Makefile
+++ b/src/mesa/drivers/dri/r300/Makefile
@@ -27,16 +27,19 @@ COMMON_SOURCES = \
../common/dri_util.c
RADEON_COMMON_SOURCES = \
- radeon_texture.c \
+ radeon_bo_legacy.c \
+ radeon_buffer_objects.c \
radeon_common_context.c \
radeon_common.c \
+ radeon_cs_legacy.c \
radeon_dma.c \
+ radeon_debug.c \
+ radeon_fbo.c \
radeon_lock.c \
- radeon_bo_legacy.c \
- radeon_cs_legacy.c \
radeon_mipmap_tree.c \
radeon_span.c \
- radeon_fbo.c
+ radeon_queryobj.c \
+ radeon_texture.c
DRIVER_SOURCES = \
radeon_screen.c \
@@ -48,17 +51,8 @@ DRIVER_SOURCES = \
r300_render.c \
r300_tex.c \
r300_texstate.c \
- radeon_program.c \
- radeon_program_alu.c \
- radeon_program_pair.c \
- radeon_nqssadce.c \
r300_vertprog.c \
r300_fragprog_common.c \
- r300_fragprog.c \
- r300_fragprog_swizzle.c \
- r300_fragprog_emit.c \
- r500_fragprog.c \
- r500_fragprog_emit.c \
r300_shader.c \
r300_emit.c \
r300_swtcl.c \
@@ -68,15 +62,22 @@ 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
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
+PIPE_DRIVERS = compiler/libr300compiler.a
+
##### TARGETS #####
include ../Makefile.template
symlinks:
+
+# Mark the archive phony so that we always check for recompilation
+.PHONY : compiler/libr300compiler.a
+
+compiler/libr300compiler.a:
+ cd compiler && $(MAKE)
diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
new file mode 100644
index 0000000000..d973844192
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/Makefile
@@ -0,0 +1,75 @@
+# src/mesa/drivers/dri/r300/compiler/Makefile
+
+TOP = ../../../../../..
+include $(TOP)/configs/current
+
+LIBNAME = r300compiler
+
+C_SOURCES = \
+ radeon_code.c \
+ radeon_compiler.c \
+ radeon_nqssadce.c \
+ radeon_program.c \
+ radeon_program_alu.c \
+ radeon_program_pair.c \
+ r3xx_fragprog.c \
+ r300_fragprog.c \
+ r300_fragprog_swizzle.c \
+ r300_fragprog_emit.c \
+ r500_fragprog.c \
+ r500_fragprog_emit.c \
+ r3xx_vertprog.c \
+ r3xx_vertprog_dump.c \
+ \
+ memory_pool.c
+
+
+### Basic defines ###
+
+OBJECTS = $(C_SOURCES:.c=.o) \
+ $(CPP_SOURCES:.cpp=.o) \
+ $(ASM_SOURCES:.S=.o)
+
+INCLUDES = \
+ -I. \
+ -I$(TOP)/include \
+ -I$(TOP)/src/mesa \
+
+
+##### TARGETS #####
+
+default: depend lib$(LIBNAME).a
+
+lib$(LIBNAME).a: $(OBJECTS) Makefile $(TOP)/configs/current
+ $(MKLIB) -o $(LIBNAME) -static $(OBJECTS)
+
+depend: $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) $(SYMLINKS)
+ rm -f depend
+ touch depend
+ $(MKDEP) $(MKDEP_OPTIONS) $(INCLUDES) $(C_SOURCES) $(CPP_SOURCES) $(ASM_SOURCES) 2> /dev/null
+
+# Emacs tags
+tags:
+ etags `find . -name \*.[ch]` `find ../include`
+
+# Remove .o and backup files
+clean:
+ rm -f $(OBJECTS) lib$(LIBNAME).a depend depend.bak
+
+# Dummy target
+install:
+ @echo -n ""
+
+##### RULES #####
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+.cpp.o:
+ $(CXX) -c $(INCLUDES) $(CXXFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+.S.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(LIBRARY_DEFINES) $< -o $@
+
+
+sinclude depend
diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.c b/src/mesa/drivers/dri/r300/compiler/memory_pool.c
new file mode 100644
index 0000000000..37aa2b6579
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.c
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "memory_pool.h"
+
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define POOL_LARGE_ALLOC 4096
+#define POOL_ALIGN 4
+
+
+struct memory_block {
+ struct memory_block * next;
+};
+
+void memory_pool_init(struct memory_pool * pool)
+{
+ memset(pool, 0, sizeof(struct memory_pool));
+}
+
+
+void memory_pool_destroy(struct memory_pool * pool)
+{
+ while(pool->blocks) {
+ struct memory_block * block = pool->blocks;
+ pool->blocks = block->next;
+ free(block);
+ }
+}
+
+static void refill_pool(struct memory_pool * pool)
+{
+ unsigned int blocksize = pool->total_allocated;
+ struct memory_block * newblock;
+
+ if (!blocksize)
+ blocksize = 2*POOL_LARGE_ALLOC;
+
+ newblock = (struct memory_block*)malloc(blocksize);
+ newblock->next = pool->blocks;
+ pool->blocks = newblock;
+
+ pool->head = (unsigned char*)(newblock + 1);
+ pool->end = ((unsigned char*)newblock) + blocksize;
+ pool->total_allocated += blocksize;
+}
+
+
+void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes)
+{
+ if (bytes < POOL_LARGE_ALLOC) {
+ if (pool->head + bytes > pool->end)
+ refill_pool(pool);
+
+ assert(pool->head + bytes <= pool->end);
+
+ void * ptr = pool->head;
+
+ pool->head += bytes;
+ pool->head = (unsigned char*)(((unsigned long)pool->head + POOL_ALIGN - 1) & ~(POOL_ALIGN - 1));
+
+ return ptr;
+ } else {
+ struct memory_block * block = (struct memory_block*)malloc(bytes + sizeof(struct memory_block));
+
+ block->next = pool->blocks;
+ pool->blocks = block;
+
+ return (block + 1);
+ }
+}
+
+
diff --git a/src/mesa/drivers/dri/r300/compiler/memory_pool.h b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
new file mode 100644
index 0000000000..ce23c319ad
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/memory_pool.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef MEMORY_POOL_H
+#define MEMORY_POOL_H
+
+struct memory_block;
+
+/**
+ * Provides a pool of memory that can quickly be allocated from, at the
+ * cost of being unable to explicitly free one of the allocated blocks.
+ * Instead, the entire pool can be freed at once.
+ *
+ * The idea is to allow one to quickly allocate a flexible amount of
+ * memory during operations like shader compilation while avoiding
+ * reference counting headaches.
+ */
+struct memory_pool {
+ unsigned char * head;
+ unsigned char * end;
+ unsigned int total_allocated;
+ struct memory_block * blocks;
+};
+
+
+void memory_pool_init(struct memory_pool * pool);
+void memory_pool_destroy(struct memory_pool * pool);
+void * memory_pool_malloc(struct memory_pool * pool, unsigned int bytes);
+
+#endif /* MEMORY_POOL_H */
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
new file mode 100644
index 0000000000..6c9fba4914
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.c
@@ -0,0 +1,416 @@
+/*
+ * Copyright (C) 2005 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "r300_fragprog.h"
+
+#include "shader/prog_parameter.h"
+
+#include "../r300_reg.h"
+
+static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
+{
+ struct prog_src_register reg = { 0, };
+
+ reg.File = PROGRAM_STATE_VAR;
+ reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
+ reg.Swizzle = SWIZZLE_WWWW;
+ return reg;
+}
+
+/**
+ * Transform TEX, TXP, TXB, and KIL instructions in the following way:
+ * - premultiply texture coordinates for RECT
+ * - extract operand swizzles
+ * - introduce a temporary register when write masks are needed
+ */
+GLboolean r300_transform_TEX(
+ struct radeon_compiler * c,
+ struct rc_instruction* inst,
+ void* data)
+{
+ struct r300_fragment_program_compiler *compiler =
+ (struct r300_fragment_program_compiler*)data;
+
+ if (inst->I.Opcode != OPCODE_TEX &&
+ inst->I.Opcode != OPCODE_TXB &&
+ inst->I.Opcode != OPCODE_TXP &&
+ inst->I.Opcode != OPCODE_KIL)
+ return GL_FALSE;
+
+ /* ARB_shadow & EXT_shadow_funcs */
+ if (inst->I.Opcode != OPCODE_KIL &&
+ c->Program.ShadowSamplers & (1 << inst->I.TexSrcUnit)) {
+ GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
+
+ if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
+ inst->I.Opcode = OPCODE_MOV;
+
+ if (comparefunc == GL_ALWAYS) {
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_1111;
+ } else {
+ inst->I.SrcReg[0] = shadow_ambient(c, inst->I.TexSrcUnit);
+ }
+
+ return GL_TRUE;
+ } else {
+ GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
+ GLuint depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
+ struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
+ struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
+ struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
+ int pass, fail;
+
+ inst_rcp->I.Opcode = OPCODE_RCP;
+ inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_rcp->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
+ inst_rcp->I.SrcReg[0] = inst->I.SrcReg[0];
+ inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
+
+ inst_cmp->I.DstReg = inst->I.DstReg;
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = rc_find_free_temporary(c);
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
+
+ inst_mad->I.Opcode = OPCODE_MAD;
+ inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mad->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_mad->I.SrcReg[0] = inst->I.SrcReg[0];
+ inst_mad->I.SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
+ inst_mad->I.SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst_mad->I.SrcReg[1].Index = inst_rcp->I.DstReg.Index;
+ inst_mad->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
+ inst_mad->I.SrcReg[2].File = PROGRAM_TEMPORARY;
+ inst_mad->I.SrcReg[2].Index = inst->I.DstReg.Index;
+ if (depthmode == 0) /* GL_LUMINANCE */
+ inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
+ else if (depthmode == 2) /* GL_ALPHA */
+ inst_mad->I.SrcReg[2].Swizzle = SWIZZLE_WWWW;
+
+ /* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
+ * r < tex <=> -tex+r < 0
+ * r >= tex <=> not (-tex+r < 0 */
+ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
+ inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ NEGATE_XYZW;
+ else
+ inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ NEGATE_XYZW;
+
+ inst_cmp->I.Opcode = OPCODE_CMP;
+ /* DstReg has been filled out above */
+ inst_cmp->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst_cmp->I.SrcReg[0].Index = inst_mad->I.DstReg.Index;
+
+ if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
+ pass = 1;
+ fail = 2;
+ } else {
+ pass = 2;
+ fail = 1;
+ }
+
+ inst_cmp->I.SrcReg[pass].File = PROGRAM_BUILTIN;
+ inst_cmp->I.SrcReg[pass].Swizzle = SWIZZLE_1111;
+ inst_cmp->I.SrcReg[fail] = shadow_ambient(c, inst->I.TexSrcUnit);
+ }
+ }
+
+ /* Hardware uses [0..1]x[0..1] range for rectangle textures
+ * instead of [0..Width]x[0..Height].
+ * Add a scaling instruction.
+ */
+ if (inst->I.Opcode != OPCODE_KIL && inst->I.TexSrcTarget == TEXTURE_RECT_INDEX) {
+ struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst->Prev);
+
+ inst_mul->I.Opcode = OPCODE_MUL;
+ inst_mul->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mul->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_mul->I.SrcReg[0] = inst->I.SrcReg[0];
+ inst_mul->I.SrcReg[1].File = PROGRAM_STATE_VAR;
+ inst_mul->I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_TEXRECT_FACTOR, inst->I.TexSrcUnit);
+
+ reset_srcreg(&inst->I.SrcReg[0]);
+ inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[0].Index = inst_mul->I.DstReg.Index;
+ }
+
+ /* Cannot write texture to output registers or with masks */
+ if (inst->I.Opcode != OPCODE_KIL &&
+ (inst->I.DstReg.File != PROGRAM_TEMPORARY || inst->I.DstReg.WriteMask != WRITEMASK_XYZW)) {
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
+
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg = inst->I.DstReg;
+ inst_mov->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst_mov->I.SrcReg[0].Index = rc_find_free_temporary(c);
+
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
+ }
+
+
+ /* Cannot read texture coordinate from constants file */
+ if (inst->I.SrcReg[0].File != PROGRAM_TEMPORARY && inst->I.SrcReg[0].File != PROGRAM_INPUT) {
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
+
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mov->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_mov->I.SrcReg[0] = inst->I.SrcReg[0];
+
+ reset_srcreg(&inst->I.SrcReg[0]);
+ inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[0].Index = inst_mov->I.DstReg.Index;
+ }
+
+ return GL_TRUE;
+}
+
+/* just some random things... */
+void r300FragmentProgramDump(struct rX00_fragment_program_code *c)
+{
+ struct r300_fragment_program_code *code = &c->code.r300;
+ int n, i, j;
+ static int pc = 0;
+
+ fprintf(stderr, "pc=%d*************************************\n", pc++);
+
+ fprintf(stderr, "Hardware program\n");
+ fprintf(stderr, "----------------\n");
+
+ for (n = 0; n <= (code->config & 3); n++) {
+ uint32_t code_addr = code->code_addr[3 - (code->config & 3) + n];
+ int alu_offset = (code_addr & R300_ALU_START_MASK) >> R300_ALU_START_SHIFT;
+ int alu_end = (code_addr & R300_ALU_SIZE_MASK) >> R300_ALU_SIZE_SHIFT;
+ int tex_offset = (code_addr & R300_TEX_START_MASK) >> R300_TEX_START_SHIFT;
+ int tex_end = (code_addr & R300_TEX_SIZE_MASK) >> R300_TEX_SIZE_SHIFT;
+
+ fprintf(stderr, "NODE %d: alu_offset: %d, tex_offset: %d, "
+ "alu_end: %d, tex_end: %d (code_addr: %08x)\n", n,
+ alu_offset, tex_offset, alu_end, tex_end, code_addr);
+
+ if (n > 0 || (code->config & R300_PFS_CNTL_FIRST_NODE_HAS_TEX)) {
+ fprintf(stderr, " TEX:\n");
+ for (i = tex_offset;
+ i <= tex_offset + tex_end;
+ ++i) {
+ const char *instr;
+
+ switch ((code->tex.
+ inst[i] >> R300_TEX_INST_SHIFT) &
+ 15) {
+ case R300_TEX_OP_LD:
+ instr = "TEX";
+ break;
+ case R300_TEX_OP_KIL:
+ instr = "KIL";
+ break;
+ case R300_TEX_OP_TXP:
+ instr = "TXP";
+ break;
+ case R300_TEX_OP_TXB:
+ instr = "TXB";
+ break;
+ default:
+ instr = "UNKNOWN";
+ }
+
+ fprintf(stderr,
+ " %s t%i, %c%i, texture[%i] (%08x)\n",
+ instr,
+ (code->tex.
+ inst[i] >> R300_DST_ADDR_SHIFT) & 31,
+ 't',
+ (code->tex.
+ inst[i] >> R300_SRC_ADDR_SHIFT) & 31,
+ (code->tex.
+ inst[i] & R300_TEX_ID_MASK) >>
+ R300_TEX_ID_SHIFT,
+ code->tex.inst[i]);
+ }
+ }
+
+ for (i = alu_offset;
+ i <= alu_offset + alu_end; ++i) {
+ char srcc[3][10], dstc[20];
+ char srca[3][10], dsta[20];
+ char argc[3][20];
+ char arga[3][20];
+ char flags[5], tmp[10];
+
+ for (j = 0; j < 3; ++j) {
+ int regc = code->alu.inst[i].rgb_addr >> (j * 6);
+ int rega = code->alu.inst[i].alpha_addr >> (j * 6);
+
+ sprintf(srcc[j], "%c%i",
+ (regc & 32) ? 'c' : 't', regc & 31);
+ sprintf(srca[j], "%c%i",
+ (rega & 32) ? 'c' : 't', rega & 31);
+ }
+
+ dstc[0] = 0;
+ sprintf(flags, "%s%s%s",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_REG_X) ? "x" : "",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_REG_Y) ? "y" : "",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_REG_Z) ? "z" : "");
+ if (flags[0] != 0) {
+ sprintf(dstc, "t%i.%s ",
+ (code->alu.inst[i].
+ rgb_addr >> R300_ALU_DSTC_SHIFT) & 31,
+ flags);
+ }
+ sprintf(flags, "%s%s%s",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_OUTPUT_X) ? "x" : "",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "",
+ (code->alu.inst[i].
+ rgb_addr & R300_ALU_DSTC_OUTPUT_Z) ? "z" : "");
+ if (flags[0] != 0) {
+ sprintf(tmp, "o%i.%s",
+ (code->alu.inst[i].
+ rgb_addr >> R300_ALU_DSTC_SHIFT) & 31,
+ flags);
+ strcat(dstc, tmp);
+ }
+
+ dsta[0] = 0;
+ if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_REG) {
+ sprintf(dsta, "t%i.w ",
+ (code->alu.inst[i].
+ alpha_addr >> R300_ALU_DSTA_SHIFT) & 31);
+ }
+ if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_OUTPUT) {
+ sprintf(tmp, "o%i.w ",
+ (code->alu.inst[i].
+ alpha_addr >> R300_ALU_DSTA_SHIFT) & 31);
+ strcat(dsta, tmp);
+ }
+ if (code->alu.inst[i].alpha_addr & R300_ALU_DSTA_DEPTH) {
+ strcat(dsta, "Z");
+ }
+
+ fprintf(stderr,
+ "%3i: xyz: %3s %3s %3s -> %-20s (%08x)\n"
+ " w: %3s %3s %3s -> %-20s (%08x)\n", i,
+ srcc[0], srcc[1], srcc[2], dstc,
+ code->alu.inst[i].rgb_addr, srca[0], srca[1],
+ srca[2], dsta, code->alu.inst[i].alpha_addr);
+
+ for (j = 0; j < 3; ++j) {
+ int regc = code->alu.inst[i].rgb_inst >> (j * 7);
+ int rega = code->alu.inst[i].alpha_inst >> (j * 7);
+ int d;
+ char buf[20];
+
+ d = regc & 31;
+ if (d < 12) {
+ switch (d % 4) {
+ case R300_ALU_ARGC_SRC0C_XYZ:
+ sprintf(buf, "%s.xyz",
+ srcc[d / 4]);
+ break;
+ case R300_ALU_ARGC_SRC0C_XXX:
+ sprintf(buf, "%s.xxx",
+ srcc[d / 4]);
+ break;
+ case R300_ALU_ARGC_SRC0C_YYY:
+ sprintf(buf, "%s.yyy",
+ srcc[d / 4]);
+ break;
+ case R300_ALU_ARGC_SRC0C_ZZZ:
+ sprintf(buf, "%s.zzz",
+ srcc[d / 4]);
+ break;
+ }
+ } else if (d < 15) {
+ sprintf(buf, "%s.www", srca[d - 12]);
+ } else if (d == 20) {
+ sprintf(buf, "0.0");
+ } else if (d == 21) {
+ sprintf(buf, "1.0");
+ } else if (d == 22) {
+ sprintf(buf, "0.5");
+ } else if (d >= 23 && d < 32) {
+ d -= 23;
+ switch (d / 3) {
+ case 0:
+ sprintf(buf, "%s.yzx",
+ srcc[d % 3]);
+ break;
+ case 1:
+ sprintf(buf, "%s.zxy",
+ srcc[d % 3]);
+ break;
+ case 2:
+ sprintf(buf, "%s.Wzy",
+ srcc[d % 3]);
+ break;
+ }
+ } else {
+ sprintf(buf, "%i", d);
+ }
+
+ sprintf(argc[j], "%s%s%s%s",
+ (regc & 32) ? "-" : "",
+ (regc & 64) ? "|" : "",
+ buf, (regc & 64) ? "|" : "");
+
+ d = rega & 31;
+ if (d < 9) {
+ sprintf(buf, "%s.%c", srcc[d / 3],
+ 'x' + (char)(d % 3));
+ } else if (d < 12) {
+ sprintf(buf, "%s.w", srca[d - 9]);
+ } else if (d == 16) {
+ sprintf(buf, "0.0");
+ } else if (d == 17) {
+ sprintf(buf, "1.0");
+ } else if (d == 18) {
+ sprintf(buf, "0.5");
+ } else {
+ sprintf(buf, "%i", d);
+ }
+
+ sprintf(arga[j], "%s%s%s%s",
+ (rega & 32) ? "-" : "",
+ (rega & 64) ? "|" : "",
+ buf, (rega & 64) ? "|" : "");
+ }
+
+ fprintf(stderr, " xyz: %8s %8s %8s op: %08x\n"
+ " w: %8s %8s %8s op: %08x\n",
+ argc[0], argc[1], argc[2],
+ code->alu.inst[i].rgb_inst, arga[0], arga[1],
+ arga[2], code->alu.inst[i].alpha_inst);
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
new file mode 100644
index 0000000000..0ac46dbd9c
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2005 Ben Skeggs.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+/*
+ * Authors:
+ * Ben Skeggs <darktama@iinet.net.au>
+ * Jerome Glisse <j.glisse@gmail.com>
+ */
+#ifndef __R300_FRAGPROG_H_
+#define __R300_FRAGPROG_H_
+
+#include "shader/program.h"
+#include "shader/prog_instruction.h"
+
+#include "radeon_compiler.h"
+#include "radeon_program.h"
+
+
+extern void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
+
+extern void r300FragmentProgramDump(struct rX00_fragment_program_code *c);
+
+extern GLboolean r300_transform_TEX(struct radeon_compiler * c, struct rc_instruction* inst, void* data);
+
+#endif
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
index b75656e7ee..c7227bbd15 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_emit.c
@@ -40,57 +40,43 @@
#include "r300_fragprog.h"
+#include "../r300_reg.h"
+
#include "radeon_program_pair.h"
#include "r300_fragprog_swizzle.h"
-#include "r300_reg.h"
+struct r300_emit_state {
+ struct r300_fragment_program_compiler * compiler;
+
+ unsigned current_node : 2;
+ unsigned node_first_tex : 8;
+ unsigned node_first_alu : 8;
+ uint32_t node_flags;
+};
+
#define PROG_CODE \
- struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \
- struct r300_fragment_program_code *code = &c->code->r300
+ struct r300_emit_state * emit = (struct r300_emit_state*)data; \
+ struct r300_fragment_program_compiler *c = emit->compiler; \
+ struct r300_fragment_program_code *code = &c->code->code.r300
#define error(fmt, args...) do { \
- fprintf(stderr, "%s::%s(): " fmt "\n", \
+ rc_error(&c->Base, "%s::%s(): " fmt "\n", \
__FILE__, __FUNCTION__, ##args); \
} while(0)
-static GLboolean emit_const(void* data, GLuint file, GLuint index, GLuint *hwindex)
-{
- PROG_CODE;
-
- for (*hwindex = 0; *hwindex < code->const_nr; ++*hwindex) {
- if (code->constant[*hwindex].File == file &&
- code->constant[*hwindex].Index == index)
- break;
- }
-
- if (*hwindex >= code->const_nr) {
- if (*hwindex >= R300_PFS_NUM_CONST_REGS) {
- error("Out of hw constants!\n");
- return GL_FALSE;
- }
-
- code->const_nr++;
- code->constant[*hwindex].File = file;
- code->constant[*hwindex].Index = index;
- }
-
- return GL_TRUE;
-}
-
-
/**
* Mark a temporary register as used.
*/
static void use_temporary(struct r300_fragment_program_code *code, GLuint index)
{
- if (index > code->max_temp_idx)
- code->max_temp_idx = index;
+ if (index > code->pixsize)
+ code->pixsize = index;
}
-static GLuint translate_rgb_opcode(GLuint opcode)
+static GLuint translate_rgb_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
{
switch(opcode) {
case OPCODE_CMP: return R300_ALU_OUTC_CMP;
@@ -109,7 +95,7 @@ static GLuint translate_rgb_opcode(GLuint opcode)
}
}
-static GLuint translate_alpha_opcode(GLuint opcode)
+static GLuint translate_alpha_opcode(struct r300_fragment_program_compiler * c, GLuint opcode)
{
switch(opcode) {
case OPCODE_CMP: return R300_ALU_OUTA_CMP;
@@ -145,63 +131,62 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
int ip = code->alu.length++;
int j;
- code->node[code->cur_node].alu_end++;
- code->alu.inst[ip].inst0 = translate_rgb_opcode(inst->RGB.Opcode);
- code->alu.inst[ip].inst2 = translate_alpha_opcode(inst->Alpha.Opcode);
+ code->alu.inst[ip].rgb_inst = translate_rgb_opcode(c, inst->RGB.Opcode);
+ code->alu.inst[ip].alpha_inst = translate_alpha_opcode(c, inst->Alpha.Opcode);
for(j = 0; j < 3; ++j) {
GLuint src = inst->RGB.Src[j].Index | (inst->RGB.Src[j].Constant << 5);
if (!inst->RGB.Src[j].Constant)
use_temporary(code, inst->RGB.Src[j].Index);
- code->alu.inst[ip].inst1 |= src << (6*j);
+ code->alu.inst[ip].rgb_addr |= src << (6*j);
src = inst->Alpha.Src[j].Index | (inst->Alpha.Src[j].Constant << 5);
if (!inst->Alpha.Src[j].Constant)
use_temporary(code, inst->Alpha.Src[j].Index);
- code->alu.inst[ip].inst3 |= src << (6*j);
+ code->alu.inst[ip].alpha_addr |= src << (6*j);
GLuint arg = r300FPTranslateRGBSwizzle(inst->RGB.Arg[j].Source, inst->RGB.Arg[j].Swizzle);
arg |= inst->RGB.Arg[j].Abs << 6;
arg |= inst->RGB.Arg[j].Negate << 5;
- code->alu.inst[ip].inst0 |= arg << (7*j);
+ code->alu.inst[ip].rgb_inst |= arg << (7*j);
arg = r300FPTranslateAlphaSwizzle(inst->Alpha.Arg[j].Source, inst->Alpha.Arg[j].Swizzle);
arg |= inst->Alpha.Arg[j].Abs << 6;
arg |= inst->Alpha.Arg[j].Negate << 5;
- code->alu.inst[ip].inst2 |= arg << (7*j);
+ code->alu.inst[ip].alpha_inst |= arg << (7*j);
}
if (inst->RGB.Saturate)
- code->alu.inst[ip].inst0 |= R300_ALU_OUTC_CLAMP;
+ code->alu.inst[ip].rgb_inst |= R300_ALU_OUTC_CLAMP;
if (inst->Alpha.Saturate)
- code->alu.inst[ip].inst2 |= R300_ALU_OUTA_CLAMP;
+ code->alu.inst[ip].alpha_inst |= R300_ALU_OUTA_CLAMP;
if (inst->RGB.WriteMask) {
use_temporary(code, inst->RGB.DestIndex);
- code->alu.inst[ip].inst1 |=
+ code->alu.inst[ip].rgb_addr |=
(inst->RGB.DestIndex << R300_ALU_DSTC_SHIFT) |
(inst->RGB.WriteMask << R300_ALU_DSTC_REG_MASK_SHIFT);
}
if (inst->RGB.OutputWriteMask) {
- code->alu.inst[ip].inst1 |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT);
- code->node[code->cur_node].flags |= R300_RGBA_OUT;
+ code->alu.inst[ip].rgb_addr |= (inst->RGB.OutputWriteMask << R300_ALU_DSTC_OUTPUT_MASK_SHIFT);
+ emit->node_flags |= R300_RGBA_OUT;
}
if (inst->Alpha.WriteMask) {
use_temporary(code, inst->Alpha.DestIndex);
- code->alu.inst[ip].inst3 |=
+ code->alu.inst[ip].alpha_addr |=
(inst->Alpha.DestIndex << R300_ALU_DSTA_SHIFT) |
R300_ALU_DSTA_REG;
}
if (inst->Alpha.OutputWriteMask) {
- code->alu.inst[ip].inst3 |= R300_ALU_DSTA_OUTPUT;
- code->node[code->cur_node].flags |= R300_RGBA_OUT;
+ code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_OUTPUT;
+ emit->node_flags |= R300_RGBA_OUT;
}
if (inst->Alpha.DepthWriteMask) {
- code->alu.inst[ip].inst3 |= R300_ALU_DSTA_DEPTH;
- code->node[code->cur_node].flags |= R300_W_OUT;
- c->fp->writes_depth = GL_TRUE;
+ code->alu.inst[ip].alpha_addr |= R300_ALU_DSTA_DEPTH;
+ emit->node_flags |= R300_W_OUT;
+ c->code->writes_depth = GL_TRUE;
}
return GL_TRUE;
@@ -211,31 +196,50 @@ static GLboolean emit_alu(void* data, struct radeon_pair_instruction* inst)
/**
* Finish the current node without advancing to the next one.
*/
-static GLboolean finish_node(struct r300_fragment_program_compiler *c)
+static GLboolean finish_node(struct r300_emit_state * emit)
{
- struct r300_fragment_program_code *code = &c->code->r300;
- struct r300_fragment_program_node *node = &code->node[code->cur_node];
+ struct r300_fragment_program_compiler * c = emit->compiler;
+ struct r300_fragment_program_code *code = &emit->compiler->code->code.r300;
- if (node->alu_end < 0) {
+ if (code->alu.length == emit->node_first_alu) {
/* Generate a single NOP for this node */
struct radeon_pair_instruction inst;
_mesa_bzero(&inst, sizeof(inst));
- if (!emit_alu(c, &inst))
+ if (!emit_alu(emit, &inst))
return GL_FALSE;
}
- if (node->tex_end < 0) {
- if (code->cur_node == 0) {
- node->tex_end = 0;
- } else {
- error("Node %i has no TEX instructions", code->cur_node);
+ unsigned alu_offset = emit->node_first_alu;
+ unsigned alu_end = code->alu.length - alu_offset - 1;
+ unsigned tex_offset = emit->node_first_tex;
+ unsigned tex_end = code->tex.length - tex_offset - 1;
+
+ if (code->tex.length == emit->node_first_tex) {
+ if (emit->current_node > 0) {
+ error("Node %i has no TEX instructions", emit->current_node);
return GL_FALSE;
}
+
+ tex_end = 0;
} else {
- if (code->cur_node == 0)
- code->first_node_has_tex = 1;
+ if (emit->current_node == 0)
+ code->config |= R300_PFS_CNTL_FIRST_NODE_HAS_TEX;
}
+ /* Write the config register.
+ * Note: The order in which the words for each node are written
+ * is not correct here and needs to be fixed up once we're entirely
+ * done
+ *
+ * Also note that the register specification from AMD is slightly
+ * incorrect in its description of this register. */
+ code->code_addr[emit->current_node] =
+ (alu_offset << R300_ALU_START_SHIFT) |
+ (alu_end << R300_ALU_SIZE_SHIFT) |
+ (tex_offset << R300_TEX_START_SHIFT) |
+ (tex_end << R300_TEX_SIZE_SHIFT) |
+ emit->node_flags;
+
return GL_TRUE;
}
@@ -248,30 +252,28 @@ static GLboolean begin_tex(void* data)
{
PROG_CODE;
- if (code->cur_node == 0) {
- if (code->node[0].alu_end < 0 &&
- code->node[0].tex_end < 0)
- return GL_TRUE;
+ if (code->alu.length == emit->node_first_alu &&
+ code->tex.length == emit->node_first_tex) {
+ return GL_TRUE;
}
- if (code->cur_node == 3) {
+ if (emit->current_node == 3) {
error("Too many texture indirections");
return GL_FALSE;
}
- if (!finish_node(c))
+ if (!finish_node(emit))
return GL_FALSE;
- struct r300_fragment_program_node *node = &code->node[++code->cur_node];
- node->alu_offset = code->alu.length;
- node->alu_end = -1;
- node->tex_offset = code->tex.length;
- node->tex_end = -1;
+ emit->current_node++;
+ emit->node_first_tex = code->tex.length;
+ emit->node_first_alu = code->alu.length;
+ emit->node_flags = 0;
return GL_TRUE;
}
-static GLboolean emit_tex(void* data, struct prog_instruction* inst)
+static GLboolean emit_tex(void* data, struct radeon_pair_texture_instruction* inst)
{
PROG_CODE;
@@ -281,31 +283,30 @@ static GLboolean emit_tex(void* data, struct prog_instruction* inst)
}
GLuint unit = inst->TexSrcUnit;
- GLuint dest = inst->DstReg.Index;
+ GLuint dest = inst->DestIndex;
GLuint opcode;
switch(inst->Opcode) {
- case OPCODE_KIL: opcode = R300_TEX_OP_KIL; break;
- case OPCODE_TEX: opcode = R300_TEX_OP_LD; break;
- case OPCODE_TXB: opcode = R300_TEX_OP_TXB; break;
- case OPCODE_TXP: opcode = R300_TEX_OP_TXP; break;
+ case RADEON_OPCODE_KIL: opcode = R300_TEX_OP_KIL; break;
+ case RADEON_OPCODE_TEX: opcode = R300_TEX_OP_LD; break;
+ case RADEON_OPCODE_TXB: opcode = R300_TEX_OP_TXB; break;
+ case RADEON_OPCODE_TXP: opcode = R300_TEX_OP_TXP; break;
default:
error("Unknown texture opcode %i", inst->Opcode);
return GL_FALSE;
}
- if (inst->Opcode == OPCODE_KIL) {
+ if (inst->Opcode == RADEON_OPCODE_KIL) {
unit = 0;
dest = 0;
} else {
use_temporary(code, dest);
}
- use_temporary(code, inst->SrcReg[0].Index);
+ use_temporary(code, inst->SrcIndex);
- code->node[code->cur_node].tex_end++;
code->tex.inst[code->tex.length++] =
- (inst->SrcReg[0].Index << R300_SRC_ADDR_SHIFT) |
+ (inst->SrcIndex << R300_SRC_ADDR_SHIFT) |
(dest << R300_DST_ADDR_SHIFT) |
(unit << R300_TEX_ID_SHIFT) |
(opcode << R300_TEX_INST_SHIFT);
@@ -314,7 +315,6 @@ static GLboolean emit_tex(void* data, struct prog_instruction* inst)
static const struct radeon_pair_handler pair_handler = {
- .EmitConst = &emit_const,
.EmitPaired = &emit_alu,
.EmitTex = &emit_tex,
.BeginTexBlock = &begin_tex,
@@ -325,20 +325,36 @@ static const struct radeon_pair_handler pair_handler = {
* Final compilation step: Turn the intermediate radeon_program into
* machine-readable instructions.
*/
-GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
+void r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
{
- struct r300_fragment_program_code *code = &compiler->code->r300;
-
- _mesa_bzero(code, sizeof(struct r300_fragment_program_code));
- code->node[0].alu_end = -1;
- code->node[0].tex_end = -1;
+ struct r300_emit_state emit;
+ struct r300_fragment_program_code *code = &compiler->code->code.r300;
- if (!radeonPairProgram(compiler->r300->radeon.glCtx, compiler->program, &pair_handler, compiler))
- return GL_FALSE;
+ memset(&emit, 0, sizeof(emit));
+ emit.compiler = compiler;
- if (!finish_node(compiler))
- return GL_FALSE;
+ _mesa_bzero(code, sizeof(struct r300_fragment_program_code));
- return GL_TRUE;
+ radeonPairProgram(compiler, &pair_handler, &emit);
+ if (compiler->Base.Error)
+ return;
+
+ /* Finish the program */
+ finish_node(&emit);
+
+ code->config |= emit.current_node; /* FIRST_NODE_HAS_TEX set by finish_node */
+ code->code_offset =
+ (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT) |
+ ((code->alu.length-1) << R300_PFS_CNTL_ALU_END_SHIFT) |
+ (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT) |
+ ((code->tex.length ? code->tex.length-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT);
+
+ if (emit.current_node < 3) {
+ int shift = 3 - emit.current_node;
+ int 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/r300_fragprog_swizzle.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
index fc9d855bce..1b14cc3888 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
@@ -33,8 +33,9 @@
#include "r300_fragprog_swizzle.h"
-#include "r300_reg.h"
+#include "../r300_reg.h"
#include "radeon_nqssadce.h"
+#include "radeon_compiler.h"
#define MAKE_SWZ3(x, y, z) (MAKE_SWIZZLE4(SWIZZLE_##x, SWIZZLE_##y, SWIZZLE_##z, SWIZZLE_ZERO))
@@ -174,18 +175,15 @@ void r300FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
}
}
- struct prog_instruction *inst;
-
- _mesa_insert_instructions(s->Program, s->IP, 1);
- inst = s->Program->Instructions + s->IP++;
- inst->Opcode = OPCODE_MOV;
- inst->DstReg = dst;
- inst->DstReg.WriteMask &= (best_matchmask | WRITEMASK_W);
- inst->SrcReg[0] = src;
- inst->SrcReg[0].Negate = (best_matchmask & src.Negate) ? NEGATE_XYZW : NEGATE_NONE;
+ struct rc_instruction *inst = rc_insert_new_instruction(s->Compiler, s->IP->Prev);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg = dst;
+ inst->I.DstReg.WriteMask &= (best_matchmask | WRITEMASK_W);
+ inst->I.SrcReg[0] = src;
+ inst->I.SrcReg[0].Negate = (best_matchmask & src.Negate) ? NEGATE_XYZW : NEGATE_NONE;
/* Note: We rely on NqSSA/DCE to set unused swizzle components to NIL */
- dst.WriteMask &= ~inst->DstReg.WriteMask;
+ dst.WriteMask &= ~inst->I.DstReg.WriteMask;
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.h b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.h
index 231bf4eef5..231bf4eef5 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_swizzle.h
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.h
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
new file mode 100644
index 0000000000..76c3a7ecfd
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "radeon_compiler.h"
+
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+#include "shader/prog_statevars.h"
+
+#include "radeon_nqssadce.h"
+#include "radeon_program_alu.h"
+#include "r300_fragprog.h"
+#include "r300_fragprog_swizzle.h"
+#include "r500_fragprog.h"
+
+
+static void nqssadce_init(struct nqssadce_state* s)
+{
+ struct r300_fragment_program_compiler * c = s->UserData;
+ s->Outputs[c->OutputColor].Sourced = WRITEMASK_XYZW;
+ s->Outputs[c->OutputDepth].Sourced = WRITEMASK_W;
+}
+
+static void rewrite_depth_out(struct r300_fragment_program_compiler * c)
+{
+ struct rc_instruction *rci;
+
+ for (rci = c->Base.Program.Instructions.Next; rci != &c->Base.Program.Instructions; rci = rci->Next) {
+ struct prog_instruction * inst = &rci->I;
+
+ if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != c->OutputDepth)
+ continue;
+
+ if (inst->DstReg.WriteMask & WRITEMASK_Z) {
+ inst->DstReg.WriteMask = WRITEMASK_W;
+ } else {
+ inst->DstReg.WriteMask = 0;
+ continue;
+ }
+
+ switch (inst->Opcode) {
+ case OPCODE_FRC:
+ case OPCODE_MOV:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ break;
+ case OPCODE_ADD:
+ case OPCODE_MAX:
+ case OPCODE_MIN:
+ case OPCODE_MUL:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
+ break;
+ case OPCODE_CMP:
+ case OPCODE_MAD:
+ inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
+ inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
+ inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
+ break;
+ default:
+ // Scalar instructions needn't be reswizzled
+ break;
+ }
+ }
+}
+
+void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
+{
+ rewrite_depth_out(c);
+
+ if (c->is_r500) {
+ struct radeon_program_transformation transformations[] = {
+ { &r500_transform_TEX, c },
+ { &radeonTransformALU, 0 },
+ { &radeonTransformDeriv, 0 },
+ { &radeonTransformTrigScale, 0 }
+ };
+ radeonLocalTransform(&c->Base, 4, transformations);
+ } else {
+ struct radeon_program_transformation transformations[] = {
+ { &r300_transform_TEX, c },
+ { &radeonTransformALU, 0 },
+ { &radeonTransformTrigSimple, 0 }
+ };
+ radeonLocalTransform(&c->Base, 3, transformations);
+ }
+
+ if (c->Base.Debug) {
+ _mesa_printf("Fragment Program: After native rewrite:\n");
+ rc_print_program(&c->Base.Program);
+ fflush(stderr);
+ }
+
+ if (c->is_r500) {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadce_init,
+ .IsNativeSwizzle = &r500FPIsNativeSwizzle,
+ .BuildSwizzle = &r500FPBuildSwizzle
+ };
+ radeonNqssaDce(&c->Base, &nqssadce, c);
+ } else {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadce_init,
+ .IsNativeSwizzle = &r300FPIsNativeSwizzle,
+ .BuildSwizzle = &r300FPBuildSwizzle
+ };
+ radeonNqssaDce(&c->Base, &nqssadce, c);
+ }
+
+ if (c->Base.Debug) {
+ _mesa_printf("Compiler: after NqSSA-DCE:\n");
+ rc_print_program(&c->Base.Program);
+ fflush(stderr);
+ }
+
+ if (c->is_r500) {
+ r500BuildFragmentProgramHwCode(c);
+ } else {
+ r300BuildFragmentProgramHwCode(c);
+ }
+
+ rc_constants_copy(&c->code->constants, &c->Base.Program.Constants);
+
+ if (c->Base.Debug) {
+ if (c->is_r500) {
+ r500FragmentProgramDump(c->code);
+ } else {
+ r300FragmentProgramDump(c->code);
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
new file mode 100644
index 0000000000..dad27fc98e
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog.c
@@ -0,0 +1,656 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "radeon_compiler.h"
+
+#include "../r300_reg.h"
+
+#include "radeon_nqssadce.h"
+#include "radeon_program.h"
+#include "radeon_program_alu.h"
+
+#include "shader/prog_print.h"
+
+
+/*
+ * Take an already-setup and valid source then swizzle it appropriately to
+ * obtain a constant ZERO or ONE source.
+ */
+#define __CONST(x, y) \
+ (PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[x]), \
+ t_swizzle(y), \
+ t_swizzle(y), \
+ t_swizzle(y), \
+ t_swizzle(y), \
+ t_src_class(vpi->SrcReg[x].File), \
+ NEGATE_NONE) | (vpi->SrcReg[x].RelAddr << 4))
+
+
+static unsigned long t_dst_mask(GLuint mask)
+{
+ /* WRITEMASK_* is equivalent to VSF_FLAG_* */
+ return mask & WRITEMASK_XYZW;
+}
+
+static unsigned long t_dst_class(gl_register_file file)
+{
+
+ switch (file) {
+ case PROGRAM_TEMPORARY:
+ return PVS_DST_REG_TEMPORARY;
+ case PROGRAM_OUTPUT:
+ return PVS_DST_REG_OUT;
+ case PROGRAM_ADDRESS:
+ return PVS_DST_REG_A0;
+ /*
+ case PROGRAM_INPUT:
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_WRITE_ONLY:
+ case PROGRAM_ADDRESS:
+ */
+ default:
+ fprintf(stderr, "problem in %s", __FUNCTION__);
+ _mesa_exit(-1);
+ return -1;
+ }
+}
+
+static unsigned long t_dst_index(struct r300_vertex_program_code *vp,
+ struct prog_dst_register *dst)
+{
+ if (dst->File == PROGRAM_OUTPUT)
+ return vp->outputs[dst->Index];
+
+ return dst->Index;
+}
+
+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:
+ return PVS_SRC_REG_INPUT;
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_CONSTANT:
+ case PROGRAM_STATE_VAR:
+ return PVS_SRC_REG_CONSTANT;
+ /*
+ case PROGRAM_OUTPUT:
+ case PROGRAM_WRITE_ONLY:
+ case PROGRAM_ADDRESS:
+ */
+ default:
+ fprintf(stderr, "problem in %s", __FUNCTION__);
+ _mesa_exit(-1);
+ return -1;
+ }
+}
+
+static GLboolean t_src_conflict(struct prog_src_register a, struct prog_src_register b)
+{
+ unsigned long aclass = t_src_class(a.File);
+ unsigned long bclass = t_src_class(b.File);
+
+ if (aclass != bclass)
+ return GL_FALSE;
+ if (aclass == PVS_SRC_REG_TEMPORARY)
+ return GL_FALSE;
+
+ if (a.RelAddr || b.RelAddr)
+ return GL_TRUE;
+ if (a.Index != b.Index)
+ return GL_TRUE;
+
+ return GL_FALSE;
+}
+
+static INLINE unsigned long t_swizzle(GLubyte swizzle)
+{
+ /* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
+ return swizzle;
+}
+
+static unsigned long t_src_index(struct r300_vertex_program_code *vp,
+ struct prog_src_register *src)
+{
+ if (src->File == PROGRAM_INPUT) {
+ assert(vp->inputs[src->Index] != -1);
+ return vp->inputs[src->Index];
+ } else {
+ if (src->Index < 0) {
+ fprintf(stderr,
+ "negative offsets for indirect addressing do not work.\n");
+ return 0;
+ }
+ return src->Index;
+ }
+}
+
+/* these two functions should probably be merged... */
+
+static unsigned long t_src(struct r300_vertex_program_code *vp,
+ struct prog_src_register *src)
+{
+ /* src->Negate uses the NEGATE_ flags from program_instruction.h,
+ * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
+ */
+ return PVS_SRC_OPERAND(t_src_index(vp, src),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 1)),
+ t_swizzle(GET_SWZ(src->Swizzle, 2)),
+ t_swizzle(GET_SWZ(src->Swizzle, 3)),
+ t_src_class(src->File),
+ src->Negate) | (src->RelAddr << 4);
+}
+
+static unsigned long t_src_scalar(struct r300_vertex_program_code *vp,
+ struct prog_src_register *src)
+{
+ /* src->Negate uses the NEGATE_ flags from program_instruction.h,
+ * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
+ */
+ return PVS_SRC_OPERAND(t_src_index(vp, src),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_swizzle(GET_SWZ(src->Swizzle, 0)),
+ t_src_class(src->File),
+ src->Negate ? NEGATE_XYZW : NEGATE_NONE) |
+ (src->RelAddr << 4);
+}
+
+static GLboolean valid_dst(struct r300_vertex_program_code *vp,
+ struct prog_dst_register *dst)
+{
+ if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
+ return GL_FALSE;
+ } else if (dst->File == PROGRAM_ADDRESS) {
+ assert(dst->Index == 0);
+ }
+
+ return GL_TRUE;
+}
+
+static void ei_vector1(struct r300_vertex_program_code *vp,
+ GLuint hw_opcode,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
+ GL_FALSE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ inst[1] = t_src(vp, &vpi->SrcReg[0]);
+ inst[2] = __CONST(0, SWIZZLE_ZERO);
+ inst[3] = __CONST(0, SWIZZLE_ZERO);
+}
+
+static void ei_vector2(struct r300_vertex_program_code *vp,
+ GLuint hw_opcode,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
+ GL_FALSE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ inst[1] = t_src(vp, &vpi->SrcReg[0]);
+ inst[2] = t_src(vp, &vpi->SrcReg[1]);
+ inst[3] = __CONST(1, SWIZZLE_ZERO);
+}
+
+static void ei_math1(struct r300_vertex_program_code *vp,
+ GLuint hw_opcode,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ inst[0] = PVS_OP_DST_OPERAND(hw_opcode,
+ GL_TRUE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
+ inst[2] = __CONST(0, SWIZZLE_ZERO);
+ inst[3] = __CONST(0, SWIZZLE_ZERO);
+}
+
+static void ei_lit(struct r300_vertex_program_code *vp,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
+
+ inst[0] = PVS_OP_DST_OPERAND(ME_LIGHT_COEFF_DX,
+ GL_TRUE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ /* NOTE: Users swizzling might not work. */
+ inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
+ PVS_SRC_SELECT_FORCE_0, // Z
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
+ t_src_class(vpi->SrcReg[0].File),
+ vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
+ (vpi->SrcReg[0].RelAddr << 4);
+ inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
+ PVS_SRC_SELECT_FORCE_0, // Z
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
+ t_src_class(vpi->SrcReg[0].File),
+ vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
+ (vpi->SrcReg[0].RelAddr << 4);
+ inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &vpi->SrcReg[0]), t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 1)), // Y
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 0)), // X
+ PVS_SRC_SELECT_FORCE_0, // Z
+ t_swizzle(GET_SWZ(vpi->SrcReg[0].Swizzle, 3)), // W
+ t_src_class(vpi->SrcReg[0].File),
+ vpi->SrcReg[0].Negate ? NEGATE_XYZW : NEGATE_NONE) |
+ (vpi->SrcReg[0].RelAddr << 4);
+}
+
+static void ei_mad(struct r300_vertex_program_code *vp,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ /* Remarks about hardware limitations of MAD
+ * (please preserve this comment, as this information is _NOT_
+ * in the documentation provided by AMD).
+ *
+ * As described in the documentation, MAD with three unique temporary
+ * source registers requires the use of the macro version.
+ *
+ * However (and this is not mentioned in the documentation), apparently
+ * the macro version is _NOT_ a full superset of the normal version.
+ * In particular, the macro version does not always work when relative
+ * addressing is used in the source operands.
+ *
+ * This limitation caused incorrect rendering in Sauerbraten's OpenGL
+ * assembly shader path when using medium quality animations
+ * (i.e. animations with matrix blending instead of quaternion blending).
+ *
+ * Unfortunately, I (nha) have been unable to extract a Piglit regression
+ * test for this issue - for some reason, it is possible to have vertex
+ * programs whose prefix is *exactly* the same as the prefix of the
+ * offending program in Sauerbraten up to the offending instruction
+ * without causing any trouble.
+ *
+ * Bottom line: Only use the macro version only when really necessary;
+ * according to AMD docs, this should improve performance by one clock
+ * as a nice side bonus.
+ */
+ if (vpi->SrcReg[0].File == PROGRAM_TEMPORARY &&
+ vpi->SrcReg[1].File == PROGRAM_TEMPORARY &&
+ vpi->SrcReg[2].File == PROGRAM_TEMPORARY &&
+ vpi->SrcReg[0].Index != vpi->SrcReg[1].Index &&
+ vpi->SrcReg[0].Index != vpi->SrcReg[2].Index &&
+ vpi->SrcReg[1].Index != vpi->SrcReg[2].Index) {
+ inst[0] = PVS_OP_DST_OPERAND(PVS_MACRO_OP_2CLK_MADD,
+ GL_FALSE,
+ GL_TRUE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ } else {
+ inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
+ GL_FALSE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ }
+ inst[1] = t_src(vp, &vpi->SrcReg[0]);
+ inst[2] = t_src(vp, &vpi->SrcReg[1]);
+ inst[3] = t_src(vp, &vpi->SrcReg[2]);
+}
+
+static void ei_pow(struct r300_vertex_program_code *vp,
+ struct prog_instruction *vpi,
+ GLuint * inst)
+{
+ inst[0] = PVS_OP_DST_OPERAND(ME_POWER_FUNC_FF,
+ GL_TRUE,
+ GL_FALSE,
+ t_dst_index(vp, &vpi->DstReg),
+ t_dst_mask(vpi->DstReg.WriteMask),
+ t_dst_class(vpi->DstReg.File));
+ inst[1] = t_src_scalar(vp, &vpi->SrcReg[0]);
+ inst[2] = __CONST(0, SWIZZLE_ZERO);
+ inst[3] = t_src_scalar(vp, &vpi->SrcReg[1]);
+}
+
+
+static void translate_vertex_program(struct r300_vertex_program_compiler * compiler)
+{
+ struct rc_instruction *rci;
+
+ compiler->code->pos_end = 0; /* Not supported yet */
+ compiler->code->length = 0;
+
+ compiler->SetHwInputOutput(compiler);
+
+ for(rci = compiler->Base.Program.Instructions.Next; rci != &compiler->Base.Program.Instructions; rci = rci->Next) {
+ struct prog_instruction *vpi = &rci->I;
+ GLuint *inst = compiler->code->body.d + compiler->code->length;
+
+ /* Skip instructions writing to non-existing destination */
+ if (!valid_dst(compiler->code, &vpi->DstReg))
+ continue;
+
+ if (compiler->code->length >= VSF_MAX_FRAGMENT_LENGTH) {
+ rc_error(&compiler->Base, "Vertex program has too many instructions\n");
+ return;
+ }
+
+ switch (vpi->Opcode) {
+ case OPCODE_ADD: ei_vector2(compiler->code, VE_ADD, vpi, inst); break;
+ case OPCODE_ARL: ei_vector1(compiler->code, VE_FLT2FIX_DX, vpi, inst); break;
+ case OPCODE_DP4: ei_vector2(compiler->code, VE_DOT_PRODUCT, vpi, inst); break;
+ case OPCODE_DST: ei_vector2(compiler->code, VE_DISTANCE_VECTOR, vpi, inst); break;
+ case OPCODE_EX2: ei_math1(compiler->code, ME_EXP_BASE2_FULL_DX, vpi, inst); break;
+ case OPCODE_EXP: ei_math1(compiler->code, ME_EXP_BASE2_DX, vpi, inst); break;
+ case OPCODE_FRC: ei_vector1(compiler->code, VE_FRACTION, vpi, inst); break;
+ case OPCODE_LG2: ei_math1(compiler->code, ME_LOG_BASE2_FULL_DX, vpi, inst); break;
+ case OPCODE_LIT: ei_lit(compiler->code, vpi, inst); break;
+ case OPCODE_LOG: ei_math1(compiler->code, ME_LOG_BASE2_DX, vpi, inst); break;
+ case OPCODE_MAD: ei_mad(compiler->code, vpi, inst); break;
+ case OPCODE_MAX: ei_vector2(compiler->code, VE_MAXIMUM, vpi, inst); break;
+ case OPCODE_MIN: ei_vector2(compiler->code, VE_MINIMUM, vpi, inst); break;
+ case OPCODE_MOV: ei_vector1(compiler->code, VE_ADD, vpi, inst); break;
+ case OPCODE_MUL: ei_vector2(compiler->code, VE_MULTIPLY, vpi, inst); break;
+ case OPCODE_POW: ei_pow(compiler->code, vpi, inst); break;
+ case OPCODE_RCP: ei_math1(compiler->code, ME_RECIP_DX, vpi, inst); break;
+ case OPCODE_RSQ: ei_math1(compiler->code, ME_RECIP_SQRT_DX, vpi, inst); break;
+ case OPCODE_SGE: ei_vector2(compiler->code, VE_SET_GREATER_THAN_EQUAL, vpi, inst); break;
+ case OPCODE_SLT: ei_vector2(compiler->code, VE_SET_LESS_THAN, vpi, inst); break;
+ default:
+ rc_error(&compiler->Base, "Unknown opcode %i\n", vpi->Opcode);
+ return;
+ }
+
+ compiler->code->length += 4;
+
+ if (compiler->Base.Error)
+ return;
+ }
+}
+
+struct temporary_allocation {
+ GLuint Allocated:1;
+ GLuint HwTemp:15;
+ struct rc_instruction * LastRead;
+};
+
+static void allocate_temporary_registers(struct r300_vertex_program_compiler * compiler)
+{
+ struct rc_instruction *inst;
+ GLuint num_orig_temps = 0;
+ GLboolean hwtemps[VSF_MAX_FRAGMENT_TEMPS];
+ struct temporary_allocation * ta;
+ GLuint i, j;
+
+ compiler->code->num_temporaries = 0;
+ memset(hwtemps, 0, sizeof(hwtemps));
+
+ /* Pass 1: Count original temporaries and allocate structures */
+ for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
+ GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
+ GLuint numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
+
+ for (i = 0; i < numsrcs; ++i) {
+ if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY) {
+ if (inst->I.SrcReg[i].Index >= num_orig_temps)
+ num_orig_temps = inst->I.SrcReg[i].Index + 1;
+ }
+ }
+
+ if (numdsts) {
+ if (inst->I.DstReg.File == PROGRAM_TEMPORARY) {
+ if (inst->I.DstReg.Index >= num_orig_temps)
+ num_orig_temps = inst->I.DstReg.Index + 1;
+ }
+ }
+ }
+
+ ta = (struct temporary_allocation*)memory_pool_malloc(&compiler->Base.Pool,
+ sizeof(struct temporary_allocation) * num_orig_temps);
+ memset(ta, 0, sizeof(struct temporary_allocation) * num_orig_temps);
+
+ /* Pass 2: Determine original temporary lifetimes */
+ for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
+ GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
+
+ for (i = 0; i < numsrcs; ++i) {
+ if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY)
+ ta[inst->I.SrcReg[i].Index].LastRead = inst;
+ }
+ }
+
+ /* Pass 3: Register allocation */
+ for(inst = compiler->Base.Program.Instructions.Next; inst != &compiler->Base.Program.Instructions; inst = inst->Next) {
+ GLuint numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
+ GLuint numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
+
+ for (i = 0; i < numsrcs; ++i) {
+ if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY) {
+ GLuint orig = inst->I.SrcReg[i].Index;
+ inst->I.SrcReg[i].Index = ta[orig].HwTemp;
+
+ if (ta[orig].Allocated && inst == ta[orig].LastRead)
+ hwtemps[ta[orig].HwTemp] = GL_FALSE;
+ }
+ }
+
+ if (numdsts) {
+ if (inst->I.DstReg.File == PROGRAM_TEMPORARY) {
+ GLuint orig = inst->I.DstReg.Index;
+
+ if (!ta[orig].Allocated) {
+ for(j = 0; j < VSF_MAX_FRAGMENT_TEMPS; ++j) {
+ if (!hwtemps[j])
+ break;
+ }
+ if (j >= VSF_MAX_FRAGMENT_TEMPS) {
+ fprintf(stderr, "Out of hw temporaries\n");
+ } else {
+ ta[orig].Allocated = GL_TRUE;
+ ta[orig].HwTemp = j;
+ hwtemps[j] = GL_TRUE;
+
+ if (j >= compiler->code->num_temporaries)
+ compiler->code->num_temporaries = j + 1;
+ }
+ }
+
+ inst->I.DstReg.Index = ta[orig].HwTemp;
+ }
+ }
+ }
+}
+
+
+/**
+ * Vertex engine cannot read two inputs or two constants at the same time.
+ * Introduce intermediate MOVs to temporary registers to account for this.
+ */
+static GLboolean transform_source_conflicts(
+ struct radeon_compiler *c,
+ struct rc_instruction* inst,
+ void* unused)
+{
+ GLuint num_operands = _mesa_num_inst_src_regs(inst->I.Opcode);
+
+ if (num_operands == 3) {
+ if (t_src_conflict(inst->I.SrcReg[1], inst->I.SrcReg[2])
+ || t_src_conflict(inst->I.SrcReg[0], inst->I.SrcReg[2])) {
+ int tmpreg = rc_find_free_temporary(c);
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mov->I.DstReg.Index = tmpreg;
+ inst_mov->I.SrcReg[0] = inst->I.SrcReg[2];
+
+ reset_srcreg(&inst->I.SrcReg[2]);
+ inst->I.SrcReg[2].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[2].Index = tmpreg;
+ }
+ }
+
+ if (num_operands >= 2) {
+ if (t_src_conflict(inst->I.SrcReg[1], inst->I.SrcReg[0])) {
+ int tmpreg = rc_find_free_temporary(c);
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mov->I.DstReg.Index = tmpreg;
+ inst_mov->I.SrcReg[0] = inst->I.SrcReg[1];
+
+ reset_srcreg(&inst->I.SrcReg[1]);
+ inst->I.SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[1].Index = tmpreg;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+static void addArtificialOutputs(struct r300_vertex_program_compiler * compiler)
+{
+ int i;
+
+ for(i = 0; i < 32; ++i) {
+ if ((compiler->RequiredOutputs & (1 << i)) &&
+ !(compiler->Base.Program.OutputsWritten & (1 << i))) {
+ struct rc_instruction * inst = rc_insert_new_instruction(&compiler->Base, compiler->Base.Program.Instructions.Prev);
+ inst->I.Opcode = OPCODE_MOV;
+
+ inst->I.DstReg.File = PROGRAM_OUTPUT;
+ inst->I.DstReg.Index = i;
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
+
+ inst->I.SrcReg[0].File = PROGRAM_CONSTANT;
+ inst->I.SrcReg[0].Index = 0;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ compiler->Base.Program.OutputsWritten |= 1 << i;
+ }
+ }
+}
+
+static void nqssadceInit(struct nqssadce_state* s)
+{
+ struct r300_vertex_program_compiler * compiler = s->UserData;
+ int i;
+
+ for(i = 0; i < VERT_RESULT_MAX; ++i) {
+ if (compiler->RequiredOutputs & (1 << i))
+ s->Outputs[i].Sourced = WRITEMASK_XYZW;
+ }
+}
+
+static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
+{
+ (void) opcode;
+ (void) reg;
+
+ return GL_TRUE;
+}
+
+
+
+void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* compiler)
+{
+ addArtificialOutputs(compiler);
+
+ {
+ struct radeon_program_transformation transformations[] = {
+ { &r300_transform_vertex_alu, 0 },
+ };
+ radeonLocalTransform(&compiler->Base, 1, transformations);
+ }
+
+ if (compiler->Base.Debug) {
+ fprintf(stderr, "Vertex program after native rewrite:\n");
+ rc_print_program(&compiler->Base.Program);
+ fflush(stderr);
+ }
+
+ {
+ /* Note: This pass has to be done seperately from ALU rewrite,
+ * otherwise non-native ALU instructions with source conflits
+ * will not be treated properly.
+ */
+ struct radeon_program_transformation transformations[] = {
+ { &transform_source_conflicts, 0 },
+ };
+ radeonLocalTransform(&compiler->Base, 1, transformations);
+ }
+
+ if (compiler->Base.Debug) {
+ fprintf(stderr, "Vertex program after source conflict resolve:\n");
+ rc_print_program(&compiler->Base.Program);
+ fflush(stderr);
+ }
+
+ {
+ struct radeon_nqssadce_descr nqssadce = {
+ .Init = &nqssadceInit,
+ .IsNativeSwizzle = &swizzleIsNative,
+ .BuildSwizzle = NULL
+ };
+ radeonNqssaDce(&compiler->Base, &nqssadce, compiler);
+
+ /* We need this step for reusing temporary registers */
+ allocate_temporary_registers(compiler);
+
+ if (compiler->Base.Debug) {
+ fprintf(stderr, "Vertex program after NQSSADCE:\n");
+ rc_print_program(&compiler->Base.Program);
+ fflush(stderr);
+ }
+ }
+
+ translate_vertex_program(compiler);
+
+ rc_constants_copy(&compiler->code->constants, &compiler->Base.Program.Constants);
+
+ compiler->code->InputsRead = compiler->Base.Program.InputsRead;
+ compiler->code->OutputsWritten = compiler->Base.Program.OutputsWritten;
+
+ if (compiler->Base.Debug) {
+ fprintf(stderr, "Final vertex program code:\n");
+ r300_vertex_program_dump(compiler->code);
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c
new file mode 100644
index 0000000000..980ef3eaea
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_vertprog_dump.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "radeon_code.h"
+
+#include <stdio.h>
+
+static char* r300_vs_ve_ops[] = {
+ /* R300 vector ops */
+ " VE_NO_OP",
+ " VE_DOT_PRODUCT",
+ " VE_MULTIPLY",
+ " VE_ADD",
+ " VE_MULTIPLY_ADD",
+ " VE_DISTANCE_FACTOR",
+ " VE_FRACTION",
+ " VE_MAXIMUM",
+ " VE_MINIMUM",
+ "VE_SET_GREATER_THAN_EQUAL",
+ " VE_SET_LESS_THAN",
+ " VE_MULTIPLYX2_ADD",
+ " VE_MULTIPLY_CLAMP",
+ " VE_FLT2FIX_DX",
+ " VE_FLT2FIX_DX_RND",
+ /* R500 vector ops */
+ " VE_PRED_SET_EQ_PUSH",
+ " VE_PRED_SET_GT_PUSH",
+ " VE_PRED_SET_GTE_PUSH",
+ " VE_PRED_SET_NEQ_PUSH",
+ " VE_COND_WRITE_EQ",
+ " VE_COND_WRITE_GT",
+ " VE_COND_WRITE_GTE",
+ " VE_COND_WRITE_NEQ",
+ " VE_SET_GREATER_THAN",
+ " VE_SET_EQUAL",
+ " VE_SET_NOT_EQUAL",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
+static char* r300_vs_me_ops[] = {
+ /* R300 math ops */
+ " ME_NO_OP",
+ " ME_EXP_BASE2_DX",
+ " ME_LOG_BASE2_DX",
+ " ME_EXP_BASEE_FF",
+ " ME_LIGHT_COEFF_DX",
+ " ME_POWER_FUNC_FF",
+ " ME_RECIP_DX",
+ " ME_RECIP_FF",
+ " ME_RECIP_SQRT_DX",
+ " ME_RECIP_SQRT_FF",
+ " ME_MULTIPLY",
+ " ME_EXP_BASE2_FULL_DX",
+ " ME_LOG_BASE2_FULL_DX",
+ " ME_POWER_FUNC_FF_CLAMP_B",
+ "ME_POWER_FUNC_FF_CLAMP_B1",
+ "ME_POWER_FUNC_FF_CLAMP_01",
+ " ME_SIN",
+ " ME_COS",
+ /* R500 math ops */
+ " ME_LOG_BASE2_IEEE",
+ " ME_RECIP_IEEE",
+ " ME_RECIP_SQRT_IEEE",
+ " ME_PRED_SET_EQ",
+ " ME_PRED_SET_GT",
+ " ME_PRED_SET_GTE",
+ " ME_PRED_SET_NEQ",
+ " ME_PRED_SET_CLR",
+ " ME_PRED_SET_INV",
+ " ME_PRED_SET_POP",
+ " ME_PRED_SET_RESTORE",
+ " (reserved)",
+ " (reserved)",
+ " (reserved)",
+};
+
+/* XXX refactor to avoid clashing symbols */
+static char* r300_vs_src_debug[] = {
+ "t",
+ "i",
+ "c",
+ "a",
+};
+
+static char* r300_vs_dst_debug[] = {
+ "t",
+ "a0",
+ "o",
+ "ox",
+ "a",
+ "i",
+ "u",
+ "u",
+};
+
+static char* r300_vs_swiz_debug[] = {
+ "X",
+ "Y",
+ "Z",
+ "W",
+ "0",
+ "1",
+ "U",
+ "U",
+};
+
+
+static void r300_vs_op_dump(uint32_t op)
+{
+ fprintf(stderr, " dst: %d%s op: ",
+ (op >> 13) & 0x7f, r300_vs_dst_debug[(op >> 8) & 0x7]);
+ if (op & 0x80) {
+ if (op & 0x1) {
+ fprintf(stderr, "PVS_MACRO_OP_2CLK_M2X_ADD\n");
+ } else {
+ fprintf(stderr, " PVS_MACRO_OP_2CLK_MADD\n");
+ }
+ } else if (op & 0x40) {
+ fprintf(stderr, "%s\n", r300_vs_me_ops[op & 0x1f]);
+ } else {
+ fprintf(stderr, "%s\n", r300_vs_ve_ops[op & 0x1f]);
+ }
+}
+
+static void r300_vs_src_dump(uint32_t src)
+{
+ fprintf(stderr, " reg: %d%s swiz: %s%s/%s%s/%s%s/%s%s\n",
+ (src >> 5) & 0x7f, r300_vs_src_debug[src & 0x3],
+ src & (1 << 25) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 13) & 0x7],
+ src & (1 << 26) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 16) & 0x7],
+ src & (1 << 27) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 19) & 0x7],
+ src & (1 << 28) ? "-" : " ",
+ r300_vs_swiz_debug[(src >> 22) & 0x7]);
+}
+
+void r300_vertex_program_dump(struct r300_vertex_program_code * vs)
+{
+ unsigned instrcount = vs->length / 4;
+ unsigned i;
+
+ for(i = 0; i < instrcount; i++) {
+ unsigned offset = i*4;
+ unsigned src;
+
+ fprintf(stderr, "%d: op: 0x%08x", i, vs->body.d[offset]);
+ r300_vs_op_dump(vs->body.d[offset]);
+
+ for(src = 0; src < 3; ++src) {
+ fprintf(stderr, " src%i: 0x%08x", src, vs->body.d[offset+1+src]);
+ r300_vs_src_dump(vs->body.d[offset+1+src]);
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
index 4d58cf2162..7e2faed690 100644
--- a/src/mesa/drivers/dri/r300/r500_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.c
@@ -27,158 +27,141 @@
#include "r500_fragprog.h"
-static void reset_srcreg(struct prog_src_register* reg)
-{
- _mesa_bzero(reg, sizeof(*reg));
- reg->Swizzle = SWIZZLE_NOOP;
-}
+#include "../r300_reg.h"
-static struct prog_src_register shadow_ambient(struct gl_program *program, int tmu)
+static struct prog_src_register shadow_ambient(struct radeon_compiler * c, int tmu)
{
- gl_state_index fail_value_tokens[STATE_LENGTH] = {
- STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0
- };
struct prog_src_register reg = { 0, };
- fail_value_tokens[2] = tmu;
reg.File = PROGRAM_STATE_VAR;
- reg.Index = _mesa_add_state_reference(program->Parameters, fail_value_tokens);
+ reg.Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_SHADOW_AMBIENT, tmu);
reg.Swizzle = SWIZZLE_WWWW;
return reg;
}
/**
* Transform TEX, TXP, TXB, and KIL instructions in the following way:
- * - premultiply texture coordinates for RECT
- * - extract operand swizzles
- * - introduce a temporary register when write masks are needed
- *
+ * - implement texture compare (shadow extensions)
+ * - extract non-native source / destination operands
*/
GLboolean r500_transform_TEX(
- struct radeon_transform_context *t,
- struct prog_instruction* orig_inst, void* data)
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
+ void* data)
{
struct r300_fragment_program_compiler *compiler =
(struct r300_fragment_program_compiler*)data;
- struct prog_instruction inst = *orig_inst;
- struct prog_instruction* tgt;
- GLboolean destredirect = GL_FALSE;
-
- if (inst.Opcode != OPCODE_TEX &&
- inst.Opcode != OPCODE_TXB &&
- inst.Opcode != OPCODE_TXP &&
- inst.Opcode != OPCODE_KIL)
+
+ if (inst->I.Opcode != OPCODE_TEX &&
+ inst->I.Opcode != OPCODE_TXB &&
+ inst->I.Opcode != OPCODE_TXP &&
+ inst->I.Opcode != OPCODE_KIL)
return GL_FALSE;
/* ARB_shadow & EXT_shadow_funcs */
- if (inst.Opcode != OPCODE_KIL &&
- t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
- GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
+ if (inst->I.Opcode != OPCODE_KIL &&
+ c->Program.ShadowSamplers & (1 << inst->I.TexSrcUnit)) {
+ GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
- tgt = radeonAppendInstructions(t->Program, 1);
+ inst->I.Opcode = OPCODE_MOV;
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg = inst.DstReg;
if (comparefunc == GL_ALWAYS) {
- tgt->SrcReg[0].File = PROGRAM_BUILTIN;
- tgt->SrcReg[0].Swizzle = SWIZZLE_1111;
+ inst->I.SrcReg[0].File = PROGRAM_BUILTIN;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_1111;
} else {
- tgt->SrcReg[0] = shadow_ambient(t->Program, inst.TexSrcUnit);
+ inst->I.SrcReg[0] = shadow_ambient(c, inst->I.TexSrcUnit);
}
+
return GL_TRUE;
+ } else {
+ GLuint comparefunc = GL_NEVER + compiler->state.unit[inst->I.TexSrcUnit].texture_compare_func;
+ GLuint depthmode = compiler->state.unit[inst->I.TexSrcUnit].depth_texture_mode;
+ struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, inst);
+ struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_rcp);
+ struct rc_instruction * inst_cmp = rc_insert_new_instruction(c, inst_mad);
+ int pass, fail;
+
+ inst_rcp->I.Opcode = OPCODE_RCP;
+ inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_rcp->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
+ inst_rcp->I.SrcReg[0] = inst->I.SrcReg[0];
+ inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
+
+ inst_cmp->I.DstReg = inst->I.DstReg;
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = rc_find_free_temporary(c);
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
+
+ inst_mad->I.Opcode = OPCODE_MAD;
+ inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mad->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_mad->I.SrcReg[0] = inst->I.SrcReg[0];
+ inst_mad->I.SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
+ inst_mad->I.SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst_mad->I.SrcReg[1].Index = inst_rcp->I.DstReg.Index;
+ inst_mad->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
+ inst_mad->I.SrcReg[2].File = PROGRAM_TEMPORARY;
+ inst_mad->I.SrcReg[2].Index = inst->I.DstReg.Index;
+ if (depthmode == 0) /* GL_LUMINANCE */
+ inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
+ else if (depthmode == 2) /* GL_ALPHA */
+ inst_mad->I.SrcReg[2].Swizzle = SWIZZLE_WWWW;
+
+ /* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
+ * r < tex <=> -tex+r < 0
+ * r >= tex <=> not (-tex+r < 0 */
+ if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
+ inst_mad->I.SrcReg[2].Negate = inst_mad->I.SrcReg[2].Negate ^ NEGATE_XYZW;
+ else
+ inst_mad->I.SrcReg[0].Negate = inst_mad->I.SrcReg[0].Negate ^ NEGATE_XYZW;
+
+ inst_cmp->I.Opcode = OPCODE_CMP;
+ /* DstReg has been filled out above */
+ inst_cmp->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst_cmp->I.SrcReg[0].Index = inst_mad->I.DstReg.Index;
+
+ if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
+ pass = 1;
+ fail = 2;
+ } else {
+ pass = 2;
+ fail = 1;
+ }
+
+ inst_cmp->I.SrcReg[pass].File = PROGRAM_BUILTIN;
+ inst_cmp->I.SrcReg[pass].Swizzle = SWIZZLE_1111;
+ inst_cmp->I.SrcReg[fail] = shadow_ambient(c, inst->I.TexSrcUnit);
}
+ }
- inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = radeonFindFreeTemporary(t);
- inst.DstReg.WriteMask = WRITEMASK_XYZW;
- } else if (inst.Opcode != OPCODE_KIL && inst.DstReg.File != PROGRAM_TEMPORARY) {
- int tempreg = radeonFindFreeTemporary(t);
+ /* Cannot write texture to output registers */
+ if (inst->I.Opcode != OPCODE_KIL && inst->I.DstReg.File != PROGRAM_TEMPORARY) {
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst);
- inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = tempreg;
- inst.DstReg.WriteMask = WRITEMASK_XYZW;
- destredirect = GL_TRUE;
- }
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg = inst->I.DstReg;
+ inst_mov->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst_mov->I.SrcReg[0].Index = rc_find_free_temporary(c);
- if (inst.SrcReg[0].File != PROGRAM_TEMPORARY && inst.SrcReg[0].File != PROGRAM_INPUT) {
- int tmpreg = radeonFindFreeTemporary(t);
- tgt = radeonAppendInstructions(t->Program, 1);
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg.File = PROGRAM_TEMPORARY;
- tgt->DstReg.Index = tmpreg;
- tgt->SrcReg[0] = inst.SrcReg[0];
-
- reset_srcreg(&inst.SrcReg[0]);
- inst.SrcReg[0].File = PROGRAM_TEMPORARY;
- inst.SrcReg[0].Index = tmpreg;
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
}
- tgt = radeonAppendInstructions(t->Program, 1);
- _mesa_copy_instructions(tgt, &inst, 1);
-
- if (inst.Opcode != OPCODE_KIL &&
- t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
- GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
- GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
- int rcptemp = radeonFindFreeTemporary(t);
- int pass, fail;
-
- tgt = radeonAppendInstructions(t->Program, 3);
-
- tgt[0].Opcode = OPCODE_RCP;
- tgt[0].DstReg.File = PROGRAM_TEMPORARY;
- tgt[0].DstReg.Index = rcptemp;
- tgt[0].DstReg.WriteMask = WRITEMASK_W;
- tgt[0].SrcReg[0] = inst.SrcReg[0];
- tgt[0].SrcReg[0].Swizzle = SWIZZLE_WWWW;
-
- tgt[1].Opcode = OPCODE_MAD;
- tgt[1].DstReg = inst.DstReg;
- tgt[1].DstReg.WriteMask = orig_inst->DstReg.WriteMask;
- tgt[1].SrcReg[0] = inst.SrcReg[0];
- tgt[1].SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
- tgt[1].SrcReg[1].File = PROGRAM_TEMPORARY;
- tgt[1].SrcReg[1].Index = rcptemp;
- tgt[1].SrcReg[1].Swizzle = SWIZZLE_WWWW;
- tgt[1].SrcReg[2].File = PROGRAM_TEMPORARY;
- tgt[1].SrcReg[2].Index = inst.DstReg.Index;
- if (depthmode == 0) /* GL_LUMINANCE */
- tgt[1].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
- else if (depthmode == 2) /* GL_ALPHA */
- tgt[1].SrcReg[2].Swizzle = SWIZZLE_WWWW;
-
- /* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
- * r < tex <=> -tex+r < 0
- * r >= tex <=> not (-tex+r < 0 */
- if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
- tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW;
- else
- tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW;
-
- tgt[2].Opcode = OPCODE_CMP;
- tgt[2].DstReg = orig_inst->DstReg;
- tgt[2].SrcReg[0].File = PROGRAM_TEMPORARY;
- tgt[2].SrcReg[0].Index = tgt[1].DstReg.Index;
-
- if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
- pass = 1;
- fail = 2;
- } else {
- pass = 2;
- fail = 1;
- }
+ /* Cannot read texture coordinate from constants file */
+ if (inst->I.SrcReg[0].File != PROGRAM_TEMPORARY && inst->I.SrcReg[0].File != PROGRAM_INPUT) {
+ struct rc_instruction * inst_mov = rc_insert_new_instruction(c, inst->Prev);
- tgt[2].SrcReg[pass].File = PROGRAM_BUILTIN;
- tgt[2].SrcReg[pass].Swizzle = SWIZZLE_1111;
- tgt[2].SrcReg[fail] = shadow_ambient(t->Program, inst.TexSrcUnit);
- } else if (destredirect) {
- tgt = radeonAppendInstructions(t->Program, 1);
+ inst_mov->I.Opcode = OPCODE_MOV;
+ inst_mov->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mov->I.DstReg.Index = rc_find_free_temporary(c);
+ inst_mov->I.SrcReg[0] = inst->I.SrcReg[0];
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg = orig_inst->DstReg;
- tgt->SrcReg[0].File = PROGRAM_TEMPORARY;
- tgt->SrcReg[0].Index = inst.DstReg.Index;
+ reset_srcreg(&inst->I.SrcReg[0]);
+ inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[0].Index = inst_mov->I.DstReg.Index;
}
return GL_TRUE;
@@ -249,7 +232,6 @@ GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg)
*/
void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src)
{
- struct prog_instruction *inst;
GLuint negatebase[2] = { 0, 0 };
int i;
@@ -260,20 +242,16 @@ void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst,
negatebase[GET_BIT(src.Negate, i)] |= 1 << i;
}
- _mesa_insert_instructions(s->Program, s->IP, (negatebase[0] ? 1 : 0) + (negatebase[1] ? 1 : 0));
- inst = s->Program->Instructions + s->IP;
-
for(i = 0; i <= 1; ++i) {
if (!negatebase[i])
continue;
- inst->Opcode = OPCODE_MOV;
- inst->DstReg = dst;
- inst->DstReg.WriteMask = negatebase[i];
- inst->SrcReg[0] = src;
- inst->SrcReg[0].Negate = (i == 0) ? NEGATE_NONE : NEGATE_XYZW;
- inst++;
- s->IP++;
+ struct rc_instruction *inst = rc_insert_new_instruction(s->Compiler, s->IP->Prev);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg = dst;
+ inst->I.DstReg.WriteMask = negatebase[i];
+ inst->I.SrcReg[0] = src;
+ inst->I.SrcReg[0].Negate = (i == 0) ? NEGATE_NONE : NEGATE_XYZW;
}
}
@@ -375,9 +353,9 @@ static char *to_texop(int val)
return NULL;
}
-void r500FragmentProgramDump(union rX00_fragment_program_code *c)
+void r500FragmentProgramDump(struct rX00_fragment_program_code *c)
{
- struct r500_fragment_program_code *code = &c->r500;
+ struct r500_fragment_program_code *code = &c->code.r500;
fprintf(stderr, "R500 Fragment Program:\n--------\n");
int n;
@@ -385,15 +363,6 @@ void r500FragmentProgramDump(union rX00_fragment_program_code *c)
uint32_t inst0;
char *str = NULL;
- if (code->const_nr) {
- fprintf(stderr, "--------\nConstants:\n");
- for (n = 0; n < code->const_nr; n++) {
- fprintf(stderr, "Constant %d: %i[%i]\n", n,
- code->constant[n].File, code->constant[n].Index);
- }
- fprintf(stderr, "--------\n");
- }
-
for (n = 0; n < code->inst_end+1; n++) {
inst0 = inst = code->inst[n].inst0;
fprintf(stderr,"%d\t0:CMN_INST 0x%08x:", n, inst);
diff --git a/src/mesa/drivers/dri/r300/r500_fragprog.h b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
index 1179bf6607..9091f65cd2 100644
--- a/src/mesa/drivers/dri/r300/r500_fragprog.h
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog.h
@@ -36,17 +36,20 @@
#include "shader/prog_parameter.h"
#include "shader/prog_instruction.h"
-#include "r300_context.h"
+#include "radeon_compiler.h"
#include "radeon_nqssadce.h"
-extern GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
+extern void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
-extern void r500FragmentProgramDump(union rX00_fragment_program_code *c);
+extern void r500FragmentProgramDump(struct rX00_fragment_program_code *c);
extern GLboolean r500FPIsNativeSwizzle(GLuint opcode, struct prog_src_register reg);
extern void r500FPBuildSwizzle(struct nqssadce_state *s, struct prog_dst_register dst, struct prog_src_register src);
-extern GLboolean r500_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data);
+extern GLboolean r500_transform_TEX(
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
+ void* data);
#endif
diff --git a/src/mesa/drivers/dri/r300/r500_fragprog_emit.c b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
index 30f4514897..d694725c9b 100644
--- a/src/mesa/drivers/dri/r300/r500_fragprog_emit.c
+++ b/src/mesa/drivers/dri/r300/compiler/r500_fragprog_emit.c
@@ -45,47 +45,22 @@
#include "r500_fragprog.h"
+#include "../r300_reg.h"
+
#include "radeon_program_pair.h"
#define PROG_CODE \
struct r300_fragment_program_compiler *c = (struct r300_fragment_program_compiler*)data; \
- struct r500_fragment_program_code *code = &c->code->r500
+ struct r500_fragment_program_code *code = &c->code->code.r500
#define error(fmt, args...) do { \
- fprintf(stderr, "%s::%s(): " fmt "\n", \
+ rc_error(&c->Base, "%s::%s(): " fmt "\n", \
__FILE__, __FUNCTION__, ##args); \
} while(0)
-/**
- * Callback to register hardware constants.
- */
-static GLboolean emit_const(void *data, GLuint file, GLuint idx, GLuint *hwindex)
-{
- PROG_CODE;
-
- for (*hwindex = 0; *hwindex < code->const_nr; ++*hwindex) {
- if (code->constant[*hwindex].File == file &&
- code->constant[*hwindex].Index == idx)
- break;
- }
-
- if (*hwindex >= code->const_nr) {
- if (*hwindex >= R500_PFS_NUM_CONST_REGS) {
- error("Out of hw constants!\n");
- return GL_FALSE;
- }
-
- code->const_nr++;
- code->constant[*hwindex].File = file;
- code->constant[*hwindex].Index = idx;
- }
-
- return GL_TRUE;
-}
-
-static GLuint translate_rgb_op(GLuint opcode)
+static GLuint translate_rgb_op(struct r300_fragment_program_compiler *c, GLuint opcode)
{
switch(opcode) {
case OPCODE_CMP: return R500_ALU_RGBA_OP_CMP;
@@ -106,7 +81,7 @@ static GLuint translate_rgb_op(GLuint opcode)
}
}
-static GLuint translate_alpha_op(GLuint opcode)
+static GLuint translate_alpha_op(struct r300_fragment_program_compiler *c, GLuint opcode)
{
switch(opcode) {
case OPCODE_CMP: return R500_ALPHA_OP_CMP;
@@ -189,8 +164,8 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
int ip = ++code->inst_end;
- code->inst[ip].inst5 = translate_rgb_op(inst->RGB.Opcode);
- code->inst[ip].inst4 = translate_alpha_op(inst->Alpha.Opcode);
+ code->inst[ip].inst5 = translate_rgb_op(c, inst->RGB.Opcode);
+ code->inst[ip].inst4 = translate_alpha_op(c, inst->Alpha.Opcode);
if (inst->RGB.OutputWriteMask || inst->Alpha.OutputWriteMask || inst->Alpha.DepthWriteMask)
code->inst[ip].inst0 = R500_INST_TYPE_OUT;
@@ -202,7 +177,7 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
code->inst[ip].inst0 |= (inst->RGB.OutputWriteMask << 15) | (inst->Alpha.OutputWriteMask << 18);
if (inst->Alpha.DepthWriteMask) {
code->inst[ip].inst4 |= R500_ALPHA_W_OMASK;
- c->fp->writes_depth = GL_TRUE;
+ c->code->writes_depth = GL_TRUE;
}
code->inst[ip].inst4 |= R500_ALPHA_ADDRD(inst->Alpha.DestIndex);
@@ -234,19 +209,19 @@ static GLboolean emit_paired(void *data, struct radeon_pair_instruction *inst)
return GL_TRUE;
}
-static GLuint translate_strq_swizzle(struct prog_src_register src)
+static GLuint translate_strq_swizzle(GLuint swizzle)
{
GLuint swiz = 0;
int i;
for (i = 0; i < 4; i++)
- swiz |= (GET_SWZ(src.Swizzle, i) & 0x3) << i*2;
+ swiz |= (GET_SWZ(swizzle, i) & 0x3) << i*2;
return swiz;
}
/**
* Emit a single TEX instruction
*/
-static GLboolean emit_tex(void *data, struct prog_instruction *inst)
+static GLboolean emit_tex(void *data, struct radeon_pair_texture_instruction *inst)
{
PROG_CODE;
@@ -258,7 +233,7 @@ static GLboolean emit_tex(void *data, struct prog_instruction *inst)
int ip = ++code->inst_end;
code->inst[ip].inst0 = R500_INST_TYPE_TEX
- | (inst->DstReg.WriteMask << 11)
+ | (inst->WriteMask << 11)
| R500_INST_TEX_SEM_WAIT;
code->inst[ip].inst1 = R500_TEX_ID(inst->TexSrcUnit)
| R500_TEX_SEM_ACQUIRE | R500_TEX_IGNORE_UNCOVERED;
@@ -267,25 +242,25 @@ static GLboolean emit_tex(void *data, struct prog_instruction *inst)
code->inst[ip].inst1 |= R500_TEX_UNSCALED;
switch (inst->Opcode) {
- case OPCODE_KIL:
+ case RADEON_OPCODE_KIL:
code->inst[ip].inst1 |= R500_TEX_INST_TEXKILL;
break;
- case OPCODE_TEX:
+ case RADEON_OPCODE_TEX:
code->inst[ip].inst1 |= R500_TEX_INST_LD;
break;
- case OPCODE_TXB:
+ case RADEON_OPCODE_TXB:
code->inst[ip].inst1 |= R500_TEX_INST_LODBIAS;
break;
- case OPCODE_TXP:
+ case RADEON_OPCODE_TXP:
code->inst[ip].inst1 |= R500_TEX_INST_PROJ;
break;
default:
error("emit_tex can't handle opcode %x\n", inst->Opcode);
}
- code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcReg[0].Index)
- | (translate_strq_swizzle(inst->SrcReg[0]) << 8)
- | R500_TEX_DST_ADDR(inst->DstReg.Index)
+ code->inst[ip].inst2 = R500_TEX_SRC_ADDR(inst->SrcIndex)
+ | (translate_strq_swizzle(inst->SrcSwizzle) << 8)
+ | R500_TEX_DST_ADDR(inst->DestIndex)
| R500_TEX_DST_R_SWIZ_R | R500_TEX_DST_G_SWIZ_G
| R500_TEX_DST_B_SWIZ_B | R500_TEX_DST_A_SWIZ_A;
@@ -293,35 +268,32 @@ static GLboolean emit_tex(void *data, struct prog_instruction *inst)
}
static const struct radeon_pair_handler pair_handler = {
- .EmitConst = emit_const,
.EmitPaired = emit_paired,
.EmitTex = emit_tex,
.MaxHwTemps = 128
};
-GLboolean r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
+void r500BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler)
{
- struct r500_fragment_program_code *code = &compiler->code->r500;
+ struct r500_fragment_program_code *code = &compiler->code->code.r500;
_mesa_bzero(code, sizeof(*code));
code->max_temp_idx = 1;
- code->inst_offset = 0;
code->inst_end = -1;
- if (!radeonPairProgram(compiler->r300->radeon.glCtx, compiler->program, &pair_handler, compiler))
- return GL_FALSE;
+ radeonPairProgram(compiler, &pair_handler, compiler);
+ if (compiler->Base.Error)
+ return;
if ((code->inst[code->inst_end].inst0 & R500_INST_TYPE_MASK) != R500_INST_TYPE_OUT) {
/* This may happen when dead-code elimination is disabled or
* when most of the fragment program logic is leading to a KIL */
if (code->inst_end >= 511) {
- error("Introducing fake OUT: Too many instructions");
- return GL_FALSE;
+ rc_error(&compiler->Base, "Introducing fake OUT: Too many instructions");
+ return;
}
int ip = ++code->inst_end;
code->inst[ip].inst0 = R500_INST_TYPE_OUT | R500_INST_TEX_SEM_WAIT;
}
-
- return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.c b/src/mesa/drivers/dri/r300/compiler/radeon_code.c
new file mode 100644
index 0000000000..c7923004df
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.c
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2009 Nicolai Haehnle.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "main/mtypes.h"
+#include "shader/prog_instruction.h"
+
+#include "radeon_code.h"
+
+void rc_constants_init(struct rc_constant_list * c)
+{
+ memset(c, 0, sizeof(*c));
+}
+
+/**
+ * Copy a constants structure, assuming that the destination structure
+ * is not initialized.
+ */
+void rc_constants_copy(struct rc_constant_list * dst, struct rc_constant_list * src)
+{
+ dst->Constants = malloc(sizeof(struct rc_constant) * src->Count);
+ memcpy(dst->Constants, src->Constants, sizeof(struct rc_constant) * src->Count);
+ dst->Count = src->Count;
+ dst->_Reserved = src->Count;
+}
+
+void rc_constants_destroy(struct rc_constant_list * c)
+{
+ free(c->Constants);
+ memset(c, 0, sizeof(*c));
+}
+
+unsigned rc_constants_add(struct rc_constant_list * c, struct rc_constant * constant)
+{
+ unsigned index = c->Count;
+
+ if (c->Count >= c->_Reserved) {
+ struct rc_constant * newlist;
+
+ c->_Reserved = c->_Reserved * 2;
+ if (!c->_Reserved)
+ c->_Reserved = 16;
+
+ newlist = malloc(sizeof(struct rc_constant) * c->_Reserved);
+ memcpy(newlist, c->Constants, sizeof(struct rc_constant) * c->Count);
+
+ free(c->Constants);
+ c->Constants = newlist;
+ }
+
+ c->Constants[index] = *constant;
+ c->Count++;
+
+ return index;
+}
+
+
+/**
+ * Add a state vector to the constant list, while trying to avoid duplicates.
+ */
+unsigned rc_constants_add_state(struct rc_constant_list * c, unsigned state0, unsigned state1)
+{
+ unsigned index;
+ struct rc_constant constant;
+
+ for(index = 0; index < c->Count; ++index) {
+ if (c->Constants[index].Type == RC_CONSTANT_STATE) {
+ if (c->Constants[index].u.State[0] == state0 &&
+ c->Constants[index].u.State[1] == state1)
+ return index;
+ }
+ }
+
+ memset(&constant, 0, sizeof(constant));
+ constant.Type = RC_CONSTANT_STATE;
+ constant.Size = 4;
+ constant.u.State[0] = state0;
+ constant.u.State[1] = state1;
+
+ return rc_constants_add(c, &constant);
+}
+
+
+/**
+ * Add an immediate vector to the constant list, while trying to avoid
+ * duplicates.
+ */
+unsigned rc_constants_add_immediate_vec4(struct rc_constant_list * c, const float * data)
+{
+ unsigned index;
+ struct rc_constant constant;
+
+ for(index = 0; index < c->Count; ++index) {
+ if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
+ if (!memcmp(c->Constants[index].u.Immediate, data, sizeof(float)*4))
+ return index;
+ }
+ }
+
+ memset(&constant, 0, sizeof(constant));
+ constant.Type = RC_CONSTANT_IMMEDIATE;
+ constant.Size = 4;
+ memcpy(constant.u.Immediate, data, sizeof(float) * 4);
+
+ return rc_constants_add(c, &constant);
+}
+
+
+/**
+ * Add an immediate scalar to the constant list, while trying to avoid
+ * duplicates.
+ */
+unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle)
+{
+ unsigned index;
+ int free_index = -1;
+ struct rc_constant constant;
+
+ for(index = 0; index < c->Count; ++index) {
+ if (c->Constants[index].Type == RC_CONSTANT_IMMEDIATE) {
+ for(unsigned comp = 0; comp < c->Constants[index].Size; ++comp) {
+ if (c->Constants[index].u.Immediate[comp] == data) {
+ *swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
+ return index;
+ }
+ }
+
+ if (c->Constants[index].Size < 4)
+ free_index = index;
+ }
+ }
+
+ if (free_index >= 0) {
+ unsigned comp = c->Constants[free_index].Size++;
+ c->Constants[free_index].u.Immediate[comp] = data;
+ *swizzle = MAKE_SWIZZLE4(comp, comp, comp, comp);
+ return free_index;
+ }
+
+ memset(&constant, 0, sizeof(constant));
+ constant.Type = RC_CONSTANT_IMMEDIATE;
+ constant.Size = 1;
+ constant.u.Immediate[0] = data;
+ *swizzle = SWIZZLE_XXXX;
+
+ return rc_constants_add(c, &constant);
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_code.h b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
new file mode 100644
index 0000000000..3e88554ba1
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_code.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef RADEON_CODE_H
+#define RADEON_CODE_H
+
+#include <stdint.h>
+
+#define R300_PFS_MAX_ALU_INST 64
+#define R300_PFS_MAX_TEX_INST 32
+#define R300_PFS_MAX_TEX_INDIRECT 4
+#define R300_PFS_NUM_TEMP_REGS 32
+#define R300_PFS_NUM_CONST_REGS 32
+
+#define R500_PFS_MAX_INST 512
+#define R500_PFS_NUM_TEMP_REGS 128
+#define R500_PFS_NUM_CONST_REGS 256
+
+
+#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
+
+enum {
+ /**
+ * External constants are constants whose meaning is unknown to this
+ * compiler. For example, a Mesa gl_program's constants are turned
+ * into external constants.
+ */
+ RC_CONSTANT_EXTERNAL = 0,
+
+ RC_CONSTANT_IMMEDIATE,
+
+ /**
+ * Constant referring to state that is known by this compiler,
+ * see RC_STATE_xxx, i.e. *not* arbitrary Mesa (or other) state.
+ */
+ RC_CONSTANT_STATE
+};
+
+enum {
+ RC_STATE_SHADOW_AMBIENT = 0,
+
+ RC_STATE_R300_WINDOW_DIMENSION,
+ RC_STATE_R300_TEXRECT_FACTOR
+};
+
+struct rc_constant {
+ unsigned Type:2; /**< RC_CONSTANT_xxx */
+ unsigned Size:3;
+
+ union {
+ unsigned External;
+ float Immediate[4];
+ unsigned State[2];
+ } u;
+};
+
+struct rc_constant_list {
+ struct rc_constant * Constants;
+ unsigned Count;
+
+ unsigned _Reserved;
+};
+
+void rc_constants_init(struct rc_constant_list * c);
+void rc_constants_copy(struct rc_constant_list * dst, struct rc_constant_list * src);
+void rc_constants_destroy(struct rc_constant_list * c);
+unsigned rc_constants_add(struct rc_constant_list * c, struct rc_constant * constant);
+unsigned rc_constants_add_state(struct rc_constant_list * c, unsigned state1, unsigned state2);
+unsigned rc_constants_add_immediate_vec4(struct rc_constant_list * c, const float * data);
+unsigned rc_constants_add_immediate_scalar(struct rc_constant_list * c, float data, unsigned * swizzle);
+
+/**
+ * Stores state that influences the compilation of a fragment program.
+ */
+struct r300_fragment_program_external_state {
+ struct {
+ /**
+ * If the sampler is used as a shadow sampler,
+ * this field is:
+ * 0 - GL_LUMINANCE
+ * 1 - GL_INTENSITY
+ * 2 - GL_ALPHA
+ * depending on the depth texture mode.
+ */
+ unsigned depth_texture_mode : 2;
+
+ /**
+ * If the sampler is used as a shadow sampler,
+ * this field is (texture_compare_func - GL_NEVER).
+ * [e.g. if compare function is GL_LEQUAL, this field is 3]
+ *
+ * Otherwise, this field is 0.
+ */
+ unsigned texture_compare_func : 3;
+ } unit[16];
+};
+
+
+
+struct r300_fragment_program_node {
+ int tex_offset; /**< first tex instruction */
+ int tex_end; /**< last tex instruction, relative to tex_offset */
+ int alu_offset; /**< first ALU instruction */
+ int alu_end; /**< last ALU instruction, relative to alu_offset */
+ int flags;
+};
+
+/**
+ * Stores an R300 fragment program in its compiled-to-hardware form.
+ */
+struct r300_fragment_program_code {
+ struct {
+ int length; /**< total # of texture instructions used */
+ uint32_t inst[R300_PFS_MAX_TEX_INST];
+ } tex;
+
+ struct {
+ int length; /**< total # of ALU instructions used */
+ struct {
+ uint32_t rgb_inst;
+ uint32_t rgb_addr;
+ uint32_t alpha_inst;
+ uint32_t alpha_addr;
+ } inst[R300_PFS_MAX_ALU_INST];
+ } alu;
+
+ uint32_t config; /* US_CONFIG */
+ uint32_t pixsize; /* US_PIXSIZE */
+ uint32_t code_offset; /* US_CODE_OFFSET */
+ uint32_t code_addr[4]; /* US_CODE_ADDR */
+};
+
+
+struct r500_fragment_program_code {
+ struct {
+ uint32_t inst0;
+ uint32_t inst1;
+ uint32_t inst2;
+ uint32_t inst3;
+ uint32_t inst4;
+ uint32_t inst5;
+ } inst[R500_PFS_MAX_INST];
+
+ int inst_end; /* Number of instructions - 1; also, last instruction to be executed */
+
+ int max_temp_idx;
+};
+
+struct rX00_fragment_program_code {
+ union {
+ struct r300_fragment_program_code r300;
+ struct r500_fragment_program_code r500;
+ } code;
+
+ unsigned writes_depth:1;
+
+ struct rc_constant_list constants;
+};
+
+
+#define VSF_MAX_FRAGMENT_LENGTH (255*4)
+#define VSF_MAX_FRAGMENT_TEMPS (14)
+
+#define VSF_MAX_INPUTS 32
+#define VSF_MAX_OUTPUTS 32
+
+struct r300_vertex_program_code {
+ int length;
+ union {
+ uint32_t d[VSF_MAX_FRAGMENT_LENGTH];
+ float f[VSF_MAX_FRAGMENT_LENGTH];
+ } body;
+
+ int pos_end;
+ int num_temporaries; /* Number of temp vars used by program */
+ int inputs[VSF_MAX_INPUTS];
+ int outputs[VSF_MAX_OUTPUTS];
+
+ struct rc_constant_list constants;
+
+ uint32_t InputsRead;
+ uint32_t OutputsWritten;
+};
+
+void r300_vertex_program_dump(struct r300_vertex_program_code * vs);
+
+#endif /* RADEON_CODE_H */
+
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
new file mode 100644
index 0000000000..da950d5289
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.c
@@ -0,0 +1,262 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#include "radeon_compiler.h"
+
+#include <stdarg.h>
+
+#include "radeon_program.h"
+
+
+void rc_init(struct radeon_compiler * c)
+{
+ memset(c, 0, sizeof(*c));
+
+ memory_pool_init(&c->Pool);
+ c->Program.Instructions.Prev = &c->Program.Instructions;
+ c->Program.Instructions.Next = &c->Program.Instructions;
+ c->Program.Instructions.I.Opcode = OPCODE_END;
+}
+
+void rc_destroy(struct radeon_compiler * c)
+{
+ rc_constants_destroy(&c->Program.Constants);
+ memory_pool_destroy(&c->Pool);
+ free(c->ErrorMsg);
+}
+
+void rc_debug(struct radeon_compiler * c, const char * fmt, ...)
+{
+ va_list ap;
+
+ if (!c->Debug)
+ return;
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+}
+
+void rc_error(struct radeon_compiler * c, const char * fmt, ...)
+{
+ va_list ap;
+
+ c->Error = GL_TRUE;
+
+ if (!c->ErrorMsg) {
+ /* Only remember the first error */
+ char buf[1024];
+ int written;
+
+ va_start(ap, fmt);
+ written = vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ if (written < sizeof(buf)) {
+ c->ErrorMsg = strdup(buf);
+ } else {
+ c->ErrorMsg = malloc(written + 1);
+
+ va_start(ap, fmt);
+ vsnprintf(c->ErrorMsg, written + 1, fmt, ap);
+ va_end(ap);
+ }
+ }
+
+ if (c->Debug) {
+ fprintf(stderr, "r300compiler error: ");
+
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ }
+}
+
+/**
+ * Rewrite the program such that everything that source the given input
+ * register will source new_input instead.
+ */
+void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_register new_input)
+{
+ struct rc_instruction * inst;
+
+ c->Program.InputsRead &= ~(1 << input);
+
+ for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
+ const unsigned numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
+ unsigned i;
+
+ for(i = 0; i < numsrcs; ++i) {
+ if (inst->I.SrcReg[i].File == PROGRAM_INPUT && inst->I.SrcReg[i].Index == input) {
+ inst->I.SrcReg[i].File = new_input.File;
+ inst->I.SrcReg[i].Index = new_input.Index;
+ inst->I.SrcReg[i].Swizzle = combine_swizzles(new_input.Swizzle, inst->I.SrcReg[i].Swizzle);
+ if (!inst->I.SrcReg[i].Abs) {
+ inst->I.SrcReg[i].Negate ^= new_input.Negate;
+ inst->I.SrcReg[i].Abs = new_input.Abs;
+ }
+
+ c->Program.InputsRead |= 1 << new_input.Index;
+ }
+ }
+ }
+}
+
+
+/**
+ * Rewrite the program such that everything that writes into the given
+ * output register will instead write to new_output. The new_output
+ * writemask is honoured.
+ */
+void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask)
+{
+ struct rc_instruction * inst;
+
+ c->Program.OutputsWritten &= ~(1 << output);
+
+ for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
+ const unsigned numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
+
+ if (numdsts) {
+ if (inst->I.DstReg.File == PROGRAM_OUTPUT && inst->I.DstReg.Index == output) {
+ inst->I.DstReg.Index = new_output;
+ inst->I.DstReg.WriteMask &= writemask;
+
+ c->Program.OutputsWritten |= 1 << new_output;
+ }
+ }
+ }
+}
+
+
+/**
+ * Rewrite the program such that a given output is duplicated.
+ */
+void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output)
+{
+ unsigned tempreg = rc_find_free_temporary(c);
+ struct rc_instruction * inst;
+
+ for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next) {
+ const unsigned numdsts = _mesa_num_inst_dst_regs(inst->I.Opcode);
+
+ if (numdsts) {
+ if (inst->I.DstReg.File == PROGRAM_OUTPUT && inst->I.DstReg.Index == output) {
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = tempreg;
+ }
+ }
+ }
+
+ inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg.File = PROGRAM_OUTPUT;
+ inst->I.DstReg.Index = output;
+
+ inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[0].Index = tempreg;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ inst = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
+ inst->I.Opcode = OPCODE_MOV;
+ inst->I.DstReg.File = PROGRAM_OUTPUT;
+ inst->I.DstReg.Index = dup_output;
+
+ inst->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[0].Index = tempreg;
+ inst->I.SrcReg[0].Swizzle = SWIZZLE_XYZW;
+
+ c->Program.OutputsWritten |= 1 << dup_output;
+}
+
+
+/**
+ * Introduce standard code fragment to deal with fragment.position.
+ */
+void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input)
+{
+ unsigned tempregi = rc_find_free_temporary(c);
+
+ c->Program.InputsRead &= ~(1 << wpos);
+ c->Program.InputsRead |= 1 << new_input;
+
+ /* perspective divide */
+ struct rc_instruction * inst_rcp = rc_insert_new_instruction(c, &c->Program.Instructions);
+ inst_rcp->I.Opcode = OPCODE_RCP;
+
+ inst_rcp->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_rcp->I.DstReg.Index = tempregi;
+ inst_rcp->I.DstReg.WriteMask = WRITEMASK_W;
+
+ inst_rcp->I.SrcReg[0].File = PROGRAM_INPUT;
+ inst_rcp->I.SrcReg[0].Index = new_input;
+ inst_rcp->I.SrcReg[0].Swizzle = SWIZZLE_WWWW;
+
+ struct rc_instruction * inst_mul = rc_insert_new_instruction(c, inst_rcp);
+ inst_mul->I.Opcode = OPCODE_MUL;
+
+ inst_mul->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mul->I.DstReg.Index = tempregi;
+ inst_mul->I.DstReg.WriteMask = WRITEMASK_XYZ;
+
+ inst_mul->I.SrcReg[0].File = PROGRAM_INPUT;
+ inst_mul->I.SrcReg[0].Index = new_input;
+
+ inst_mul->I.SrcReg[1].File = PROGRAM_TEMPORARY;
+ inst_mul->I.SrcReg[1].Index = tempregi;
+ inst_mul->I.SrcReg[1].Swizzle = SWIZZLE_WWWW;
+
+ /* viewport transformation */
+ struct rc_instruction * inst_mad = rc_insert_new_instruction(c, inst_mul);
+ inst_mad->I.Opcode = OPCODE_MAD;
+
+ inst_mad->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst_mad->I.DstReg.Index = tempregi;
+ inst_mad->I.DstReg.WriteMask = WRITEMASK_XYZ;
+
+ inst_mad->I.SrcReg[0].File = PROGRAM_TEMPORARY;
+ inst_mad->I.SrcReg[0].Index = tempregi;
+ inst_mad->I.SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ inst_mad->I.SrcReg[1].File = PROGRAM_STATE_VAR;
+ inst_mad->I.SrcReg[1].Index = rc_constants_add_state(&c->Program.Constants, RC_STATE_R300_WINDOW_DIMENSION, 0);
+ inst_mad->I.SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ inst_mad->I.SrcReg[2].File = PROGRAM_STATE_VAR;
+ inst_mad->I.SrcReg[2].Index = inst_mad->I.SrcReg[1].Index;
+ inst_mad->I.SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
+
+ struct rc_instruction * inst;
+ for (inst = inst_mad->Next; inst != &c->Program.Instructions; inst = inst->Next) {
+ const unsigned numsrcs = _mesa_num_inst_src_regs(inst->I.Opcode);
+ unsigned i;
+
+ for(i = 0; i < numsrcs; i++) {
+ if (inst->I.SrcReg[i].File == PROGRAM_INPUT &&
+ inst->I.SrcReg[i].Index == wpos) {
+ inst->I.SrcReg[i].File = PROGRAM_TEMPORARY;
+ inst->I.SrcReg[i].Index = tempregi;
+ }
+ }
+ }
+}
+
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
new file mode 100644
index 0000000000..e63ab8840a
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_compiler.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2009 Nicolai Hähnle <nhaehnle@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE. */
+
+#ifndef RADEON_COMPILER_H
+#define RADEON_COMPILER_H
+
+#include "main/mtypes.h"
+#include "shader/prog_instruction.h"
+
+#include "memory_pool.h"
+#include "radeon_code.h"
+
+
+struct rc_instruction {
+ struct rc_instruction * Prev;
+ struct rc_instruction * Next;
+ struct prog_instruction I;
+};
+
+struct rc_program {
+ /**
+ * Instructions.Next points to the first instruction,
+ * Instructions.Prev points to the last instruction.
+ */
+ struct rc_instruction Instructions;
+
+ /* Long term, we should probably remove InputsRead & OutputsWritten,
+ * since updating dependent state can be fragile, and they aren't
+ * actually used very often. */
+ uint32_t InputsRead;
+ uint32_t OutputsWritten;
+ uint32_t ShadowSamplers; /**< Texture units used for shadow sampling. */
+
+ struct rc_constant_list Constants;
+};
+
+struct radeon_compiler {
+ struct memory_pool Pool;
+ struct rc_program Program;
+ unsigned Debug:1;
+ unsigned Error:1;
+ char * ErrorMsg;
+};
+
+void rc_init(struct radeon_compiler * c);
+void rc_destroy(struct radeon_compiler * c);
+
+void rc_debug(struct radeon_compiler * c, const char * fmt, ...);
+void rc_error(struct radeon_compiler * c, const char * fmt, ...);
+
+void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program);
+
+void rc_calculate_inputs_outputs(struct radeon_compiler * c);
+
+void rc_move_input(struct radeon_compiler * c, unsigned input, struct prog_src_register new_input);
+void rc_move_output(struct radeon_compiler * c, unsigned output, unsigned new_output, unsigned writemask);
+void rc_copy_output(struct radeon_compiler * c, unsigned output, unsigned dup_output);
+void rc_transform_fragment_wpos(struct radeon_compiler * c, unsigned wpos, unsigned new_input);
+
+struct r300_fragment_program_compiler {
+ struct radeon_compiler Base;
+ struct rX00_fragment_program_code *code;
+ struct r300_fragment_program_external_state state;
+ unsigned is_r500;
+ unsigned OutputDepth;
+ unsigned OutputColor;
+
+ void * UserData;
+ void (*AllocateHwInputs)(
+ struct r300_fragment_program_compiler * c,
+ void (*allocate)(void * data, unsigned input, unsigned hwreg),
+ void * mydata);
+};
+
+void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c);
+
+
+struct r300_vertex_program_compiler {
+ struct radeon_compiler Base;
+ struct r300_vertex_program_code *code;
+ GLbitfield RequiredOutputs;
+
+ void * UserData;
+ void (*SetHwInputOutput)(struct r300_vertex_program_compiler * c);
+};
+
+void r3xx_compile_vertex_program(struct r300_vertex_program_compiler* c);
+
+#endif /* RADEON_COMPILER_H */
diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.c b/src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.c
index 840c9733b1..aaaa50ad1f 100644
--- a/src/mesa/drivers/dri/r300/radeon_nqssadce.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.c
@@ -36,6 +36,8 @@
#include "radeon_nqssadce.h"
+#include "radeon_compiler.h"
+
/**
* Return the @ref register_state for the given register (or 0 for untracked
@@ -76,9 +78,10 @@ struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register s
}
-static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s,
- struct prog_instruction *inst, GLint src, GLuint sourced)
+static void track_used_srcreg(struct nqssadce_state* s,
+ GLint src, GLuint sourced)
{
+ struct prog_instruction * inst = &s->IP->I;
int i;
GLuint deswz_source = 0;
@@ -95,12 +98,11 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s,
if (!s->Descr->IsNativeSwizzle(inst->Opcode, inst->SrcReg[src])) {
struct prog_dst_register dstreg = inst->DstReg;
dstreg.File = PROGRAM_TEMPORARY;
- dstreg.Index = _mesa_find_free_register(s->Program, PROGRAM_TEMPORARY);
+ dstreg.Index = rc_find_free_temporary(s->Compiler);
dstreg.WriteMask = sourced;
s->Descr->BuildSwizzle(s, dstreg, inst->SrcReg[src]);
- inst = s->Program->Instructions + s->IP;
inst->SrcReg[src].File = PROGRAM_TEMPORARY;
inst->SrcReg[src].Index = dstreg.Index;
inst->SrcReg[src].Swizzle = 0;
@@ -117,37 +119,36 @@ static struct prog_instruction* track_used_srcreg(struct nqssadce_state* s,
struct register_state *regstate;
- if (inst->SrcReg[src].RelAddr)
+ if (inst->SrcReg[src].RelAddr) {
regstate = get_reg_state(s, PROGRAM_ADDRESS, 0);
- else
+ if (regstate)
+ regstate->Sourced |= WRITEMASK_X;
+ } else {
regstate = get_reg_state(s, inst->SrcReg[src].File, inst->SrcReg[src].Index);
-
- if (regstate)
- regstate->Sourced |= deswz_source & 0xf;
-
- return inst;
+ if (regstate)
+ regstate->Sourced |= deswz_source & 0xf;
+ }
}
-static void unalias_srcregs(struct prog_instruction *inst, GLuint oldindex, GLuint newindex)
+static void unalias_srcregs(struct rc_instruction *inst, GLuint oldindex, GLuint newindex)
{
- int nsrc = _mesa_num_inst_src_regs(inst->Opcode);
+ int nsrc = _mesa_num_inst_src_regs(inst->I.Opcode);
int i;
for(i = 0; i < nsrc; ++i)
- if (inst->SrcReg[i].File == PROGRAM_TEMPORARY && inst->SrcReg[i].Index == oldindex)
- inst->SrcReg[i].Index = newindex;
+ if (inst->I.SrcReg[i].File == PROGRAM_TEMPORARY && inst->I.SrcReg[i].Index == oldindex)
+ inst->I.SrcReg[i].Index = newindex;
}
static void unalias_temporary(struct nqssadce_state* s, GLuint oldindex)
{
- GLuint newindex = _mesa_find_free_register(s->Program, PROGRAM_TEMPORARY);
- int ip;
- for(ip = 0; ip < s->IP; ++ip) {
- struct prog_instruction* inst = s->Program->Instructions + ip;
- if (inst->DstReg.File == PROGRAM_TEMPORARY && inst->DstReg.Index == oldindex)
- inst->DstReg.Index = newindex;
+ GLuint newindex = rc_find_free_temporary(s->Compiler);
+ struct rc_instruction * inst;
+ for(inst = s->Compiler->Program.Instructions.Next; inst != s->IP; inst = inst->Next) {
+ if (inst->I.DstReg.File == PROGRAM_TEMPORARY && inst->I.DstReg.Index == oldindex)
+ inst->I.DstReg.Index = newindex;
unalias_srcregs(inst, oldindex, newindex);
}
- unalias_srcregs(s->Program->Instructions + s->IP, oldindex, newindex);
+ unalias_srcregs(s->IP, oldindex, newindex);
}
@@ -156,7 +157,8 @@ static void unalias_temporary(struct nqssadce_state* s, GLuint oldindex)
*/
static void process_instruction(struct nqssadce_state* s)
{
- struct prog_instruction *inst = s->Program->Instructions + s->IP;
+ struct prog_instruction *inst = &s->IP->I;
+ GLuint WriteMask;
if (inst->Opcode == OPCODE_END)
return;
@@ -164,7 +166,7 @@ static void process_instruction(struct nqssadce_state* s)
if (inst->Opcode != OPCODE_KIL) {
struct register_state *regstate = get_reg_state(s, inst->DstReg.File, inst->DstReg.Index);
if (!regstate) {
- _mesa_problem(s->Ctx, "NqssaDce: bad destination register (%i[%i])\n",
+ rc_error(s->Compiler, "NqssaDce: bad destination register (%i[%i])\n",
inst->DstReg.File, inst->DstReg.Index);
return;
}
@@ -173,7 +175,9 @@ static void process_instruction(struct nqssadce_state* s)
regstate->Sourced &= ~inst->DstReg.WriteMask;
if (inst->DstReg.WriteMask == 0) {
- _mesa_delete_instructions(s->Program, s->IP, 1);
+ struct rc_instruction * inst_remove = s->IP;
+ s->IP = s->IP->Prev;
+ rc_remove_instruction(inst_remove);
return;
}
@@ -181,16 +185,15 @@ static void process_instruction(struct nqssadce_state* s)
unalias_temporary(s, inst->DstReg.Index);
}
- /* Attention: Due to swizzle emulation code, the following
- * might change the instruction stream under us, so we have
- * to be careful with the inst pointer. */
+ WriteMask = inst->DstReg.WriteMask;
+
switch (inst->Opcode) {
case OPCODE_ARL:
case OPCODE_DDX:
case OPCODE_DDY:
case OPCODE_FRC:
case OPCODE_MOV:
- inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask);
+ track_used_srcreg(s, 0, WriteMask);
break;
case OPCODE_ADD:
case OPCODE_MAX:
@@ -198,14 +201,14 @@ static void process_instruction(struct nqssadce_state* s)
case OPCODE_MUL:
case OPCODE_SGE:
case OPCODE_SLT:
- inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask);
- inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask);
+ track_used_srcreg(s, 0, WriteMask);
+ track_used_srcreg(s, 1, WriteMask);
break;
case OPCODE_CMP:
case OPCODE_MAD:
- inst = track_used_srcreg(s, inst, 0, inst->DstReg.WriteMask);
- inst = track_used_srcreg(s, inst, 1, inst->DstReg.WriteMask);
- inst = track_used_srcreg(s, inst, 2, inst->DstReg.WriteMask);
+ track_used_srcreg(s, 0, WriteMask);
+ track_used_srcreg(s, 1, WriteMask);
+ track_used_srcreg(s, 2, WriteMask);
break;
case OPCODE_COS:
case OPCODE_EX2:
@@ -213,83 +216,79 @@ static void process_instruction(struct nqssadce_state* s)
case OPCODE_RCP:
case OPCODE_RSQ:
case OPCODE_SIN:
- inst = track_used_srcreg(s, inst, 0, 0x1);
+ track_used_srcreg(s, 0, 0x1);
break;
case OPCODE_DP3:
- inst = track_used_srcreg(s, inst, 0, 0x7);
- inst = track_used_srcreg(s, inst, 1, 0x7);
+ track_used_srcreg(s, 0, 0x7);
+ track_used_srcreg(s, 1, 0x7);
break;
case OPCODE_DP4:
- inst = track_used_srcreg(s, inst, 0, 0xf);
- inst = track_used_srcreg(s, inst, 1, 0xf);
+ track_used_srcreg(s, 0, 0xf);
+ track_used_srcreg(s, 1, 0xf);
break;
case OPCODE_KIL:
case OPCODE_TEX:
case OPCODE_TXB:
case OPCODE_TXP:
- inst = track_used_srcreg(s, inst, 0, 0xf);
+ track_used_srcreg(s, 0, 0xf);
break;
case OPCODE_DST:
- inst = track_used_srcreg(s, inst, 0, 0x6);
- inst = track_used_srcreg(s, inst, 1, 0xa);
+ track_used_srcreg(s, 0, 0x6);
+ track_used_srcreg(s, 1, 0xa);
break;
case OPCODE_EXP:
case OPCODE_LOG:
case OPCODE_POW:
- inst = track_used_srcreg(s, inst, 0, 0x3);
+ track_used_srcreg(s, 0, 0x3);
break;
case OPCODE_LIT:
- inst = track_used_srcreg(s, inst, 0, 0xb);
+ track_used_srcreg(s, 0, 0xb);
break;
default:
- _mesa_problem(s->Ctx, "NqssaDce: Unknown opcode %d\n", inst->Opcode);
+ rc_error(s->Compiler, "NqssaDce: Unknown opcode %d\n", inst->Opcode);
return;
}
+
+ s->IP = s->IP->Prev;
}
-static void calculateInputsOutputs(struct gl_program *p)
+void rc_calculate_inputs_outputs(struct radeon_compiler * c)
{
- struct prog_instruction *inst;
- GLuint InputsRead, OutputsWritten;
+ struct rc_instruction *inst;
- inst = p->Instructions;
- InputsRead = 0;
- OutputsWritten = 0;
- while (inst->Opcode != OPCODE_END)
+ c->Program.InputsRead = 0;
+ c->Program.OutputsWritten = 0;
+
+ for(inst = c->Program.Instructions.Next; inst != &c->Program.Instructions; inst = inst->Next)
{
- int i, num_src_regs;
+ int i;
+ int num_src_regs = _mesa_num_inst_src_regs(inst->I.Opcode);
- num_src_regs = _mesa_num_inst_src_regs(inst->Opcode);
for (i = 0; i < num_src_regs; ++i) {
- if (inst->SrcReg[i].File == PROGRAM_INPUT)
- InputsRead |= 1 << inst->SrcReg[i].Index;
+ if (inst->I.SrcReg[i].File == PROGRAM_INPUT)
+ c->Program.InputsRead |= 1 << inst->I.SrcReg[i].Index;
}
- if (inst->DstReg.File == PROGRAM_OUTPUT)
- OutputsWritten |= 1 << inst->DstReg.Index;
-
- ++inst;
+ if (_mesa_num_inst_dst_regs(inst->I.Opcode)) {
+ if (inst->I.DstReg.File == PROGRAM_OUTPUT)
+ c->Program.OutputsWritten |= 1 << inst->I.DstReg.Index;
+ }
}
-
- p->InputsRead = InputsRead;
- p->OutputsWritten = OutputsWritten;
}
-void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr)
+void radeonNqssaDce(struct radeon_compiler * c, struct radeon_nqssadce_descr* descr, void * data)
{
struct nqssadce_state s;
_mesa_bzero(&s, sizeof(s));
- s.Ctx = ctx;
- s.Program = p;
+ s.Compiler = c;
s.Descr = descr;
+ s.UserData = data;
s.Descr->Init(&s);
- s.IP = p->NumInstructions;
+ s.IP = c->Program.Instructions.Prev;
- while(s.IP > 0) {
- s.IP--;
+ while(s.IP != &c->Program.Instructions && !c->Error)
process_instruction(&s);
- }
- calculateInputsOutputs(p);
+ rc_calculate_inputs_outputs(c);
}
diff --git a/src/mesa/drivers/dri/r300/radeon_nqssadce.h b/src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.h
index 8626f21c25..b3fc77a35a 100644
--- a/src/mesa/drivers/dri/r300/radeon_nqssadce.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_nqssadce.h
@@ -30,7 +30,6 @@
#include "radeon_program.h"
-
struct register_state {
/**
* Bitmask indicating which components of the register are sourced
@@ -44,14 +43,13 @@ struct register_state {
* read from, etc.
*/
struct nqssadce_state {
- GLcontext *Ctx;
- struct gl_program *Program;
+ struct radeon_compiler *Compiler;
struct radeon_nqssadce_descr *Descr;
/**
* All instructions after this instruction pointer have been dealt with.
*/
- int IP;
+ struct rc_instruction * IP;
/**
* Which registers are read by subsequent instructions?
@@ -59,6 +57,8 @@ struct nqssadce_state {
struct register_state Temps[MAX_PROGRAM_TEMPS];
struct register_state Outputs[VERT_RESULT_MAX];
struct register_state Address;
+
+ void * UserData;
};
@@ -83,11 +83,9 @@ struct radeon_nqssadce_descr {
* The transformation will work recursively on the emitted instruction(s).
*/
void (*BuildSwizzle)(struct nqssadce_state*, struct prog_dst_register dst, struct prog_src_register src);
-
- void *Data;
};
-void radeonNqssaDce(GLcontext *ctx, struct gl_program *p, struct radeon_nqssadce_descr* descr);
+void radeonNqssaDce(struct radeon_compiler * c, struct radeon_nqssadce_descr* descr, void * data);
struct prog_src_register lmul_swizzle(GLuint swizzle, struct prog_src_register srcreg);
#endif /* __RADEON_PROGRAM_NQSSADCE_H_ */
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program.c b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
new file mode 100644
index 0000000000..b636f90a96
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (C) 2008 Nicolai Haehnle.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "radeon_program.h"
+
+#include "radeon_compiler.h"
+#include "shader/prog_parameter.h"
+#include "shader/prog_print.h"
+
+
+/**
+ * Transform the given clause in the following way:
+ * 1. Replace it with an empty clause
+ * 2. For every instruction in the original clause, try the given
+ * transformations in order.
+ * 3. If one of the transformations returns GL_TRUE, assume that it
+ * has emitted the appropriate instruction(s) into the new clause;
+ * otherwise, copy the instruction verbatim.
+ *
+ * \note The transformation is currently not recursive; in other words,
+ * instructions emitted by transformations are not transformed.
+ *
+ * \note The transform is called 'local' because it can only look at
+ * one instruction at a time.
+ */
+void radeonLocalTransform(
+ struct radeon_compiler * c,
+ int num_transformations,
+ struct radeon_program_transformation* transformations)
+{
+ struct rc_instruction * inst = c->Program.Instructions.Next;
+
+ while(inst != &c->Program.Instructions) {
+ struct rc_instruction * current = inst;
+ int i;
+
+ inst = inst->Next;
+
+ for(i = 0; i < num_transformations; ++i) {
+ struct radeon_program_transformation* t = transformations + i;
+
+ if (t->function(c, current, t->userData))
+ break;
+ }
+ }
+}
+
+
+GLint rc_find_free_temporary(struct radeon_compiler * c)
+{
+ GLboolean used[MAX_PROGRAM_TEMPS];
+ GLuint i;
+
+ memset(used, 0, sizeof(used));
+
+ for (struct rc_instruction * rcinst = c->Program.Instructions.Next; rcinst != &c->Program.Instructions; rcinst = rcinst->Next) {
+ const struct prog_instruction *inst = &rcinst->I;
+ const GLuint nsrc = _mesa_num_inst_src_regs(inst->Opcode);
+ const GLuint ndst = _mesa_num_inst_dst_regs(inst->Opcode);
+ GLuint k;
+
+ for (k = 0; k < nsrc; k++) {
+ if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
+ used[inst->SrcReg[k].Index] = GL_TRUE;
+ }
+
+ if (ndst) {
+ if (inst->DstReg.File == PROGRAM_TEMPORARY)
+ used[inst->DstReg.Index] = GL_TRUE;
+ }
+ }
+
+ for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+ if (!used[i])
+ return i;
+ }
+
+ return -1;
+}
+
+
+struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c)
+{
+ struct rc_instruction * inst = memory_pool_malloc(&c->Pool, sizeof(struct rc_instruction));
+
+ inst->Prev = 0;
+ inst->Next = 0;
+
+ _mesa_init_instructions(&inst->I, 1);
+
+ return inst;
+}
+
+
+struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after)
+{
+ struct rc_instruction * inst = rc_alloc_instruction(c);
+
+ inst->Prev = after;
+ inst->Next = after->Next;
+
+ inst->Prev->Next = inst;
+ inst->Next->Prev = inst;
+
+ return inst;
+}
+
+void rc_remove_instruction(struct rc_instruction * inst)
+{
+ inst->Prev->Next = inst->Next;
+ inst->Next->Prev = inst->Prev;
+}
+
+
+void rc_mesa_to_rc_program(struct radeon_compiler * c, struct gl_program * program)
+{
+ struct prog_instruction *source;
+ unsigned int i;
+
+ for(source = program->Instructions; source->Opcode != OPCODE_END; ++source) {
+ struct rc_instruction * dest = rc_insert_new_instruction(c, c->Program.Instructions.Prev);
+ dest->I = *source;
+ }
+
+ c->Program.ShadowSamplers = program->ShadowSamplers;
+ c->Program.InputsRead = program->InputsRead;
+ c->Program.OutputsWritten = program->OutputsWritten;
+
+ int isNVProgram = 0;
+
+ 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;
+
+ 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);
+ }
+ }
+}
+
+
+/**
+ * Print program to stderr, default options.
+ */
+void rc_print_program(const struct rc_program *prog)
+{
+ GLuint indent = 0;
+ GLuint linenum = 1;
+ struct rc_instruction *inst;
+
+ fprintf(stderr, "# Radeon Compiler Program\n");
+
+ for(inst = prog->Instructions.Next; inst != &prog->Instructions; inst = inst->Next) {
+ fprintf(stderr, "%3d: ", linenum);
+
+ /* Massive hack: We rely on the fact that the printers do not actually
+ * use the gl_program argument (last argument) in debug mode */
+ indent = _mesa_fprint_instruction_opt(
+ stderr, &inst->I,
+ indent, PROG_PRINT_DEBUG, 0);
+
+ linenum++;
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/radeon_program.h b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
index 88474d43a2..561958608c 100644
--- a/src/mesa/drivers/dri/r300/radeon_program.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program.h
@@ -34,12 +34,9 @@
#include "shader/program.h"
#include "shader/prog_instruction.h"
-
-enum {
- CLAUSE_MIXED = 0,
- CLAUSE_ALU,
- CLAUSE_TEX
-};
+struct radeon_compiler;
+struct rc_instruction;
+struct rc_program;
enum {
PROGRAM_BUILTIN = PROGRAM_FILE_MAX /**< not a real register, but a special swizzle constant */
@@ -83,19 +80,12 @@ static inline GLuint combine_swizzles(GLuint src, GLuint swz)
return ret;
}
+static INLINE void reset_srcreg(struct prog_src_register* reg)
+{
+ _mesa_bzero(reg, sizeof(*reg));
+ reg->Swizzle = SWIZZLE_NOOP;
+}
-/**
- * Transformation context that is passed to local transformations.
- *
- * Care must be taken with some operations during transformation,
- * e.g. finding new temporary registers must use @ref radeonFindFreeTemporary
- */
-struct radeon_transform_context {
- GLcontext *Ctx;
- struct gl_program *Program;
- struct prog_instruction *OldInstructions;
- GLuint OldNumInstructions;
-};
/**
* A transformation that can be passed to \ref radeonLocalTransform.
@@ -109,23 +99,23 @@ struct radeon_transform_context {
*/
struct radeon_program_transformation {
GLboolean (*function)(
- struct radeon_transform_context*,
- struct prog_instruction*,
+ struct radeon_compiler*,
+ struct rc_instruction*,
void*);
void *userData;
};
void radeonLocalTransform(
- GLcontext* ctx,
- struct gl_program *program,
+ struct radeon_compiler *c,
int num_transformations,
struct radeon_program_transformation* transformations);
-/**
- * Find a usable free temporary register during program transformation
- */
-GLint radeonFindFreeTemporary(struct radeon_transform_context *ctx);
+GLint rc_find_free_temporary(struct radeon_compiler * c);
+
+struct rc_instruction *rc_alloc_instruction(struct radeon_compiler * c);
+struct rc_instruction *rc_insert_new_instruction(struct radeon_compiler * c, struct rc_instruction * after);
+void rc_remove_instruction(struct rc_instruction * inst);
-struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count);
+void rc_print_program(const struct rc_program *prog);
#endif
diff --git a/src/mesa/drivers/dri/r300/radeon_program_alu.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
index 8283723bad..f23ce301ca 100644
--- a/src/mesa/drivers/dri/r300/radeon_program_alu.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.c
@@ -35,49 +35,52 @@
#include "radeon_program_alu.h"
-#include "shader/prog_parameter.h"
+#include "radeon_compiler.h"
-static struct prog_instruction *emit1(struct gl_program* p,
+static struct rc_instruction *emit1(
+ struct radeon_compiler * c, struct rc_instruction * after,
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
struct prog_src_register SrcReg)
{
- struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
+ struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
- fpi->Opcode = Opcode;
- fpi->SaturateMode = Saturate;
- fpi->DstReg = DstReg;
- fpi->SrcReg[0] = SrcReg;
+ fpi->I.Opcode = Opcode;
+ fpi->I.SaturateMode = Saturate;
+ fpi->I.DstReg = DstReg;
+ fpi->I.SrcReg[0] = SrcReg;
return fpi;
}
-static struct prog_instruction *emit2(struct gl_program* p,
+static struct rc_instruction *emit2(
+ struct radeon_compiler * c, struct rc_instruction * after,
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1)
{
- struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
+ struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
- fpi->Opcode = Opcode;
- fpi->SaturateMode = Saturate;
- fpi->DstReg = DstReg;
- fpi->SrcReg[0] = SrcReg0;
- fpi->SrcReg[1] = SrcReg1;
+ fpi->I.Opcode = Opcode;
+ fpi->I.SaturateMode = Saturate;
+ fpi->I.DstReg = DstReg;
+ fpi->I.SrcReg[0] = SrcReg0;
+ fpi->I.SrcReg[1] = SrcReg1;
return fpi;
}
-static struct prog_instruction *emit3(struct gl_program* p,
+static struct rc_instruction *emit3(
+ struct radeon_compiler * c, struct rc_instruction * after,
gl_inst_opcode Opcode, GLuint Saturate, struct prog_dst_register DstReg,
struct prog_src_register SrcReg0, struct prog_src_register SrcReg1,
struct prog_src_register SrcReg2)
{
- struct prog_instruction *fpi = radeonAppendInstructions(p, 1);
-
- fpi->Opcode = Opcode;
- fpi->SaturateMode = Saturate;
- fpi->DstReg = DstReg;
- fpi->SrcReg[0] = SrcReg0;
- fpi->SrcReg[1] = SrcReg1;
- fpi->SrcReg[2] = SrcReg2;
+ struct rc_instruction *fpi = rc_insert_new_instruction(c, after);
+
+ fpi->I.Opcode = Opcode;
+ fpi->I.SaturateMode = Saturate;
+ fpi->I.DstReg = DstReg;
+ fpi->I.SrcReg[0] = SrcReg0;
+ fpi->I.SrcReg[1] = SrcReg1;
+ fpi->I.SrcReg[2] = SrcReg2;
return fpi;
}
@@ -88,6 +91,7 @@ static struct prog_dst_register dstreg(int file, int index)
dst.Index = index;
dst.WriteMask = WRITEMASK_XYZW;
dst.CondMask = COND_TR;
+ dst.RelAddr = 0;
dst.CondSwizzle = SWIZZLE_NOOP;
dst.CondSrc = 0;
dst.pad = 0;
@@ -96,10 +100,11 @@ static struct prog_dst_register dstreg(int file, int index)
static struct prog_dst_register dstregtmpmask(int index, int mask)
{
- struct prog_dst_register dst;
+ struct prog_dst_register dst = {0};
dst.File = PROGRAM_TEMPORARY;
dst.Index = index;
dst.WriteMask = mask;
+ dst.RelAddr = 0;
dst.CondMask = COND_TR;
dst.CondSwizzle = SWIZZLE_NOOP;
dst.CondSrc = 0;
@@ -171,44 +176,63 @@ static struct prog_src_register scalar(struct prog_src_register reg)
return swizzle(reg, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X);
}
-static void transform_ABS(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_ABS(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- struct prog_src_register src = inst->SrcReg[0];
+ struct prog_src_register src = inst->I.SrcReg[0];
src.Abs = 1;
src.Negate = NEGATE_NONE;
- emit1(t->Program, OPCODE_MOV, inst->SaturateMode, inst->DstReg, src);
+ emit1(c, inst->Prev, OPCODE_MOV, inst->I.SaturateMode, inst->I.DstReg, src);
+ rc_remove_instruction(inst);
}
-static void transform_DPH(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_DP3(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- struct prog_src_register src0 = inst->SrcReg[0];
+ struct prog_src_register src0 = inst->I.SrcReg[0];
+ struct prog_src_register src1 = inst->I.SrcReg[1];
+ src0.Negate &= ~NEGATE_W;
+ src0.Swizzle &= ~(7 << (3 * 3));
+ src0.Swizzle |= SWIZZLE_ZERO << (3 * 3);
+ src1.Negate &= ~NEGATE_W;
+ src1.Swizzle &= ~(7 << (3 * 3));
+ src1.Swizzle |= SWIZZLE_ZERO << (3 * 3);
+ emit2(c, inst->Prev, OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, src1);
+ rc_remove_instruction(inst);
+}
+
+static void transform_DPH(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ struct prog_src_register src0 = inst->I.SrcReg[0];
src0.Negate &= ~NEGATE_W;
src0.Swizzle &= ~(7 << (3 * 3));
src0.Swizzle |= SWIZZLE_ONE << (3 * 3);
- emit2(t->Program, OPCODE_DP4, inst->SaturateMode, inst->DstReg, src0, inst->SrcReg[1]);
+ emit2(c, inst->Prev, OPCODE_DP4, inst->I.SaturateMode, inst->I.DstReg, src0, inst->I.SrcReg[1]);
+ rc_remove_instruction(inst);
}
/**
* [1, src0.y*src1.y, src0.z, src1.w]
* So basically MUL with lotsa swizzling.
*/
-static void transform_DST(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_DST(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- emit2(t->Program, OPCODE_MUL, inst->SaturateMode, inst->DstReg,
- swizzle(inst->SrcReg[0], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE),
- swizzle(inst->SrcReg[1], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_W));
+ emit2(c, inst->Prev, OPCODE_MUL, inst->I.SaturateMode, inst->I.DstReg,
+ swizzle(inst->I.SrcReg[0], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE),
+ swizzle(inst->I.SrcReg[1], SWIZZLE_ONE, SWIZZLE_Y, SWIZZLE_ONE, SWIZZLE_W));
+ rc_remove_instruction(inst);
}
-static void transform_FLR(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_FLR(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
- emit1(t->Program, OPCODE_FRC, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0]);
- emit2(t->Program, OPCODE_ADD, inst->SaturateMode, inst->DstReg,
- inst->SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
+ int tempreg = rc_find_free_temporary(c);
+ emit1(c, inst->Prev, OPCODE_FRC, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0]);
+ emit2(c, inst->Prev, OPCODE_ADD, inst->I.SaturateMode, inst->I.DstReg,
+ inst->I.SrcReg[0], negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
+ rc_remove_instruction(inst);
}
/**
@@ -229,152 +253,159 @@ static void transform_FLR(struct radeon_transform_context* t,
* 5 slots, if the subsequent optimization passes are clever enough
* to pair instructions correctly.
*/
-static void transform_LIT(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_LIT(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- static const GLfloat LitConst[4] = { -127.999999 };
-
GLuint constant;
GLuint constant_swizzle;
GLuint temp;
- int needTemporary = 0;
struct prog_src_register srctemp;
- constant = _mesa_add_unnamed_constant(t->Program->Parameters, LitConst, 1, &constant_swizzle);
+ constant = rc_constants_add_immediate_scalar(&c->Program.Constants, -127.999999, &constant_swizzle);
- if (inst->DstReg.WriteMask != WRITEMASK_XYZW) {
- needTemporary = 1;
- } else if (inst->DstReg.File != PROGRAM_TEMPORARY) {
- // LIT is typically followed by DP3/DP4, so there's no point
- // in creating special code for this case
- needTemporary = 1;
- }
+ if (inst->I.DstReg.WriteMask != WRITEMASK_XYZW || inst->I.DstReg.File != PROGRAM_TEMPORARY) {
+ struct rc_instruction * inst_mov;
- if (needTemporary) {
- temp = radeonFindFreeTemporary(t);
- } else {
- temp = inst->DstReg.Index;
+ inst_mov = emit1(c, inst,
+ OPCODE_MOV, 0, inst->I.DstReg,
+ srcreg(PROGRAM_TEMPORARY, rc_find_free_temporary(c)));
+
+ inst->I.DstReg.File = PROGRAM_TEMPORARY;
+ inst->I.DstReg.Index = inst_mov->I.SrcReg[0].Index;
+ inst->I.DstReg.WriteMask = WRITEMASK_XYZW;
}
+
+ temp = inst->I.DstReg.Index;
srctemp = srcreg(PROGRAM_TEMPORARY, temp);
// tmp.x = max(0.0, Src.x);
// tmp.y = max(0.0, Src.y);
// tmp.w = clamp(Src.z, -128+eps, 128-eps);
- emit2(t->Program, OPCODE_MAX, 0,
+ emit2(c, inst->Prev, OPCODE_MAX, 0,
dstregtmpmask(temp, WRITEMASK_XYW),
- inst->SrcReg[0],
+ inst->I.SrcReg[0],
swizzle(srcreg(PROGRAM_CONSTANT, constant),
SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ZERO, constant_swizzle&3));
- emit2(t->Program, OPCODE_MIN, 0,
+ emit2(c, inst->Prev, OPCODE_MIN, 0,
dstregtmpmask(temp, WRITEMASK_Z),
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
negate(srcregswz(PROGRAM_CONSTANT, constant, constant_swizzle)));
// tmp.w = Pow(tmp.y, tmp.w)
- emit1(t->Program, OPCODE_LG2, 0,
+ emit1(c, inst->Prev, OPCODE_LG2, 0,
dstregtmpmask(temp, WRITEMASK_W),
swizzle(srctemp, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y));
- emit2(t->Program, OPCODE_MUL, 0,
+ emit2(c, inst->Prev, OPCODE_MUL, 0,
dstregtmpmask(temp, WRITEMASK_W),
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
swizzle(srctemp, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z));
- emit1(t->Program, OPCODE_EX2, 0,
+ emit1(c, inst->Prev, OPCODE_EX2, 0,
dstregtmpmask(temp, WRITEMASK_W),
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
// tmp.z = (tmp.x > 0) ? tmp.w : 0.0
- emit3(t->Program, OPCODE_CMP, inst->SaturateMode,
+ emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode,
dstregtmpmask(temp, WRITEMASK_Z),
negate(swizzle(srctemp, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X)),
swizzle(srctemp, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
builtin_zero);
// tmp.x, tmp.y, tmp.w = 1.0, tmp.x, 1.0
- emit1(t->Program, OPCODE_MOV, inst->SaturateMode,
+ emit1(c, inst->Prev, OPCODE_MOV, inst->I.SaturateMode,
dstregtmpmask(temp, WRITEMASK_XYW),
swizzle(srctemp, SWIZZLE_ONE, SWIZZLE_X, SWIZZLE_ONE, SWIZZLE_ONE));
- if (needTemporary)
- emit1(t->Program, OPCODE_MOV, 0, inst->DstReg, srctemp);
+ rc_remove_instruction(inst);
}
-static void transform_LRP(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_LRP(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
+ int tempreg = rc_find_free_temporary(c);
- emit2(t->Program, OPCODE_ADD, 0,
+ emit2(c, inst->Prev, OPCODE_ADD, 0,
dstreg(PROGRAM_TEMPORARY, tempreg),
- inst->SrcReg[1], negate(inst->SrcReg[2]));
- emit3(t->Program, OPCODE_MAD, inst->SaturateMode,
- inst->DstReg,
- inst->SrcReg[0], srcreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[2]);
+ inst->I.SrcReg[1], negate(inst->I.SrcReg[2]));
+ emit3(c, inst->Prev, OPCODE_MAD, inst->I.SaturateMode,
+ inst->I.DstReg,
+ inst->I.SrcReg[0], srcreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[2]);
+
+ rc_remove_instruction(inst);
}
-static void transform_POW(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_POW(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
+ int tempreg = rc_find_free_temporary(c);
struct prog_dst_register tempdst = dstreg(PROGRAM_TEMPORARY, tempreg);
struct prog_src_register tempsrc = srcreg(PROGRAM_TEMPORARY, tempreg);
tempdst.WriteMask = WRITEMASK_W;
tempsrc.Swizzle = SWIZZLE_WWWW;
- emit1(t->Program, OPCODE_LG2, 0, tempdst, scalar(inst->SrcReg[0]));
- emit2(t->Program, OPCODE_MUL, 0, tempdst, tempsrc, scalar(inst->SrcReg[1]));
- emit1(t->Program, OPCODE_EX2, inst->SaturateMode, inst->DstReg, tempsrc);
+ emit1(c, inst->Prev, OPCODE_LG2, 0, tempdst, scalar(inst->I.SrcReg[0]));
+ emit2(c, inst->Prev, OPCODE_MUL, 0, tempdst, tempsrc, scalar(inst->I.SrcReg[1]));
+ emit1(c, inst->Prev, OPCODE_EX2, inst->I.SaturateMode, inst->I.DstReg, tempsrc);
+
+ rc_remove_instruction(inst);
}
-static void transform_RSQ(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_RSQ(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- emit1(t->Program, OPCODE_RSQ, inst->SaturateMode, inst->DstReg, absolute(inst->SrcReg[0]));
+ inst->I.SrcReg[0] = absolute(inst->I.SrcReg[0]);
}
-static void transform_SGE(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_SGE(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
+ int tempreg = rc_find_free_temporary(c);
- emit2(t->Program, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
- emit3(t->Program, OPCODE_CMP, inst->SaturateMode, inst->DstReg,
+ emit2(c, inst->Prev, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
+ emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
srcreg(PROGRAM_TEMPORARY, tempreg), builtin_zero, builtin_one);
+
+ rc_remove_instruction(inst);
}
-static void transform_SLT(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_SLT(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
+ int tempreg = rc_find_free_temporary(c);
- emit2(t->Program, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->SrcReg[0], negate(inst->SrcReg[1]));
- emit3(t->Program, OPCODE_CMP, inst->SaturateMode, inst->DstReg,
+ emit2(c, inst->Prev, OPCODE_ADD, 0, dstreg(PROGRAM_TEMPORARY, tempreg), inst->I.SrcReg[0], negate(inst->I.SrcReg[1]));
+ emit3(c, inst->Prev, OPCODE_CMP, inst->I.SaturateMode, inst->I.DstReg,
srcreg(PROGRAM_TEMPORARY, tempreg), builtin_one, builtin_zero);
+
+ rc_remove_instruction(inst);
}
-static void transform_SUB(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_SUB(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- emit2(t->Program, OPCODE_ADD, inst->SaturateMode, inst->DstReg, inst->SrcReg[0], negate(inst->SrcReg[1]));
+ inst->I.Opcode = OPCODE_ADD;
+ inst->I.SrcReg[1] = negate(inst->I.SrcReg[1]);
}
-static void transform_SWZ(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_SWZ(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- emit1(t->Program, OPCODE_MOV, inst->SaturateMode, inst->DstReg, inst->SrcReg[0]);
+ inst->I.Opcode = OPCODE_MOV;
}
-static void transform_XPD(struct radeon_transform_context* t,
- struct prog_instruction* inst)
+static void transform_XPD(struct radeon_compiler* c,
+ struct rc_instruction* inst)
{
- int tempreg = radeonFindFreeTemporary(t);
-
- emit2(t->Program, OPCODE_MUL, 0, dstreg(PROGRAM_TEMPORARY, tempreg),
- swizzle(inst->SrcReg[0], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
- swizzle(inst->SrcReg[1], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W));
- emit3(t->Program, OPCODE_MAD, inst->SaturateMode, inst->DstReg,
- swizzle(inst->SrcReg[0], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W),
- swizzle(inst->SrcReg[1], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
+ int tempreg = rc_find_free_temporary(c);
+
+ emit2(c, inst->Prev, OPCODE_MUL, 0, dstreg(PROGRAM_TEMPORARY, tempreg),
+ swizzle(inst->I.SrcReg[0], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
+ swizzle(inst->I.SrcReg[1], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W));
+ emit3(c, inst->Prev, OPCODE_MAD, inst->I.SaturateMode, inst->I.DstReg,
+ swizzle(inst->I.SrcReg[0], SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W),
+ swizzle(inst->I.SrcReg[1], SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W),
negate(srcreg(PROGRAM_TEMPORARY, tempreg)));
+
+ rc_remove_instruction(inst);
}
@@ -392,31 +423,64 @@ static void transform_XPD(struct radeon_transform_context* t,
*
* @note should be applicable to R300 and R500 fragment programs.
*/
-GLboolean radeonTransformALU(struct radeon_transform_context* t,
- struct prog_instruction* inst,
+GLboolean radeonTransformALU(
+ struct radeon_compiler * c,
+ struct rc_instruction* inst,
void* unused)
{
- switch(inst->Opcode) {
- case OPCODE_ABS: transform_ABS(t, inst); return GL_TRUE;
- case OPCODE_DPH: transform_DPH(t, inst); return GL_TRUE;
- case OPCODE_DST: transform_DST(t, inst); return GL_TRUE;
- case OPCODE_FLR: transform_FLR(t, inst); return GL_TRUE;
- case OPCODE_LIT: transform_LIT(t, inst); return GL_TRUE;
- case OPCODE_LRP: transform_LRP(t, inst); return GL_TRUE;
- case OPCODE_POW: transform_POW(t, inst); return GL_TRUE;
- case OPCODE_RSQ: transform_RSQ(t, inst); return GL_TRUE;
- case OPCODE_SGE: transform_SGE(t, inst); return GL_TRUE;
- case OPCODE_SLT: transform_SLT(t, inst); return GL_TRUE;
- case OPCODE_SUB: transform_SUB(t, inst); return GL_TRUE;
- case OPCODE_SWZ: transform_SWZ(t, inst); return GL_TRUE;
- case OPCODE_XPD: transform_XPD(t, inst); return GL_TRUE;
+ switch(inst->I.Opcode) {
+ case OPCODE_ABS: transform_ABS(c, inst); return GL_TRUE;
+ case OPCODE_DPH: transform_DPH(c, inst); return GL_TRUE;
+ case OPCODE_DST: transform_DST(c, inst); return GL_TRUE;
+ case OPCODE_FLR: transform_FLR(c, inst); return GL_TRUE;
+ case OPCODE_LIT: transform_LIT(c, inst); return GL_TRUE;
+ case OPCODE_LRP: transform_LRP(c, inst); return GL_TRUE;
+ case OPCODE_POW: transform_POW(c, inst); return GL_TRUE;
+ case OPCODE_RSQ: transform_RSQ(c, inst); return GL_TRUE;
+ case OPCODE_SGE: transform_SGE(c, inst); return GL_TRUE;
+ case OPCODE_SLT: transform_SLT(c, inst); return GL_TRUE;
+ case OPCODE_SUB: transform_SUB(c, inst); return GL_TRUE;
+ case OPCODE_SWZ: transform_SWZ(c, inst); return GL_TRUE;
+ case OPCODE_XPD: transform_XPD(c, inst); return GL_TRUE;
default:
return GL_FALSE;
}
}
-static void sincos_constants(struct radeon_transform_context* t, GLuint *constants)
+static void transform_r300_vertex_ABS(struct radeon_compiler* c,
+ struct rc_instruction* inst)
+{
+ /* Note: r500 can take absolute values, but r300 cannot. */
+ inst->I.Opcode = OPCODE_MAX;
+ inst->I.SrcReg[1] = inst->I.SrcReg[0];
+ inst->I.SrcReg[1].Negate ^= NEGATE_XYZW;
+}
+
+/**
+ * For use with radeonLocalTransform, this transforms non-native ALU
+ * instructions of the r300 up to r500 vertex engine.
+ */
+GLboolean r300_transform_vertex_alu(
+ struct radeon_compiler * c,
+ struct rc_instruction* inst,
+ void* unused)
+{
+ switch(inst->I.Opcode) {
+ case OPCODE_ABS: transform_r300_vertex_ABS(c, inst); return GL_TRUE;
+ case OPCODE_DP3: transform_DP3(c, inst); return GL_TRUE;
+ case OPCODE_DPH: transform_DPH(c, inst); return GL_TRUE;
+ case OPCODE_FLR: transform_FLR(c, inst); return GL_TRUE;
+ case OPCODE_LRP: transform_LRP(c, inst); return GL_TRUE;
+ case OPCODE_SUB: transform_SUB(c, inst); return GL_TRUE;
+ case OPCODE_SWZ: transform_SWZ(c, inst); return GL_TRUE;
+ case OPCODE_XPD: transform_XPD(c, inst); return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+static void sincos_constants(struct radeon_compiler* c, GLuint *constants)
{
static const GLfloat SinCosConsts[2][4] = {
{
@@ -434,11 +498,8 @@ static void sincos_constants(struct radeon_transform_context* t, GLuint *constan
};
int i;
- for(i = 0; i < 2; ++i) {
- GLuint swz;
- constants[i] = _mesa_add_unnamed_constant(t->Program->Parameters, SinCosConsts[i], 4, &swz);
- ASSERT(swz == SWIZZLE_NOOP);
- }
+ for(i = 0; i < 2; ++i)
+ constants[i] = rc_constants_add_immediate_vec4(&c->Program.Constants, SinCosConsts[i]);
}
/**
@@ -449,23 +510,24 @@ static void sincos_constants(struct radeon_transform_context* t, GLuint *constan
* MAD tmp.y, tmp.x, |tmp.x|, -tmp.x
* MAD dest, tmp.y, weight, tmp.x
*/
-static void sin_approx(struct radeon_transform_context* t,
+static void sin_approx(
+ struct radeon_compiler* c, struct rc_instruction * before,
struct prog_dst_register dst, struct prog_src_register src, const GLuint* constants)
{
- GLuint tempreg = radeonFindFreeTemporary(t);
+ GLuint tempreg = rc_find_free_temporary(c);
- emit2(t->Program, 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(t->Program, 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(t->Program, 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(t->Program, 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));
@@ -476,78 +538,80 @@ static void sin_approx(struct radeon_transform_context* t,
* using only the basic instructions
* MOV, ADD, MUL, MAD, FRC
*/
-GLboolean radeonTransformTrigSimple(struct radeon_transform_context* t,
- struct prog_instruction* inst,
+GLboolean radeonTransformTrigSimple(struct radeon_compiler* c,
+ struct rc_instruction* inst,
void* unused)
{
- if (inst->Opcode != OPCODE_COS &&
- inst->Opcode != OPCODE_SIN &&
- inst->Opcode != OPCODE_SCS)
+ if (inst->I.Opcode != OPCODE_COS &&
+ inst->I.Opcode != OPCODE_SIN &&
+ inst->I.Opcode != OPCODE_SCS)
return GL_FALSE;
GLuint constants[2];
- GLuint tempreg = radeonFindFreeTemporary(t);
+ GLuint tempreg = rc_find_free_temporary(c);
- sincos_constants(t, constants);
+ sincos_constants(c, constants);
- if (inst->Opcode == OPCODE_COS) {
+ if (inst->I.Opcode == OPCODE_COS) {
// MAD tmp.x, src, 1/(2*PI), 0.75
// FRC tmp.x, tmp.x
// MAD tmp.z, tmp.x, 2*PI, -PI
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
- swizzle(inst->SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X));
- emit1(t->Program, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
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(t, inst->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->Opcode == OPCODE_SIN) {
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
- swizzle(inst->SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ } else if (inst->I.Opcode == OPCODE_SIN) {
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y));
- emit1(t->Program, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_W),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W));
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_W),
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
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(t, inst->DstReg,
+ sin_approx(c, inst, inst->I.DstReg,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_W, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W),
constants);
} else {
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
- swizzle(inst->SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
+ swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z, SWIZZLE_Z),
swizzle(srcreg(PROGRAM_CONSTANT, constants[1]), SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_W));
- emit1(t->Program, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
+ emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
srcreg(PROGRAM_TEMPORARY, tempreg));
- emit3(t->Program, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
+ emit3(c, inst->Prev, OPCODE_MAD, 0, dstregtmpmask(tempreg, WRITEMASK_XY),
srcreg(PROGRAM_TEMPORARY, tempreg),
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)));
- struct prog_dst_register dst = inst->DstReg;
+ struct prog_dst_register dst = inst->I.DstReg;
- dst.WriteMask = inst->DstReg.WriteMask & WRITEMASK_X;
- sin_approx(t, dst,
+ dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_X;
+ sin_approx(c, inst, dst,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
constants);
- dst.WriteMask = inst->DstReg.WriteMask & WRITEMASK_Y;
- sin_approx(t, dst,
+ dst.WriteMask = inst->I.DstReg.WriteMask & WRITEMASK_Y;
+ sin_approx(c, inst, dst,
swizzle(srcreg(PROGRAM_TEMPORARY, tempreg), SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y, SWIZZLE_Y),
constants);
}
+ rc_remove_instruction(inst);
+
return GL_TRUE;
}
@@ -560,50 +624,52 @@ GLboolean radeonTransformTrigSimple(struct radeon_transform_context* t,
*
* @warning This transformation implicitly changes the semantics of SIN and COS!
*/
-GLboolean radeonTransformTrigScale(struct radeon_transform_context* t,
- struct prog_instruction* inst,
+GLboolean radeonTransformTrigScale(struct radeon_compiler* c,
+ struct rc_instruction* inst,
void* unused)
{
- if (inst->Opcode != OPCODE_COS &&
- inst->Opcode != OPCODE_SIN &&
- inst->Opcode != OPCODE_SCS)
+ if (inst->I.Opcode != OPCODE_COS &&
+ inst->I.Opcode != OPCODE_SIN &&
+ inst->I.Opcode != OPCODE_SCS)
return GL_FALSE;
- static const GLfloat RCP_2PI[] = { 0.15915494309189535 };
+ static const GLfloat RCP_2PI = 0.15915494309189535;
GLuint temp;
GLuint constant;
GLuint constant_swizzle;
- temp = radeonFindFreeTemporary(t);
- constant = _mesa_add_unnamed_constant(t->Program->Parameters, RCP_2PI, 1, &constant_swizzle);
+ temp = rc_find_free_temporary(c);
+ constant = rc_constants_add_immediate_scalar(&c->Program.Constants, RCP_2PI, &constant_swizzle);
- emit2(t->Program, OPCODE_MUL, 0, dstregtmpmask(temp, WRITEMASK_W),
- swizzle(inst->SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
+ emit2(c, inst->Prev, OPCODE_MUL, 0, dstregtmpmask(temp, WRITEMASK_W),
+ swizzle(inst->I.SrcReg[0], SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X),
srcregswz(PROGRAM_CONSTANT, constant, constant_swizzle));
- emit1(t->Program, OPCODE_FRC, 0, dstregtmpmask(temp, WRITEMASK_W),
+ emit1(c, inst->Prev, OPCODE_FRC, 0, dstregtmpmask(temp, WRITEMASK_W),
srcreg(PROGRAM_TEMPORARY, temp));
- if (inst->Opcode == OPCODE_COS) {
- emit1(t->Program, OPCODE_COS, inst->SaturateMode, inst->DstReg,
+ if (inst->I.Opcode == OPCODE_COS) {
+ emit1(c, inst->Prev, OPCODE_COS, inst->I.SaturateMode, inst->I.DstReg,
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
- } else if (inst->Opcode == OPCODE_SIN) {
- emit1(t->Program, OPCODE_SIN, inst->SaturateMode,
- inst->DstReg, srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
- } else if (inst->Opcode == OPCODE_SCS) {
- struct prog_dst_register moddst = inst->DstReg;
+ } else if (inst->I.Opcode == OPCODE_SIN) {
+ emit1(c, inst->Prev, OPCODE_SIN, inst->I.SaturateMode,
+ inst->I.DstReg, srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
+ } else if (inst->I.Opcode == OPCODE_SCS) {
+ struct prog_dst_register moddst = inst->I.DstReg;
- if (inst->DstReg.WriteMask & WRITEMASK_X) {
+ if (inst->I.DstReg.WriteMask & WRITEMASK_X) {
moddst.WriteMask = WRITEMASK_X;
- emit1(t->Program, OPCODE_COS, inst->SaturateMode, moddst,
+ emit1(c, inst->Prev, OPCODE_COS, inst->I.SaturateMode, moddst,
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
}
- if (inst->DstReg.WriteMask & WRITEMASK_Y) {
+ if (inst->I.DstReg.WriteMask & WRITEMASK_Y) {
moddst.WriteMask = WRITEMASK_Y;
- emit1(t->Program, OPCODE_SIN, inst->SaturateMode, moddst,
+ emit1(c, inst->Prev, OPCODE_SIN, inst->I.SaturateMode, moddst,
srcregswz(PROGRAM_TEMPORARY, temp, SWIZZLE_WWWW));
}
}
+ rc_remove_instruction(inst);
+
return GL_TRUE;
}
@@ -615,21 +681,15 @@ GLboolean radeonTransformTrigScale(struct radeon_transform_context* t,
* @warning This explicitly changes the form of DDX and DDY!
*/
-GLboolean radeonTransformDeriv(struct radeon_transform_context* t,
- struct prog_instruction* inst,
+GLboolean radeonTransformDeriv(struct radeon_compiler* c,
+ struct rc_instruction* inst,
void* unused)
{
- if (inst->Opcode != OPCODE_DDX && inst->Opcode != OPCODE_DDY)
+ if (inst->I.Opcode != OPCODE_DDX && inst->I.Opcode != OPCODE_DDY)
return GL_FALSE;
- struct prog_src_register B = inst->SrcReg[1];
-
- B.Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE,
- SWIZZLE_ONE, SWIZZLE_ONE);
- B.Negate = NEGATE_XYZW;
-
- emit2(t->Program, inst->Opcode, inst->SaturateMode, inst->DstReg,
- inst->SrcReg[0], B);
+ inst->I.SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE, SWIZZLE_ONE);
+ inst->I.SrcReg[1].Negate = NEGATE_XYZW;
return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r300/radeon_program_alu.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h
index b45958115c..147efec6fc 100644
--- a/src/mesa/drivers/dri/r300/radeon_program_alu.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_alu.h
@@ -31,23 +31,28 @@
#include "radeon_program.h"
GLboolean radeonTransformALU(
- struct radeon_transform_context *t,
- struct prog_instruction*,
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
+ void*);
+
+GLboolean r300_transform_vertex_alu(
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
void*);
GLboolean radeonTransformTrigSimple(
- struct radeon_transform_context *t,
- struct prog_instruction*,
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
void*);
GLboolean radeonTransformTrigScale(
- struct radeon_transform_context *t,
- struct prog_instruction*,
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
void*);
GLboolean radeonTransformDeriv(
- struct radeon_transform_context *t,
- struct prog_instruction*,
+ struct radeon_compiler * c,
+ struct rc_instruction * inst,
void*);
#endif /* __RADEON_PROGRAM_ALU_H_ */
diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
index d6fb474cf2..4c26db5d24 100644
--- a/src/mesa/drivers/dri/r300/radeon_program_pair.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.c
@@ -35,17 +35,19 @@
#include "radeon_program_pair.h"
-#include "radeon_common.h"
-
+#include "memory_pool.h"
+#include "radeon_compiler.h"
#include "shader/prog_print.h"
#define error(fmt, args...) do { \
- _mesa_problem(s->Ctx, "%s::%s(): " fmt "\n", \
+ rc_error(&s->Compiler->Base, "%s::%s(): " fmt "\n", \
__FILE__, __FUNCTION__, ##args); \
- s->Error = GL_TRUE; \
} while(0)
struct pair_state_instruction {
+ struct prog_instruction Instruction;
+ GLuint IP; /**< Position of this instruction in original program */
+
GLuint IsTex:1; /**< Is a texture instruction */
GLuint NeedRGB:1; /**< Needs the RGB ALU */
GLuint NeedAlpha:1; /**< Needs the Alpha ALU */
@@ -73,7 +75,7 @@ struct pair_state_instruction {
* Used to keep track of which instructions read a value.
*/
struct reg_value_reader {
- GLuint IP; /**< IP of the instruction that performs this access */
+ struct pair_state_instruction *Reader;
struct reg_value_reader *Next;
};
@@ -82,7 +84,7 @@ struct reg_value_reader {
* PROGRAM_TEMPORARY.
*/
struct reg_value {
- GLuint IP; /**< IP of the instruction that writes this value */
+ struct pair_state_instruction *Writer;
struct reg_value *Next; /**< Pointer to the next value to be written to the same PROGRAM_TEMPORARY component */
/**
@@ -116,11 +118,8 @@ struct pair_register_translation {
};
struct pair_state {
- GLcontext *Ctx;
- struct gl_program *Program;
+ struct r300_fragment_program_compiler * Compiler;
const struct radeon_pair_handler *Handler;
- GLboolean Error;
- GLboolean Debug;
GLboolean Verbose;
void *UserData;
@@ -130,11 +129,6 @@ struct pair_state {
struct pair_register_translation Inputs[FRAG_ATTRIB_MAX];
struct pair_register_translation Temps[MAX_PROGRAM_TEMPS];
- /**
- * Derived information about program instructions.
- */
- struct pair_state_instruction *Instructions;
-
struct {
GLuint RefCount; /**< # of times this occurs in an unscheduled SrcReg or DstReg */
} HwTemps[128];
@@ -147,14 +141,6 @@ struct pair_state {
struct pair_state_instruction *ReadyRGB;
struct pair_state_instruction *ReadyAlpha;
struct pair_state_instruction *ReadyTEX;
-
- /**
- * Pool of @ref reg_value structures for fast allocation.
- */
- struct reg_value *ValuePool;
- GLuint ValuePoolUsed;
- struct reg_value_reader *ReaderPool;
- GLuint ReaderPoolUsed;
};
@@ -183,7 +169,7 @@ static GLuint get_hw_reg(struct pair_state *s, GLuint file, GLuint index)
struct pair_register_translation *t = get_register(s, file, index);
if (!t) {
- _mesa_problem(s->Ctx, "get_hw_reg: %i[%i]\n", file, index);
+ error("get_hw_reg: %i[%i]\n", file, index);
return 0;
}
@@ -221,15 +207,13 @@ static void add_pairinst_to_list(struct pair_state_instruction **list, struct pa
}
/**
- * The instruction at the given IP has become ready. Link it into the ready
+ * The given instruction has become ready. Link it into the ready
* instructions.
*/
-static void instruction_ready(struct pair_state *s, int ip)
+static void instruction_ready(struct pair_state *s, struct pair_state_instruction *pairinst)
{
- struct pair_state_instruction *pairinst = s->Instructions + ip;
-
if (s->Verbose)
- _mesa_printf("instruction_ready(%i)\n", ip);
+ _mesa_printf("instruction_ready(%i)\n", pairinst->IP);
if (pairinst->IsTex)
add_pairinst_to_list(&s->ReadyTEX, pairinst);
@@ -296,12 +280,12 @@ static void final_rewrite(struct pair_state *s, struct prog_instruction *inst)
* Classify an instruction according to which ALUs etc. it needs
*/
static void classify_instruction(struct pair_state *s,
- struct prog_instruction *inst, struct pair_state_instruction *pairinst)
+ struct pair_state_instruction *psi)
{
- pairinst->NeedRGB = (inst->DstReg.WriteMask & WRITEMASK_XYZ) ? 1 : 0;
- pairinst->NeedAlpha = (inst->DstReg.WriteMask & WRITEMASK_W) ? 1 : 0;
+ psi->NeedRGB = (psi->Instruction.DstReg.WriteMask & WRITEMASK_XYZ) ? 1 : 0;
+ psi->NeedAlpha = (psi->Instruction.DstReg.WriteMask & WRITEMASK_W) ? 1 : 0;
- switch(inst->Opcode) {
+ switch(psi->Instruction.Opcode) {
case OPCODE_ADD:
case OPCODE_CMP:
case OPCODE_DDX:
@@ -319,24 +303,24 @@ static void classify_instruction(struct pair_state *s,
case OPCODE_RCP:
case OPCODE_RSQ:
case OPCODE_SIN:
- pairinst->IsTranscendent = 1;
- pairinst->NeedAlpha = 1;
+ psi->IsTranscendent = 1;
+ psi->NeedAlpha = 1;
break;
case OPCODE_DP4:
- pairinst->NeedAlpha = 1;
+ psi->NeedAlpha = 1;
/* fall through */
case OPCODE_DP3:
- pairinst->NeedRGB = 1;
+ psi->NeedRGB = 1;
break;
case OPCODE_KIL:
case OPCODE_TEX:
case OPCODE_TXB:
case OPCODE_TXP:
case OPCODE_END:
- pairinst->IsTex = 1;
+ psi->IsTex = 1;
break;
default:
- error("Unknown opcode %d\n", inst->Opcode);
+ error("Unknown opcode %d\n", psi->Instruction.Opcode);
break;
}
}
@@ -348,30 +332,34 @@ static void classify_instruction(struct pair_state *s,
*/
static void scan_instructions(struct pair_state *s)
{
- struct prog_instruction *inst;
- struct pair_state_instruction *pairinst;
+ struct rc_instruction *source;
GLuint ip;
- for(inst = s->Program->Instructions, pairinst = s->Instructions, ip = 0;
- inst->Opcode != OPCODE_END;
- ++inst, ++pairinst, ++ip) {
- final_rewrite(s, inst);
- classify_instruction(s, inst, pairinst);
+ for(source = s->Compiler->Base.Program.Instructions.Next, ip = 0;
+ source != &s->Compiler->Base.Program.Instructions;
+ source = source->Next, ++ip) {
+ struct pair_state_instruction *pairinst = memory_pool_malloc(&s->Compiler->Base.Pool, sizeof(*pairinst));
+ memset(pairinst, 0, sizeof(struct pair_state_instruction));
+
+ pairinst->Instruction = source->I;
+ pairinst->IP = ip;
+ final_rewrite(s, &pairinst->Instruction);
+ classify_instruction(s, pairinst);
- int nsrc = _mesa_num_inst_src_regs(inst->Opcode);
+ int nsrc = _mesa_num_inst_src_regs(pairinst->Instruction.Opcode);
int j;
for(j = 0; j < nsrc; j++) {
struct pair_register_translation *t =
- get_register(s, inst->SrcReg[j].File, inst->SrcReg[j].Index);
+ get_register(s, pairinst->Instruction.SrcReg[j].File, pairinst->Instruction.SrcReg[j].Index);
if (!t)
continue;
t->RefCount++;
- if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+ if (pairinst->Instruction.SrcReg[j].File == PROGRAM_TEMPORARY) {
int i;
for(i = 0; i < 4; ++i) {
- GLuint swz = GET_SWZ(inst->SrcReg[j].Swizzle, i);
+ GLuint swz = GET_SWZ(pairinst->Instruction.SrcReg[j].Swizzle, i);
if (swz >= 4)
continue; /* constant or NIL swizzle */
if (!t->Value[swz])
@@ -381,36 +369,37 @@ static void scan_instructions(struct pair_state *s)
* also rewrites the value. The code below adds
* a dependency for the DstReg, which is a superset
* of the SrcReg dependency. */
- if (inst->DstReg.File == PROGRAM_TEMPORARY &&
- inst->DstReg.Index == inst->SrcReg[j].Index &&
- GET_BIT(inst->DstReg.WriteMask, swz))
+ if (pairinst->Instruction.DstReg.File == PROGRAM_TEMPORARY &&
+ pairinst->Instruction.DstReg.Index == pairinst->Instruction.SrcReg[j].Index &&
+ GET_BIT(pairinst->Instruction.DstReg.WriteMask, swz))
continue;
- struct reg_value_reader* r = &s->ReaderPool[s->ReaderPoolUsed++];
+ struct reg_value_reader* r = memory_pool_malloc(&s->Compiler->Base.Pool, sizeof(*r));
pairinst->NumDependencies++;
t->Value[swz]->NumReaders++;
- r->IP = ip;
+ r->Reader = pairinst;
r->Next = t->Value[swz]->Readers;
t->Value[swz]->Readers = r;
}
}
}
- int ndst = _mesa_num_inst_dst_regs(inst->Opcode);
+ int ndst = _mesa_num_inst_dst_regs(pairinst->Instruction.Opcode);
if (ndst) {
struct pair_register_translation *t =
- get_register(s, inst->DstReg.File, inst->DstReg.Index);
+ get_register(s, pairinst->Instruction.DstReg.File, pairinst->Instruction.DstReg.Index);
if (t) {
t->RefCount++;
- if (inst->DstReg.File == PROGRAM_TEMPORARY) {
+ if (pairinst->Instruction.DstReg.File == PROGRAM_TEMPORARY) {
int j;
for(j = 0; j < 4; ++j) {
- if (!GET_BIT(inst->DstReg.WriteMask, j))
+ if (!GET_BIT(pairinst->Instruction.DstReg.WriteMask, j))
continue;
- struct reg_value* v = &s->ValuePool[s->ValuePoolUsed++];
- v->IP = ip;
+ struct reg_value* v = memory_pool_malloc(&s->Compiler->Base.Pool, sizeof(*v));
+ memset(v, 0, sizeof(struct reg_value));
+ v->Writer = pairinst;
if (t->Value[j]) {
pairinst->NumDependencies++;
t->Value[j]->Next = v;
@@ -426,7 +415,7 @@ static void scan_instructions(struct pair_state *s)
_mesa_printf("scan(%i): NumDeps = %i\n", ip, pairinst->NumDependencies);
if (!pairinst->NumDependencies)
- instruction_ready(s, ip);
+ instruction_ready(s, pairinst);
}
/* Clear the PROGRAM_TEMPORARY state */
@@ -438,70 +427,23 @@ static void scan_instructions(struct pair_state *s)
}
-/**
- * Reserve hardware temporary registers for the program inputs.
- *
- * @note This allocation is performed explicitly, because the order of inputs
- * is determined by the RS hardware.
- */
-static void allocate_input_registers(struct pair_state *s)
-{
- GLuint InputsRead = s->Program->InputsRead;
- int i;
- GLuint hwindex = 0;
-
- /* Primary colour */
- if (InputsRead & FRAG_BIT_COL0)
- alloc_hw_reg(s, PROGRAM_INPUT, FRAG_ATTRIB_COL0, hwindex++);
- InputsRead &= ~FRAG_BIT_COL0;
-
- /* Secondary color */
- if (InputsRead & FRAG_BIT_COL1)
- alloc_hw_reg(s, PROGRAM_INPUT, FRAG_ATTRIB_COL1, hwindex++);
- InputsRead &= ~FRAG_BIT_COL1;
-
- /* Texcoords */
- for (i = 0; i < s->Ctx->Const.MaxTextureUnits; i++) {
- if (InputsRead & (FRAG_BIT_TEX0 << i))
- alloc_hw_reg(s, PROGRAM_INPUT, FRAG_ATTRIB_TEX0+i, hwindex++);
- }
- InputsRead &= ~FRAG_BITS_TEX_ANY;
-
- /* Fogcoords treated as a texcoord */
- if (InputsRead & FRAG_BIT_FOGC)
- alloc_hw_reg(s, PROGRAM_INPUT, FRAG_ATTRIB_FOGC, hwindex++);
- InputsRead &= ~FRAG_BIT_FOGC;
-
- /* fragment position treated as a texcoord */
- if (InputsRead & FRAG_BIT_WPOS)
- alloc_hw_reg(s, PROGRAM_INPUT, FRAG_ATTRIB_WPOS, hwindex++);
- InputsRead &= ~FRAG_BIT_WPOS;
-
- /* Anything else */
- if (InputsRead)
- error("Don't know how to handle inputs 0x%x\n", InputsRead);
-}
-
-
-static void decrement_dependencies(struct pair_state *s, int ip)
+static void decrement_dependencies(struct pair_state *s, struct pair_state_instruction *pairinst)
{
- struct pair_state_instruction *pairinst = s->Instructions + ip;
ASSERT(pairinst->NumDependencies > 0);
if (!--pairinst->NumDependencies)
- instruction_ready(s, ip);
+ instruction_ready(s, pairinst);
}
/**
* Update the dependency tracking state based on what the instruction
* at the given IP does.
*/
-static void commit_instruction(struct pair_state *s, int ip)
+static void commit_instruction(struct pair_state *s, struct pair_state_instruction *pairinst)
{
- struct prog_instruction *inst = s->Program->Instructions + ip;
- struct pair_state_instruction *pairinst = s->Instructions + ip;
+ struct prog_instruction *inst = &pairinst->Instruction;
if (s->Verbose)
- _mesa_printf("commit_instruction(%i)\n", ip);
+ _mesa_printf("commit_instruction(%i)\n", pairinst->IP);
if (inst->DstReg.File == PROGRAM_TEMPORARY) {
struct pair_register_translation *t = &s->Temps[inst->DstReg.Index];
@@ -516,11 +458,11 @@ static void commit_instruction(struct pair_state *s, int ip)
if (t->Value[i]->NumReaders) {
struct reg_value_reader *r;
for(r = pairinst->Values[i]->Readers; r; r = r->Next)
- decrement_dependencies(s, r->IP);
+ decrement_dependencies(s, r->Reader);
} else if (t->Value[i]->Next) {
/* This happens when the only reader writes
* the register at the same time */
- decrement_dependencies(s, t->Value[i]->Next->IP);
+ decrement_dependencies(s, t->Value[i]->Next->Writer);
}
}
}
@@ -554,7 +496,7 @@ static void commit_instruction(struct pair_state *s, int ip)
if (!--t->Value[swz]->NumReaders) {
if (t->Value[swz]->Next)
- decrement_dependencies(s, t->Value[swz]->Next->IP);
+ decrement_dependencies(s, t->Value[swz]->Next->Writer);
}
}
}
@@ -585,36 +527,52 @@ static void emit_all_tex(struct pair_state *s)
// Allocate destination hardware registers in one block to avoid conflicts.
for(pairinst = readytex; pairinst; pairinst = pairinst->NextReady) {
- int ip = pairinst - s->Instructions;
- struct prog_instruction *inst = s->Program->Instructions + ip;
+ struct prog_instruction *inst = &pairinst->Instruction;
if (inst->Opcode != OPCODE_KIL)
get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
}
- if (s->Debug)
+ if (s->Compiler->Base.Debug)
_mesa_printf(" BEGIN_TEX\n");
if (s->Handler->BeginTexBlock)
- s->Error = s->Error || !s->Handler->BeginTexBlock(s->UserData);
+ s->Compiler->Base.Error = s->Compiler->Base.Error || !s->Handler->BeginTexBlock(s->UserData);
for(pairinst = readytex; pairinst; pairinst = pairinst->NextReady) {
- int ip = pairinst - s->Instructions;
- struct prog_instruction *inst = s->Program->Instructions + ip;
- commit_instruction(s, ip);
+ struct prog_instruction *inst = &pairinst->Instruction;
+ commit_instruction(s, pairinst);
if (inst->Opcode != OPCODE_KIL)
inst->DstReg.Index = get_hw_reg(s, inst->DstReg.File, inst->DstReg.Index);
inst->SrcReg[0].Index = get_hw_reg(s, inst->SrcReg[0].File, inst->SrcReg[0].Index);
- if (s->Debug) {
+ if (s->Compiler->Base.Debug) {
_mesa_printf(" ");
_mesa_print_instruction(inst);
- fflush(stdout);
+ fflush(stderr);
+ }
+
+ struct radeon_pair_texture_instruction rpti;
+
+ switch(inst->Opcode) {
+ case OPCODE_TEX: rpti.Opcode = RADEON_OPCODE_TEX; break;
+ case OPCODE_TXB: rpti.Opcode = RADEON_OPCODE_TXB; break;
+ case OPCODE_TXP: rpti.Opcode = RADEON_OPCODE_TXP; break;
+ default:
+ case OPCODE_KIL: rpti.Opcode = RADEON_OPCODE_KIL; break;
}
- s->Error = s->Error || !s->Handler->EmitTex(s->UserData, inst);
+
+ rpti.DestIndex = inst->DstReg.Index;
+ rpti.WriteMask = inst->DstReg.WriteMask;
+ rpti.TexSrcUnit = inst->TexSrcUnit;
+ rpti.TexSrcTarget = inst->TexSrcTarget;
+ rpti.SrcIndex = inst->SrcReg[0].Index;
+ rpti.SrcSwizzle = inst->SrcReg[0].Swizzle;
+
+ s->Compiler->Base.Error = s->Compiler->Base.Error || !s->Handler->EmitTex(s->UserData, &rpti);
}
- if (s->Debug)
+ if (s->Compiler->Base.Debug)
_mesa_printf(" END_TEX\n");
}
@@ -637,7 +595,7 @@ static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instructio
index = get_hw_reg(s, src.File, src.Index);
} else {
constant = 1;
- s->Error |= !s->Handler->EmitConst(s->UserData, src.File, src.Index, &index);
+ index = src.Index;
}
for(i = 0; i < 3; ++i) {
@@ -684,10 +642,12 @@ static int alloc_pair_source(struct pair_state *s, struct radeon_pair_instructio
* Fill the given ALU instruction's opcodes and source operands into the given pair,
* if possible.
*/
-static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_pair_instruction *pair, int ip)
+static GLboolean fill_instruction_into_pair(
+ struct pair_state *s,
+ struct radeon_pair_instruction *pair,
+ struct pair_state_instruction *pairinst)
{
- struct pair_state_instruction *pairinst = s->Instructions + ip;
- struct prog_instruction *inst = s->Program->Instructions + ip;
+ struct prog_instruction *inst = &pairinst->Instruction;
ASSERT(!pairinst->NeedRGB || pair->RGB.Opcode == OPCODE_NOP);
ASSERT(!pairinst->NeedAlpha || pair->Alpha.Opcode == OPCODE_NOP);
@@ -768,16 +728,18 @@ static GLboolean fill_instruction_into_pair(struct pair_state *s, struct radeon_
* we are absolutely certain that we're going to emit a certain
* instruction pairing.
*/
-static void fill_dest_into_pair(struct pair_state *s, struct radeon_pair_instruction *pair, int ip)
+static void fill_dest_into_pair(
+ struct pair_state *s,
+ struct radeon_pair_instruction *pair,
+ struct pair_state_instruction *pairinst)
{
- struct pair_state_instruction *pairinst = s->Instructions + ip;
- struct prog_instruction *inst = s->Program->Instructions + ip;
+ struct prog_instruction *inst = &pairinst->Instruction;
if (inst->DstReg.File == PROGRAM_OUTPUT) {
- if (inst->DstReg.Index == FRAG_RESULT_COLOR) {
+ if (inst->DstReg.Index == s->Compiler->OutputColor) {
pair->RGB.OutputWriteMask |= inst->DstReg.WriteMask & WRITEMASK_XYZ;
pair->Alpha.OutputWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
- } else if (inst->DstReg.Index == FRAG_RESULT_DEPTH) {
+ } else if (inst->DstReg.Index == s->Compiler->OutputDepth) {
pair->Alpha.DepthWriteMask |= GET_BIT(inst->DstReg.WriteMask, 3);
}
} else {
@@ -804,24 +766,24 @@ static void fill_dest_into_pair(struct pair_state *s, struct radeon_pair_instruc
static void emit_alu(struct pair_state *s)
{
struct radeon_pair_instruction pair;
+ struct pair_state_instruction *psi;
if (s->ReadyFullALU || !(s->ReadyRGB && s->ReadyAlpha)) {
- int ip;
if (s->ReadyFullALU) {
- ip = s->ReadyFullALU - s->Instructions;
+ psi = s->ReadyFullALU;
s->ReadyFullALU = s->ReadyFullALU->NextReady;
} else if (s->ReadyRGB) {
- ip = s->ReadyRGB - s->Instructions;
+ psi = s->ReadyRGB;
s->ReadyRGB = s->ReadyRGB->NextReady;
} else {
- ip = s->ReadyAlpha - s->Instructions;
+ psi = s->ReadyAlpha;
s->ReadyAlpha = s->ReadyAlpha->NextReady;
}
_mesa_bzero(&pair, sizeof(pair));
- fill_instruction_into_pair(s, &pair, ip);
- fill_dest_into_pair(s, &pair, ip);
- commit_instruction(s, ip);
+ fill_instruction_into_pair(s, &pair, psi);
+ fill_dest_into_pair(s, &pair, psi);
+ commit_instruction(s, psi);
} else {
struct pair_state_instruction **prgb;
struct pair_state_instruction **palpha;
@@ -830,65 +792,65 @@ static void emit_alu(struct pair_state *s)
* many source slots; try all possible pairings if necessary */
for(prgb = &s->ReadyRGB; *prgb; prgb = &(*prgb)->NextReady) {
for(palpha = &s->ReadyAlpha; *palpha; palpha = &(*palpha)->NextReady) {
- int rgbip = *prgb - s->Instructions;
- int alphaip = *palpha - s->Instructions;
+ struct pair_state_instruction * psirgb = *prgb;
+ struct pair_state_instruction * psialpha = *palpha;
_mesa_bzero(&pair, sizeof(pair));
- fill_instruction_into_pair(s, &pair, rgbip);
- if (!fill_instruction_into_pair(s, &pair, alphaip))
+ fill_instruction_into_pair(s, &pair, psirgb);
+ if (!fill_instruction_into_pair(s, &pair, psialpha))
continue;
*prgb = (*prgb)->NextReady;
*palpha = (*palpha)->NextReady;
- fill_dest_into_pair(s, &pair, rgbip);
- fill_dest_into_pair(s, &pair, alphaip);
- commit_instruction(s, rgbip);
- commit_instruction(s, alphaip);
+ fill_dest_into_pair(s, &pair, psirgb);
+ fill_dest_into_pair(s, &pair, psialpha);
+ commit_instruction(s, psirgb);
+ commit_instruction(s, psialpha);
goto success;
}
}
/* No success in pairing; just take the first RGB instruction */
- int ip = s->ReadyRGB - s->Instructions;
+ psi = s->ReadyRGB;
s->ReadyRGB = s->ReadyRGB->NextReady;
+
_mesa_bzero(&pair, sizeof(pair));
- fill_instruction_into_pair(s, &pair, ip);
- fill_dest_into_pair(s, &pair, ip);
- commit_instruction(s, ip);
+ fill_instruction_into_pair(s, &pair, psi);
+ fill_dest_into_pair(s, &pair, psi);
+ commit_instruction(s, psi);
success: ;
}
- if (s->Debug)
+ if (s->Compiler->Base.Debug)
radeonPrintPairInstruction(&pair);
- s->Error = s->Error || !s->Handler->EmitPaired(s->UserData, &pair);
+ s->Compiler->Base.Error = s->Compiler->Base.Error || !s->Handler->EmitPaired(s->UserData, &pair);
}
+/* Callback function for assigning input registers to hardware registers */
+static void alloc_helper(void * data, unsigned input, unsigned hwreg)
+{
+ struct pair_state * s = data;
+ alloc_hw_reg(s, PROGRAM_INPUT, input, hwreg);
+}
-GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
+void radeonPairProgram(
+ struct r300_fragment_program_compiler * compiler,
const struct radeon_pair_handler* handler, void *userdata)
{
struct pair_state s;
_mesa_bzero(&s, sizeof(s));
- s.Ctx = ctx;
- s.Program = _mesa_clone_program(ctx, program);
+ s.Compiler = compiler;
s.Handler = handler;
s.UserData = userdata;
- s.Debug = (RADEON_DEBUG & DEBUG_PIXEL) ? GL_TRUE : GL_FALSE;
- s.Verbose = GL_FALSE && s.Debug;
+ s.Verbose = GL_FALSE && s.Compiler->Base.Debug;
- s.Instructions = (struct pair_state_instruction*)_mesa_calloc(
- sizeof(struct pair_state_instruction)*s.Program->NumInstructions);
- s.ValuePool = (struct reg_value*)_mesa_calloc(sizeof(struct reg_value)*s.Program->NumInstructions*4);
- s.ReaderPool = (struct reg_value_reader*)_mesa_calloc(
- sizeof(struct reg_value_reader)*s.Program->NumInstructions*12);
-
- if (s.Debug)
+ if (s.Compiler->Base.Debug)
_mesa_printf("Emit paired program\n");
scan_instructions(&s);
- allocate_input_registers(&s);
+ s.Compiler->AllocateHwInputs(s.Compiler, &alloc_helper, &s);
- while(!s.Error &&
+ while(!s.Compiler->Base.Error &&
(s.ReadyTEX || s.ReadyRGB || s.ReadyAlpha || s.ReadyFullALU)) {
if (s.ReadyTEX)
emit_all_tex(&s);
@@ -897,16 +859,8 @@ GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
emit_alu(&s);
}
- if (s.Debug)
+ if (s.Compiler->Base.Debug)
_mesa_printf(" END\n");
-
- _mesa_free(s.Instructions);
- _mesa_free(s.ValuePool);
- _mesa_free(s.ReaderPool);
-
- _mesa_reference_program(ctx, &s.Program, NULL);
-
- return !s.Error;
}
diff --git a/src/mesa/drivers/dri/r300/radeon_program_pair.h b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
index 4624a24629..ff76178551 100644
--- a/src/mesa/drivers/dri/r300/radeon_program_pair.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_pair.h
@@ -30,6 +30,8 @@
#include "radeon_program.h"
+struct r300_fragment_program_compiler;
+
/**
* Represents a paired instruction, as found in R300 and R500
@@ -82,18 +84,32 @@ struct radeon_pair_instruction {
};
+enum {
+ RADEON_OPCODE_TEX = 0,
+ RADEON_OPCODE_TXB,
+ RADEON_OPCODE_TXP,
+ RADEON_OPCODE_KIL
+};
+
+struct radeon_pair_texture_instruction {
+ GLuint Opcode:2; /**< one of RADEON_OPCODE_xxx */
+
+ GLuint DestIndex:8;
+ GLuint WriteMask:4;
+
+ GLuint TexSrcUnit:5;
+ GLuint TexSrcTarget:3;
+
+ GLuint SrcIndex:8;
+ GLuint SrcSwizzle:12;
+};
+
+
/**
*
*/
struct radeon_pair_handler {
/**
- * Fill in the proper hardware index for the given constant register.
- *
- * @return GL_FALSE on error.
- */
- GLboolean (*EmitConst)(void*, GLuint file, GLuint index, GLuint *hwindex);
-
- /**
* Write a paired instruction to the hardware.
*
* @return GL_FALSE on error.
@@ -107,7 +123,7 @@ struct radeon_pair_handler {
*
* @return GL_FALSE on error.
*/
- GLboolean (*EmitTex)(void*, struct prog_instruction*);
+ GLboolean (*EmitTex)(void*, struct radeon_pair_texture_instruction*);
/**
* Called before a block of contiguous, independent texture
@@ -115,10 +131,11 @@ struct radeon_pair_handler {
*/
GLboolean (*BeginTexBlock)(void*);
- GLuint MaxHwTemps;
+ unsigned MaxHwTemps;
};
-GLboolean radeonPairProgram(GLcontext *ctx, struct gl_program *program,
+void radeonPairProgram(
+ struct r300_fragment_program_compiler * compiler,
const struct radeon_pair_handler*, void *userdata);
void radeonPrintPairInstruction(struct radeon_pair_instruction *inst);
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
index af535037d0..da5b7ba642 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c
@@ -54,6 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_mipmap_tree.h"
#include "r300_state.h"
#include "radeon_reg.h"
+#include "radeon_queryobj.h"
/** # of dwords reserved for additional instructions that may need to be written
* during flushing.
@@ -73,48 +74,40 @@ static unsigned packet0_count(r300ContextPtr r300, uint32_t *pkt)
#define vpu_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->vpu.count)
#define r500fp_count(ptr) (((drm_r300_cmd_header_t*)(ptr))->r500fp.count)
+int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ int cnt;
+ int extra = 1;
+ cnt = vpu_count(atom->cmd);
+
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ extra = 5;
+ }
+
+ return cnt ? (cnt * 4) + extra : 0;
+}
+
+
void emit_vpu(GLcontext *ctx, struct radeon_state_atom * atom)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
BATCH_LOCALS(&r300->radeon);
drm_r300_cmd_header_t cmd;
- uint32_t addr, ndw, i;
-
- if (!r300->radeon.radeonScreen->kernel_mm) {
- uint32_t dwords;
- dwords = (*atom->check) (ctx, atom);
- BEGIN_BATCH_NO_AUTOSTATE(dwords);
- OUT_BATCH_TABLE(atom->cmd, dwords);
- END_BATCH();
- return;
- }
+ uint32_t addr, ndw;
cmd.u = atom->cmd[0];
addr = (cmd.vpu.adrhi << 8) | cmd.vpu.adrlo;
- ndw = cmd.vpu.count * 4;
- if (ndw) {
+ ndw = atom->check(ctx, atom);
- if (r300->vap_flush_needed) {
- BEGIN_BATCH_NO_AUTOSTATE(15 + ndw);
+ BEGIN_BATCH_NO_AUTOSTATE(ndw);
- /* flush processing vertices */
- OUT_BATCH_REGVAL(R300_SC_SCREENDOOR, 0);
- OUT_BATCH_REGVAL(R300_RB3D_DSTCACHE_CTLSTAT, R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D);
- OUT_BATCH_REGVAL(RADEON_WAIT_UNTIL, RADEON_WAIT_3D_IDLECLEAN);
- OUT_BATCH_REGVAL(R300_SC_SCREENDOOR, 0xffffff);
- OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
- r300->vap_flush_needed = GL_FALSE;
- } else {
- BEGIN_BATCH_NO_AUTOSTATE(5 + ndw);
- }
- OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr);
- OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR);
- for (i = 0; i < ndw; i++) {
- OUT_BATCH(atom->cmd[i+1]);
- }
- OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
- END_BATCH();
- }
+ ndw -= 5;
+ OUT_BATCH_REGVAL(R300_VAP_PVS_VECTOR_INDX_REG, addr);
+ OUT_BATCH(CP_PACKET0(R300_VAP_PVS_UPLOAD_DATA, ndw-1) | RADEON_ONE_REG_WR);
+ OUT_BATCH_TABLE(&atom->cmd[1], ndw);
+ OUT_BATCH_REGVAL(R300_VAP_PVS_STATE_FLUSH_REG, 0);
+ END_BATCH();
}
void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom)
@@ -122,17 +115,10 @@ void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom)
r300ContextPtr r300 = R300_CONTEXT(ctx);
BATCH_LOCALS(&r300->radeon);
drm_r300_cmd_header_t cmd;
- uint32_t addr, ndw, i, sz;
- int type, clamp, stride;
+ uint32_t addr, ndw, sz;
+ int type, clamp;
- if (!r300->radeon.radeonScreen->kernel_mm) {
- uint32_t dwords;
- dwords = (*atom->check) (ctx, atom);
- BEGIN_BATCH_NO_AUTOSTATE(dwords);
- OUT_BATCH_TABLE(atom->cmd, dwords);
- END_BATCH();
- return;
- }
+ ndw = atom->check(ctx, atom);
cmd.u = atom->cmd[0];
sz = cmd.r500fp.count;
@@ -143,20 +129,34 @@ void emit_r500fp(GLcontext *ctx, struct radeon_state_atom * atom)
addr |= (type << 16);
addr |= (clamp << 17);
- stride = type ? 4 : 6;
-
- ndw = sz * stride;
- if (ndw) {
+ BEGIN_BATCH_NO_AUTOSTATE(ndw);
+ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0));
+ OUT_BATCH(addr);
+ ndw-=3;
+ OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, ndw-1) | RADEON_ONE_REG_WR);
+ OUT_BATCH_TABLE(&atom->cmd[1], ndw);
+ END_BATCH();
+}
- BEGIN_BATCH_NO_AUTOSTATE(3 + ndw);
- OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_INDEX, 0));
- OUT_BATCH(addr);
- OUT_BATCH(CP_PACKET0(R500_GA_US_VECTOR_DATA, ndw-1) | RADEON_ONE_REG_WR);
- for (i = 0; i < ndw; i++) {
- OUT_BATCH(atom->cmd[i+1]);
- }
- END_BATCH();
+static int check_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd);
+ int dw = 0, i;
+ if (atom->cmd[0] == CP_PACKET2) {
+ return dw;
}
+ for(i = 0; i < numtmus; ++i) {
+ radeonTexObj *t = r300->hw.textures[i];
+ if (!t && !r300->radeon.radeonScreen->kernel_mm) {
+ dw += 0;
+ } else if (t && t->image_override && !t->bo) {
+ if (!r300->radeon.radeonScreen->kernel_mm)
+ dw += 2;
+ } else
+ dw += 4;
+ }
+ return dw;
}
static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
@@ -164,47 +164,46 @@ static void emit_tex_offsets(GLcontext *ctx, struct radeon_state_atom * atom)
r300ContextPtr r300 = R300_CONTEXT(ctx);
BATCH_LOCALS(&r300->radeon);
int numtmus = packet0_count(r300, r300->hw.tex.offset.cmd);
- int notexture = 0;
-
- if (numtmus) {
- int i;
-
- for(i = 0; i < numtmus; ++i) {
- radeonTexObj *t = r300->hw.textures[i];
-
- if (!t)
- notexture = 1;
- }
-
- if (r300->radeon.radeonScreen->kernel_mm && notexture) {
- return;
- }
- for(i = 0; i < numtmus; ++i) {
- radeonTexObj *t = r300->hw.textures[i];
- if (t && !t->image_override) {
- BEGIN_BATCH_NO_AUTOSTATE(4);
- OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
- END_BATCH();
- } else if (!t) {
- /* Texture unit hasn't a texture bound nothings to do */
- } else { /* override cases */
- if (t->bo) {
- BEGIN_BATCH_NO_AUTOSTATE(4);
- OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_BATCH_RELOC(t->tile_bits, t->bo, 0,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
- END_BATCH();
- } else if (!r300->radeon.radeonScreen->kernel_mm) {
- BEGIN_BATCH_NO_AUTOSTATE(2);
- OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
- OUT_BATCH(t->override_offset);
- END_BATCH();
- } else {
- /* Texture unit hasn't a texture bound nothings to do */
- }
- }
+ int i;
+
+ for(i = 0; i < numtmus; ++i) {
+ radeonTexObj *t = r300->hw.textures[i];
+ if (t && !t->image_override) {
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+ OUT_BATCH_RELOC(t->tile_bits, t->mt->bo, 0,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ } else if (!t) {
+ /* Texture unit hasn't a texture bound.
+ * We assign the current color buffer as a fakery to make
+ * KIL work on KMS (without it, the CS checker will complain).
+ */
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ struct radeon_renderbuffer *rrb = radeon_get_colorbuffer(&r300->radeon);
+ if (rrb && rrb->bo) {
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+ OUT_BATCH_RELOC(0, rrb->bo, 0,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ }
+ }
+ } else { /* override cases */
+ if (t->bo) {
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+ OUT_BATCH_RELOC(t->tile_bits, t->bo, 0,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ } else if (!r300->radeon.radeonScreen->kernel_mm) {
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ OUT_BATCH_REGSEQ(R300_TX_OFFSET_0 + (i * 4), 1);
+ OUT_BATCH(t->override_offset);
+ END_BATCH();
+ } else {
+ /* Texture unit hasn't a texture bound nothings to do */
+ }
}
}
}
@@ -227,8 +226,8 @@ void r300_emit_scissor(GLcontext *ctx)
if (r300->radeon.state.scissor.enabled) {
x1 = r300->radeon.state.scissor.rect.x1;
y1 = r300->radeon.state.scissor.rect.y1;
- x2 = r300->radeon.state.scissor.rect.x2 - 1;
- y2 = r300->radeon.state.scissor.rect.y2 - 1;
+ x2 = r300->radeon.state.scissor.rect.x2;
+ y2 = r300->radeon.state.scissor.rect.y2;
} else {
x1 = 0;
y1 = 0;
@@ -247,6 +246,17 @@ void r300_emit_scissor(GLcontext *ctx)
OUT_BATCH((x2 << R300_SCISSORS_X_SHIFT)|(y2 << R300_SCISSORS_Y_SHIFT));
END_BATCH();
}
+static int check_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ uint32_t dw = 6 + 3 + 16;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ dw += 2;
+ if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+ dw -= 3 + 16;
+ }
+ return dw;
+}
static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
{
@@ -256,7 +266,7 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
uint32_t cbpitch;
uint32_t offset = r300->radeon.state.color.draw_offset;
uint32_t dw = 6;
- int i;
+ int i;
rrb = radeon_get_colorbuffer(&r300->radeon);
if (!rrb || !rrb->bo) {
@@ -264,7 +274,7 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
return;
}
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr,"rrb is %p %d %dx%d\n", rrb, offset, rrb->base.Width, rrb->base.Height);
cbpitch = (rrb->pitch / rrb->cpp);
if (rrb->cpp == 4)
@@ -338,13 +348,23 @@ static void emit_cb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
}
}
+static int check_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ uint32_t dw;
+ dw = 6;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ dw += 2;
+ return dw;
+}
+
static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
BATCH_LOCALS(&r300->radeon);
struct radeon_renderbuffer *rrb;
uint32_t zbpitch;
- uint32_t dw;
+ uint32_t dw = atom->check(ctx, atom);
rrb = radeon_get_depthbuffer(&r300->radeon);
if (!rrb)
@@ -360,9 +380,6 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
}
}
- dw = 6;
- if (r300->radeon.radeonScreen->kernel_mm)
- dw += 2;
BEGIN_BATCH_NO_AUTOSTATE(dw);
OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_BATCH_RELOC(0, rrb->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
@@ -374,46 +391,6 @@ static void emit_zb_offset(GLcontext *ctx, struct radeon_state_atom * atom)
END_BATCH();
}
-static void emit_gb_misc(GLcontext *ctx, struct radeon_state_atom * atom)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- BATCH_LOCALS(&r300->radeon);
- if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
- BEGIN_BATCH_NO_AUTOSTATE(4);
- OUT_BATCH(atom->cmd[0]);
- OUT_BATCH(atom->cmd[1]);
- OUT_BATCH(atom->cmd[2]);
- OUT_BATCH(atom->cmd[3]);
- END_BATCH();
- }
-}
-
-static void emit_threshold_misc(GLcontext *ctx, struct radeon_state_atom * atom)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- BATCH_LOCALS(&r300->radeon);
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- BEGIN_BATCH_NO_AUTOSTATE(3);
- OUT_BATCH(atom->cmd[0]);
- OUT_BATCH(atom->cmd[1]);
- OUT_BATCH(atom->cmd[2]);
- END_BATCH();
- }
-}
-
-static void emit_shade_misc(GLcontext *ctx, struct radeon_state_atom * atom)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- BATCH_LOCALS(&r300->radeon);
-
- if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
- BEGIN_BATCH_NO_AUTOSTATE(2);
- OUT_BATCH(atom->cmd[0]);
- OUT_BATCH(atom->cmd[1]);
- END_BATCH();
- }
-}
-
static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
@@ -431,6 +408,7 @@ static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom
format = R300_DEPTHFORMAT_24BIT_INT_Z_8BIT_STENCIL;
}
+ BEGIN_BATCH_NO_AUTOSTATE(atom->cmd_size);
OUT_BATCH(atom->cmd[0]);
atom->cmd[1] &= ~0xf;
atom->cmd[1] |= format;
@@ -438,6 +416,12 @@ static void emit_zstencil_format(GLcontext *ctx, struct radeon_state_atom * atom
OUT_BATCH(atom->cmd[2]);
OUT_BATCH(atom->cmd[3]);
OUT_BATCH(atom->cmd[4]);
+ END_BATCH();
+}
+
+static int check_never(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ return 0;
}
static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
@@ -456,28 +440,29 @@ static int check_variable(GLcontext *ctx, struct radeon_state_atom *atom)
return cnt ? cnt + 1 : 0;
}
-int check_vpu(GLcontext *ctx, struct radeon_state_atom *atom)
-{
- int cnt;
-
- cnt = vpu_count(atom->cmd);
- return cnt ? (cnt * 4) + 1 : 0;
-}
-
int check_r500fp(GLcontext *ctx, struct radeon_state_atom *atom)
{
int cnt;
-
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ int extra = 1;
cnt = r500fp_count(atom->cmd);
- return cnt ? (cnt * 6) + 1 : 0;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ extra = 3;
+
+ return cnt ? (cnt * 6) + extra : 0;
}
int check_r500fp_const(GLcontext *ctx, struct radeon_state_atom *atom)
{
int cnt;
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ int extra = 1;
+ cnt = r500fp_count(atom->cmd);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ extra = 3;
cnt = r500fp_count(atom->cmd);
- return cnt ? (cnt * 4) + 1 : 0;
+ return cnt ? (cnt * 4) + extra : 0;
}
#define ALLOC_STATE( ATOM, CHK, SZ, IDX ) \
@@ -509,7 +494,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->radeon.hw.max_state_size = 2 + 2; /* reserve extra space for WAIT_IDLE and tex cache flush */
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
- if (RADEON_DEBUG & DEBUG_TEXTURE) {
+ if (RADEON_DEBUG & RADEON_TEXTURE) {
fprintf(stderr, "Using %d maximum texture units..\n", mtu);
}
@@ -567,11 +552,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
ALLOC_STATE(gb_enable, always, 2, 0);
r300->hw.gb_enable.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_ENABLE, 1);
- ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0);
+ if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+ ALLOC_STATE(gb_misc, always, R300_GB_MISC_CMDSIZE, 0);
+ } else {
+ ALLOC_STATE(gb_misc, never, R300_GB_MISC_CMDSIZE, 0);
+ }
r300->hw.gb_misc.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GB_MSPOS0, 3);
- r300->hw.gb_misc.emit = emit_gb_misc;
ALLOC_STATE(gb_misc2, always, R300_GB_MISC2_CMDSIZE, 0);
- r300->hw.gb_misc2.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x401C, 2);
+ r300->hw.gb_misc2.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x401C, 2);
ALLOC_STATE(txe, always, R300_TXE_CMDSIZE, 0);
r300->hw.txe.cmd[R300_TXE_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_ENABLE, 1);
ALLOC_STATE(ga_point_s0, always, 5, 0);
@@ -586,9 +574,12 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.lcntl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_CNTL, 1);
ALLOC_STATE(ga_line_stipple, always, 4, 0);
r300->hw.ga_line_stipple.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_LINE_STIPPLE_VALUE, 3);
- ALLOC_STATE(shade, always, 2, 0);
+ if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
+ ALLOC_STATE(shade, always, 2, 0);
+ } else {
+ ALLOC_STATE(shade, never, 2, 0);
+ }
r300->hw.shade.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_GA_ENHANCE, 1);
- r300->hw.shade.emit = emit_shade_misc;
ALLOC_STATE(shade2, always, 4, 0);
r300->hw.shade2.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, 0x4278, 3);
ALLOC_STATE(polygon_mode, always, 4, 0);
@@ -637,11 +628,14 @@ void r300InitCmdBuf(r300ContextPtr r300)
ALLOC_STATE(r500fp, r500fp, R500_FPI_CMDSIZE, 0);
r300->hw.r500fp.cmd[R300_FPI_CMD_0] =
cmdr500fp(r300->radeon.radeonScreen, 0, 0, 0, 0);
- r300->hw.r500fp.emit = emit_r500fp;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.r500fp.emit = emit_r500fp;
+
ALLOC_STATE(r500fp_const, r500fp_const, R500_FPP_CMDSIZE, 0);
r300->hw.r500fp_const.cmd[R300_FPI_CMD_0] =
cmdr500fp(r300->radeon.radeonScreen, 0, 0, 1, 0);
- r300->hw.r500fp_const.emit = emit_r500fp;
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.r500fp_const.emit = emit_r500fp;
} else {
ALLOC_STATE(fp, always, R300_FP_CMDSIZE, 0);
r300->hw.fp.cmd[R300_FP_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_US_CONFIG, 3);
@@ -684,25 +678,36 @@ void r300InitCmdBuf(r300ContextPtr r300)
}
ALLOC_STATE(rop, always, 2, 0);
r300->hw.rop.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_ROPCNTL, 1);
- ALLOC_STATE(cb, always, R300_CB_CMDSIZE, 0);
+ ALLOC_STATE(cb, cb_offset, R300_CB_CMDSIZE, 0);
r300->hw.cb.emit = &emit_cb_offset;
ALLOC_STATE(rb3d_dither_ctl, always, 10, 0);
r300->hw.rb3d_dither_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DITHER_CTL, 9);
ALLOC_STATE(rb3d_aaresolve_ctl, always, 2, 0);
r300->hw.rb3d_aaresolve_ctl.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_AARESOLVE_CTL, 1);
- ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0);
- r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2);
- r300->hw.rb3d_discard_src_pixel_lte_threshold.emit = emit_threshold_misc;
+ if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV350) {
+ ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, always, 3, 0);
+ } else {
+ ALLOC_STATE(rb3d_discard_src_pixel_lte_threshold, never, 3, 0);
+ }
+ r300->hw.rb3d_discard_src_pixel_lte_threshold.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R500_RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD, 2);
ALLOC_STATE(zs, always, R300_ZS_CMDSIZE, 0);
r300->hw.zs.cmd[R300_ZS_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_ZB_CNTL, 3);
+ if (is_r500) {
+ if (r300->radeon.radeonScreen->kernel_mm)
+ ALLOC_STATE(zsb, always, R300_ZSB_CMDSIZE, 0);
+ else
+ ALLOC_STATE(zsb, never, R300_ZSB_CMDSIZE, 0);
+ r300->hw.zsb.cmd[R300_ZSB_CMD_0] =
+ cmdpacket0(r300->radeon.radeonScreen, R500_ZB_STENCILREFMASK_BF, 1);
+ }
ALLOC_STATE(zstencil_format, always, 5, 0);
r300->hw.zstencil_format.cmd[0] =
cmdpacket0(r300->radeon.radeonScreen, R300_ZB_FORMAT, 4);
r300->hw.zstencil_format.emit = emit_zstencil_format;
- ALLOC_STATE(zb, always, R300_ZB_CMDSIZE, 0);
+ ALLOC_STATE(zb, zb_offset, R300_ZB_CMDSIZE, 0);
r300->hw.zb.emit = emit_zb_offset;
ALLOC_STATE(zb_depthclearvalue, always, 2, 0);
r300->hw.zb_depthclearvalue.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_DEPTHCLEARVALUE, 1);
@@ -715,47 +720,72 @@ void r300InitCmdBuf(r300ContextPtr r300)
/* VPU only on TCL */
if (has_tcl) {
- int i;
+ int i;
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE(vap_flush, always, 10, 0);
+ /* flush processing vertices */
+ r300->hw.vap_flush.cmd[0] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1);
+ r300->hw.vap_flush.cmd[1] = 0;
+ r300->hw.vap_flush.cmd[2] = cmdpacket0(r300->radeon.radeonScreen, R300_RB3D_DSTCACHE_CTLSTAT, 1);
+ r300->hw.vap_flush.cmd[3] = R300_RB3D_DSTCACHE_CTLSTAT_DC_FLUSH_FLUSH_DIRTY_3D;
+ r300->hw.vap_flush.cmd[4] = cmdpacket0(r300->radeon.radeonScreen, RADEON_WAIT_UNTIL, 1);
+ r300->hw.vap_flush.cmd[5] = RADEON_WAIT_3D_IDLECLEAN;
+ r300->hw.vap_flush.cmd[6] = cmdpacket0(r300->radeon.radeonScreen, R300_SC_SCREENDOOR, 1);
+ r300->hw.vap_flush.cmd[7] = 0xffffff;
+ r300->hw.vap_flush.cmd[8] = cmdpacket0(r300->radeon.radeonScreen, R300_VAP_PVS_STATE_FLUSH_REG, 1);
+ r300->hw.vap_flush.cmd[9] = 0;
+ } else {
+ ALLOC_STATE(vap_flush, never, 10, 0);
+ }
+
+
ALLOC_STATE(vpi, vpu, R300_VPI_CMDSIZE, 0);
r300->hw.vpi.cmd[0] =
- cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0);
- r300->hw.vpi.emit = emit_vpu;
+ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CODE_START, 0);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vpi.emit = emit_vpu;
if (is_r500) {
- ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
- r300->hw.vpp.cmd[0] =
- cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0);
- r300->hw.vpp.emit = emit_vpu;
-
- ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
- r300->hw.vps.cmd[0] =
- cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1);
- r300->hw.vps.emit = emit_vpu;
+ ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
+ r300->hw.vpp.cmd[0] =
+ cmdvpu(r300->radeon.radeonScreen, R500_PVS_CONST_START, 0);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vpp.emit = emit_vpu;
+
+ ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
+ r300->hw.vps.cmd[0] =
+ cmdvpu(r300->radeon.radeonScreen, R500_POINT_VPORT_SCALE_OFFSET, 1);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vps.emit = emit_vpu;
for (i = 0; i < 6; i++) {
- ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
- r300->hw.vpucp[i].cmd[0] =
- cmdvpu(r300->radeon.radeonScreen,
- R500_PVS_UCP_START + i, 1);
- r300->hw.vpucp[i].emit = emit_vpu;
+ ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
+ r300->hw.vpucp[i].cmd[0] =
+ cmdvpu(r300->radeon.radeonScreen,
+ R500_PVS_UCP_START + i, 1);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vpucp[i].emit = emit_vpu;
}
} else {
- ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
- r300->hw.vpp.cmd[0] =
- cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0);
- r300->hw.vpp.emit = emit_vpu;
-
- ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
- r300->hw.vps.cmd[0] =
- cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1);
- r300->hw.vps.emit = emit_vpu;
+ ALLOC_STATE(vpp, vpu, R300_VPP_CMDSIZE, 0);
+ r300->hw.vpp.cmd[0] =
+ cmdvpu(r300->radeon.radeonScreen, R300_PVS_CONST_START, 0);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vpp.emit = emit_vpu;
+
+ ALLOC_STATE(vps, vpu, R300_VPS_CMDSIZE, 0);
+ r300->hw.vps.cmd[0] =
+ cmdvpu(r300->radeon.radeonScreen, R300_POINT_VPORT_SCALE_OFFSET, 1);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vps.emit = emit_vpu;
for (i = 0; i < 6; i++) {
ALLOC_STATE(vpucp[i], vpu, R300_VPUCP_CMDSIZE, 0);
r300->hw.vpucp[i].cmd[0] =
cmdvpu(r300->radeon.radeonScreen,
- R300_PVS_UCP_START + i, 1);
- r300->hw.vpucp[i].emit = emit_vpu;
+ R300_PVS_UCP_START + i, 1);
+ if (r300->radeon.radeonScreen->kernel_mm)
+ r300->hw.vpucp[i].emit = emit_vpu;
}
}
}
@@ -779,7 +809,7 @@ void r300InitCmdBuf(r300ContextPtr r300)
ALLOC_STATE(tex.pitch, variable, mtu + 1, 0);
r300->hw.tex.pitch.cmd[R300_TEX_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_TX_FORMAT2_0, 0);
- ALLOC_STATE(tex.offset, variable, 1, 0);
+ ALLOC_STATE(tex.offset, tex_offsets, 1, 0);
r300->hw.tex.offset.cmd[R300_TEX_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_TX_OFFSET_0, 0);
r300->hw.tex.offset.emit = &emit_tex_offsets;
@@ -792,6 +822,17 @@ void r300InitCmdBuf(r300ContextPtr r300)
r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, 0);
+ radeon_init_query_stateobj(&r300->radeon, R300_QUERYOBJ_CMDSIZE);
+ if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV530) {
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, RV530_FG_ZBREG_DEST, 1);
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL;
+ } else {
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_0] = cmdpacket0(r300->radeon.radeonScreen, R300_SU_REG_DEST, 1);
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_0] = R300_RASTER_PIPE_SELECT_ALL;
+ }
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_CMD_1] = cmdpacket0(r300->radeon.radeonScreen, R300_ZB_ZPASS_DATA, 1);
+ r300->radeon.query.queryobj.cmd[R300_QUERYOBJ_DATA_1] = 0;
+
r300->radeon.hw.is_dirty = GL_TRUE;
r300->radeon.hw.all_dirty = GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
index 53bcc0eeb4..1b703e518a 100644
--- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h
+++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h
@@ -38,6 +38,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_context.h"
+#define CACHE_FLUSH_BUFSZ (4*2)
+#define PRE_EMIT_STATE_BUFSZ (2+2)
+#define AOS_BUFSZ(nr) (3+(nr >>1)*3 + (nr&1)*2 + (nr*2))
+#define FIREAOS_BUFSZ (3)
+#define SCISSORS_BUFSZ (3)
+
extern void r300InitCmdBuf(r300ContextPtr r300);
void r300_emit_scissor(GLcontext *ctx);
diff --git a/src/mesa/drivers/dri/r300/r300_context.c b/src/mesa/drivers/dri/r300/r300_context.c
index 6f3aab986d..6fcf209af6 100644
--- a/src/mesa/drivers/dri/r300/r300_context.c
+++ b/src/mesa/drivers/dri/r300/r300_context.c
@@ -64,24 +64,27 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_ioctl.h"
#include "r300_tex.h"
#include "r300_emit.h"
-#include "r300_render.h"
#include "r300_swtcl.h"
#include "radeon_bocs_wrapper.h"
-
+#include "radeon_buffer_objects.h"
+#include "radeon_queryobj.h"
#include "vblank.h"
#include "utils.h"
#include "xmlpool.h" /* for symbolic values of enum-type options */
#define need_GL_VERSION_2_0
+#define need_GL_ARB_occlusion_query
#define need_GL_ARB_point_parameters
#define need_GL_ARB_vertex_program
#define need_GL_EXT_blend_equation_separate
#define need_GL_EXT_blend_func_separate
#define need_GL_EXT_blend_minmax
+#define need_GL_EXT_framebuffer_blit
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_fog_coord
#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
#define need_GL_ATI_separate_stencil
@@ -94,6 +97,7 @@ const struct dri_extension card_extensions[] = {
/* *INDENT-OFF* */
{"GL_ARB_depth_texture", NULL},
{"GL_ARB_fragment_program", NULL},
+ {"GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
{"GL_ARB_multitexture", NULL},
{"GL_ARB_point_parameters", GL_ARB_point_parameters_functions},
{"GL_ARB_shadow", NULL},
@@ -113,6 +117,7 @@ const struct dri_extension card_extensions[] = {
{"GL_EXT_packed_depth_stencil", NULL},
{"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
+ {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions },
{"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
{"GL_EXT_shadow_funcs", NULL},
{"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
@@ -141,6 +146,7 @@ const struct dri_extension card_extensions[] = {
const struct dri_extension mm_extensions[] = {
+ { "GL_EXT_framebuffer_blit", GL_EXT_framebuffer_blit_functions },
{ "GL_EXT_framebuffer_object", GL_EXT_framebuffer_object_functions },
{ NULL, NULL }
};
@@ -154,7 +160,6 @@ const struct dri_extension gl_20_extension[] = {
};
static const struct tnl_pipeline_stage *r300_pipeline[] = {
-
/* Catch any t&l fallbacks
*/
&_tnl_vertex_transform_stage,
@@ -165,21 +170,7 @@ static const struct tnl_pipeline_stage *r300_pipeline[] = {
&_tnl_texture_transform_stage,
&_tnl_point_attenuation_stage,
&_tnl_vertex_program_stage,
-
- /* Try again to go to tcl?
- * - no good for asymmetric-twoside (do with multipass)
- * - no good for asymmetric-unfilled (do with multipass)
- * - good for material
- * - good for texgen
- * - need to manipulate a bit of state
- *
- * - worth it/not worth it?
- */
-
- /* Else do them here.
- */
- &_r300_render_stage,
- &_tnl_render_stage, /* FALLBACK */
+ &_tnl_render_stage,
0,
};
@@ -225,11 +216,8 @@ static void r300_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes
static void r300_vtbl_pre_emit_atoms(radeonContextPtr radeon)
{
- r300ContextPtr r300 = (r300ContextPtr)radeon;
BATCH_LOCALS(radeon);
- r300->vap_flush_needed = GL_TRUE;
-
cp_wait(radeon, R300_WAIT_3D | R300_WAIT_3D_CLEAN);
BEGIN_BATCH_NO_AUTOSTATE(2);
OUT_BATCH_REGVAL(R300_TX_INVALTAGS, R300_TX_FLUSH);
@@ -246,6 +234,81 @@ static void r300_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
r300->radeon.Fallback &= ~bit;
}
+static void r300_emit_query_finish(radeonContextPtr radeon)
+{
+ r300ContextPtr r300 = (r300ContextPtr)radeon;
+ struct radeon_query_object *query = radeon->query.current;
+ BATCH_LOCALS(radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(3 * 2 *r300->radeon.radeonScreen->num_gb_pipes + 2);
+ switch (r300->radeon.radeonScreen->num_gb_pipes) {
+ case 4:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+3*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 3:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_2);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+2*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 2:
+ if (r300->radeon.radeonScreen->chip_family <= CHIP_FAMILY_RV380) {
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_3);
+ } else {
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_1);
+ }
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset+1*sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ case 1:
+ default:
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ break;
+ }
+ OUT_BATCH_REGVAL(R300_SU_REG_DEST, R300_RASTER_PIPE_SELECT_ALL);
+ END_BATCH();
+ query->curr_offset += r300->radeon.radeonScreen->num_gb_pipes * sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
+static void rv530_emit_query_finish_single_z(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(8);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+ END_BATCH();
+
+ query->curr_offset += sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
+static void rv530_emit_query_finish_double_z(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(14);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_0);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_1);
+ OUT_BATCH_REGSEQ(R300_ZB_ZPASS_ADDR, 1);
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset + sizeof(uint32_t), 0, RADEON_GEM_DOMAIN_GTT, 0);
+ OUT_BATCH_REGVAL(RV530_FG_ZBREG_DEST, RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL);
+ END_BATCH();
+
+ query->curr_offset += 2 * sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
static void r300_init_vtbl(radeonContextPtr radeon)
{
radeon->vtbl.get_lock = r300_get_lock;
@@ -254,6 +317,13 @@ static void r300_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.swtcl_flush = r300_swtcl_flush;
radeon->vtbl.pre_emit_atoms = r300_vtbl_pre_emit_atoms;
radeon->vtbl.fallback = r300_fallback;
+ if (radeon->radeonScreen->chip_family == CHIP_FAMILY_RV530) {
+ if (radeon->radeonScreen->num_z_pipes == 2)
+ radeon->vtbl.emit_query_finish = rv530_emit_query_finish_double_z;
+ else
+ radeon->vtbl.emit_query_finish = rv530_emit_query_finish_single_z;
+ } else
+ radeon->vtbl.emit_query_finish = r300_emit_query_finish;
}
static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
@@ -295,13 +365,10 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
/* currently bogus data */
if (r300->options.hw_tcl_enabled) {
- ctx->Const.VertexProgram.MaxInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
- ctx->Const.VertexProgram.MaxNativeInstructions =
- VSF_MAX_FRAGMENT_LENGTH / 4;
+ ctx->Const.VertexProgram.MaxNativeInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
+ ctx->Const.VertexProgram.MaxNativeAluInstructions = VSF_MAX_FRAGMENT_LENGTH / 4;
ctx->Const.VertexProgram.MaxNativeAttribs = 16; /* r420 */
- ctx->Const.VertexProgram.MaxTemps = 32;
- ctx->Const.VertexProgram.MaxNativeTemps =
- /*VSF_MAX_FRAGMENT_TEMPS */ 32;
+ ctx->Const.VertexProgram.MaxNativeTemps = 32;
ctx->Const.VertexProgram.MaxNativeParameters = 256; /* r420 */
ctx->Const.VertexProgram.MaxNativeAddressRegs = 1;
}
@@ -325,6 +392,7 @@ static void r300InitConstValues(GLcontext *ctx, radeonScreenPtr screen)
ctx->Const.FragmentProgram.MaxNativeTexIndirections = R300_PFS_MAX_TEX_INDIRECT;
ctx->Const.FragmentProgram.MaxNativeAddressRegs = 0;
}
+
}
static void r300ParseOptions(r300ContextPtr r300, radeonScreenPtr screen)
@@ -361,12 +429,16 @@ static void r300InitGLExtensions(GLcontext *ctx)
if (r300->options.stencil_two_side_disabled)
_mesa_disable_extension(ctx, "GL_EXT_stencil_two_side");
- if (ctx->Mesa_DXTn && !r300->options.s3tc_force_enabled) {
+ if (r300->options.s3tc_force_enabled) {
_mesa_enable_extension(ctx, "GL_EXT_texture_compression_s3tc");
_mesa_enable_extension(ctx, "GL_S3_s3tc");
} else if (r300->options.s3tc_force_disabled) {
_mesa_disable_extension(ctx, "GL_EXT_texture_compression_s3tc");
}
+
+ if (!r300->radeon.radeonScreen->drmSupportsOcclusionQueries) {
+ _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
+ }
}
/* Create the device specific rendering context.
@@ -391,6 +463,7 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300ParseOptions(r300, screen);
+ r300->radeon.radeonScreen = screen;
r300_init_vtbl(&r300->radeon);
_mesa_init_driver_functions(&functions);
@@ -398,6 +471,8 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300InitStateFuncs(&functions);
r300InitTextureFuncs(&functions);
r300InitShaderFuncs(&functions);
+ radeonInitQueryObjFunctions(&functions);
+ radeonInitBufferObjectFuncs(&functions);
if (!radeonInitContext(&r300->radeon, &functions,
glVisual, driContextPriv,
@@ -451,11 +526,6 @@ GLboolean r300CreateContext(const __GLcontextModes * glVisual,
r300InitState(r300);
r300InitShaderFunctions(r300);
- if (screen->chip_family == CHIP_FAMILY_RS600 || screen->chip_family == CHIP_FAMILY_RS690 ||
- screen->chip_family == CHIP_FAMILY_RS740) {
- r300->radeon.texture_row_align = 64;
- }
-
r300InitGLExtensions(ctx);
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h
index f7af7d4e57..518d5cdbf4 100644
--- a/src/mesa/drivers/dri/r300/r300_context.h
+++ b/src/mesa/drivers/dri/r300/r300_context.h
@@ -44,28 +44,13 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/mtypes.h"
#include "shader/prog_instruction.h"
+#include "compiler/radeon_code.h"
struct r300_context;
typedef struct r300_context r300ContextRec;
typedef struct r300_context *r300ContextPtr;
-/* 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__){ \
- fprintf(stderr, "*********************************WARN_ONCE*********************************\n"); \
- fprintf(stderr, "File %s function %s line %d\n", \
- __FILE__, __FUNCTION__, __LINE__); \
- fprintf(stderr, a, ## __VA_ARGS__);\
- fprintf(stderr, "***************************************************************************\n"); \
- warn##__LINE__=0;\
- } \
- }
-
#include "r300_vertprog.h"
@@ -249,6 +234,10 @@ typedef struct r300_context *r300ContextPtr;
#define R300_ZS_CNTL_2 3
#define R300_ZS_CMDSIZE 4
+#define R300_ZSB_CMD_0 0
+#define R300_ZSB_CNTL_0 1
+#define R300_ZSB_CMDSIZE 2
+
#define R300_ZB_CMD_0 0
#define R300_ZB_OFFSET 1
#define R300_ZB_PITCH 2
@@ -289,6 +278,12 @@ typedef struct r300_context *r300ContextPtr;
#define R300_TEX_CMDSIZE (MAX_TEXTURE_UNITS+1)
*/
+#define R300_QUERYOBJ_CMD_0 0
+#define R300_QUERYOBJ_DATA_0 1
+#define R300_QUERYOBJ_CMD_1 2
+#define R300_QUERYOBJ_DATA_1 3
+#define R300_QUERYOBJ_CMDSIZE 4
+
/**
* Cache for hardware register state.
*/
@@ -352,6 +347,7 @@ struct r300_hw_state {
struct radeon_state_atom rb3d_aaresolve_ctl; /* (4E88) */
struct radeon_state_atom rb3d_discard_src_pixel_lte_threshold; /* (4E88) I saw it only written on RV350 hardware.. */
struct radeon_state_atom zs; /* zstencil control (4F00) */
+ struct radeon_state_atom zsb; /* zstencil bf */
struct radeon_state_atom zstencil_format;
struct radeon_state_atom zb; /* z buffer (4F20) */
struct radeon_state_atom zb_depthclearvalue; /* (4F28) */
@@ -359,6 +355,7 @@ struct r300_hw_state {
struct radeon_state_atom zb_hiz_offset; /* (4F44) */
struct radeon_state_atom zb_hiz_pitch; /* (4F54) */
+ struct radeon_state_atom vap_flush;
struct radeon_state_atom vpi; /* vp instructions */
struct radeon_state_atom vpp; /* vp parameters */
struct radeon_state_atom vps; /* vertex point size (?) */
@@ -379,7 +376,6 @@ struct r300_hw_state {
struct radeon_state_atom border_color;
} tex;
struct radeon_state_atom txe; /* tex enable (4104) */
-
radeonTexObj *textures[R300_MAX_TEXTURE_UNITS];
};
@@ -389,46 +385,25 @@ struct r300_hw_state {
/* Vertex shader state */
-/* Perhaps more if we store programs in vmem? */
-/* drm_r300_cmd_header_t->vpu->count is unsigned char */
-#define VSF_MAX_FRAGMENT_LENGTH (255*4)
-
-/* Can be tested with colormat currently. */
-#define VSF_MAX_FRAGMENT_TEMPS (14)
-
-#define STATE_R300_WINDOW_DIMENSION (STATE_INTERNAL_DRIVER+0)
-#define STATE_R300_TEXRECT_FACTOR (STATE_INTERNAL_DRIVER+1)
-
#define COLOR_IS_RGBA
#define TAG(x) r300##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
+struct r300_vertex_program_key {
+ GLbitfield FpReads;
+ GLuint FogAttr;
+ GLuint WPosAttr;
+};
+
struct r300_vertex_program {
struct gl_vertex_program *Base;
struct r300_vertex_program *next;
- struct r300_vertex_program_key {
- GLuint FpReads;
- GLuint FogAttr;
- GLuint WPosAttr;
- } key;
-
- struct r300_vertex_shader_hw_code {
- int length;
- union {
- GLuint d[VSF_MAX_FRAGMENT_LENGTH];
- float f[VSF_MAX_FRAGMENT_LENGTH];
- } body;
- } hw_code;
-
- GLboolean translated;
- GLboolean error;
+ struct r300_vertex_program_key key;
+ struct r300_vertex_program_code code;
- int pos_end;
- int num_temporaries; /* Number of temp vars used by program */
- int inputs[VERT_ATTRIB_MAX];
- int outputs[VERT_RESULT_MAX];
+ GLboolean error;
};
struct r300_vertex_program_cont {
@@ -441,131 +416,18 @@ struct r300_vertex_program_cont {
struct r300_vertex_program *progs;
};
-#define R300_PFS_MAX_ALU_INST 64
-#define R300_PFS_MAX_TEX_INST 32
-#define R300_PFS_MAX_TEX_INDIRECT 4
-#define R300_PFS_NUM_TEMP_REGS 32
-#define R300_PFS_NUM_CONST_REGS 32
-
-#define R500_PFS_MAX_INST 512
-#define R500_PFS_NUM_TEMP_REGS 128
-#define R500_PFS_NUM_CONST_REGS 256
-
-struct r300_pfs_compile_state;
-struct r500_pfs_compile_state;
-
-/**
- * Stores state that influences the compilation of a fragment program.
- */
-struct r300_fragment_program_external_state {
- struct {
- /**
- * If the sampler is used as a shadow sampler,
- * this field is:
- * 0 - GL_LUMINANCE
- * 1 - GL_INTENSITY
- * 2 - GL_ALPHA
- * depending on the depth texture mode.
- */
- GLuint depth_texture_mode : 2;
-
- /**
- * If the sampler is used as a shadow sampler,
- * this field is (texture_compare_func - GL_NEVER).
- * [e.g. if compare function is GL_LEQUAL, this field is 3]
- *
- * Otherwise, this field is 0.
- */
- GLuint texture_compare_func : 3;
- } unit[16];
-};
-
-
-struct r300_fragment_program_node {
- int tex_offset; /**< first tex instruction */
- int tex_end; /**< last tex instruction, relative to tex_offset */
- int alu_offset; /**< first ALU instruction */
- int alu_end; /**< last ALU instruction, relative to alu_offset */
- int flags;
-};
-
-/**
- * Stores an R300 fragment program in its compiled-to-hardware form.
- */
-struct r300_fragment_program_code {
- struct {
- int length; /**< total # of texture instructions used */
- GLuint inst[R300_PFS_MAX_TEX_INST];
- } tex;
-
- struct {
- int length; /**< total # of ALU instructions used */
- struct {
- GLuint inst0;
- GLuint inst1;
- GLuint inst2;
- GLuint inst3;
- } inst[R300_PFS_MAX_ALU_INST];
- } alu;
-
- struct r300_fragment_program_node node[4];
- int cur_node;
- int first_node_has_tex;
-
- /**
- * Remember which program register a given hardware constant
- * belongs to.
- */
- struct prog_src_register constant[R300_PFS_NUM_CONST_REGS];
- int const_nr;
-
- int max_temp_idx;
-};
-
-
-struct r500_fragment_program_code {
- struct {
- GLuint inst0;
- GLuint inst1;
- GLuint inst2;
- GLuint inst3;
- GLuint inst4;
- GLuint inst5;
- } inst[R500_PFS_MAX_INST];
-
- int inst_offset;
- int inst_end;
-
- /**
- * Remember which program register a given hardware constant
- * belongs to.
- */
- struct prog_src_register constant[R500_PFS_NUM_CONST_REGS];
- int const_nr;
-
- int max_temp_idx;
-};
/**
* Store everything about a fragment program that is needed
* to render with that program.
*/
struct r300_fragment_program {
- struct gl_program *Base;
-
- GLboolean translated;
GLboolean error;
-
+ struct r300_fragment_program *next;
struct r300_fragment_program_external_state state;
- union rX00_fragment_program_code {
- struct r300_fragment_program_code r300;
- struct r500_fragment_program_code r500;
- } code;
- GLboolean writes_depth;
- GLuint optimization;
-
- struct r300_fragment_program *next;
+ struct rX00_fragment_program_code code;
+ GLbitfield InputsRead;
/* attribute that we are sending the WPOS in */
gl_frag_attrib wpos_attr;
@@ -583,12 +445,6 @@ struct r300_fragment_program_cont {
struct r300_fragment_program *progs;
};
-struct r300_fragment_program_compiler {
- r300ContextPtr r300;
- struct r300_fragment_program *fp;
- union rX00_fragment_program_code *code;
- struct gl_program *program;
-};
#define R300_MAX_AOS_ARRAYS 16
@@ -610,8 +466,6 @@ struct r300_swtcl_info {
struct r300_vtable {
void (* SetupRSUnit)(GLcontext *ctx);
void (* SetupFragmentShaderTextures)(GLcontext *ctx, int *tmu_mappings);
- GLboolean (* BuildFragmentProgramHwCode)(struct r300_fragment_program_compiler *compiler);
- void (* FragmentProgramDump)(union rX00_fragment_program_code *code);
void (* SetupPixelShader)(GLcontext *ctx);
};
@@ -619,11 +473,12 @@ struct r300_vertex_buffer {
struct vertex_attribute {
/* generic */
GLubyte element;
- GLvoid *data;
- GLboolean free_needed;
GLuint stride;
GLuint dwords;
GLubyte size; /* number of components */
+ GLboolean is_named_bo;
+ struct radeon_bo *bo;
+ GLint bo_offset;
/* hw specific */
uint32_t data_type:4;
@@ -638,12 +493,14 @@ struct r300_vertex_buffer {
};
struct r300_index_buffer {
- GLvoid *ptr;
+ struct radeon_bo *bo;
+ int bo_offset;
+
GLboolean is_32bit;
- GLboolean free_needed;
GLuint count;
};
+
/**
* \brief R300 context structure.
*/
@@ -669,11 +526,10 @@ struct r300_context {
uint32_t s3tc_force_disabled:1;
uint32_t stencil_two_side_disabled:1;
} options;
-
+
struct r300_swtcl_info swtcl;
struct r300_vertex_buffer vbuf;
struct r300_index_buffer ind_buf;
- GLboolean vap_flush_needed;
uint32_t fallback;
diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c
index 9769ff5399..e9968f9ffe 100644
--- a/src/mesa/drivers/dri/r300/r300_draw.c
+++ b/src/mesa/drivers/dri/r300/r300_draw.c
@@ -31,6 +31,7 @@
#include "main/state.h"
#include "main/api_validate.h"
#include "main/enums.h"
+#include "main/simple_list.h"
#include "r300_reg.h"
#include "r300_context.h"
@@ -38,6 +39,10 @@
#include "r300_render.h"
#include "r300_state.h"
#include "r300_tex.h"
+#include "r300_cmdbuf.h"
+
+#include "radeon_buffer_objects.h"
+#include "radeon_common_context.h"
#include "tnl/tnl.h"
#include "tnl/t_vp_build.h"
@@ -45,32 +50,59 @@
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
-static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf, struct gl_buffer_object **bo, GLuint *nr_bo)
+
+static 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 r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
- struct r300_index_buffer *ind_buf = &r300->ind_buf;
GLvoid *src_ptr;
+ GLuint *out;
+ int i;
+ GLboolean mapped_named_bo = GL_FALSE;
- if (!mesa_ind_buf) {
- ind_buf->ptr = NULL;
- return;
- }
-
- ind_buf->count = mesa_ind_buf->count;
if (mesa_ind_buf->obj->Name && !mesa_ind_buf->obj->Pointer) {
- bo[*nr_bo] = mesa_ind_buf->obj;
- (*nr_bo)++;
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);
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
+ "%s: Fixing index buffer format. type %d\n",
+ __func__, mesa_ind_buf->type);
+
if (mesa_ind_buf->type == GL_UNSIGNED_BYTE) {
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
GLubyte *in = (GLubyte *)src_ptr;
- GLuint *out = _mesa_malloc(sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1));
- int i;
- ind_buf->ptr = out;
+ radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
+
+ assert(r300->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) {
*out++ = in[i] | in[i + 1] << 16;
@@ -80,16 +112,16 @@ static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
*out++ = in[i];
}
- ind_buf->free_needed = GL_TRUE;
- ind_buf->is_32bit = GL_FALSE;
- } else if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) {
#if MESA_BIG_ENDIAN
+ } else { /* if (mesa_ind_buf->type == GL_UNSIGNED_SHORT) */
GLushort *in = (GLushort *)src_ptr;
- GLuint *out = _mesa_malloc(sizeof(GLushort) *
- ((mesa_ind_buf->count + 1) & ~1));
- int i;
+ GLuint size = sizeof(GLushort) * ((mesa_ind_buf->count + 1) & ~1);
+
+ radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo,
+ &r300->ind_buf.bo_offset, size, 4);
- ind_buf->ptr = out;
+ assert(r300->ind_buf.bo->ptr != NULL);
+ out = (GLuint *)ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
for (i = 0; i + 1 < mesa_ind_buf->count; i += 2) {
*out++ = in[i] | in[i + 1] << 16;
@@ -98,42 +130,61 @@ static void r300FixupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer
if (i < mesa_ind_buf->count) {
*out++ = in[i];
}
-
- ind_buf->free_needed = GL_TRUE;
-#else
- ind_buf->ptr = src_ptr;
- ind_buf->free_needed = GL_FALSE;
#endif
- ind_buf->is_32bit = GL_FALSE;
- } else {
- ind_buf->ptr = src_ptr;
- ind_buf->free_needed = GL_FALSE;
- ind_buf->is_32bit = GL_TRUE;
+ }
+
+ r300->ind_buf.is_32bit = GL_FALSE;
+ r300->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo) {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
}
}
-static int getTypeSize(GLenum type)
+
+static void r300SetupIndexBuffer(GLcontext *ctx, const struct _mesa_index_buffer *mesa_ind_buf)
{
- 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;
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+
+ if (!mesa_ind_buf) {
+ r300->ind_buf.bo = NULL;
+ return;
+ }
+ radeon_print(RADEON_RENDER, RADEON_TRACE, "%s\n", __func__);
+
+#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);
+
+ radeonAllocDmaRegion(&r300->radeon, &r300->ind_buf.bo, &r300->ind_buf.bo_offset, size, 4);
+
+ assert(r300->ind_buf.bo->ptr != NULL);
+ dst_ptr = ADD_POINTERS(r300->ind_buf.bo->ptr, r300->ind_buf.bo_offset);
+ _mesa_memcpy(dst_ptr, src_ptr, size);
+
+ r300->ind_buf.is_32bit = (mesa_ind_buf->type == GL_UNSIGNED_INT);
+ r300->ind_buf.count = mesa_ind_buf->count;
+
+ if (mapped_named_bo) {
+ ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, mesa_ind_buf->obj);
+ }
+ } else {
+ r300FixupIndexBuffer(ctx, mesa_ind_buf);
}
}
@@ -161,27 +212,123 @@ static int getTypeSize(GLenum type)
} \
} while (0)
-static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const struct gl_client_array *input, struct gl_buffer_object **bo, GLuint *nr_bo)
+/**
+ * Convert attribute data type to float
+ * If the attribute uses named buffer object replace the bo with newly allocated bo
+ */
+static void r300ConvertAttrib(GLcontext *ctx, int count, const struct gl_client_array *input, struct vertex_attribute *attr)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
- struct r300_vertex_buffer *vbuf = &r300->vbuf;
- struct vertex_attribute r300_attr;
- const void *src_ptr;
- GLenum type;
+ 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) {
- bo[*nr_bo] = input->BufferObj;
- (*nr_bo)++;
ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY_ARB, input->BufferObj);
- assert(input->BufferObj->Pointer != NULL);
+ mapped_named_bo = GL_TRUE;
}
src_ptr = ADD_POINTERS(input->BufferObj->Pointer, input->Ptr);
- } else
+ } else {
src_ptr = input->Ptr;
+ }
+
+ radeonAllocDmaRegion(&r300->radeon, &attr->bo, &attr->bo_offset, sizeof(GLfloat) * input->Size * count, 32);
+ dst_ptr = (GLfloat *)ADD_POINTERS(attr->bo->ptr, attr->bo_offset);
+
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
+ "%s: Converting vertex attributes, attribute data format %x,"
+ "stride %d, components %d\n"
+ , __FUNCTION__, input->Type
+ , stride, input->Size);
+
+ 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 r300AlignDataToDword(GLcontext *ctx, const struct gl_client_array *input, int count, struct vertex_attribute *attr)
+{
+ r300ContextPtr r300 = R300_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(&r300->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;
+ }
+
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s. Vertex alignment doesn't match hw requirements.\n", __func__);
+ {
+ 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 r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const struct gl_client_array *input)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_vertex_buffer *vbuf = &r300->vbuf;
+ struct vertex_attribute r300_attr;
+ GLenum type;
+ GLuint stride;
+
+ radeon_print(RADEON_RENDER, RADEON_TRACE, "%s\n", __func__);
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 ||
@@ -189,62 +336,29 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st
getTypeSize(input->Type) != 4 ||
#endif
stride < 4) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS) {
- fprintf(stderr, "%s: Converting vertex attributes, attribute data format %x,", __FUNCTION__, input->Type);
- fprintf(stderr, "stride %d, components %d\n", stride, input->Size);
- }
-
- GLfloat *dst_ptr, *tmp;
-
- /* Convert value for first element only */
- if (input->StrideB == 0)
- count = 1;
-
- tmp = dst_ptr = _mesa_malloc(sizeof(GLfloat) * input->Size * count);
-
- 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;
- }
type = GL_FLOAT;
- r300_attr.free_needed = GL_TRUE;
- r300_attr.data = tmp;
+
if (input->StrideB == 0) {
r300_attr.stride = 0;
} else {
r300_attr.stride = sizeof(GLfloat) * input->Size;
}
r300_attr.dwords = input->Size;
+ r300_attr.is_named_bo = GL_FALSE;
} else {
type = input->Type;
- r300_attr.free_needed = GL_FALSE;
- r300_attr.data = (GLvoid *)src_ptr;
- r300_attr.stride = input->StrideB;
- r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4;
+ r300_attr.dwords = (getTypeSize(type) * input->Size + 3)/ 4;
+ if (!input->BufferObj->Name) {
+
+ if (input->StrideB == 0) {
+ r300_attr.stride = 0;
+ } else {
+ r300_attr.stride = (getTypeSize(type) * input->Size + 3) & ~3;
+ }
+
+ r300_attr.is_named_bo = GL_FALSE;
+ }
}
r300_attr.size = input->Size;
@@ -333,15 +447,15 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st
++vbuf->num_attribs;
}
-static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count, struct gl_buffer_object **bo, GLuint *nr_bo)
+static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *arrays[], int count)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_vertex_buffer *vbuf = &r300->vbuf;
-
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s\n", __func__);
{
int i, tmp;
- tmp = r300->selected_vp->Base->Base.InputsRead;
+ tmp = r300->selected_vp->code.InputsRead;
i = 0;
vbuf->num_attribs = 0;
while (tmp) {
@@ -351,7 +465,7 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar
++i;
}
- r300TranslateAttrib(ctx, i, count, arrays[i], bo, nr_bo);
+ r300TranslateAttrib(ctx, i, count, arrays[i]);
tmp >>= 1;
++i;
@@ -361,45 +475,139 @@ static void r300SetVertexFormat(GLcontext *ctx, const struct gl_client_array *ar
r300SwitchFallback(ctx, R300_FALLBACK_AOS_LIMIT, vbuf->num_attribs > R300_MAX_AOS_ARRAYS);
if (r300->fallback)
return;
+}
- {
- int i;
+static void r300AllocDmaRegions(GLcontext *ctx, const struct gl_client_array *input[], int count)
+{
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
+ struct r300_vertex_buffer *vbuf = &r300->vbuf;
+ GLuint stride;
+ int ret;
+ int i, index;
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE,
+ "%s: count %d num_attribs %d\n",
+ __func__, count, vbuf->num_attribs);
+
+ for (index = 0; index < vbuf->num_attribs; index++) {
+ struct radeon_aos *aos = &r300->radeon.tcl.aos[index];
+ i = vbuf->attribs[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) {
- for (i = 0; i < vbuf->num_attribs; i++) {
- rcommon_emit_vector(ctx, &r300->radeon.tcl.aos[i],
- vbuf->attribs[i].data, vbuf->attribs[i].dwords,
- vbuf->attribs[i].stride, count);
+ r300ConvertAttrib(ctx, count, input[i], &vbuf->attribs[index]);
+ } else {
+ if (input[i]->BufferObj->Name) {
+ if (stride % 4 != 0) {
+ assert(((intptr_t) input[i]->Ptr) % input[i]->StrideB == 0);
+ r300AlignDataToDword(ctx, input[i], count, &vbuf->attribs[index]);
+ vbuf->attribs[index].is_named_bo = GL_FALSE;
+ } else {
+ vbuf->attribs[index].stride = input[i]->StrideB;
+ vbuf->attribs[index].bo_offset = (intptr_t) input[i]->Ptr;
+ vbuf->attribs[index].bo = get_radeon_buffer_object(input[i]->BufferObj)->bo;
+ vbuf->attribs[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(&r300->radeon, &vbuf->attribs[index].bo, &vbuf->attribs[index].bo_offset, size, 32);
+ assert(vbuf->attribs[index].bo->ptr != NULL);
+ dst = (uint32_t *)ADD_POINTERS(vbuf->attribs[index].bo->ptr, vbuf->attribs[index].bo_offset);
+ switch (vbuf->attribs[index].dwords) {
+ case 1: radeonEmitVec4(dst, input[i]->Ptr, input[i]->StrideB, local_count); break;
+ case 2: radeonEmitVec8(dst, input[i]->Ptr, input[i]->StrideB, local_count); break;
+ case 3: radeonEmitVec12(dst, input[i]->Ptr, input[i]->StrideB, local_count); break;
+ case 4: radeonEmitVec16(dst, input[i]->Ptr, input[i]->StrideB, local_count); break;
+ default: assert(0); break;
+ }
+
+ }
}
- r300->radeon.tcl.aos_count = vbuf->num_attribs;
+ aos->count = vbuf->attribs[index].stride == 0 ? 1 : count;
+ aos->stride = vbuf->attribs[index].stride / sizeof(float);
+ aos->components = vbuf->attribs[index].dwords;
+ aos->bo = vbuf->attribs[index].bo;
+ aos->offset = vbuf->attribs[index].bo_offset;
+
+ if (vbuf->attribs[index].is_named_bo) {
+ radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs, r300->vbuf.attribs[index].bo, RADEON_GEM_DOMAIN_GTT, 0);
+ }
}
+
+ r300->radeon.tcl.aos_count = vbuf->num_attribs;
+ ret = radeon_cs_space_check_with_bo(r300->radeon.cmdbuf.cs, first_elem(&r300->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
+ r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, ret);
+
}
-static void r300FreeData(GLcontext *ctx, struct gl_buffer_object **bo, GLuint nr_bo)
+static void r300FreeData(GLcontext *ctx)
{
+ /* Need to zero tcl.aos[n].bo and tcl.elt_dma_bo
+ * to prevent double unref in radeonReleaseArrays
+ * called during context destroy
+ */
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s\n", __func__);
+ r300ContextPtr r300 = R300_CONTEXT(ctx);
{
- struct r300_vertex_buffer *vbuf = &R300_CONTEXT(ctx)->vbuf;
int i;
- for (i = 0; i < vbuf->num_attribs; i++) {
- if (vbuf->attribs[i].free_needed)
- _mesa_free(vbuf->attribs[i].data);
+ for (i = 0; i < r300->vbuf.num_attribs; i++) {
+ if (!r300->vbuf.attribs[i].is_named_bo) {
+ radeon_bo_unref(r300->vbuf.attribs[i].bo);
+ }
+ r300->radeon.tcl.aos[i].bo = NULL;
}
}
{
- struct r300_index_buffer *ind_buf = &R300_CONTEXT(ctx)->ind_buf;
- if (ind_buf->free_needed)
- _mesa_free(ind_buf->ptr);
+ if (r300->ind_buf.bo != NULL) {
+ radeon_bo_unref(r300->ind_buf.bo);
+ }
}
+}
- {
- int i;
+static GLuint r300PredictTryDrawPrimsSize(GLcontext *ctx, GLuint nr_prims)
+{
+ struct r300_context *r300 = R300_CONTEXT(ctx);
+ struct r300_vertex_buffer *vbuf = &r300->vbuf;
+ GLboolean flushed;
+ GLuint dwords;
+ GLuint state_size;
+
+ dwords = 2*CACHE_FLUSH_BUFSZ;
+ dwords += PRE_EMIT_STATE_BUFSZ;
+ dwords += (AOS_BUFSZ(vbuf->num_attribs)
+ + SCISSORS_BUFSZ*2
+ + FIREAOS_BUFSZ )*nr_prims;
+
+ state_size = radeonCountStateEmitSize(&r300->radeon);
+ flushed = rcommonEnsureCmdBufSpace(&r300->radeon,
+ dwords + state_size,
+ __FUNCTION__);
+ if (flushed)
+ dwords += radeonCountStateEmitSize(&r300->radeon);
+ else
+ dwords += state_size;
- for (i = 0; i < nr_bo; ++i) {
- ctx->Driver.UnmapBuffer(ctx, 0, bo[i]);
- }
- }
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s: total prediction size is %d.\n", __FUNCTION__, dwords);
+ return dwords;
}
static GLboolean r300TryDrawPrims(GLcontext *ctx,
@@ -411,8 +619,10 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
GLuint max_index )
{
struct r300_context *r300 = R300_CONTEXT(ctx);
- struct gl_buffer_object *bo[VERT_ATTRIB_MAX+1];
- GLuint i, nr_bo = 0;
+ GLuint i;
+
+ radeon_print(RADEON_RENDER, RADEON_NORMAL, "%s: %u (%d-%d) cs begin at %d\n",
+ __FUNCTION__, nr_prims, min_index, max_index, r300->radeon.cmdbuf.cs->cdw );
if (ctx->NewState)
_mesa_update_state( ctx );
@@ -424,23 +634,27 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
r300SwitchFallback(ctx, R300_FALLBACK_INVALID_BUFFERS, !r300ValidateBuffers(ctx));
- r300FixupIndexBuffer(ctx, ib, bo, &nr_bo);
-
- /* ensure we have the cmd buf space in advance to cover
- * the state + DMA AOS pointers */
- rcommonEnsureCmdBufSpace(&r300->radeon,
- r300->radeon.hw.max_state_size + (50*sizeof(int)),
- __FUNCTION__);
-
- r300SetVertexFormat(ctx, arrays, max_index + 1, bo, &nr_bo);
+ r300SetVertexFormat(ctx, arrays, max_index + 1);
if (r300->fallback)
return GL_FALSE;
- r300SetupVAP(ctx, r300->selected_vp->Base->Base.InputsRead, r300->selected_vp->Base->Base.OutputsWritten);
+ r300SetupVAP(ctx, r300->selected_vp->code.InputsRead, r300->selected_vp->code.OutputsWritten);
r300UpdateShaderStates(r300);
+ /* ensure we have the cmd buf space in advance to cover
+ * the state + DMA AOS pointers */
+ GLuint emit_end = r300PredictTryDrawPrimsSize(ctx, nr_prims)
+ + r300->radeon.cmdbuf.cs->cdw;
+
+ r300SetupIndexBuffer(ctx, ib);
+
+ r300AllocDmaRegions(ctx, arrays, max_index + 1);
+
+ if (r300->fallback)
+ return GL_FALSE;
+
r300EmitCacheFlush(r300);
radeonEmitState(&r300->radeon);
@@ -450,9 +664,14 @@ static GLboolean r300TryDrawPrims(GLcontext *ctx,
r300EmitCacheFlush(r300);
- radeonReleaseArrays(ctx, ~0);
+ r300FreeData(ctx);
- r300FreeData(ctx, bo, nr_bo);
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s: %u (%d-%d) cs ending at %d\n",
+ __FUNCTION__, nr_prims, min_index, max_index, r300->radeon.cmdbuf.cs->cdw );
+
+ if (emit_end < r300->radeon.cmdbuf.cs->cdw)
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n", r300->radeon.cmdbuf.cs->cdw - emit_end);
return GL_TRUE;
}
@@ -462,28 +681,26 @@ static void r300DrawPrims(GLcontext *ctx,
const struct _mesa_prim *prim,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
- struct split_limits limits;
GLboolean retval;
- if (ib)
- limits.max_verts = 0xffffffff;
- else
- limits.max_verts = 65535;
-
- limits.max_indices = 65535;
- limits.max_vb_size = 1024*1024;
+ /* 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) {
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT,
+ "%s: Rebasing primitives. %p nr_prims %d min_index %u max_index %u\n",
+ __func__, prim, nr_prims, min_index, max_index);
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims );
return;
}
- if ((ib && ib->count > 65535)) {
- vbo_split_prims (ctx, arrays, prim, nr_prims, ib, min_index, max_index, r300DrawPrims, &limits);
- return;
- }
/* Make an attempt at drawing */
retval = r300TryDrawPrims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
diff --git a/src/mesa/drivers/dri/r300/r300_emit.c b/src/mesa/drivers/dri/r300/r300_emit.c
index feb3370f37..07e6223087 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.c
+++ b/src/mesa/drivers/dri/r300/r300_emit.c
@@ -124,41 +124,6 @@ GLuint r300VAPOutputCntl1(GLcontext * ctx, GLuint vp_writes)
return ret;
}
-GLboolean r300EmitArrays(GLcontext * ctx)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- struct r300_vertex_buffer *vbuf = &r300->vbuf;
- GLuint InputsRead, OutputsWritten;
-
- r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten);
-
- r300SwitchFallback(ctx, R300_FALLBACK_AOS_LIMIT, vbuf->num_attribs > R300_MAX_AOS_ARRAYS);
- if (r300->fallback & R300_RASTER_FALLBACK_MASK)
- return GL_FALSE;
-
- {
- struct vertex_buffer *mesa_vb = &TNL_CONTEXT(ctx)->vb;
- GLuint attr, i;
-
- for (i = 0; i < vbuf->num_attribs; i++) {
- attr = vbuf->attribs[i].element;
- rcommon_emit_vector(ctx, &r300->radeon.tcl.aos[i], mesa_vb->AttribPtr[attr]->data,
- mesa_vb->AttribPtr[attr]->size, mesa_vb->AttribPtr[attr]->stride, mesa_vb->Count);
- }
-
- r300->radeon.tcl.aos_count = vbuf->num_attribs;
-
- /* Fill index buffer info */
- r300->ind_buf.ptr = mesa_vb->Elts;
- r300->ind_buf.is_32bit = GL_TRUE;
- r300->ind_buf.free_needed = GL_FALSE;
- }
-
- r300SetupVAP(ctx, InputsRead, OutputsWritten);
-
- return GL_TRUE;
-}
-
void r300EmitCacheFlush(r300ContextPtr rmesa)
{
BATCH_LOCALS(&rmesa->radeon);
diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h
index 3f8c60ffae..8e57e354d1 100644
--- a/src/mesa/drivers/dri/r300/r300_emit.h
+++ b/src/mesa/drivers/dri/r300/r300_emit.h
@@ -104,7 +104,7 @@ static INLINE uint32_t cmdpacket3(struct radeon_screen *rscrn, int packet)
return cmd.u;
}
-static INLINE uint32_t cmdcpdelay(struct radeon_screen *rscrn,
+static INLINE uint32_t cmdcpdelay(struct radeon_screen *rscrn,
unsigned short count)
{
drm_r300_cmd_header_t cmd;
@@ -216,8 +216,6 @@ void static INLINE cp_wait(radeonContextPtr radeon, unsigned char flags)
}
}
-extern GLboolean r300EmitArrays(GLcontext * ctx);
-
extern int r300PrimitiveType(r300ContextPtr rmesa, int prim);
extern int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim);
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.c b/src/mesa/drivers/dri/r300/r300_fragprog.c
deleted file mode 100644
index 55c1cfe631..0000000000
--- a/src/mesa/drivers/dri/r300/r300_fragprog.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Copyright (C) 2005 Ben Skeggs.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "r300_fragprog.h"
-
-#include "shader/prog_parameter.h"
-
-#include "r300_context.h"
-#include "r300_fragprog_swizzle.h"
-
-static void reset_srcreg(struct prog_src_register* reg)
-{
- _mesa_bzero(reg, sizeof(*reg));
- reg->Swizzle = SWIZZLE_NOOP;
-}
-
-static struct prog_src_register shadow_ambient(struct gl_program *program, int tmu)
-{
- gl_state_index fail_value_tokens[STATE_LENGTH] = {
- STATE_INTERNAL, STATE_SHADOW_AMBIENT, 0, 0, 0
- };
- struct prog_src_register reg = { 0, };
-
- fail_value_tokens[2] = tmu;
- reg.File = PROGRAM_STATE_VAR;
- reg.Index = _mesa_add_state_reference(program->Parameters, fail_value_tokens);
- reg.Swizzle = SWIZZLE_WWWW;
- return reg;
-}
-
-/**
- * Transform TEX, TXP, TXB, and KIL instructions in the following way:
- * - premultiply texture coordinates for RECT
- * - extract operand swizzles
- * - introduce a temporary register when write masks are needed
- *
- * \todo If/when r5xx uses the radeon_program architecture, this can probably
- * be reused.
- */
-GLboolean r300_transform_TEX(
- struct radeon_transform_context *t,
- struct prog_instruction* orig_inst, void* data)
-{
- struct r300_fragment_program_compiler *compiler =
- (struct r300_fragment_program_compiler*)data;
- struct prog_instruction inst = *orig_inst;
- struct prog_instruction* tgt;
- GLboolean destredirect = GL_FALSE;
-
- if (inst.Opcode != OPCODE_TEX &&
- inst.Opcode != OPCODE_TXB &&
- inst.Opcode != OPCODE_TXP &&
- inst.Opcode != OPCODE_KIL)
- return GL_FALSE;
-
- if (inst.Opcode != OPCODE_KIL &&
- t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
- GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
-
- if (comparefunc == GL_NEVER || comparefunc == GL_ALWAYS) {
- tgt = radeonAppendInstructions(t->Program, 1);
-
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg = inst.DstReg;
- if (comparefunc == GL_ALWAYS) {
- tgt->SrcReg[0].File = PROGRAM_BUILTIN;
- tgt->SrcReg[0].Swizzle = SWIZZLE_1111;
- } else {
- tgt->SrcReg[0] = shadow_ambient(t->Program, inst.TexSrcUnit);
- }
- return GL_TRUE;
- }
-
- inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = radeonFindFreeTemporary(t);
- inst.DstReg.WriteMask = WRITEMASK_XYZW;
- }
-
-
- /* Hardware uses [0..1]x[0..1] range for rectangle textures
- * instead of [0..Width]x[0..Height].
- * Add a scaling instruction.
- */
- if (inst.Opcode != OPCODE_KIL && inst.TexSrcTarget == TEXTURE_RECT_INDEX) {
- gl_state_index tokens[STATE_LENGTH] = {
- STATE_INTERNAL, STATE_R300_TEXRECT_FACTOR, 0, 0,
- 0
- };
-
- int tempreg = radeonFindFreeTemporary(t);
- int factor_index;
-
- tokens[2] = inst.TexSrcUnit;
- factor_index = _mesa_add_state_reference(t->Program->Parameters, tokens);
-
- tgt = radeonAppendInstructions(t->Program, 1);
-
- tgt->Opcode = OPCODE_MUL;
- tgt->DstReg.File = PROGRAM_TEMPORARY;
- tgt->DstReg.Index = tempreg;
- tgt->SrcReg[0] = inst.SrcReg[0];
- tgt->SrcReg[1].File = PROGRAM_STATE_VAR;
- tgt->SrcReg[1].Index = factor_index;
-
- reset_srcreg(&inst.SrcReg[0]);
- inst.SrcReg[0].File = PROGRAM_TEMPORARY;
- inst.SrcReg[0].Index = tempreg;
- }
-
- if (inst.Opcode != OPCODE_KIL) {
- if (inst.DstReg.File != PROGRAM_TEMPORARY ||
- inst.DstReg.WriteMask != WRITEMASK_XYZW) {
- int tempreg = radeonFindFreeTemporary(t);
-
- inst.DstReg.File = PROGRAM_TEMPORARY;
- inst.DstReg.Index = tempreg;
- inst.DstReg.WriteMask = WRITEMASK_XYZW;
- destredirect = GL_TRUE;
- } else if (inst.SaturateMode) {
- destredirect = GL_TRUE;
- }
- }
-
- if (inst.SrcReg[0].File != PROGRAM_TEMPORARY && inst.SrcReg[0].File != PROGRAM_INPUT) {
- int tmpreg = radeonFindFreeTemporary(t);
- tgt = radeonAppendInstructions(t->Program, 1);
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg.File = PROGRAM_TEMPORARY;
- tgt->DstReg.Index = tmpreg;
- tgt->SrcReg[0] = inst.SrcReg[0];
-
- reset_srcreg(&inst.SrcReg[0]);
- inst.SrcReg[0].File = PROGRAM_TEMPORARY;
- inst.SrcReg[0].Index = tmpreg;
- }
-
- tgt = radeonAppendInstructions(t->Program, 1);
- _mesa_copy_instructions(tgt, &inst, 1);
-
- if (inst.Opcode != OPCODE_KIL &&
- t->Program->ShadowSamplers & (1 << inst.TexSrcUnit)) {
- GLuint comparefunc = GL_NEVER + compiler->fp->state.unit[inst.TexSrcUnit].texture_compare_func;
- GLuint depthmode = compiler->fp->state.unit[inst.TexSrcUnit].depth_texture_mode;
- int rcptemp = radeonFindFreeTemporary(t);
- int pass, fail;
-
- tgt = radeonAppendInstructions(t->Program, 3);
-
- tgt[0].Opcode = OPCODE_RCP;
- tgt[0].DstReg.File = PROGRAM_TEMPORARY;
- tgt[0].DstReg.Index = rcptemp;
- tgt[0].DstReg.WriteMask = WRITEMASK_W;
- tgt[0].SrcReg[0] = inst.SrcReg[0];
- tgt[0].SrcReg[0].Swizzle = SWIZZLE_WWWW;
-
- tgt[1].Opcode = OPCODE_MAD;
- tgt[1].DstReg = inst.DstReg;
- tgt[1].DstReg.WriteMask = orig_inst->DstReg.WriteMask;
- tgt[1].SrcReg[0] = inst.SrcReg[0];
- tgt[1].SrcReg[0].Swizzle = SWIZZLE_ZZZZ;
- tgt[1].SrcReg[1].File = PROGRAM_TEMPORARY;
- tgt[1].SrcReg[1].Index = rcptemp;
- tgt[1].SrcReg[1].Swizzle = SWIZZLE_WWWW;
- tgt[1].SrcReg[2].File = PROGRAM_TEMPORARY;
- tgt[1].SrcReg[2].Index = inst.DstReg.Index;
- if (depthmode == 0) /* GL_LUMINANCE */
- tgt[1].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_Z);
- else if (depthmode == 2) /* GL_ALPHA */
- tgt[1].SrcReg[2].Swizzle = SWIZZLE_WWWW;
-
- /* Recall that SrcReg[0] is tex, SrcReg[2] is r and:
- * r < tex <=> -tex+r < 0
- * r >= tex <=> not (-tex+r < 0 */
- if (comparefunc == GL_LESS || comparefunc == GL_GEQUAL)
- tgt[1].SrcReg[2].Negate = tgt[0].SrcReg[2].Negate ^ NEGATE_XYZW;
- else
- tgt[1].SrcReg[0].Negate = tgt[0].SrcReg[0].Negate ^ NEGATE_XYZW;
-
- tgt[2].Opcode = OPCODE_CMP;
- tgt[2].DstReg = orig_inst->DstReg;
- tgt[2].SrcReg[0].File = PROGRAM_TEMPORARY;
- tgt[2].SrcReg[0].Index = tgt[1].DstReg.Index;
-
- if (comparefunc == GL_LESS || comparefunc == GL_GREATER) {
- pass = 1;
- fail = 2;
- } else {
- pass = 2;
- fail = 1;
- }
-
- tgt[2].SrcReg[pass].File = PROGRAM_BUILTIN;
- tgt[2].SrcReg[pass].Swizzle = SWIZZLE_1111;
- tgt[2].SrcReg[fail] = shadow_ambient(t->Program, inst.TexSrcUnit);
- } else if (destredirect) {
- tgt = radeonAppendInstructions(t->Program, 1);
-
- tgt->Opcode = OPCODE_MOV;
- tgt->DstReg = orig_inst->DstReg;
- tgt->SaturateMode = inst.SaturateMode;
- tgt->SrcReg[0].File = PROGRAM_TEMPORARY;
- tgt->SrcReg[0].Index = inst.DstReg.Index;
- }
-
- return GL_TRUE;
-}
-
-/* just some random things... */
-void r300FragmentProgramDump(union rX00_fragment_program_code *c)
-{
- struct r300_fragment_program_code *code = &c->r300;
- int n, i, j;
- static int pc = 0;
-
- fprintf(stderr, "pc=%d*************************************\n", pc++);
-
- fprintf(stderr, "Hardware program\n");
- fprintf(stderr, "----------------\n");
-
- for (n = 0; n < (code->cur_node + 1); n++) {
- fprintf(stderr, "NODE %d: alu_offset: %d, tex_offset: %d, "
- "alu_end: %d, tex_end: %d, flags: %08x\n", n,
- code->node[n].alu_offset,
- code->node[n].tex_offset,
- code->node[n].alu_end, code->node[n].tex_end,
- code->node[n].flags);
-
- if (n > 0 || code->first_node_has_tex) {
- fprintf(stderr, " TEX:\n");
- for (i = code->node[n].tex_offset;
- i <= code->node[n].tex_offset + code->node[n].tex_end;
- ++i) {
- const char *instr;
-
- switch ((code->tex.
- inst[i] >> R300_TEX_INST_SHIFT) &
- 15) {
- case R300_TEX_OP_LD:
- instr = "TEX";
- break;
- case R300_TEX_OP_KIL:
- instr = "KIL";
- break;
- case R300_TEX_OP_TXP:
- instr = "TXP";
- break;
- case R300_TEX_OP_TXB:
- instr = "TXB";
- break;
- default:
- instr = "UNKNOWN";
- }
-
- fprintf(stderr,
- " %s t%i, %c%i, texture[%i] (%08x)\n",
- instr,
- (code->tex.
- inst[i] >> R300_DST_ADDR_SHIFT) & 31,
- 't',
- (code->tex.
- inst[i] >> R300_SRC_ADDR_SHIFT) & 31,
- (code->tex.
- inst[i] & R300_TEX_ID_MASK) >>
- R300_TEX_ID_SHIFT,
- code->tex.inst[i]);
- }
- }
-
- for (i = code->node[n].alu_offset;
- i <= code->node[n].alu_offset + code->node[n].alu_end; ++i) {
- char srcc[3][10], dstc[20];
- char srca[3][10], dsta[20];
- char argc[3][20];
- char arga[3][20];
- char flags[5], tmp[10];
-
- for (j = 0; j < 3; ++j) {
- int regc = code->alu.inst[i].inst1 >> (j * 6);
- int rega = code->alu.inst[i].inst3 >> (j * 6);
-
- sprintf(srcc[j], "%c%i",
- (regc & 32) ? 'c' : 't', regc & 31);
- sprintf(srca[j], "%c%i",
- (rega & 32) ? 'c' : 't', rega & 31);
- }
-
- dstc[0] = 0;
- sprintf(flags, "%s%s%s",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_REG_X) ? "x" : "",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_REG_Y) ? "y" : "",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_REG_Z) ? "z" : "");
- if (flags[0] != 0) {
- sprintf(dstc, "t%i.%s ",
- (code->alu.inst[i].
- inst1 >> R300_ALU_DSTC_SHIFT) & 31,
- flags);
- }
- sprintf(flags, "%s%s%s",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_OUTPUT_X) ? "x" : "",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_OUTPUT_Y) ? "y" : "",
- (code->alu.inst[i].
- inst1 & R300_ALU_DSTC_OUTPUT_Z) ? "z" : "");
- if (flags[0] != 0) {
- sprintf(tmp, "o%i.%s",
- (code->alu.inst[i].
- inst1 >> R300_ALU_DSTC_SHIFT) & 31,
- flags);
- strcat(dstc, tmp);
- }
-
- dsta[0] = 0;
- if (code->alu.inst[i].inst3 & R300_ALU_DSTA_REG) {
- sprintf(dsta, "t%i.w ",
- (code->alu.inst[i].
- inst3 >> R300_ALU_DSTA_SHIFT) & 31);
- }
- if (code->alu.inst[i].inst3 & R300_ALU_DSTA_OUTPUT) {
- sprintf(tmp, "o%i.w ",
- (code->alu.inst[i].
- inst3 >> R300_ALU_DSTA_SHIFT) & 31);
- strcat(dsta, tmp);
- }
- if (code->alu.inst[i].inst3 & R300_ALU_DSTA_DEPTH) {
- strcat(dsta, "Z");
- }
-
- fprintf(stderr,
- "%3i: xyz: %3s %3s %3s -> %-20s (%08x)\n"
- " w: %3s %3s %3s -> %-20s (%08x)\n", i,
- srcc[0], srcc[1], srcc[2], dstc,
- code->alu.inst[i].inst1, srca[0], srca[1],
- srca[2], dsta, code->alu.inst[i].inst3);
-
- for (j = 0; j < 3; ++j) {
- int regc = code->alu.inst[i].inst0 >> (j * 7);
- int rega = code->alu.inst[i].inst2 >> (j * 7);
- int d;
- char buf[20];
-
- d = regc & 31;
- if (d < 12) {
- switch (d % 4) {
- case R300_ALU_ARGC_SRC0C_XYZ:
- sprintf(buf, "%s.xyz",
- srcc[d / 4]);
- break;
- case R300_ALU_ARGC_SRC0C_XXX:
- sprintf(buf, "%s.xxx",
- srcc[d / 4]);
- break;
- case R300_ALU_ARGC_SRC0C_YYY:
- sprintf(buf, "%s.yyy",
- srcc[d / 4]);
- break;
- case R300_ALU_ARGC_SRC0C_ZZZ:
- sprintf(buf, "%s.zzz",
- srcc[d / 4]);
- break;
- }
- } else if (d < 15) {
- sprintf(buf, "%s.www", srca[d - 12]);
- } else if (d == 20) {
- sprintf(buf, "0.0");
- } else if (d == 21) {
- sprintf(buf, "1.0");
- } else if (d == 22) {
- sprintf(buf, "0.5");
- } else if (d >= 23 && d < 32) {
- d -= 23;
- switch (d / 3) {
- case 0:
- sprintf(buf, "%s.yzx",
- srcc[d % 3]);
- break;
- case 1:
- sprintf(buf, "%s.zxy",
- srcc[d % 3]);
- break;
- case 2:
- sprintf(buf, "%s.Wzy",
- srcc[d % 3]);
- break;
- }
- } else {
- sprintf(buf, "%i", d);
- }
-
- sprintf(argc[j], "%s%s%s%s",
- (regc & 32) ? "-" : "",
- (regc & 64) ? "|" : "",
- buf, (regc & 64) ? "|" : "");
-
- d = rega & 31;
- if (d < 9) {
- sprintf(buf, "%s.%c", srcc[d / 3],
- 'x' + (char)(d % 3));
- } else if (d < 12) {
- sprintf(buf, "%s.w", srca[d - 9]);
- } else if (d == 16) {
- sprintf(buf, "0.0");
- } else if (d == 17) {
- sprintf(buf, "1.0");
- } else if (d == 18) {
- sprintf(buf, "0.5");
- } else {
- sprintf(buf, "%i", d);
- }
-
- sprintf(arga[j], "%s%s%s%s",
- (rega & 32) ? "-" : "",
- (rega & 64) ? "|" : "",
- buf, (rega & 64) ? "|" : "");
- }
-
- fprintf(stderr, " xyz: %8s %8s %8s op: %08x\n"
- " w: %8s %8s %8s op: %08x\n",
- argc[0], argc[1], argc[2],
- code->alu.inst[i].inst0, arga[0], arga[1],
- arga[2], code->alu.inst[i].inst2);
- }
- }
-}
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog.h b/src/mesa/drivers/dri/r300/r300_fragprog.h
deleted file mode 100644
index 5ce6f33cee..0000000000
--- a/src/mesa/drivers/dri/r300/r300_fragprog.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2005 Ben Skeggs.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-/*
- * Authors:
- * Ben Skeggs <darktama@iinet.net.au>
- * Jerome Glisse <j.glisse@gmail.com>
- */
-#ifndef __R300_FRAGPROG_H_
-#define __R300_FRAGPROG_H_
-
-#include "shader/program.h"
-#include "shader/prog_instruction.h"
-
-#include "r300_context.h"
-#include "radeon_program.h"
-
-#define DRI_CONF_FP_OPTIMIZATION_SPEED 0
-#define DRI_CONF_FP_OPTIMIZATION_QUALITY 1
-
-#if 1
-
-/**
- * Fragment program helper macros
- */
-
-/* Produce unshifted source selectors */
-#define FP_TMP(idx) (idx)
-#define FP_CONST(idx) ((idx) | (1 << 5))
-
-/* Produce source/dest selector dword */
-#define FP_SELC_MASK_NO 0
-#define FP_SELC_MASK_X 1
-#define FP_SELC_MASK_Y 2
-#define FP_SELC_MASK_XY 3
-#define FP_SELC_MASK_Z 4
-#define FP_SELC_MASK_XZ 5
-#define FP_SELC_MASK_YZ 6
-#define FP_SELC_MASK_XYZ 7
-
-#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
- (((destidx) << R300_ALU_DSTC_SHIFT) | \
- (FP_SELC_MASK_##regmask << 23) | \
- (FP_SELC_MASK_##outmask << 26) | \
- ((src0) << R300_ALU_SRC0C_SHIFT) | \
- ((src1) << R300_ALU_SRC1C_SHIFT) | \
- ((src2) << R300_ALU_SRC2C_SHIFT))
-
-#define FP_SELA_MASK_NO 0
-#define FP_SELA_MASK_W 1
-
-#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
- (((destidx) << R300_ALU_DSTA_SHIFT) | \
- (FP_SELA_MASK_##regmask << 23) | \
- (FP_SELA_MASK_##outmask << 24) | \
- ((src0) << R300_ALU_SRC0A_SHIFT) | \
- ((src1) << R300_ALU_SRC1A_SHIFT) | \
- ((src2) << R300_ALU_SRC2A_SHIFT))
-
-/* Produce unshifted argument selectors */
-#define FP_ARGC(source) R300_ALU_ARGC_##source
-#define FP_ARGA(source) R300_ALU_ARGA_##source
-#define FP_ABS(arg) ((arg) | (1 << 6))
-#define FP_NEG(arg) ((arg) ^ (1 << 5))
-
-/* Produce instruction dword */
-#define FP_INSTRC(opcode,arg0,arg1,arg2) \
- (R300_ALU_OUTC_##opcode | \
- ((arg0) << R300_ALU_ARG0C_SHIFT) | \
- ((arg1) << R300_ALU_ARG1C_SHIFT) | \
- ((arg2) << R300_ALU_ARG2C_SHIFT))
-
-#define FP_INSTRA(opcode,arg0,arg1,arg2) \
- (R300_ALU_OUTA_##opcode | \
- ((arg0) << R300_ALU_ARG0A_SHIFT) | \
- ((arg1) << R300_ALU_ARG1A_SHIFT) | \
- ((arg2) << R300_ALU_ARG2A_SHIFT))
-
-#endif
-
-extern GLboolean r300BuildFragmentProgramHwCode(struct r300_fragment_program_compiler *compiler);
-
-extern void r300FragmentProgramDump(union rX00_fragment_program_code *c);
-
-extern GLboolean r300_transform_TEX(struct radeon_transform_context *t, struct prog_instruction* orig_inst, void* data);
-
-#endif
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.c b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
index f5c4c0f4a0..469c278b51 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.c
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.c
@@ -42,21 +42,51 @@
#include "shader/prog_parameter.h"
#include "shader/prog_print.h"
+#include "compiler/radeon_compiler.h"
+
#include "r300_state.h"
-#include "r300_fragprog.h"
-#include "r300_fragprog_swizzle.h"
-#include "r500_fragprog.h"
-#include "radeon_program.h"
-#include "radeon_program_alu.h"
-static void nqssadce_init(struct nqssadce_state* s)
+static GLuint build_dtm(GLuint depthmode)
+{
+ switch(depthmode) {
+ default:
+ case GL_LUMINANCE: return 0;
+ case GL_INTENSITY: return 1;
+ case GL_ALPHA: return 2;
+ }
+}
+
+static GLuint build_func(GLuint comparefunc)
{
- s->Outputs[FRAG_RESULT_COLOR].Sourced = WRITEMASK_XYZW;
- s->Outputs[FRAG_RESULT_DEPTH].Sourced = WRITEMASK_W;
+ return comparefunc - GL_NEVER;
}
/**
+ * Collect all external state that is relevant for compiling the given
+ * fragment program.
+ */
+static void build_state(
+ r300ContextPtr r300,
+ struct gl_fragment_program *fp,
+ struct r300_fragment_program_external_state *state)
+{
+ int unit;
+
+ _mesa_bzero(state, sizeof(*state));
+
+ for(unit = 0; unit < 16; ++unit) {
+ if (fp->Base.ShadowSamplers & (1 << unit)) {
+ struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current;
+
+ state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode);
+ state->unit[unit].texture_compare_func = build_func(tex->CompareFunc);
+ }
+ }
+}
+
+
+/**
* Transform the program to support fragment.position.
*
* Introduce a small fragment at the start of the program that will be
@@ -65,104 +95,26 @@ static void nqssadce_init(struct nqssadce_state* s)
* to read from a newly allocated temporary.
*
*/
-static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
+static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler, struct r300_fragment_program * fp)
{
- GLuint InputsRead = compiler->fp->Base->InputsRead;
+ int i;
- if (!(InputsRead & FRAG_BIT_WPOS)) {
- compiler->fp->wpos_attr = FRAG_ATTRIB_MAX;
+ if (!(compiler->Base.Program.InputsRead & FRAG_BIT_WPOS)) {
+ fp->wpos_attr = FRAG_ATTRIB_MAX;
return;
}
- static gl_state_index tokens[STATE_LENGTH] = {
- STATE_INTERNAL, STATE_R300_WINDOW_DIMENSION, 0, 0, 0
- };
- struct prog_instruction *fpi;
- GLuint window_index;
- int i = 0;
-
for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
- if (!(InputsRead & (1 << i))) {
- InputsRead &= ~(1 << FRAG_ATTRIB_WPOS);
- InputsRead |= 1 << i;
- compiler->fp->Base->InputsRead = InputsRead;
- compiler->fp->wpos_attr = i;
+ if (!(compiler->Base.Program.InputsRead & (1 << i))) {
+ fp->wpos_attr = i;
break;
}
}
- GLuint tempregi = _mesa_find_free_register(compiler->program, PROGRAM_TEMPORARY);
-
- _mesa_insert_instructions(compiler->program, 0, 3);
- fpi = compiler->program->Instructions;
- i = 0;
-
- /* perspective divide */
- fpi[i].Opcode = OPCODE_RCP;
-
- fpi[i].DstReg.File = PROGRAM_TEMPORARY;
- fpi[i].DstReg.Index = tempregi;
- fpi[i].DstReg.WriteMask = WRITEMASK_W;
- fpi[i].DstReg.CondMask = COND_TR;
-
- fpi[i].SrcReg[0].File = PROGRAM_INPUT;
- fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
- fpi[i].SrcReg[0].Swizzle = SWIZZLE_WWWW;
- i++;
-
- fpi[i].Opcode = OPCODE_MUL;
-
- fpi[i].DstReg.File = PROGRAM_TEMPORARY;
- fpi[i].DstReg.Index = tempregi;
- fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
- fpi[i].DstReg.CondMask = COND_TR;
-
- fpi[i].SrcReg[0].File = PROGRAM_INPUT;
- fpi[i].SrcReg[0].Index = compiler->fp->wpos_attr;
- fpi[i].SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- fpi[i].SrcReg[1].File = PROGRAM_TEMPORARY;
- fpi[i].SrcReg[1].Index = tempregi;
- fpi[i].SrcReg[1].Swizzle = SWIZZLE_WWWW;
- i++;
-
- /* viewport transformation */
- window_index = _mesa_add_state_reference(compiler->program->Parameters, tokens);
-
- fpi[i].Opcode = OPCODE_MAD;
-
- fpi[i].DstReg.File = PROGRAM_TEMPORARY;
- fpi[i].DstReg.Index = tempregi;
- fpi[i].DstReg.WriteMask = WRITEMASK_XYZ;
- fpi[i].DstReg.CondMask = COND_TR;
-
- fpi[i].SrcReg[0].File = PROGRAM_TEMPORARY;
- fpi[i].SrcReg[0].Index = tempregi;
- fpi[i].SrcReg[0].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
-
- fpi[i].SrcReg[1].File = PROGRAM_STATE_VAR;
- fpi[i].SrcReg[1].Index = window_index;
- fpi[i].SrcReg[1].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
-
- fpi[i].SrcReg[2].File = PROGRAM_STATE_VAR;
- fpi[i].SrcReg[2].Index = window_index;
- fpi[i].SrcReg[2].Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
- i++;
-
- for (; i < compiler->program->NumInstructions; ++i) {
- int reg;
- for (reg = 0; reg < 3; reg++) {
- if (fpi[i].SrcReg[reg].File == PROGRAM_INPUT &&
- fpi[i].SrcReg[reg].Index == FRAG_ATTRIB_WPOS) {
- fpi[i].SrcReg[reg].File = PROGRAM_TEMPORARY;
- fpi[i].SrcReg[reg].Index = tempregi;
- }
- }
- }
+ rc_transform_fragment_wpos(&compiler->Base, FRAG_ATTRIB_WPOS, fp->wpos_attr);
}
-
/**
* Rewrite fragment.fogcoord to use a texture coordinate slot.
* Note that fogcoord is forced into an X001 pattern, and this enforcement
@@ -170,205 +122,117 @@ static void insert_WPOS_trailer(struct r300_fragment_program_compiler *compiler)
*
* See also the counterpart rewriting for vertex programs.
*/
-static void rewriteFog(struct r300_fragment_program_compiler *compiler)
+static void rewriteFog(struct r300_fragment_program_compiler *compiler, struct r300_fragment_program * fp)
{
- struct r300_fragment_program *fp = compiler->fp;
- GLuint InputsRead;
+ struct prog_src_register src;
int i;
- InputsRead = fp->Base->InputsRead;
-
- if (!(InputsRead & FRAG_BIT_FOGC)) {
+ if (!(compiler->Base.Program.InputsRead & FRAG_BIT_FOGC)) {
fp->fog_attr = FRAG_ATTRIB_MAX;
return;
}
for (i = FRAG_ATTRIB_TEX0; i <= FRAG_ATTRIB_TEX7; ++i)
{
- if (!(InputsRead & (1 << i))) {
- InputsRead &= ~(1 << FRAG_ATTRIB_FOGC);
- InputsRead |= 1 << i;
- fp->Base->InputsRead = InputsRead;
+ if (!(compiler->Base.Program.InputsRead & (1 << i))) {
fp->fog_attr = i;
break;
}
}
- {
- struct prog_instruction *inst;
-
- inst = compiler->program->Instructions;
- while (inst->Opcode != OPCODE_END) {
- const int src_regs = _mesa_num_inst_src_regs(inst->Opcode);
- for (i = 0; i < src_regs; ++i) {
- if (inst->SrcReg[i].File == PROGRAM_INPUT && inst->SrcReg[i].Index == FRAG_ATTRIB_FOGC) {
- inst->SrcReg[i].Index = fp->fog_attr;
- inst->SrcReg[i].Swizzle = combine_swizzles(
- MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE),
- inst->SrcReg[i].Swizzle);
- }
- }
- ++inst;
- }
- }
+ memset(&src, 0, sizeof(src));
+ src.File = PROGRAM_INPUT;
+ src.Index = fp->fog_attr;
+ src.Swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, SWIZZLE_ZERO, SWIZZLE_ONE);
+ rc_move_input(&compiler->Base, FRAG_ATTRIB_FOGC, src);
}
-static GLuint build_dtm(GLuint depthmode)
-{
- switch(depthmode) {
- default:
- case GL_LUMINANCE: return 0;
- case GL_INTENSITY: return 1;
- case GL_ALPHA: return 2;
- }
-}
-
-static GLuint build_func(GLuint comparefunc)
-{
- return comparefunc - GL_NEVER;
-}
/**
- * Collect all external state that is relevant for compiling the given
- * fragment program.
+ * Reserve hardware temporary registers for the program inputs.
+ *
+ * @note This allocation is performed explicitly, because the order of inputs
+ * is determined by the RS hardware.
*/
-static void build_state(
- r300ContextPtr r300,
- struct gl_fragment_program *fp,
- struct r300_fragment_program_external_state *state)
+static void allocate_hw_inputs(
+ struct r300_fragment_program_compiler * c,
+ void (*allocate)(void * data, unsigned input, unsigned hwreg),
+ void * mydata)
{
- int unit;
-
- _mesa_bzero(state, sizeof(*state));
-
- for(unit = 0; unit < 16; ++unit) {
- if (fp->Base.ShadowSamplers & (1 << unit)) {
- struct gl_texture_object* tex = r300->radeon.glCtx->Texture.Unit[unit]._Current;
-
- state->unit[unit].depth_texture_mode = build_dtm(tex->DepthMode);
- state->unit[unit].texture_compare_func = build_func(tex->CompareFunc);
- }
+ GLuint InputsRead = c->Base.Program.InputsRead;
+ int i;
+ GLuint hwindex = 0;
+
+ /* Primary colour */
+ if (InputsRead & FRAG_BIT_COL0)
+ allocate(mydata, FRAG_ATTRIB_COL0, hwindex++);
+ InputsRead &= ~FRAG_BIT_COL0;
+
+ /* Secondary color */
+ if (InputsRead & FRAG_BIT_COL1)
+ allocate(mydata, FRAG_ATTRIB_COL1, hwindex++);
+ InputsRead &= ~FRAG_BIT_COL1;
+
+ /* Texcoords */
+ for (i = 0; i < 8; i++) {
+ if (InputsRead & (FRAG_BIT_TEX0 << i))
+ allocate(mydata, FRAG_ATTRIB_TEX0+i, hwindex++);
}
-}
+ InputsRead &= ~FRAG_BITS_TEX_ANY;
-static void rewrite_depth_out(struct gl_program *prog)
-{
- struct prog_instruction *inst;
+ /* Fogcoords treated as a texcoord */
+ if (InputsRead & FRAG_BIT_FOGC)
+ allocate(mydata, FRAG_ATTRIB_FOGC, hwindex++);
+ InputsRead &= ~FRAG_BIT_FOGC;
- for (inst = prog->Instructions; inst->Opcode != OPCODE_END; ++inst) {
- if (inst->DstReg.File != PROGRAM_OUTPUT || inst->DstReg.Index != FRAG_RESULT_DEPTH)
- continue;
+ /* fragment position treated as a texcoord */
+ if (InputsRead & FRAG_BIT_WPOS)
+ allocate(mydata, FRAG_ATTRIB_WPOS, hwindex++);
+ InputsRead &= ~FRAG_BIT_WPOS;
- if (inst->DstReg.WriteMask & WRITEMASK_Z) {
- inst->DstReg.WriteMask = WRITEMASK_W;
- } else {
- inst->DstReg.WriteMask = 0;
- continue;
- }
-
- switch (inst->Opcode) {
- case OPCODE_FRC:
- case OPCODE_MOV:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- break;
- case OPCODE_ADD:
- case OPCODE_MAX:
- case OPCODE_MIN:
- case OPCODE_MUL:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
- break;
- case OPCODE_CMP:
- case OPCODE_MAD:
- inst->SrcReg[0] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[0]);
- inst->SrcReg[1] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[1]);
- inst->SrcReg[2] = lmul_swizzle(SWIZZLE_ZZZZ, inst->SrcReg[2]);
- break;
- default:
- // Scalar instructions needn't be reswizzled
- break;
- }
- }
+ /* Anything else */
+ if (InputsRead)
+ rc_error(&c->Base, "Don't know how to handle inputs 0x%x\n", InputsRead);
}
-void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp)
+
+static void translate_fragment_program(GLcontext *ctx, struct r300_fragment_program_cont *cont, struct r300_fragment_program *fp)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_fragment_program_compiler compiler;
- compiler.r300 = r300;
- compiler.fp = fp;
- compiler.code = &fp->code;
- compiler.program = fp->Base;
+ rc_init(&compiler.Base);
+ compiler.Base.Debug = (RADEON_DEBUG & RADEON_PIXEL) ? GL_TRUE : GL_FALSE;
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- fflush(stdout);
+ compiler.code = &fp->code;
+ compiler.state = fp->state;
+ compiler.is_r500 = (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) ? GL_TRUE : GL_FALSE;
+ compiler.OutputDepth = FRAG_RESULT_DEPTH;
+ compiler.OutputColor = FRAG_RESULT_COLOR;
+ compiler.AllocateHwInputs = &allocate_hw_inputs;
+
+ if (compiler.Base.Debug) {
+ fflush(stderr);
_mesa_printf("Fragment Program: Initial program:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
+ _mesa_print_program(&cont->Base.Base);
+ fflush(stderr);
}
- insert_WPOS_trailer(&compiler);
-
- rewriteFog(&compiler);
-
- rewrite_depth_out(compiler.program);
-
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct radeon_program_transformation transformations[] = {
- { &r500_transform_TEX, &compiler },
- { &radeonTransformALU, 0 },
- { &radeonTransformDeriv, 0 },
- { &radeonTransformTrigScale, 0 }
- };
- radeonLocalTransform(ctx, compiler.program, 4, transformations);
- } else {
- struct radeon_program_transformation transformations[] = {
- { &r300_transform_TEX, &compiler },
- { &radeonTransformALU, 0 },
- { &radeonTransformTrigSimple, 0 }
- };
- radeonLocalTransform(ctx, compiler.program, 3, transformations);
- }
-
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Fragment Program: After native rewrite:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
- }
+ rc_mesa_to_rc_program(&compiler.Base, &cont->Base.Base);
- if (r300->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
- struct radeon_nqssadce_descr nqssadce = {
- .Init = &nqssadce_init,
- .IsNativeSwizzle = &r500FPIsNativeSwizzle,
- .BuildSwizzle = &r500FPBuildSwizzle
- };
- radeonNqssaDce(ctx, compiler.program, &nqssadce);
- } else {
- struct radeon_nqssadce_descr nqssadce = {
- .Init = &nqssadce_init,
- .IsNativeSwizzle = &r300FPIsNativeSwizzle,
- .BuildSwizzle = &r300FPBuildSwizzle
- };
- radeonNqssaDce(ctx, compiler.program, &nqssadce);
- }
+ insert_WPOS_trailer(&compiler, fp);
- if (RADEON_DEBUG & DEBUG_PIXEL) {
- _mesa_printf("Compiler: after NqSSA-DCE:\n");
- _mesa_print_program(compiler.program);
- fflush(stdout);
- }
+ rewriteFog(&compiler, fp);
- if (!r300->vtbl.BuildFragmentProgramHwCode(&compiler))
- fp->error = GL_TRUE;
+ r3xx_compile_fragment_program(&compiler);
+ fp->error = compiler.Base.Error;
- fp->translated = GL_TRUE;
+ fp->InputsRead = compiler.Base.Program.InputsRead;
- if (fp->error || (RADEON_DEBUG & DEBUG_PIXEL))
- r300->vtbl.FragmentProgramDump(&fp->code);
+ rc_destroy(&compiler.Base);
}
-struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx)
+struct r300_fragment_program *r300SelectAndTranslateFragmentShader(GLcontext *ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_fragment_program_cont *fp_list;
@@ -389,11 +253,11 @@ struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx)
fp = _mesa_calloc(sizeof(struct r300_fragment_program));
fp->state = state;
- fp->translated = GL_FALSE;
- fp->Base = _mesa_clone_program(ctx, &ctx->FragmentProgram._Current->Base);
fp->next = fp_list->progs;
fp_list->progs = fp;
+ translate_fragment_program(ctx, fp_list, fp);
+
return r300->selected_fp = fp;
}
diff --git a/src/mesa/drivers/dri/r300/r300_fragprog_common.h b/src/mesa/drivers/dri/r300/r300_fragprog_common.h
index 5e103ee408..3d64c08cee 100644
--- a/src/mesa/drivers/dri/r300/r300_fragprog_common.h
+++ b/src/mesa/drivers/dri/r300/r300_fragprog_common.h
@@ -32,8 +32,6 @@
#include "r300_context.h"
-extern void r300TranslateFragmentShader(GLcontext *ctx, struct r300_fragment_program *fp);
-
-struct r300_fragment_program *r300SelectFragmentShader(GLcontext *ctx);
+struct r300_fragment_program *r300SelectAndTranslateFragmentShader(GLcontext *ctx);
#endif
diff --git a/src/mesa/drivers/dri/r300/r300_ioctl.c b/src/mesa/drivers/dri/r300/r300_ioctl.c
index ddabd53992..5cb04e2bb6 100644
--- a/src/mesa/drivers/dri/r300/r300_ioctl.c
+++ b/src/mesa/drivers/dri/r300/r300_ioctl.c
@@ -44,6 +44,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/imports.h"
#include "main/macros.h"
#include "main/context.h"
+#include "main/simple_list.h"
#include "swrast/swrast.h"
#include "radeon_common.h"
@@ -55,7 +56,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_vertprog.h"
#include "radeon_reg.h"
#include "r300_emit.h"
-#include "r300_fragprog.h"
#include "r300_context.h"
#include "vblank.h"
@@ -66,6 +66,66 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define CLEARBUFFER_DEPTH 0x2
#define CLEARBUFFER_STENCIL 0x4
+#if 1
+
+/**
+ * Fragment program helper macros
+ */
+
+/* Produce unshifted source selectors */
+#define FP_TMP(idx) (idx)
+#define FP_CONST(idx) ((idx) | (1 << 5))
+
+/* Produce source/dest selector dword */
+#define FP_SELC_MASK_NO 0
+#define FP_SELC_MASK_X 1
+#define FP_SELC_MASK_Y 2
+#define FP_SELC_MASK_XY 3
+#define FP_SELC_MASK_Z 4
+#define FP_SELC_MASK_XZ 5
+#define FP_SELC_MASK_YZ 6
+#define FP_SELC_MASK_XYZ 7
+
+#define FP_SELC(destidx,regmask,outmask,src0,src1,src2) \
+ (((destidx) << R300_ALU_DSTC_SHIFT) | \
+ (FP_SELC_MASK_##regmask << 23) | \
+ (FP_SELC_MASK_##outmask << 26) | \
+ ((src0) << R300_ALU_SRC0C_SHIFT) | \
+ ((src1) << R300_ALU_SRC1C_SHIFT) | \
+ ((src2) << R300_ALU_SRC2C_SHIFT))
+
+#define FP_SELA_MASK_NO 0
+#define FP_SELA_MASK_W 1
+
+#define FP_SELA(destidx,regmask,outmask,src0,src1,src2) \
+ (((destidx) << R300_ALU_DSTA_SHIFT) | \
+ (FP_SELA_MASK_##regmask << 23) | \
+ (FP_SELA_MASK_##outmask << 24) | \
+ ((src0) << R300_ALU_SRC0A_SHIFT) | \
+ ((src1) << R300_ALU_SRC1A_SHIFT) | \
+ ((src2) << R300_ALU_SRC2A_SHIFT))
+
+/* Produce unshifted argument selectors */
+#define FP_ARGC(source) R300_ALU_ARGC_##source
+#define FP_ARGA(source) R300_ALU_ARGA_##source
+#define FP_ABS(arg) ((arg) | (1 << 6))
+#define FP_NEG(arg) ((arg) ^ (1 << 5))
+
+/* Produce instruction dword */
+#define FP_INSTRC(opcode,arg0,arg1,arg2) \
+ (R300_ALU_OUTC_##opcode | \
+ ((arg0) << R300_ALU_ARG0C_SHIFT) | \
+ ((arg1) << R300_ALU_ARG1C_SHIFT) | \
+ ((arg2) << R300_ALU_ARG2C_SHIFT))
+
+#define FP_INSTRA(opcode,arg0,arg1,arg2) \
+ (R300_ALU_OUTA_##opcode | \
+ ((arg0) << R300_ALU_ARG0A_SHIFT) | \
+ ((arg1) << R300_ALU_ARG1A_SHIFT) | \
+ ((arg2) << R300_ALU_ARG2A_SHIFT))
+
+#endif
+
static void r300EmitClearState(GLcontext * ctx);
static void r300ClearBuffer(r300ContextPtr r300, int flags,
@@ -78,7 +138,7 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
GLuint cbpitch = 0;
r300ContextPtr rmesa = r300;
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s: buffer %p (%i,%i %ix%i)\n",
__FUNCTION__, rrb, dPriv->x, dPriv->y,
dPriv->w, dPriv->h);
@@ -109,18 +169,21 @@ static void r300ClearBuffer(r300ContextPtr r300, int flags,
}
#if 1
if (flags & (CLEARBUFFER_DEPTH | CLEARBUFFER_STENCIL)) {
- assert(rrbd != 0);
- cbpitch = (rrbd->pitch / rrbd->cpp);
+ uint32_t zbpitch = (rrbd->pitch / rrbd->cpp);
if (rrbd->bo->flags & RADEON_BO_FLAGS_MACRO_TILE){
- cbpitch |= R300_DEPTHMACROTILE_ENABLE;
+ zbpitch |= R300_DEPTHMACROTILE_ENABLE;
}
if (rrbd->bo->flags & RADEON_BO_FLAGS_MICRO_TILE){
- cbpitch |= R300_DEPTHMICROTILE_TILED;
+ zbpitch |= R300_DEPTHMICROTILE_TILED;
}
BEGIN_BATCH_NO_AUTOSTATE(6);
OUT_BATCH_REGSEQ(R300_ZB_DEPTHOFFSET, 1);
OUT_BATCH_RELOC(0, rrbd->bo, 0, 0, RADEON_GEM_DOMAIN_VRAM, 0);
- OUT_BATCH_REGVAL(R300_ZB_DEPTHPITCH, cbpitch);
+ OUT_BATCH_REGSEQ(R300_ZB_DEPTHPITCH, 1);
+ if (!r300->radeon.radeonScreen->kernel_mm)
+ OUT_BATCH(zbpitch);
+ else
+ OUT_BATCH_RELOC(zbpitch, rrbd->bo, zbpitch, 0, RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
}
#endif
@@ -444,7 +507,15 @@ static void r300EmitClearState(GLcontext * ctx)
R500_ALU_RGBA_A_SWIZ_0;
r500fp.cmd[7] = 0;
- emit_r500fp(ctx, &r500fp);
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ emit_r500fp(ctx, &r500fp);
+ } else {
+ int dwords = r500fp.check(ctx,&r500fp);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(r500fp.cmd, dwords);
+ END_BATCH();
+ }
+
}
BEGIN_BATCH(2);
@@ -488,6 +559,7 @@ static void r300EmitClearState(GLcontext * ctx)
struct radeon_state_atom vpu;
uint32_t _cmd[10];
R300_STATECHANGE(r300, pvs);
+ R300_STATECHANGE(r300, vap_flush);
R300_STATECHANGE(r300, vpi);
BEGIN_BATCH(4);
@@ -508,12 +580,12 @@ static void r300EmitClearState(GLcontext * ctx)
0, 0xf, PVS_DST_REG_OUT);
vpu.cmd[2] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y,
PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W,
- PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+ PVS_SRC_REG_INPUT, NEGATE_NONE);
vpu.cmd[3] = PVS_SRC_OPERAND(0, PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
- PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+ PVS_SRC_REG_INPUT, NEGATE_NONE);
vpu.cmd[4] = 0x0;
vpu.cmd[5] = PVS_OP_DST_OPERAND(VE_ADD, GL_FALSE, GL_FALSE, 1, 0xf,
@@ -521,17 +593,27 @@ static void r300EmitClearState(GLcontext * ctx)
vpu.cmd[6] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_X,
PVS_SRC_SELECT_Y, PVS_SRC_SELECT_Z,
PVS_SRC_SELECT_W, PVS_SRC_REG_INPUT,
-
- VSF_FLAG_NONE);
+ NEGATE_NONE);
vpu.cmd[7] = PVS_SRC_OPERAND(1, PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
PVS_SRC_SELECT_FORCE_0,
- PVS_SRC_REG_INPUT, VSF_FLAG_NONE);
+ PVS_SRC_REG_INPUT, NEGATE_NONE);
vpu.cmd[8] = 0x0;
- r300->vap_flush_needed = GL_TRUE;
- emit_vpu(ctx, &vpu);
+ if (r300->radeon.radeonScreen->kernel_mm) {
+ int dwords = r300->hw.vap_flush.check(ctx,&r300->hw.vap_flush);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(r300->hw.vap_flush.cmd, dwords);
+ END_BATCH();
+ emit_vpu(ctx, &vpu);
+ } else {
+ int dwords = vpu.check(ctx,&vpu);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(vpu.cmd, dwords);
+ END_BATCH();
+ }
+
}
}
@@ -546,7 +628,7 @@ static int r300KernelClear(GLcontext *ctx, GLuint flags)
/* Make sure it fits there. */
radeon_cs_space_reset_bos(r300->radeon.cmdbuf.cs);
-
+
if (flags & BUFFER_BIT_COLOR0) {
rrb = radeon_get_renderbuffer(&rfb->base, BUFFER_COLOR0);
radeon_cs_space_add_persistent_bo(r300->radeon.cmdbuf.cs,
@@ -623,7 +705,7 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
int i, ret;
struct gl_framebuffer *fb = ctx->DrawBuffer;
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "r300Clear\n");
if (!r300->radeon.radeonScreen->driScreen->dri2.enabled) {
@@ -685,14 +767,13 @@ static void r300Clear(GLcontext * ctx, GLbitfield mask)
}
if (swrast_mask) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n",
__FUNCTION__, swrast_mask);
_swrast_Clear(ctx, swrast_mask);
}
}
-
void r300InitIoctlFuncs(struct dd_function_table *functions)
{
functions->Clear = r300Clear;
diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h
index 357c600af9..b9ccd098dc 100644
--- a/src/mesa/drivers/dri/r300/r300_reg.h
+++ b/src/mesa/drivers/dri/r300/r300_reg.h
@@ -1022,15 +1022,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
R300_GA_COLOR_CONTROL_RGB0_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_GOURAUD | \
R300_GA_COLOR_CONTROL_RGB1_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \
R300_GA_COLOR_CONTROL_RGB2_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_GOURAUD | \
- R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \
- R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST )
+ R300_GA_COLOR_CONTROL_RGB3_SHADING_GOURAUD | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD)
/** TODO: might be candidate for removal, the GOURAUD stuff also looks buggy to me */
# define R300_RE_SHADE_MODEL_FLAT ( \
R300_GA_COLOR_CONTROL_RGB0_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA0_SHADING_FLAT | \
R300_GA_COLOR_CONTROL_RGB1_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA1_SHADING_GOURAUD | \
R300_GA_COLOR_CONTROL_RGB2_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA2_SHADING_FLAT | \
- R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD | \
- R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST )
+ R300_GA_COLOR_CONTROL_RGB3_SHADING_FLAT | R300_GA_COLOR_CONTROL_ALPHA3_SHADING_GOURAUD)
/* Specifies red & green components of fill color -- S312 format -- Backwards comp. */
#define R300_GA_SOLID_RG 0x427c
@@ -1128,6 +1126,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
/* SU Depth Offset value */
#define R300_SU_DEPTH_OFFSET 0x42c4
+#define R300_SU_REG_DEST 0x42c8
+# define R300_RASTER_PIPE_SELECT_0 (1 << 0)
+# define R300_RASTER_PIPE_SELECT_1 (1 << 1)
+# define R300_RASTER_PIPE_SELECT_2 (1 << 2)
+# define R300_RASTER_PIPE_SELECT_3 (1 << 3)
+# define R300_RASTER_PIPE_SELECT_ALL 0xf
+
/* BEGIN: Rasterization / Interpolators - many guesses */
@@ -2014,6 +2019,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define R500_FG_ALPHA_VALUE 0x4be0
# define R500_FG_ALPHA_VALUE_MASK 0x0000ffff
+#define RV530_FG_ZBREG_DEST 0x4be8
+# define RV530_FG_ZBREG_DEST_PIPE_SELECT_0 (1 << 0)
+# define RV530_FG_ZBREG_DEST_PIPE_SELECT_1 (1 << 1)
+# define RV530_FG_ZBREG_DEST_PIPE_SELECT_ALL (3 << 0)
+
/* gap */
/* Fragment program parameters in 7.16 floating point */
@@ -2303,6 +2313,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
# define R300_Z_WRITE_ENABLE (1 << 2)
# define R300_Z_SIGNED_COMPARE (1 << 3)
# define R300_STENCIL_FRONT_BACK (1 << 4)
+# define R400_ZSIGNED_MAGNITUDE (1 << 5)
+# define R500_STENCIL_REFMASK_FRONT_BACK (1 << 6)
#define R300_ZB_ZSTENCILCNTL 0x4f04
/* functions */
@@ -2667,6 +2679,24 @@ enum {
PVS_SRC_ADDR_MODE_1_SHIFT = 32,
};
+
+#define PVS_OP_DST_OPERAND(opcode, math_inst, macro_inst, reg_index, reg_writemask, reg_class) \
+ (((opcode & PVS_DST_OPCODE_MASK) << PVS_DST_OPCODE_SHIFT) \
+ | ((math_inst & PVS_DST_MATH_INST_MASK) << PVS_DST_MATH_INST_SHIFT) \
+ | ((macro_inst & PVS_DST_MACRO_INST_MASK) << PVS_DST_MACRO_INST_SHIFT) \
+ | ((reg_index & PVS_DST_OFFSET_MASK) << PVS_DST_OFFSET_SHIFT) \
+ | ((reg_writemask & 0xf) << PVS_DST_WE_X_SHIFT) /* X Y Z W */ \
+ | ((reg_class & PVS_DST_REG_TYPE_MASK) << PVS_DST_REG_TYPE_SHIFT))
+
+#define PVS_SRC_OPERAND(in_reg_index, comp_x, comp_y, comp_z, comp_w, reg_class, negate) \
+ (((in_reg_index & PVS_SRC_OFFSET_MASK) << PVS_SRC_OFFSET_SHIFT) \
+ | ((comp_x & PVS_SRC_SWIZZLE_X_MASK) << PVS_SRC_SWIZZLE_X_SHIFT) \
+ | ((comp_y & PVS_SRC_SWIZZLE_Y_MASK) << PVS_SRC_SWIZZLE_Y_SHIFT) \
+ | ((comp_z & PVS_SRC_SWIZZLE_Z_MASK) << PVS_SRC_SWIZZLE_Z_SHIFT) \
+ | ((comp_w & PVS_SRC_SWIZZLE_W_MASK) << PVS_SRC_SWIZZLE_W_SHIFT) \
+ | ((negate & 0xf) << PVS_SRC_MODIFIER_X_SHIFT) /* X Y Z W */ \
+ | ((reg_class & PVS_SRC_REG_TYPE_MASK) << PVS_SRC_REG_TYPE_SHIFT))
+
/*\}*/
/* BEGIN: Packet 3 commands */
diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c
index 08d67b73ed..3cd38753b8 100644
--- a/src/mesa/drivers/dri/r300/r300_render.c
+++ b/src/mesa/drivers/dri/r300/r300_render.c
@@ -64,6 +64,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "swrast/swrast.h"
#include "swrast_setup/swrast_setup.h"
#include "vbo/vbo.h"
+#include "vbo/vbo_split.h"
#include "tnl/tnl.h"
#include "tnl/t_vp_build.h"
#include "radeon_reg.h"
@@ -172,64 +173,45 @@ int r300NumVerts(r300ContextPtr rmesa, int num_verts, int prim)
return num_verts - verts_off;
}
-static void r300EmitElts(GLcontext * ctx, unsigned long n_elts)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- void *out;
- GLuint size;
-
- size = ((rmesa->ind_buf.is_32bit ? 4 : 2) * n_elts + 3) & ~3;
-
- radeonAllocDmaRegion(&rmesa->radeon, &rmesa->radeon.tcl.elt_dma_bo,
- &rmesa->radeon.tcl.elt_dma_offset, size, 4);
- radeon_bo_map(rmesa->radeon.tcl.elt_dma_bo, 1);
- out = rmesa->radeon.tcl.elt_dma_bo->ptr + rmesa->radeon.tcl.elt_dma_offset;
- memcpy(out, rmesa->ind_buf.ptr, size);
- radeon_bo_unmap(rmesa->radeon.tcl.elt_dma_bo);
-}
-
-static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type)
+static void r300FireEB(r300ContextPtr rmesa, int vertex_count, int type, int offset)
{
BATCH_LOCALS(&rmesa->radeon);
+ int size;
+
+ /* offset is in indices */
+ BEGIN_BATCH(10);
+ OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0);
+ if (rmesa->ind_buf.is_32bit) {
+ /* convert to bytes */
+ offset *= 4;
+ size = vertex_count;
+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
+ (vertex_count << 16) | type |
+ R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
+ } else {
+ /* convert to bytes */
+ offset *= 2;
+ size = (vertex_count + 1) >> 1;
+ OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
+ (vertex_count << 16) | type);
+ }
- r300_emit_scissor(rmesa->radeon.glCtx);
- if (vertex_count > 0) {
- int size;
-
- BEGIN_BATCH(10);
- OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_INDX_2, 0);
- if (rmesa->ind_buf.is_32bit) {
- size = vertex_count;
- OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
- ((vertex_count + 0) << 16) | type |
- R300_VAP_VF_CNTL__INDEX_SIZE_32bit);
- } else {
- size = (vertex_count + 1) >> 1;
- OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_INDICES |
- ((vertex_count + 0) << 16) | type);
- }
-
- if (!rmesa->radeon.radeonScreen->kernel_mm) {
- OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
- OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
- (R300_VAP_PORT_IDX0 >> 2));
- OUT_BATCH_RELOC(rmesa->radeon.tcl.elt_dma_offset,
- rmesa->radeon.tcl.elt_dma_bo,
- rmesa->radeon.tcl.elt_dma_offset,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- OUT_BATCH(size);
- } else {
- OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
- OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
- (R300_VAP_PORT_IDX0 >> 2));
- OUT_BATCH(rmesa->radeon.tcl.elt_dma_offset);
- OUT_BATCH(size);
- radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
- rmesa->radeon.tcl.elt_dma_bo,
- RADEON_GEM_DOMAIN_GTT, 0, 0);
- }
- END_BATCH();
+ if (!rmesa->radeon.radeonScreen->kernel_mm) {
+ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
+ OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
+ (R300_VAP_PORT_IDX0 >> 2));
+ OUT_BATCH_RELOC(0, rmesa->ind_buf.bo, rmesa->ind_buf.bo_offset + offset, RADEON_GEM_DOMAIN_GTT, 0, 0);
+ OUT_BATCH(size);
+ } else {
+ OUT_BATCH_PACKET3(R300_PACKET3_INDX_BUFFER, 2);
+ OUT_BATCH(R300_INDX_BUFFER_ONE_REG_WR | (0 << R300_INDX_BUFFER_SKIP_SHIFT) |
+ (R300_VAP_PORT_IDX0 >> 2));
+ OUT_BATCH(rmesa->ind_buf.bo_offset + offset);
+ OUT_BATCH(size);
+ radeon_cs_write_reloc(rmesa->radeon.cmdbuf.cs,
+ rmesa->ind_buf.bo, RADEON_GEM_DOMAIN_GTT, 0, 0);
}
+ END_BATCH();
}
static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
@@ -239,7 +221,7 @@ static void r300EmitAOS(r300ContextPtr rmesa, GLuint nr, GLuint offset)
int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s: nr=%d, ofs=0x%08x\n", __FUNCTION__, nr,
offset);
@@ -340,7 +322,7 @@ static void r300FireAOS(r300ContextPtr rmesa, int vertex_count, int type)
{
BATCH_LOCALS(&rmesa->radeon);
- r300_emit_scissor(rmesa->radeon.glCtx);
+ r300_emit_scissor(rmesa->radeon.glCtx);
BEGIN_BATCH(3);
OUT_BATCH_PACKET3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
OUT_BATCH(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (vertex_count << 16) | type);
@@ -359,14 +341,16 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
if (type < 0 || num_verts <= 0)
return;
- /* Make space for at least 128 dwords.
- * This is supposed to ensure that we can get all rendering
- * commands into a single command buffer.
- */
- rcommonEnsureCmdBufSpace(&rmesa->radeon, 128, __FUNCTION__);
+ if (rmesa->ind_buf.bo) {
+ GLuint first, incr, offset = 0;
+
+ if (!split_prim_inplace(prim & PRIM_MODE_MASK, &first, &incr) &&
+ num_verts > 65500) {
+ WARN_ONCE("Fixme: can't handle spliting prim %d\n", prim);
+ return;
+ }
+
- if (rmesa->ind_buf.ptr) {
- r300EmitElts(ctx, num_verts);
r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, 0);
if (rmesa->radeon.radeonScreen->kernel_mm) {
BEGIN_BATCH_NO_AUTOSTATE(2);
@@ -374,45 +358,56 @@ void r300RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
OUT_BATCH(rmesa->radeon.tcl.aos[0].count);
END_BATCH();
}
- r300FireEB(rmesa, num_verts, type);
- } else {
- r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start);
- r300FireAOS(rmesa, num_verts, type);
- }
- COMMIT_BATCH();
-}
-static void r300RunRender(GLcontext * ctx, struct tnl_pipeline_stage *stage)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
- int i;
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *vb = &tnl->vb;
-
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- r300UpdateShaders(rmesa);
- r300EmitArrays(ctx);
+ r300_emit_scissor(rmesa->radeon.glCtx);
+ while (num_verts > 0) {
+ int nr;
+ int align;
+
+ nr = MIN2(num_verts, 65535);
+ nr -= (nr - first) % incr;
+
+ /* get alignment for IB correct */
+ if (nr != num_verts) {
+ do {
+ align = nr * (rmesa->ind_buf.is_32bit ? 4 : 2);
+ if (align % 4)
+ nr -= incr;
+ } while(align % 4);
+ if (nr <= 0) {
+ WARN_ONCE("did the impossible happen? we never aligned nr to dword\n");
+ return;
+ }
+
+ }
+ r300FireEB(rmesa, nr, type, offset);
- r300UpdateShaderStates(rmesa);
+ num_verts -= nr;
+ offset += nr;
+ }
- r300EmitCacheFlush(rmesa);
- radeonEmitState(&rmesa->radeon);
+ } else {
+ GLuint first, incr, offset = 0;
- for (i = 0; i < vb->PrimitiveCount; i++) {
- GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
- GLuint start = vb->Primitive[i].start;
- GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
- r300RunRenderPrimitive(ctx, start, end, prim);
+ if (!split_prim_inplace(prim & PRIM_MODE_MASK, &first, &incr) &&
+ num_verts > 65535) {
+ WARN_ONCE("Fixme: can't handle spliting prim %d\n", prim);
+ return;
+ }
+ r300_emit_scissor(rmesa->radeon.glCtx);
+ while (num_verts > 0) {
+ int nr;
+ nr = MIN2(num_verts, 65535);
+ nr -= (nr - first) % incr;
+ r300EmitAOS(rmesa, rmesa->radeon.tcl.aos_count, start + offset);
+ r300FireAOS(rmesa, nr, type);
+ num_verts -= nr;
+ offset += nr;
+ }
}
-
- r300EmitCacheFlush(rmesa);
-
- radeonReleaseArrays(ctx, ~0);
+ COMMIT_BATCH();
}
-
static const char *getFallbackString(uint32_t bit)
{
switch (bit) {
@@ -449,10 +444,10 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
uint32_t old_fallback = rmesa->fallback;
static uint32_t fallback_warn = 0;
-
+
if (mode) {
if ((fallback_warn & bit) == 0) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
_mesa_fprintf(stderr, "WARNING! Falling back to software for %s\n", getFallbackString(bit));
fallback_warn |= bit;
}
@@ -470,7 +465,7 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
/* update only if we change from no raster fallbacks to some raster fallbacks */
if (((old_fallback & R300_RASTER_FALLBACK_MASK) == 0) &&
((bit & R300_RASTER_FALLBACK_MASK) > 0)) {
-
+
radeon_firevertices(&rmesa->radeon);
rmesa->radeon.swtcl.RenderIndex = ~0;
_swsetup_Wakeup( ctx );
@@ -480,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;
}
@@ -489,7 +484,7 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
/* update only if we have disabled all raster fallbacks */
if ((old_fallback & R300_RASTER_FALLBACK_MASK) == bit) {
_swrast_flush( ctx );
-
+
tnl->Driver.Render.Start = r300RenderStart;
tnl->Driver.Render.Finish = r300RenderFinish;
tnl->Driver.Render.PrimitiveNotify = r300RenderPrimitive;
@@ -497,38 +492,10 @@ void r300SwitchFallback(GLcontext *ctx, uint32_t bit, GLboolean mode)
tnl->Driver.Render.BuildVertices = _tnl_build_vertices;
tnl->Driver.Render.CopyPV = _tnl_copy_pv;
tnl->Driver.Render.Interp = _tnl_interp;
-
+
_tnl_invalidate_vertex_state( ctx, ~0 );
_tnl_invalidate_vertices( ctx, ~0 );
}
}
-
-}
-
-static GLboolean r300RunNonTCLRender(GLcontext * ctx,
- struct tnl_pipeline_stage *stage)
-{
- r300ContextPtr rmesa = R300_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "%s\n", __FUNCTION__);
-
- if (rmesa->fallback & R300_RASTER_FALLBACK_MASK)
- return GL_TRUE;
- if (rmesa->options.hw_tcl_enabled == GL_FALSE)
- return GL_TRUE;
-
- r300RunRender(ctx, stage);
-
- return GL_FALSE;
}
-
-const struct tnl_pipeline_stage _r300_render_stage = {
- "r300 Hardware Rasterization",
- NULL,
- NULL,
- NULL,
- NULL,
- r300RunNonTCLRender
-};
diff --git a/src/mesa/drivers/dri/r300/r300_shader.c b/src/mesa/drivers/dri/r300/r300_shader.c
index 62228a3786..a4f9db13ec 100644
--- a/src/mesa/drivers/dri/r300/r300_shader.c
+++ b/src/mesa/drivers/dri/r300/r300_shader.c
@@ -38,7 +38,7 @@ static void freeFragProgCache(GLcontext *ctx, struct r300_fragment_program_cont
while (fp) {
tmp = fp->next;
- _mesa_reference_program(ctx, &fp->Base, NULL);
+ rc_constants_destroy(&fp->code.constants);
_mesa_free(fp);
fp = tmp;
}
@@ -50,6 +50,7 @@ static void freeVertProgCache(GLcontext *ctx, struct r300_vertex_program_cont *c
while (vp) {
tmp = vp->next;
+ rc_constants_destroy(&vp->code.constants);
_mesa_reference_vertprog(ctx, &vp->Base, NULL);
_mesa_free(vp);
vp = tmp;
@@ -122,15 +123,11 @@ static GLboolean
r300IsProgramNative(GLcontext * ctx, GLenum target, struct gl_program *prog)
{
if (target == GL_FRAGMENT_PROGRAM_ARB) {
- struct r300_fragment_program *fp = r300SelectFragmentShader(ctx);
- if (!fp->translated)
- r300TranslateFragmentShader(ctx, fp);
+ struct r300_fragment_program *fp = r300SelectAndTranslateFragmentShader(ctx);
return !fp->error;
} else {
- struct r300_vertex_program *vp = r300SelectVertexShader(ctx);
- if (!vp->translated)
- r300TranslateVertexShader(vp);
+ struct r300_vertex_program *vp = r300SelectAndTranslateVertexShader(ctx);
return !vp->error;
}
diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c
index 12fbf281d9..3060f49aaf 100644
--- a/src/mesa/drivers/dri/r300/r300_state.c
+++ b/src/mesa/drivers/dri/r300/r300_state.c
@@ -62,8 +62,6 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_emit.h"
#include "r300_tex.h"
#include "r300_fragprog_common.h"
-#include "r300_fragprog.h"
-#include "r500_fragprog.h"
#include "r300_render.h"
#include "r300_vertprog.h"
@@ -373,6 +371,7 @@ static void r300ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
ip = (GLint *)ctx->Transform._ClipUserPlane[p];
+ R300_STATECHANGE( rmesa, vap_flush );
R300_STATECHANGE( rmesa, vpucp[p] );
rmesa->hw.vpucp[p].cmd[R300_VPUCP_X] = ip[0];
rmesa->hw.vpucp[p].cmd[R300_VPUCP_Y] = ip[1];
@@ -458,7 +457,7 @@ static GLboolean current_fragment_program_writes_depth(GLcontext* ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
- return ctx->FragmentProgram._Current && r300->selected_fp->writes_depth;
+ return ctx->FragmentProgram._Current && r300->selected_fp->code.writes_depth;
}
static void r300SetEarlyZState(GLcontext * ctx)
@@ -473,6 +472,8 @@ static void r300SetEarlyZState(GLcontext * ctx)
topZ = R300_ZTOP_DISABLE;
else if (ctx->FragmentProgram._Current && ctx->FragmentProgram._Current->UsesKill)
topZ = R300_ZTOP_DISABLE;
+ else if (r300->radeon.query.current)
+ topZ = R300_ZTOP_DISABLE;
if (topZ != r300->hw.zstencil_format.cmd[2]) {
/* Note: This completely reemits the stencil format.
@@ -589,7 +590,9 @@ static void r300SetDepthState(GLcontext * ctx)
r300ContextPtr r300 = R300_CONTEXT(ctx);
R300_STATECHANGE(r300, zs);
- r300->hw.zs.cmd[R300_ZS_CNTL_0] &= R300_STENCIL_ENABLE|R300_STENCIL_FRONT_BACK;
+ r300->hw.zs.cmd[R300_ZS_CNTL_0] &= (R300_STENCIL_ENABLE |
+ R300_STENCIL_FRONT_BACK |
+ R500_STENCIL_REFMASK_FRONT_BACK);
r300->hw.zs.cmd[R300_ZS_CNTL_1] &= ~(R300_ZS_MASK << R300_Z_FUNC_SHIFT);
if (ctx->Depth.Test) {
@@ -603,11 +606,16 @@ static void r300SetDepthState(GLcontext * ctx)
static void r300CatchStencilFallback(GLcontext *ctx)
{
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
const unsigned back = ctx->Stencil._BackFace;
- if (ctx->Stencil._Enabled && (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
- || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[back]
- || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[back])) {
+ if (rmesa->radeon.radeonScreen->kernel_mm &&
+ (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515)) {
+ r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_FALSE);
+ } else if (ctx->Stencil._Enabled &&
+ (ctx->Stencil.Ref[0] != ctx->Stencil.Ref[back]
+ || ctx->Stencil.ValueMask[0] != ctx->Stencil.ValueMask[back]
+ || ctx->Stencil.WriteMask[0] != ctx->Stencil.WriteMask[back])) {
r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_TRUE);
} else {
r300SwitchFallback(ctx, R300_FALLBACK_STENCIL_TWOSIDE, GL_FALSE);
@@ -914,11 +922,24 @@ static void r300StencilFuncSeparate(GLcontext * ctx, GLenum face,
rmesa->hw.zs.cmd[R300_ZS_CNTL_1] |=
(flag << R300_S_BACK_FUNC_SHIFT);
rmesa->hw.zs.cmd[R300_ZS_CNTL_2] |= refmask;
+
+ if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ rmesa->hw.zs.cmd[R300_ZS_CNTL_0] |= R500_STENCIL_REFMASK_FRONT_BACK;
+ R300_STATECHANGE(rmesa, zsb);
+ refmask = ((ctx->Stencil.Ref[back] & 0xff) << R300_STENCILREF_SHIFT)
+ | ((ctx->Stencil.ValueMask[back] & 0xff) << R300_STENCILMASK_SHIFT);
+
+ rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] &=
+ ~((R300_STENCILREF_MASK << R300_STENCILREF_SHIFT) |
+ (R300_STENCILREF_MASK << R300_STENCILMASK_SHIFT));
+ rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] |= refmask;
+ }
}
static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ const unsigned back = ctx->Stencil._BackFace;
r300CatchStencilFallback(ctx);
@@ -930,6 +951,13 @@ static void r300StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask)
(ctx->Stencil.
WriteMask[0] & R300_STENCILREF_MASK) <<
R300_STENCILWRITEMASK_SHIFT;
+ if (rmesa->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV515) {
+ R300_STATECHANGE(rmesa, zsb);
+ rmesa->hw.zsb.cmd[R300_ZSB_CNTL_0] |=
+ (ctx->Stencil.
+ WriteMask[back] & R300_STENCILREF_MASK) <<
+ R300_STENCILWRITEMASK_SHIFT;
+ }
}
static void r300StencilOpSeparate(GLcontext * ctx, GLenum face,
@@ -1046,53 +1074,6 @@ void r300UpdateViewportOffset(GLcontext * ctx)
radeonUpdateScissor(ctx);
}
-static void
-r300FetchStateParameter(GLcontext * ctx,
- const gl_state_index state[STATE_LENGTH],
- GLfloat * value)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
-
- switch (state[0]) {
- case STATE_INTERNAL:
- switch (state[1]) {
- case STATE_R300_WINDOW_DIMENSION: {
- __DRIdrawablePrivate * drawable = radeon_get_drawable(&r300->radeon);
- value[0] = drawable->w * 0.5f; /* width*0.5 */
- value[1] = drawable->h * 0.5f; /* height*0.5 */
- value[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
- value[3] = 1.0F; /* not used */
- break;
- }
-
- case STATE_R300_TEXRECT_FACTOR:{
- struct gl_texture_object *t =
- ctx->Texture.Unit[state[2]].CurrentTex[TEXTURE_RECT_INDEX];
-
- if (t && t->Image[0][t->BaseLevel]) {
- struct gl_texture_image *image =
- t->Image[0][t->BaseLevel];
- value[0] = 1.0 / image->Width2;
- value[1] = 1.0 / image->Height2;
- } else {
- value[0] = 1.0;
- value[1] = 1.0;
- }
- value[2] = 1.0;
- value[3] = 1.0;
- break;
- }
-
- default:
- break;
- }
- break;
-
- default:
- break;
- }
-}
-
/**
* Update R300's own internal state parameters.
* For now just STATE_R300_WINDOW_DIMENSION
@@ -1101,7 +1082,6 @@ static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct gl_program_parameter_list *paramList;
- GLuint i;
if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
return;
@@ -1109,21 +1089,12 @@ static void r300UpdateStateParameters(GLcontext * ctx, GLuint new_state)
if (!ctx->FragmentProgram._Current || !rmesa->selected_fp)
return;
- paramList = rmesa->selected_fp->Base->Parameters;
+ paramList = ctx->FragmentProgram._Current->Base.Parameters;
if (!paramList)
return;
_mesa_load_state_parameters(ctx, paramList);
-
- for (i = 0; i < paramList->NumParameters; i++) {
- if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR) {
- r300FetchStateParameter(ctx,
- paramList->Parameters[i].
- StateIndexes,
- paramList->ParameterValues[i]);
- }
- }
}
/* =============================================================
@@ -1230,7 +1201,7 @@ static void r300SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
- struct r300_fragment_program_code *code = &r300->selected_fp->code.r300;
+ struct r300_fragment_program_code *code = &r300->selected_fp->code.code.r300;
R300_STATECHANGE(r300, fpt);
@@ -1272,7 +1243,7 @@ static void r500SetupFragmentShaderTextures(GLcontext *ctx, int *tmu_mappings)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
int i;
- struct r500_fragment_program_code *code = &r300->selected_fp->code.r500;
+ struct r500_fragment_program_code *code = &r300->selected_fp->code.code.r500;
/* find all the texture instructions and relocate the texture units */
for (i = 0; i < code->inst_end + 1; i++) {
@@ -1312,6 +1283,7 @@ static GLuint translate_lod_bias(GLfloat bias)
return (((GLuint)b) << R300_LOD_BIAS_SHIFT) & R300_LOD_BIAS_MASK;
}
+
static void r300SetupTextures(GLcontext * ctx)
{
int i, mtu;
@@ -1334,7 +1306,7 @@ static void r300SetupTextures(GLcontext * ctx)
r300->hw.txe.cmd[R300_TXE_ENABLE] = 0x0;
mtu = r300->radeon.glCtx->Const.MaxTextureUnits;
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "mtu=%d\n", mtu);
if (mtu > R300_MAX_TEXTURE_UNITS) {
@@ -1359,7 +1331,7 @@ static void r300SetupTextures(GLcontext * ctx)
t->pp_txformat & 0xff);
}
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr,
"Activating texture unit %d\n", i);
@@ -1404,6 +1376,28 @@ static void r300SetupTextures(GLcontext * ctx)
}
}
+ /* R3xx and R4xx chips require that the texture unit corresponding to
+ * KIL instructions is really enabled.
+ *
+ * We do some fakery here and in the state atom emit logic to enable
+ * the texture without tripping up the CS checker in the kernel.
+ */
+ if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
+ if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
+ last_hw_tmu++;
+
+ r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
+
+ r300->hw.tex.border_color.cmd[R300_TEX_VALUE_0] = 0;
+ r300->hw.tex.chroma_key.cmd[R300_TEX_VALUE_0] = 0;
+ r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
+ r300->hw.tex.filter_1.cmd[R300_TEX_VALUE_0] = 0;
+ r300->hw.tex.size.cmd[R300_TEX_VALUE_0] = 0; /* 1x1 texture */
+ r300->hw.tex.format.cmd[R300_TEX_VALUE_0] = 0; /* A8 format */
+ r300->hw.tex.pitch.cmd[R300_TEX_VALUE_0] = 0;
+ }
+ }
+
r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, last_hw_tmu + 1);
r300->hw.tex.filter_1.cmd[R300_TEX_CMD_0] =
@@ -1421,19 +1415,9 @@ static void r300SetupTextures(GLcontext * ctx)
r300->hw.tex.border_color.cmd[R300_TEX_CMD_0] =
cmdpacket0(r300->radeon.radeonScreen, R300_TX_BORDER_COLOR_0, last_hw_tmu + 1);
- if (r300->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV515) {
- if (ctx->FragmentProgram._Current->UsesKill && last_hw_tmu < 0) {
- // The KILL operation requires the first texture unit
- // to be enabled.
- r300->hw.txe.cmd[R300_TXE_ENABLE] |= 1;
- r300->hw.tex.filter.cmd[R300_TEX_VALUE_0] = 0;
- r300->hw.tex.filter.cmd[R300_TEX_CMD_0] =
- cmdpacket0(r300->radeon.radeonScreen, R300_TX_FILTER0_0, 1);
- }
- }
r300->vtbl.SetupFragmentShaderTextures(ctx, tmu_mappings);
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "TX_ENABLE: %08x last_hw_tmu=%d\n",
r300->hw.txe.cmd[R300_TXE_ENABLE], last_hw_tmu);
}
@@ -1460,11 +1444,11 @@ static void r300SetupRSUnit(GLcontext * ctx)
hw_tcl_on = r300->options.hw_tcl_enabled;
if (hw_tcl_on)
- OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
+ OutputsWritten.vp_outputs = r300->selected_vp->code.OutputsWritten;
else
RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
- InputsRead = r300->selected_fp->Base->InputsRead;
+ InputsRead = r300->selected_fp->InputsRead;
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
@@ -1554,11 +1538,11 @@ static void r500SetupRSUnit(GLcontext * ctx)
hw_tcl_on = r300->options.hw_tcl_enabled;
if (hw_tcl_on)
- OutputsWritten.vp_outputs = r300->selected_vp->Base->Base.OutputsWritten;
+ OutputsWritten.vp_outputs = r300->selected_vp->code.OutputsWritten;
else
RENDERINPUTS_COPY(OutputsWritten.index_bitset, r300->render_inputs_bitset);
- InputsRead = r300->selected_fp->Base->InputsRead;
+ InputsRead = r300->selected_fp->InputsRead;
R300_STATECHANGE(r300, ri);
R300_STATECHANGE(r300, rc);
@@ -1703,7 +1687,7 @@ void r300VapCntl(r300ContextPtr rmesa, GLuint input_count,
static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(cap),
state ? "GL_TRUE" : "GL_FALSE");
@@ -1780,7 +1764,7 @@ static void r300ResetHwState(r300ContextPtr r300)
has_tcl = r300->options.hw_tcl_enabled;
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
radeon_firevertices(&r300->radeon);
@@ -1997,9 +1981,7 @@ void r300UpdateShaders(r300ContextPtr rmesa)
{
struct r300_fragment_program *fp;
- fp = r300SelectFragmentShader(ctx);
- if (!fp->translated)
- r300TranslateFragmentShader(ctx, fp);
+ fp = r300SelectAndTranslateFragmentShader(ctx);
r300SwitchFallback(ctx, R300_FALLBACK_FRAGMENT_PROGRAM, fp->error);
}
@@ -2024,9 +2006,7 @@ void r300UpdateShaders(r300ContextPtr rmesa)
}
}
- vp = r300SelectVertexShader(ctx);
- if (!vp->translated)
- r300TranslateVertexShader(vp);
+ vp = r300SelectAndTranslateVertexShader(ctx);
r300SwitchFallback(ctx, R300_FALLBACK_VERTEX_PROGRAM, vp->error);
}
@@ -2035,24 +2015,61 @@ void r300UpdateShaders(r300ContextPtr rmesa)
rmesa->radeon.NewGLState = 0;
}
-static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx,
- struct gl_program *program, struct prog_src_register srcreg)
+static const GLfloat *get_fragmentprogram_constant(GLcontext *ctx, GLuint index, GLfloat * buffer)
{
static const GLfloat dummy[4] = { 0, 0, 0, 0 };
+ r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ struct rc_constant * rcc = &rmesa->selected_fp->code.constants.Constants[index];
+
+ switch(rcc->Type) {
+ case RC_CONSTANT_EXTERNAL:
+ return ctx->FragmentProgram._Current->Base.Parameters->ParameterValues[rcc->u.External];
+ case RC_CONSTANT_IMMEDIATE:
+ return rcc->u.Immediate;
+ case RC_CONSTANT_STATE:
+ switch(rcc->u.State[0]) {
+ case RC_STATE_SHADOW_AMBIENT: {
+ const int unit = (int) rcc->u.State[1];
+ const struct gl_texture_object *texObj = ctx->Texture.Unit[unit]._Current;
+ if (texObj) {
+ buffer[0] =
+ buffer[1] =
+ buffer[2] =
+ buffer[3] = texObj->CompareFailValue;
+ }
+ return buffer;
+ }
- switch(srcreg.File) {
- case PROGRAM_LOCAL_PARAM:
- return program->LocalParams[srcreg.Index];
- case PROGRAM_ENV_PARAM:
- return ctx->FragmentProgram.Parameters[srcreg.Index];
- case PROGRAM_STATE_VAR:
- case PROGRAM_NAMED_PARAM:
- case PROGRAM_CONSTANT:
- return program->Parameters->ParameterValues[srcreg.Index];
- default:
- _mesa_problem(ctx, "get_fragmentprogram_constant: Unknown\n");
- return dummy;
+ case RC_STATE_R300_WINDOW_DIMENSION: {
+ __DRIdrawablePrivate * drawable = radeon_get_drawable(&rmesa->radeon);
+ buffer[0] = drawable->w * 0.5f; /* width*0.5 */
+ buffer[1] = drawable->h * 0.5f; /* height*0.5 */
+ buffer[2] = 0.5F; /* for moving range [-1 1] -> [0 1] */
+ buffer[3] = 1.0F; /* not used */
+ return buffer;
+ }
+
+ case RC_STATE_R300_TEXRECT_FACTOR: {
+ struct gl_texture_object *t =
+ ctx->Texture.Unit[rcc->u.State[1]].CurrentTex[TEXTURE_RECT_INDEX];
+
+ if (t && t->Image[0][t->BaseLevel]) {
+ struct gl_texture_image *image =
+ t->Image[0][t->BaseLevel];
+ buffer[0] = 1.0 / image->Width2;
+ buffer[1] = 1.0 / image->Height2;
+ } else {
+ buffer[0] = 1.0;
+ buffer[1] = 1.0;
+ }
+ buffer[2] = 1.0;
+ buffer[3] = 1.0;
+ return buffer;
+ }
+ }
}
+
+ return dummy;
}
@@ -2061,9 +2078,9 @@ static void r300SetupPixelShader(GLcontext *ctx)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
struct r300_fragment_program *fp = rmesa->selected_fp;
struct r300_fragment_program_code *code;
- int i, k;
+ int i;
- code = &fp->code.r300;
+ code = &fp->code.code.r300;
R300_STATECHANGE(rmesa, fpi[0]);
R300_STATECHANGE(rmesa, fpi[1]);
@@ -2074,38 +2091,24 @@ static void r300SetupPixelShader(GLcontext *ctx)
rmesa->hw.fpi[2].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_INST_0, code->alu.length);
rmesa->hw.fpi[3].cmd[R300_FPI_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_US_ALU_ALPHA_ADDR_0, code->alu.length);
for (i = 0; i < code->alu.length; i++) {
- rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst0;
- rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst1;
- rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst2;
- rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].inst3;
+ rmesa->hw.fpi[0].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].rgb_inst;
+ rmesa->hw.fpi[1].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].rgb_addr;
+ rmesa->hw.fpi[2].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].alpha_inst;
+ rmesa->hw.fpi[3].cmd[R300_FPI_INSTR_0 + i] = code->alu.inst[i].alpha_addr;
}
R300_STATECHANGE(rmesa, fp);
- rmesa->hw.fp.cmd[R300_FP_CNTL0] = code->cur_node | (code->first_node_has_tex << 3);
- rmesa->hw.fp.cmd[R300_FP_CNTL1] = code->max_temp_idx;
- rmesa->hw.fp.cmd[R300_FP_CNTL2] =
- (0 << R300_PFS_CNTL_ALU_OFFSET_SHIFT) |
- ((code->alu.length-1) << R300_PFS_CNTL_ALU_END_SHIFT) |
- (0 << R300_PFS_CNTL_TEX_OFFSET_SHIFT) |
- ((code->tex.length ? code->tex.length-1 : 0) << R300_PFS_CNTL_TEX_END_SHIFT);
- /* I just want to say, the way these nodes are stored.. weird.. */
- for (i = 0, k = (4 - (code->cur_node + 1)); i < 4; i++, k++) {
- if (i < (code->cur_node + 1)) {
- rmesa->hw.fp.cmd[R300_FP_NODE0 + k] =
- (code->node[i].alu_offset << R300_ALU_START_SHIFT) |
- (code->node[i].alu_end << R300_ALU_SIZE_SHIFT) |
- (code->node[i].tex_offset << R300_TEX_START_SHIFT) |
- (code->node[i].tex_end << R300_TEX_SIZE_SHIFT) |
- code->node[i].flags;
- } else {
- rmesa->hw.fp.cmd[R300_FP_NODE0 + (3 - i)] = 0;
- }
- }
+ rmesa->hw.fp.cmd[R300_FP_CNTL0] = code->config;
+ rmesa->hw.fp.cmd[R300_FP_CNTL1] = code->pixsize;
+ rmesa->hw.fp.cmd[R300_FP_CNTL2] = code->code_offset;
+ for (i = 0; i < 4; i++)
+ rmesa->hw.fp.cmd[R300_FP_NODE0 + i] = code->code_addr[i];
R300_STATECHANGE(rmesa, fpp);
- rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, code->const_nr * 4);
- for (i = 0; i < code->const_nr; i++) {
- const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
+ rmesa->hw.fpp.cmd[R300_FPP_CMD_0] = cmdpacket0(rmesa->radeon.radeonScreen, R300_PFS_PARAM_0_X, fp->code.constants.Count * 4);
+ for (i = 0; i < fp->code.constants.Count; i++) {
+ GLfloat buffer[4];
+ const GLfloat *constant = get_fragmentprogram_constant(ctx, i, buffer);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat24(constant[0]);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat24(constant[1]);
rmesa->hw.fpp.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat24(constant[2]);
@@ -2137,19 +2140,19 @@ static void r500SetupPixelShader(GLcontext *ctx)
((drm_r300_cmd_header_t *) rmesa->hw.r500fp.cmd)->r500fp.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.r500fp_const.cmd)->r500fp.count = 0;
- code = &fp->code.r500;
+ code = &fp->code.code.r500;
R300_STATECHANGE(rmesa, fp);
rmesa->hw.fp.cmd[R500_FP_PIXSIZE] = code->max_temp_idx;
rmesa->hw.fp.cmd[R500_FP_CODE_ADDR] =
- R500_US_CODE_START_ADDR(code->inst_offset) |
+ R500_US_CODE_START_ADDR(0) |
R500_US_CODE_END_ADDR(code->inst_end);
rmesa->hw.fp.cmd[R500_FP_CODE_RANGE] =
- R500_US_CODE_RANGE_ADDR(code->inst_offset) |
+ R500_US_CODE_RANGE_ADDR(0) |
R500_US_CODE_RANGE_SIZE(code->inst_end);
rmesa->hw.fp.cmd[R500_FP_CODE_OFFSET] =
- R500_US_CODE_OFFSET_ADDR(0); /* FIXME when we add flow control */
+ R500_US_CODE_OFFSET_ADDR(0);
R300_STATECHANGE(rmesa, r500fp);
/* Emit our shader... */
@@ -2165,14 +2168,15 @@ static void r500SetupPixelShader(GLcontext *ctx)
bump_r500fp_count(rmesa->hw.r500fp.cmd, (code->inst_end + 1) * 6);
R300_STATECHANGE(rmesa, r500fp_const);
- for (i = 0; i < code->const_nr; i++) {
- const GLfloat *constant = get_fragmentprogram_constant(ctx, fp->Base, code->constant[i]);
+ for (i = 0; i < fp->code.constants.Count; i++) {
+ GLfloat buffer[4];
+ const GLfloat *constant = get_fragmentprogram_constant(ctx, i, buffer);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 0] = r300PackFloat32(constant[0]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 1] = r300PackFloat32(constant[1]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 2] = r300PackFloat32(constant[2]);
rmesa->hw.r500fp_const.cmd[R300_FPP_PARAM_0 + 4 * i + 3] = r300PackFloat32(constant[3]);
}
- bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, code->const_nr * 4);
+ bump_r500fp_const_count(rmesa->hw.r500fp_const.cmd, fp->code.constants.Count * 4);
}
void r300SetupVAP(GLcontext *ctx, GLuint InputsRead, GLuint OutputsWritten)
@@ -2273,6 +2277,15 @@ static void r300InvalidateState(GLcontext * ctx, GLuint new_state)
_mesa_update_draw_buffer_bounds(ctx);
R300_STATECHANGE(r300, cb);
+ R300_STATECHANGE(r300, zb);
+ }
+
+ if (new_state & (_NEW_LIGHT)) {
+ R300_STATECHANGE(r300, shade2);
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION)
+ r300->hw.shade2.cmd[1] |= R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
+ else
+ r300->hw.shade2.cmd[1] &= ~R300_GA_COLOR_CONTROL_PROVOKING_VERTEX_LAST;
}
r300->radeon.NewGLState |= new_state;
@@ -2345,13 +2358,9 @@ void r300InitShaderFunctions(r300ContextPtr r300)
r300->vtbl.SetupRSUnit = r500SetupRSUnit;
r300->vtbl.SetupPixelShader = r500SetupPixelShader;
r300->vtbl.SetupFragmentShaderTextures = r500SetupFragmentShaderTextures;
- r300->vtbl.BuildFragmentProgramHwCode = r500BuildFragmentProgramHwCode;
- r300->vtbl.FragmentProgramDump = r500FragmentProgramDump;
} else {
r300->vtbl.SetupRSUnit = r300SetupRSUnit;
r300->vtbl.SetupPixelShader = r300SetupPixelShader;
r300->vtbl.SetupFragmentShaderTextures = r300SetupFragmentShaderTextures;
- r300->vtbl.BuildFragmentProgramHwCode = r300BuildFragmentProgramHwCode;
- r300->vtbl.FragmentProgramDump = r300FragmentProgramDump;
}
}
diff --git a/src/mesa/drivers/dri/r300/r300_swtcl.c b/src/mesa/drivers/dri/r300/r300_swtcl.c
index 56ed519cf4..ee2c71e1a7 100644
--- a/src/mesa/drivers/dri/r300/r300_swtcl.c
+++ b/src/mesa/drivers/dri/r300/r300_swtcl.c
@@ -39,12 +39,13 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "r300_emit.h"
#include "r300_tex.h"
#include "r300_render.h"
+#include "main/simple_list.h"
#define EMIT_ATTR( ATTR, STYLE ) \
do { \
- rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
- rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
- rmesa->radeon.swtcl.vertex_attr_count++; \
+ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].attrib = (ATTR); \
+ rmesa->radeon.swtcl.vertex_attrs[rmesa->radeon.swtcl.vertex_attr_count].format = (STYLE); \
+ rmesa->radeon.swtcl.vertex_attr_count++; \
} while (0)
#define EMIT_PAD( N ) \
@@ -76,12 +77,16 @@ void r300ChooseSwtclVertexFormat(GLcontext *ctx, GLuint *_InputsRead, GLuint *_
GLuint InputsRead = 0;
GLuint OutputsWritten = 0;
int num_attrs = 0;
- GLuint fp_reads = rmesa->selected_fp->Base->InputsRead;
+ GLuint fp_reads = rmesa->selected_fp->InputsRead;
struct vertex_attribute *attrs = rmesa->vbuf.attribs;
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
rmesa->swtcl.coloroffset = rmesa->swtcl.specoffset = 0;
rmesa->radeon.swtcl.vertex_attr_count = 0;
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
+
/* We always want non Ndc coords format */
VB->AttribPtr[VERT_ATTRIB_POS] = VB->ClipPtr;
@@ -225,6 +230,7 @@ static void r300PrepareVertices(GLcontext *ctx)
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLuint InputsRead, OutputsWritten;
+ radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
r300ChooseSwtclVertexFormat(ctx, &InputsRead, &OutputsWritten);
r300SetupVAP(ctx, InputsRead, OutputsWritten);
@@ -238,6 +244,33 @@ static void r300PrepareVertices(GLcontext *ctx)
rmesa->radeon.swtcl.vertex_size /= 4;
}
+static void r300_predict_emit_size( r300ContextPtr rmesa )
+{
+ if (!rmesa->radeon.swtcl.emit_prediction) {
+ const int vertex_size = 7;
+ const int prim_size = 3;
+ const int cache_flush_size = 4;
+ const int pre_emit_state = 4;
+ const int scissor_size = 3;
+ const int state_size = radeonCountStateEmitSize(&rmesa->radeon);
+
+ if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
+ state_size + pre_emit_state + scissor_size
+ + vertex_size + prim_size + cache_flush_size * 2,
+ __FUNCTION__))
+ rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize(&rmesa->radeon);
+ else
+ rmesa->radeon.swtcl.emit_prediction = state_size;
+
+ rmesa->radeon.swtcl.emit_prediction += rmesa->radeon.cmdbuf.cs->cdw
+ + vertex_size + scissor_size + prim_size + cache_flush_size * 2 + pre_emit_state;
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE,
+ "%s, size %d\n",
+ __func__, rmesa->radeon.cmdbuf.cs->cdw
+ + vertex_size + scissor_size + prim_size + cache_flush_size * 2 + pre_emit_state);
+ }
+}
+
static GLuint reduced_prim[] = {
GL_POINTS,
@@ -271,11 +304,21 @@ static void r300RasterPrimitive( GLcontext *ctx, GLuint prim );
#define HAVE_POLYGONS 1
#define HAVE_ELTS 1
+static void* r300_alloc_verts(r300ContextPtr rmesa, GLuint n, GLuint size)
+{
+ void *rv;
+ do {
+ r300_predict_emit_size( rmesa );
+ rv = rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 );
+ } while (!rv);
+ return rv;
+}
+
#undef LOCAL_VARS
#undef ALLOC_VERTS
#define CTX_ARG r300ContextPtr rmesa
#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
-#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, size * 4 )
+#define ALLOC_VERTS( n, size ) r300_alloc_verts(rmesa, n, size);
#define LOCAL_VARS \
r300ContextPtr rmesa = R300_CONTEXT(ctx); \
const char *r300verts = (char *)rmesa->radeon.swtcl.verts;
@@ -461,6 +504,7 @@ static void r300ChooseRenderState( GLcontext *ctx )
r300ContextPtr rmesa = R300_CONTEXT(ctx);
GLuint index = 0;
GLuint flags = ctx->_TriangleCaps;
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
if (flags & DD_TRI_UNFILLED) index |= R300_UNFILLED_BIT;
@@ -485,9 +529,9 @@ static void r300ChooseRenderState( GLcontext *ctx )
}
}
-
void r300RenderStart(GLcontext *ctx)
{
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __func__);
r300ContextPtr rmesa = R300_CONTEXT( ctx );
r300ChooseRenderState(ctx);
@@ -500,7 +544,6 @@ void r300RenderStart(GLcontext *ctx)
r300UpdateShaderStates(rmesa);
- r300EmitCacheFlush(rmesa);
/* investigate if we can put back flush optimisation if needed */
if (rmesa->radeon.dma.flush != NULL) {
@@ -515,6 +558,7 @@ void r300RenderFinish(GLcontext *ctx)
static void r300RasterPrimitive( GLcontext *ctx, GLuint hwprim )
{
r300ContextPtr rmesa = R300_CONTEXT(ctx);
+ radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
if (rmesa->radeon.swtcl.hw_primitive != hwprim) {
R300_NEWPRIM( rmesa );
@@ -527,6 +571,7 @@ void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
rmesa->radeon.swtcl.render_primitive = prim;
+ radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
if ((prim == GL_TRIANGLES) && (ctx->_TriangleCaps & DD_TRI_UNFILLED))
return;
@@ -536,6 +581,8 @@ void r300RenderPrimitive(GLcontext *ctx, GLenum prim)
void r300ResetLineStipple(GLcontext *ctx)
{
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
}
void r300InitSwtcl(GLcontext *ctx)
@@ -543,11 +590,13 @@ void r300InitSwtcl(GLcontext *ctx)
TNLcontext *tnl = TNL_CONTEXT(ctx);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
static int firsttime = 1;
+ radeon_print(RADEON_SWRENDER, RADEON_NORMAL, "%s\n", __func__);
if (firsttime) {
init_rast_tab();
firsttime = 0;
}
+ rmesa->radeon.swtcl.emit_prediction = 0;
tnl->Driver.Render.Start = r300RenderStart;
tnl->Driver.Render.Finish = r300RenderFinish;
@@ -580,8 +629,8 @@ static void r300EmitVertexAOS(r300ContextPtr rmesa, GLuint vertex_size, struct r
{
BATCH_LOCALS(&rmesa->radeon);
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s: vertex_size %d, offset 0x%x \n",
+ radeon_print(RADEON_SWRENDER, RADEON_TRACE,
+ "%s: vertex_size %d, offset 0x%x \n",
__FUNCTION__, vertex_size, offset);
BEGIN_BATCH(7);
@@ -596,6 +645,8 @@ static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vert
{
BATCH_LOCALS(&rmesa->radeon);
int type, num_verts;
+ if (RADEON_DEBUG & RADEON_VERTS)
+ fprintf(stderr, "%s\n", __func__);
type = r300PrimitiveType(rmesa, primitive);
num_verts = r300NumVerts(rmesa, vertex_nr, primitive);
@@ -608,21 +659,26 @@ static void r300EmitVbufPrim(r300ContextPtr rmesa, GLuint primitive, GLuint vert
void r300_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
{
+ radeon_print(RADEON_SWRENDER, RADEON_TRACE, "%s\n", __func__);
r300ContextPtr rmesa = R300_CONTEXT(ctx);
- rcommonEnsureCmdBufSpace(&rmesa->radeon,
- rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
- __FUNCTION__);
+ r300EmitCacheFlush(rmesa);
+
radeonEmitState(&rmesa->radeon);
r300_emit_scissor(ctx);
r300EmitVertexAOS(rmesa,
rmesa->radeon.swtcl.vertex_size,
- rmesa->radeon.dma.current,
+ first_elem(&rmesa->radeon.dma.reserved)->bo,
current_offset);
r300EmitVbufPrim(rmesa,
rmesa->radeon.swtcl.hw_primitive,
rmesa->radeon.swtcl.numverts);
r300EmitCacheFlush(rmesa);
+ if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n",
+ rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
+ rmesa->radeon.swtcl.emit_prediction = 0;
COMMIT_BATCH();
}
diff --git a/src/mesa/drivers/dri/r300/r300_tex.c b/src/mesa/drivers/dri/r300/r300_tex.c
index 0af5bb4f46..433e5a87d4 100644
--- a/src/mesa/drivers/dri/r300/r300_tex.c
+++ b/src/mesa/drivers/dri/r300/r300_tex.c
@@ -137,7 +137,7 @@ static void r300SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloa
| R300_TX_MIN_FILTER_ANISO
| R300_TX_MIN_FILTER_MIP_LINEAR
| aniso_filter(anisotropy);
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
return;
}
@@ -197,7 +197,7 @@ static void r300TexParameter(GLcontext * ctx, GLenum target,
{
radeonTexObj* t = radeon_tex_obj(texObj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) {
fprintf(stderr, "%s( %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(pname));
}
@@ -260,7 +260,7 @@ static void r300DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
r300ContextPtr rmesa = R300_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) {
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
(void *)texObj,
_mesa_lookup_enum_by_nr(texObj->Target));
@@ -302,7 +302,7 @@ static struct gl_texture_object *r300NewTextureObject(GLcontext * ctx,
radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
+ if (RADEON_DEBUG & (RADEON_STATE | RADEON_TEXTURE)) {
fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
t, _mesa_lookup_enum_by_nr(target));
}
diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c
index 6f489ace7b..f030451b28 100644
--- a/src/mesa/drivers/dri/r300/r300_texstate.c
+++ b/src/mesa/drivers/dri/r300/r300_texstate.c
@@ -43,6 +43,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/teximage.h"
#include "main/texobj.h"
#include "main/enums.h"
+#include "main/simple_list.h"
#include "r300_context.h"
#include "r300_state.h"
@@ -323,7 +324,7 @@ GLboolean r300ValidateBuffers(GLcontext * ctx)
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
return GL_FALSE;
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c
index de32013032..2f7b67c143 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.c
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.c
@@ -40,927 +40,125 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "shader/prog_statevars.h"
#include "tnl/tnl.h"
-#include "radeon_nqssadce.h"
+#include "compiler/radeon_compiler.h"
+#include "compiler/radeon_nqssadce.h"
#include "r300_context.h"
+#include "r300_fragprog_common.h"
#include "r300_state.h"
-/* TODO: Get rid of t_src_class call */
-#define CMP_SRCS(a, b) ((a.RelAddr != b.RelAddr) || (a.Index != b.Index && \
- ((t_src_class(a.File) == PVS_SRC_REG_CONSTANT && \
- t_src_class(b.File) == PVS_SRC_REG_CONSTANT) || \
- (t_src_class(a.File) == PVS_SRC_REG_INPUT && \
- t_src_class(b.File) == PVS_SRC_REG_INPUT)))) \
-
-/*
- * Take an already-setup and valid source then swizzle it appropriately to
- * obtain a constant ZERO or ONE source.
+/**
+ * Write parameter array for the given vertex program into dst.
+ * Return the total number of components written.
*/
-#define __CONST(x, y) \
- (PVS_SRC_OPERAND(t_src_index(vp, &src[x]), \
- t_swizzle(y), \
- t_swizzle(y), \
- t_swizzle(y), \
- t_swizzle(y), \
- t_src_class(src[x].File), \
- VSF_FLAG_NONE) | (src[x].RelAddr << 4))
-
-#define FREE_TEMPS() \
- do { \
- int u_temp_used = (VSF_MAX_FRAGMENT_TEMPS - 1) - u_temp_i; \
- if((vp->num_temporaries + u_temp_used) > VSF_MAX_FRAGMENT_TEMPS) { \
- WARN_ONCE("Ran out of temps, num temps %d, us %d\n", vp->num_temporaries, u_temp_used); \
- vp->error = GL_TRUE; \
- } \
- u_temp_i=VSF_MAX_FRAGMENT_TEMPS-1; \
- } while (0)
-
-static int r300VertexProgUpdateParams(GLcontext * ctx, struct gl_vertex_program *vp, float *dst)
+static int r300VertexProgUpdateParams(GLcontext * ctx, struct r300_vertex_program *vp, float *dst)
{
- int pi;
- float *dst_o = dst;
- struct gl_program_parameter_list *paramList;
+ int i;
- if (vp->IsNVProgram) {
+ if (vp->Base->IsNVProgram) {
_mesa_load_tracked_matrices(ctx);
-
- for (pi = 0; pi < MAX_NV_VERTEX_PROGRAM_PARAMS; pi++) {
- *dst++ = ctx->VertexProgram.Parameters[pi][0];
- *dst++ = ctx->VertexProgram.Parameters[pi][1];
- *dst++ = ctx->VertexProgram.Parameters[pi][2];
- *dst++ = ctx->VertexProgram.Parameters[pi][3];
+ } else {
+ if (vp->Base->Base.Parameters) {
+ _mesa_load_state_parameters(ctx, vp->Base->Base.Parameters);
}
- return dst - dst_o;
}
- if (!vp->Base.Parameters)
- return 0;
-
- _mesa_load_state_parameters(ctx, vp->Base.Parameters);
-
- if (vp->Base.Parameters->NumParameters * 4 >
- VSF_MAX_FRAGMENT_LENGTH) {
+ if (vp->code.constants.Count * 4 > VSF_MAX_FRAGMENT_LENGTH) {
+ /* Should have checked this earlier... */
fprintf(stderr, "%s:Params exhausted\n", __FUNCTION__);
_mesa_exit(-1);
}
- paramList = vp->Base.Parameters;
- for (pi = 0; pi < paramList->NumParameters; pi++) {
- switch (paramList->Parameters[pi].Type) {
- case PROGRAM_STATE_VAR:
- case PROGRAM_NAMED_PARAM:
- //fprintf(stderr, "%s", vp->Parameters->Parameters[pi].Name);
- case PROGRAM_CONSTANT:
- *dst++ = paramList->ParameterValues[pi][0];
- *dst++ = paramList->ParameterValues[pi][1];
- *dst++ = paramList->ParameterValues[pi][2];
- *dst++ = paramList->ParameterValues[pi][3];
- break;
- default:
- _mesa_problem(NULL, "Bad param type in %s",
- __FUNCTION__);
- }
-
- }
-
- return dst - dst_o;
-}
-
-static unsigned long t_dst_mask(GLuint mask)
-{
- /* WRITEMASK_* is equivalent to VSF_FLAG_* */
- return mask & VSF_FLAG_ALL;
-}
-
-static unsigned long t_dst_class(gl_register_file file)
-{
-
- switch (file) {
- case PROGRAM_TEMPORARY:
- return PVS_DST_REG_TEMPORARY;
- case PROGRAM_OUTPUT:
- return PVS_DST_REG_OUT;
- case PROGRAM_ADDRESS:
- return PVS_DST_REG_A0;
- /*
- case PROGRAM_INPUT:
- case PROGRAM_LOCAL_PARAM:
- case PROGRAM_ENV_PARAM:
- case PROGRAM_NAMED_PARAM:
- case PROGRAM_STATE_VAR:
- case PROGRAM_WRITE_ONLY:
- case PROGRAM_ADDRESS:
- */
- default:
- fprintf(stderr, "problem in %s", __FUNCTION__);
- _mesa_exit(-1);
- return -1;
- }
-}
+ for(i = 0; i < vp->code.constants.Count; ++i) {
+ const float * src = 0;
+ const struct rc_constant * constant = &vp->code.constants.Constants[i];
-static unsigned long t_dst_index(struct r300_vertex_program *vp,
- struct prog_dst_register *dst)
-{
- if (dst->File == PROGRAM_OUTPUT)
- return vp->outputs[dst->Index];
+ switch(constant->Type) {
+ case RC_CONSTANT_EXTERNAL:
+ if (vp->Base->IsNVProgram) {
+ src = ctx->VertexProgram.Parameters[constant->u.External];
+ } else {
+ src = vp->Base->Base.Parameters->ParameterValues[constant->u.External];
+ }
+ break;
- return dst->Index;
-}
+ case RC_CONSTANT_IMMEDIATE:
+ src = constant->u.Immediate;
+ break;
+ }
-static unsigned long t_src_class(gl_register_file file)
-{
- switch (file) {
- case PROGRAM_TEMPORARY:
- return PVS_SRC_REG_TEMPORARY;
- case PROGRAM_INPUT:
- return PVS_SRC_REG_INPUT;
- case PROGRAM_LOCAL_PARAM:
- case PROGRAM_ENV_PARAM:
- case PROGRAM_NAMED_PARAM:
- case PROGRAM_CONSTANT:
- case PROGRAM_STATE_VAR:
- return PVS_SRC_REG_CONSTANT;
- /*
- case PROGRAM_OUTPUT:
- case PROGRAM_WRITE_ONLY:
- case PROGRAM_ADDRESS:
- */
- default:
- fprintf(stderr, "problem in %s", __FUNCTION__);
- _mesa_exit(-1);
- return -1;
+ dst[4*i] = src[0];
+ dst[4*i + 1] = src[1];
+ dst[4*i + 2] = src[2];
+ dst[4*i + 3] = src[3];
}
-}
-static INLINE unsigned long t_swizzle(GLubyte swizzle)
-{
-/* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */
- return swizzle;
+ return 4 * vp->code.constants.Count;
}
-#if 0
-static void vp_dump_inputs(struct r300_vertex_program *vp, char *caller)
+static GLbitfield compute_required_outputs(struct gl_vertex_program * vp, GLbitfield fpreads)
{
+ GLbitfield outputs = 0;
int i;
- if (vp == NULL) {
- fprintf(stderr, "vp null in call to %s from %s\n", __FUNCTION__,
- caller);
- return;
- }
-
- fprintf(stderr, "%s:<", caller);
- for (i = 0; i < VERT_ATTRIB_MAX; i++)
- fprintf(stderr, "%d ", vp->inputs[i]);
- fprintf(stderr, ">\n");
-
-}
-#endif
-
-static unsigned long t_src_index(struct r300_vertex_program *vp,
- struct prog_src_register *src)
-{
- if (src->File == PROGRAM_INPUT) {
- assert(vp->inputs[src->Index] != -1);
- return vp->inputs[src->Index];
- } else {
- if (src->Index < 0) {
- fprintf(stderr,
- "negative offsets for indirect addressing do not work.\n");
- return 0;
- }
- return src->Index;
- }
-}
-
-/* these two functions should probably be merged... */
-
-static unsigned long t_src(struct r300_vertex_program *vp,
- struct prog_src_register *src)
-{
- /* src->Negate uses the NEGATE_ flags from program_instruction.h,
- * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
- */
- return PVS_SRC_OPERAND(t_src_index(vp, src),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 1)),
- t_swizzle(GET_SWZ(src->Swizzle, 2)),
- t_swizzle(GET_SWZ(src->Swizzle, 3)),
- t_src_class(src->File),
- src->Negate) | (src->RelAddr << 4);
-}
+#define ADD_OUTPUT(fp_attr, vp_result) \
+ do { \
+ if (fpreads & (1 << (fp_attr))) \
+ outputs |= (1 << (vp_result)); \
+ } while (0)
-static unsigned long t_src_scalar(struct r300_vertex_program *vp,
- struct prog_src_register *src)
-{
- /* src->Negate uses the NEGATE_ flags from program_instruction.h,
- * which equal our VSF_FLAGS_ values, so it's safe to just pass it here.
- */
- return PVS_SRC_OPERAND(t_src_index(vp, src),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_swizzle(GET_SWZ(src->Swizzle, 0)),
- t_src_class(src->File),
- src->Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src->RelAddr << 4);
-}
+ ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0);
+ ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1);
-static GLboolean valid_dst(struct r300_vertex_program *vp,
- struct prog_dst_register *dst)
-{
- if (dst->File == PROGRAM_OUTPUT && vp->outputs[dst->Index] == -1) {
- return GL_FALSE;
- } else if (dst->File == PROGRAM_ADDRESS) {
- assert(dst->Index == 0);
+ for (i = 0; i <= 7; ++i) {
+ ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i);
}
- return GL_TRUE;
-}
-
-static GLuint *r300TranslateOpcodeABS(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //MAX RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-
- inst[0] = PVS_OP_DST_OPERAND(VE_MAXIMUM,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)),
- t_src_class(src[0].File),
- (!src[0].
- Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[3] = 0;
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeADD(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeARL(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_FLT2FIX_DX,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeDP3(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ZERO} PARAM 0{} {X Y Z ZERO}
-
- inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
- SWIZZLE_ZERO,
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[2] =
- PVS_SRC_OPERAND(t_src_index(vp, &src[1]),
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)), SWIZZLE_ZERO,
- t_src_class(src[1].File),
- src[1].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeDP4(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeDPH(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //DOT RESULT 1.X Y Z W PARAM 0{} {X Y Z ONE} PARAM 0{} {X Y Z W}
- inst[0] = PVS_OP_DST_OPERAND(VE_DOT_PRODUCT,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 2)),
- PVS_SRC_SELECT_FORCE_1,
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_XYZ : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeDST(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_DISTANCE_VECTOR,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeEX2(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_FULL_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeEXP(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_EXP_BASE2_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeFLR(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3],
- int *u_temp_i)
-{
- /* FRC TMP 0.X Y Z W PARAM 0{} {X Y Z W}
- ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} TMP 0{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W */
-
- inst[0] = PVS_OP_DST_OPERAND(VE_FRACTION,
- GL_FALSE,
- GL_FALSE,
- *u_temp_i,
- t_dst_mask(vpi->DstReg.WriteMask),
- PVS_DST_REG_TEMPORARY);
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
- inst += 4;
-
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = PVS_SRC_OPERAND(*u_temp_i,
- PVS_SRC_SELECT_X,
- PVS_SRC_SELECT_Y,
- PVS_SRC_SELECT_Z,
- PVS_SRC_SELECT_W, PVS_SRC_REG_TEMPORARY,
- /* Not 100% sure about this */
- (!src[0].
- Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE
- /*VSF_FLAG_ALL */ );
- inst[3] = __CONST(0, SWIZZLE_ZERO);
- (*u_temp_i)--;
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeFRC(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_FRACTION,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeLG2(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- // LG2 RESULT 1.X Y Z W PARAM 0{} {X X X X}
-
- inst[0] = PVS_OP_DST_OPERAND(ME_LOG_BASE2_FULL_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)),
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeLIT(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //LIT TMP 1.Y Z TMP 1{} {X W Z Y} TMP 1{} {Y W Z X} TMP 1{} {Y X Z W}
-
- inst[0] = PVS_OP_DST_OPERAND(ME_LIGHT_COEFF_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- /* NOTE: Users swizzling might not work. */
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
- PVS_SRC_SELECT_FORCE_0, // Z
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
- PVS_SRC_SELECT_FORCE_0, // Z
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
- PVS_SRC_SELECT_FORCE_0, // Z
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeLOG(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_LOG_BASE2_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeMAD(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(PVS_MACRO_OP_2CLK_MADD,
- GL_FALSE,
- GL_TRUE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = t_src(vp, &src[2]);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeMAX(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_MAXIMUM,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeMIN(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_MINIMUM,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeMOV(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
-
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeMUL(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodePOW(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_POWER_FUNC_FF,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = t_src_scalar(vp, &src[1]);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeRCP(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_RECIP_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
+#undef ADD_OUTPUT
-static GLuint *r300TranslateOpcodeRSQ(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(ME_RECIP_SQRT_DX,
- GL_TRUE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src_scalar(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
+ if ((fpreads & (1 << FRAG_ATTRIB_COL0)) &&
+ (vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC0)))
+ outputs |= 1 << VERT_RESULT_BFC0;
+ if ((fpreads & (1 << FRAG_ATTRIB_COL1)) &&
+ (vp->Base.OutputsWritten & (1 << VERT_RESULT_BFC1)))
+ outputs |= 1 << VERT_RESULT_BFC1;
-static GLuint *r300TranslateOpcodeSGE(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_SET_GREATER_THAN_EQUAL,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
-}
+ outputs |= 1 << VERT_RESULT_HPOS;
+ if (vp->Base.OutputsWritten & (1 << VERT_RESULT_PSIZ))
+ outputs |= 1 << VERT_RESULT_PSIZ;
-static GLuint *r300TranslateOpcodeSLT(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- inst[0] = PVS_OP_DST_OPERAND(VE_SET_LESS_THAN,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = t_src(vp, &src[1]);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
-
- return inst;
+ return outputs;
}
-static GLuint *r300TranslateOpcodeSUB(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //ADD RESULT 1.X Y Z W TMP 0{} {X Y Z W} PARAM 1{X Y Z W } {X Y Z W} neg Xneg Yneg Zneg W
-
-#if 0
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]),
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
- t_src_class(src[1].File),
- (!src[1].
- Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
- inst[3] = 0;
-#else
- inst[0] =
- PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ONE);
- inst[3] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]),
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)),
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)),
- t_src_class(src[1].File),
- (!src[1].
- Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
-#endif
-
- return inst;
-}
-static GLuint *r300TranslateOpcodeSWZ(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3])
-{
- //ADD RESULT 1.X Y Z W PARAM 0{} {X Y Z W} PARAM 0{} {ZERO ZERO ZERO ZERO}
-
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = t_src(vp, &src[0]);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
-
- return inst;
-}
-
-static GLuint *r300TranslateOpcodeXPD(struct r300_vertex_program *vp,
- struct prog_instruction *vpi,
- GLuint * inst,
- struct prog_src_register src[3],
- int *u_temp_i)
-{
- /* mul r0, r1.yzxw, r2.zxyw
- mad r0, -r2.yzxw, r1.zxyw, r0
- */
-
- inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
- GL_FALSE,
- GL_FALSE,
- *u_temp_i,
- t_dst_mask(vpi->DstReg.WriteMask),
- PVS_DST_REG_TEMPORARY);
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X
- t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W
- t_src_class(src[1].File),
- src[1].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
- inst[3] = __CONST(1, SWIZZLE_ZERO);
- inst += 4;
-
- inst[0] = PVS_OP_DST_OPERAND(VE_MULTIPLY_ADD,
- GL_FALSE,
- GL_FALSE,
- t_dst_index(vp, &vpi->DstReg),
- t_dst_mask(vpi->DstReg.WriteMask),
- t_dst_class(vpi->DstReg.File));
- inst[1] = PVS_SRC_OPERAND(t_src_index(vp, &src[1]), t_swizzle(GET_SWZ(src[1].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[1].Swizzle, 2)), // Z
- t_swizzle(GET_SWZ(src[1].Swizzle, 0)), // X
- t_swizzle(GET_SWZ(src[1].Swizzle, 3)), // W
- t_src_class(src[1].File),
- (!src[1].
- Negate) ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[1].RelAddr << 4);
- inst[2] = PVS_SRC_OPERAND(t_src_index(vp, &src[0]), t_swizzle(GET_SWZ(src[0].Swizzle, 2)), // Z
- t_swizzle(GET_SWZ(src[0].Swizzle, 0)), // X
- t_swizzle(GET_SWZ(src[0].Swizzle, 1)), // Y
- t_swizzle(GET_SWZ(src[0].Swizzle, 3)), // W
- t_src_class(src[0].File),
- src[0].Negate ? VSF_FLAG_ALL : VSF_FLAG_NONE) |
- (src[0].RelAddr << 4);
- inst[3] =
- PVS_SRC_OPERAND(*u_temp_i, PVS_SRC_SELECT_X, PVS_SRC_SELECT_Y,
- PVS_SRC_SELECT_Z, PVS_SRC_SELECT_W,
- PVS_SRC_REG_TEMPORARY, VSF_FLAG_NONE);
-
- (*u_temp_i)--;
-
- return inst;
-}
-
-static void t_inputs_outputs(struct r300_vertex_program *vp)
+static void t_inputs_outputs(struct r300_vertex_program_compiler * c)
{
int i;
int cur_reg;
GLuint OutputsWritten, InputsRead;
- OutputsWritten = vp->Base->Base.OutputsWritten;
- InputsRead = vp->Base->Base.InputsRead;
+ OutputsWritten = c->Base.Program.OutputsWritten;
+ InputsRead = c->Base.Program.InputsRead;
cur_reg = -1;
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
if (InputsRead & (1 << i))
- vp->inputs[i] = ++cur_reg;
+ c->code->inputs[i] = ++cur_reg;
else
- vp->inputs[i] = -1;
+ c->code->inputs[i] = -1;
}
cur_reg = 0;
for (i = 0; i < VERT_RESULT_MAX; i++)
- vp->outputs[i] = -1;
+ c->code->outputs[i] = -1;
assert(OutputsWritten & (1 << VERT_RESULT_HPOS));
if (OutputsWritten & (1 << VERT_RESULT_HPOS)) {
- vp->outputs[VERT_RESULT_HPOS] = cur_reg++;
+ c->code->outputs[VERT_RESULT_HPOS] = cur_reg++;
}
if (OutputsWritten & (1 << VERT_RESULT_PSIZ)) {
- vp->outputs[VERT_RESULT_PSIZ] = cur_reg++;
+ c->code->outputs[VERT_RESULT_PSIZ] = cur_reg++;
}
/* If we're writing back facing colors we need to send
@@ -970,668 +168,130 @@ static void t_inputs_outputs(struct r300_vertex_program *vp)
* get written into appropriate output vectors.
*/
if (OutputsWritten & (1 << VERT_RESULT_COL0)) {
- vp->outputs[VERT_RESULT_COL0] = cur_reg++;
+ c->code->outputs[VERT_RESULT_COL0] = cur_reg++;
} else if (OutputsWritten & (1 << VERT_RESULT_BFC0) ||
OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
if (OutputsWritten & (1 << VERT_RESULT_COL1)) {
- vp->outputs[VERT_RESULT_COL1] = cur_reg++;
+ c->code->outputs[VERT_RESULT_COL1] = cur_reg++;
} else if (OutputsWritten & (1 << VERT_RESULT_BFC0) ||
OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
if (OutputsWritten & (1 << VERT_RESULT_BFC0)) {
- vp->outputs[VERT_RESULT_BFC0] = cur_reg++;
+ c->code->outputs[VERT_RESULT_BFC0] = cur_reg++;
} else if (OutputsWritten & (1 << VERT_RESULT_BFC1)) {
cur_reg++;
}
if (OutputsWritten & (1 << VERT_RESULT_BFC1)) {
- vp->outputs[VERT_RESULT_BFC1] = cur_reg++;
+ c->code->outputs[VERT_RESULT_BFC1] = cur_reg++;
} else if (OutputsWritten & (1 << VERT_RESULT_BFC0)) {
cur_reg++;
}
for (i = VERT_RESULT_TEX0; i <= VERT_RESULT_TEX7; i++) {
if (OutputsWritten & (1 << i)) {
- vp->outputs[i] = cur_reg++;
+ c->code->outputs[i] = cur_reg++;
}
}
if (OutputsWritten & (1 << VERT_RESULT_FOGC)) {
- vp->outputs[VERT_RESULT_FOGC] = cur_reg++;
- }
-}
-
-void r300TranslateVertexShader(struct r300_vertex_program *vp)
-{
- struct prog_instruction *vpi = vp->Base->Base.Instructions;
- int i;
- GLuint *inst;
- unsigned long num_operands;
- /* Initial value should be last tmp reg that hw supports.
- Strangely enough r300 doesnt mind even though these would be out of range.
- Smart enough to realize that it doesnt need it? */
- int u_temp_i = VSF_MAX_FRAGMENT_TEMPS - 1;
- struct prog_src_register src[3];
-
- vp->pos_end = 0; /* Not supported yet */
- vp->hw_code.length = 0;
- vp->translated = GL_TRUE;
- vp->error = GL_FALSE;
-
- t_inputs_outputs(vp);
-
- for (inst = vp->hw_code.body.d; vpi->Opcode != OPCODE_END;
- vpi++, inst += 4) {
-
- FREE_TEMPS();
-
- if (!valid_dst(vp, &vpi->DstReg)) {
- /* redirect result to unused temp */
- vpi->DstReg.File = PROGRAM_TEMPORARY;
- vpi->DstReg.Index = u_temp_i;
- }
-
- num_operands = _mesa_num_inst_src_regs(vpi->Opcode);
-
- /* copy the sources (src) from mesa into a local variable... is this needed? */
- for (i = 0; i < num_operands; i++) {
- src[i] = vpi->SrcReg[i];
- }
-
- if (num_operands == 3) { /* TODO: scalars */
- if (CMP_SRCS(src[1], src[2])
- || CMP_SRCS(src[0], src[2])) {
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- u_temp_i,
- VSF_FLAG_ALL,
- PVS_DST_REG_TEMPORARY);
- inst[1] =
- PVS_SRC_OPERAND(t_src_index(vp, &src[2]),
- SWIZZLE_X,
- SWIZZLE_Y,
- SWIZZLE_Z,
- SWIZZLE_W,
- t_src_class(src[2].File),
- VSF_FLAG_NONE) | (src[2].
- RelAddr <<
- 4);
- inst[2] = __CONST(2, SWIZZLE_ZERO);
- inst[3] = __CONST(2, SWIZZLE_ZERO);
- inst += 4;
-
- src[2].File = PROGRAM_TEMPORARY;
- src[2].Index = u_temp_i;
- src[2].RelAddr = 0;
- u_temp_i--;
- }
- }
-
- if (num_operands >= 2) {
- if (CMP_SRCS(src[1], src[0])) {
- inst[0] = PVS_OP_DST_OPERAND(VE_ADD,
- GL_FALSE,
- GL_FALSE,
- u_temp_i,
- VSF_FLAG_ALL,
- PVS_DST_REG_TEMPORARY);
- inst[1] =
- PVS_SRC_OPERAND(t_src_index(vp, &src[0]),
- SWIZZLE_X,
- SWIZZLE_Y,
- SWIZZLE_Z,
- SWIZZLE_W,
- t_src_class(src[0].File),
- VSF_FLAG_NONE) | (src[0].
- RelAddr <<
- 4);
- inst[2] = __CONST(0, SWIZZLE_ZERO);
- inst[3] = __CONST(0, SWIZZLE_ZERO);
- inst += 4;
-
- src[0].File = PROGRAM_TEMPORARY;
- src[0].Index = u_temp_i;
- src[0].RelAddr = 0;
- u_temp_i--;
- }
- }
-
- switch (vpi->Opcode) {
- case OPCODE_ABS:
- inst = r300TranslateOpcodeABS(vp, vpi, inst, src);
- break;
- case OPCODE_ADD:
- inst = r300TranslateOpcodeADD(vp, vpi, inst, src);
- break;
- case OPCODE_ARL:
- inst = r300TranslateOpcodeARL(vp, vpi, inst, src);
- break;
- case OPCODE_DP3:
- inst = r300TranslateOpcodeDP3(vp, vpi, inst, src);
- break;
- case OPCODE_DP4:
- inst = r300TranslateOpcodeDP4(vp, vpi, inst, src);
- break;
- case OPCODE_DPH:
- inst = r300TranslateOpcodeDPH(vp, vpi, inst, src);
- break;
- case OPCODE_DST:
- inst = r300TranslateOpcodeDST(vp, vpi, inst, src);
- break;
- case OPCODE_EX2:
- inst = r300TranslateOpcodeEX2(vp, vpi, inst, src);
- break;
- case OPCODE_EXP:
- inst = r300TranslateOpcodeEXP(vp, vpi, inst, src);
- break;
- case OPCODE_FLR:
- inst = r300TranslateOpcodeFLR(vp, vpi, inst, src, /* FIXME */
- &u_temp_i);
- break;
- case OPCODE_FRC:
- inst = r300TranslateOpcodeFRC(vp, vpi, inst, src);
- break;
- case OPCODE_LG2:
- inst = r300TranslateOpcodeLG2(vp, vpi, inst, src);
- break;
- case OPCODE_LIT:
- inst = r300TranslateOpcodeLIT(vp, vpi, inst, src);
- break;
- case OPCODE_LOG:
- inst = r300TranslateOpcodeLOG(vp, vpi, inst, src);
- break;
- case OPCODE_MAD:
- inst = r300TranslateOpcodeMAD(vp, vpi, inst, src);
- break;
- case OPCODE_MAX:
- inst = r300TranslateOpcodeMAX(vp, vpi, inst, src);
- break;
- case OPCODE_MIN:
- inst = r300TranslateOpcodeMIN(vp, vpi, inst, src);
- break;
- case OPCODE_MOV:
- inst = r300TranslateOpcodeMOV(vp, vpi, inst, src);
- break;
- case OPCODE_MUL:
- inst = r300TranslateOpcodeMUL(vp, vpi, inst, src);
- break;
- case OPCODE_POW:
- inst = r300TranslateOpcodePOW(vp, vpi, inst, src);
- break;
- case OPCODE_RCP:
- inst = r300TranslateOpcodeRCP(vp, vpi, inst, src);
- break;
- case OPCODE_RSQ:
- inst = r300TranslateOpcodeRSQ(vp, vpi, inst, src);
- break;
- case OPCODE_SGE:
- inst = r300TranslateOpcodeSGE(vp, vpi, inst, src);
- break;
- case OPCODE_SLT:
- inst = r300TranslateOpcodeSLT(vp, vpi, inst, src);
- break;
- case OPCODE_SUB:
- inst = r300TranslateOpcodeSUB(vp, vpi, inst, src);
- break;
- case OPCODE_SWZ:
- inst = r300TranslateOpcodeSWZ(vp, vpi, inst, src);
- break;
- case OPCODE_XPD:
- inst = r300TranslateOpcodeXPD(vp, vpi, inst, src, /* FIXME */
- &u_temp_i);
- break;
- default:
- vp->error = GL_TRUE;
- break;
- }
- }
-
- vp->hw_code.length = (inst - vp->hw_code.body.d);
- if (vp->hw_code.length >= VSF_MAX_FRAGMENT_LENGTH) {
- vp->error = GL_TRUE;
+ c->code->outputs[VERT_RESULT_FOGC] = cur_reg++;
}
}
-static void insert_wpos(struct gl_program *prog, GLuint temp_index, int tex_id)
-{
- struct prog_instruction *vpi;
-
- _mesa_insert_instructions(prog, prog->NumInstructions - 1, 2);
-
- vpi = &prog->Instructions[prog->NumInstructions - 3];
-
- vpi->Opcode = OPCODE_MOV;
-
- vpi->DstReg.File = PROGRAM_OUTPUT;
- vpi->DstReg.Index = VERT_RESULT_HPOS;
- vpi->DstReg.WriteMask = WRITEMASK_XYZW;
- vpi->DstReg.CondMask = COND_TR;
-
- vpi->SrcReg[0].File = PROGRAM_TEMPORARY;
- vpi->SrcReg[0].Index = temp_index;
- vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- ++vpi;
-
- vpi->Opcode = OPCODE_MOV;
-
- vpi->DstReg.File = PROGRAM_OUTPUT;
- vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
- vpi->DstReg.WriteMask = WRITEMASK_XYZW;
- vpi->DstReg.CondMask = COND_TR;
-
- vpi->SrcReg[0].File = PROGRAM_TEMPORARY;
- vpi->SrcReg[0].Index = temp_index;
- vpi->SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- ++vpi;
-
- vpi->Opcode = OPCODE_END;
-}
-
-static void pos_as_texcoord(struct gl_program *prog, int tex_id)
-{
- struct prog_instruction *vpi;
- GLuint tempregi = prog->NumTemporaries;
-
- prog->NumTemporaries++;
-
- for (vpi = prog->Instructions; vpi->Opcode != OPCODE_END; vpi++) {
- if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_HPOS) {
- vpi->DstReg.File = PROGRAM_TEMPORARY;
- vpi->DstReg.Index = tempregi;
- }
- }
-
- insert_wpos(prog, tempregi, tex_id);
-
- prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
-}
-
/**
- * The fogcoord attribute is special in that only the first component
- * is relevant, and the remaining components are always fixed (when read
- * from by the fragment program) to yield an X001 pattern.
+ * The NV_vertex_program spec mandates that all registers be
+ * initialized to zero. We do this here unconditionally.
*
- * We need to enforce this either in the vertex program or in the fragment
- * program, and this code chooses not to enforce it in the vertex program.
- * This is slightly cheaper, as long as the fragment program does not use
- * weird swizzles.
- *
- * And it seems that usually, weird swizzles are not used, so...
- *
- * See also the counterpart rewriting for fragment programs.
+ * \note We rely on dead-code elimination in the compiler.
*/
-static void fog_as_texcoord(struct gl_program *prog, int tex_id)
-{
- struct prog_instruction *vpi;
-
- vpi = prog->Instructions;
- while (vpi->Opcode != OPCODE_END) {
- if (vpi->DstReg.File == PROGRAM_OUTPUT && vpi->DstReg.Index == VERT_RESULT_FOGC) {
- vpi->DstReg.Index = VERT_RESULT_TEX0 + tex_id;
- vpi->DstReg.WriteMask = WRITEMASK_X;
- }
-
- ++vpi;
- }
-
- prog->OutputsWritten &= ~(1 << VERT_RESULT_FOGC);
- prog->OutputsWritten |= 1 << (VERT_RESULT_TEX0 + tex_id);
-}
-
-static int translateABS(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
-
- inst = &prog->Instructions[pos];
-
- inst->Opcode = OPCODE_MAX;
- inst->SrcReg[1] = inst->SrcReg[0];
- inst->SrcReg[1].Negate ^= NEGATE_XYZW;
-
- return 0;
-}
-
-static int translateDP3(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
-
- inst = &prog->Instructions[pos];
-
- inst->Opcode = OPCODE_DP4;
- inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ZERO);
-
- return 0;
-}
-
-static int translateDPH(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
-
- inst = &prog->Instructions[pos];
-
- inst->Opcode = OPCODE_DP4;
- inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE);
-
- return 0;
-}
-
-static int translateFLR(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
- struct prog_dst_register dst;
- int tmp_idx;
-
- tmp_idx = prog->NumTemporaries++;
-
- _mesa_insert_instructions(prog, pos + 1, 1);
-
- inst = &prog->Instructions[pos];
- dst = inst->DstReg;
-
- inst->Opcode = OPCODE_FRC;
- inst->DstReg.File = PROGRAM_TEMPORARY;
- inst->DstReg.Index = tmp_idx;
- ++inst;
-
- inst->Opcode = OPCODE_ADD;
- inst->DstReg = dst;
- inst->SrcReg[0] = (inst-1)->SrcReg[0];
- inst->SrcReg[1].File = PROGRAM_TEMPORARY;
- inst->SrcReg[1].Index = tmp_idx;
- inst->SrcReg[1].Negate = NEGATE_XYZW;
-
- return 1;
-}
-
-static int translateSUB(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
-
- inst = &prog->Instructions[pos];
-
- inst->Opcode = OPCODE_ADD;
- inst->SrcReg[1].Negate ^= NEGATE_XYZW;
-
- return 0;
-}
-
-static int translateSWZ(struct gl_program *prog, int pos)
-{
- prog->Instructions[pos].Opcode = OPCODE_MOV;
-
- return 0;
-}
-
-static int translateXPD(struct gl_program *prog, int pos)
-{
- struct prog_instruction *inst;
- int tmp_idx;
-
- tmp_idx = prog->NumTemporaries++;
-
- _mesa_insert_instructions(prog, pos + 1, 1);
-
- inst = &prog->Instructions[pos];
-
- *(inst+1) = *inst;
-
- inst->Opcode = OPCODE_MUL;
- inst->DstReg.File = PROGRAM_TEMPORARY;
- inst->DstReg.Index = tmp_idx;
- inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W);
- inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W);
- ++inst;
-
- inst->Opcode = OPCODE_MAD;
- inst->SrcReg[0].Swizzle = combine_swizzles4(inst->SrcReg[0].Swizzle, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_Y, SWIZZLE_W);
- inst->SrcReg[1].Swizzle = combine_swizzles4(inst->SrcReg[1].Swizzle, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_X, SWIZZLE_W);
- inst->SrcReg[1].Negate ^= NEGATE_XYZW;
- inst->SrcReg[2].File = PROGRAM_TEMPORARY;
- inst->SrcReg[2].Index = tmp_idx;
-
- return 1;
-}
-
-static void translateInsts(struct gl_program *prog)
+static void initialize_NV_registers(struct radeon_compiler * compiler)
{
- struct prog_instruction *inst;
- int i;
+ unsigned int reg;
+ struct rc_instruction * inst;
- for (i = 0; i < prog->NumInstructions; ++i) {
- inst = &prog->Instructions[i];
-
- switch (inst->Opcode) {
- case OPCODE_ABS:
- i += translateABS(prog, i);
- break;
- case OPCODE_DP3:
- i += translateDP3(prog, i);
- break;
- case OPCODE_DPH:
- i += translateDPH(prog, i);
- break;
- case OPCODE_FLR:
- i += translateFLR(prog, i);
- break;
- case OPCODE_SUB:
- i += translateSUB(prog, i);
- break;
- case OPCODE_SWZ:
- i += translateSWZ(prog, i);
- break;
- case OPCODE_XPD:
- i += translateXPD(prog, i);
- break;
- default:
- break;
- }
+ 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;
}
-}
-
-#define ADD_OUTPUT(fp_attr, vp_result) \
- do { \
- if ((FpReads & (1 << (fp_attr))) && !(prog->OutputsWritten & (1 << (vp_result)))) { \
- OutputsAdded |= 1 << (vp_result); \
- count++; \
- } \
- } while (0)
-
-static void addArtificialOutputs(GLcontext *ctx, struct gl_program *prog)
-{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
- GLuint OutputsAdded, FpReads;
- int i, count;
-
- OutputsAdded = 0;
- count = 0;
- FpReads = r300->selected_fp->Base->InputsRead;
-
- ADD_OUTPUT(FRAG_ATTRIB_COL0, VERT_RESULT_COL0);
- ADD_OUTPUT(FRAG_ATTRIB_COL1, VERT_RESULT_COL1);
-
- for (i = 0; i < 7; ++i) {
- ADD_OUTPUT(FRAG_ATTRIB_TEX0 + i, VERT_RESULT_TEX0 + i);
- }
-
- /* Some outputs may be artificially added, to match the inputs of the fragment program.
- * Issue 16 of vertex program spec says that all vertex attributes that are unwritten by
- * vertex program are undefined, so just use MOV [vertex_result], CONST[0]
- */
- if (count > 0) {
- struct prog_instruction *inst;
-
- _mesa_insert_instructions(prog, prog->NumInstructions - 1, count);
- inst = &prog->Instructions[prog->NumInstructions - 1 - count];
- for (i = 0; i < VERT_RESULT_MAX; ++i) {
- if (OutputsAdded & (1 << i)) {
- inst->Opcode = OPCODE_MOV;
-
- inst->DstReg.File = PROGRAM_OUTPUT;
- inst->DstReg.Index = i;
- inst->DstReg.WriteMask = WRITEMASK_XYZW;
- inst->DstReg.CondMask = COND_TR;
-
- inst->SrcReg[0].File = PROGRAM_CONSTANT;
- inst->SrcReg[0].Index = 0;
- inst->SrcReg[0].Swizzle = SWIZZLE_XYZW;
-
- ++inst;
- }
- }
-
- prog->OutputsWritten |= OutputsAdded;
- }
-}
-
-#undef ADD_OUTPUT
-
-static void nqssadceInit(struct nqssadce_state* s)
-{
- r300ContextPtr r300 = R300_CONTEXT(s->Ctx);
- GLuint fp_reads;
-
- fp_reads = r300->selected_fp->Base->InputsRead;
- {
- if (fp_reads & FRAG_BIT_COL0) {
- s->Outputs[VERT_RESULT_COL0].Sourced = WRITEMASK_XYZW;
- s->Outputs[VERT_RESULT_BFC0].Sourced = WRITEMASK_XYZW;
- }
-
- if (fp_reads & FRAG_BIT_COL1) {
- s->Outputs[VERT_RESULT_COL1].Sourced = WRITEMASK_XYZW;
- s->Outputs[VERT_RESULT_BFC1].Sourced = WRITEMASK_XYZW;
- }
- }
-
- {
- int i;
- for (i = 0; i < 8; ++i) {
- if (fp_reads & FRAG_BIT_TEX(i)) {
- s->Outputs[VERT_RESULT_TEX0 + i].Sourced = WRITEMASK_XYZW;
- }
- }
- }
-
- s->Outputs[VERT_RESULT_HPOS].Sourced = WRITEMASK_XYZW;
- if (s->Program->OutputsWritten & (1 << VERT_RESULT_PSIZ))
- s->Outputs[VERT_RESULT_PSIZ].Sourced = WRITEMASK_X;
-}
-
-static GLboolean swizzleIsNative(GLuint opcode, struct prog_src_register reg)
-{
- (void) opcode;
- (void) reg;
-
- return GL_TRUE;
+ 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,
const struct gl_vertex_program *mesa_vp)
{
- r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_vertex_program *vp;
- struct gl_program *prog;
+ struct r300_vertex_program_compiler compiler;
vp = _mesa_calloc(sizeof(*vp));
vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base);
_mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key));
- prog = &vp->Base->Base;
+ rc_init(&compiler.Base);
+ compiler.Base.Debug = (RADEON_DEBUG & RADEON_VERTS) ? GL_TRUE : GL_FALSE;
- if (RADEON_DEBUG & DEBUG_VERTS) {
+ compiler.code = &vp->code;
+ compiler.RequiredOutputs = compute_required_outputs(vp->Base, vp->key.FpReads);
+ compiler.SetHwInputOutput = &t_inputs_outputs;
+
+ if (compiler.Base.Debug) {
fprintf(stderr, "Initial vertex program:\n");
- _mesa_print_program(prog);
- fflush(stdout);
+ _mesa_print_program(&vp->Base->Base);
+ fflush(stderr);
}
- if (vp->Base->IsPositionInvariant) {
+ if (mesa_vp->IsPositionInvariant) {
_mesa_insert_mvp_code(ctx, vp->Base);
}
- if (r300->selected_fp->wpos_attr != FRAG_ATTRIB_MAX) {
- pos_as_texcoord(&vp->Base->Base, r300->selected_fp->wpos_attr - FRAG_ATTRIB_TEX0);
- }
+ rc_mesa_to_rc_program(&compiler.Base, &vp->Base->Base);
- if (r300->selected_fp->fog_attr != FRAG_ATTRIB_MAX) {
- fog_as_texcoord(&vp->Base->Base, r300->selected_fp->fog_attr - FRAG_ATTRIB_TEX0);
- }
+ if (mesa_vp->IsNVProgram)
+ initialize_NV_registers(&compiler.Base);
- addArtificialOutputs(ctx, prog);
+ rc_move_output(&compiler.Base, VERT_RESULT_PSIZ, VERT_RESULT_PSIZ, WRITEMASK_X);
- translateInsts(prog);
-
- if (RADEON_DEBUG & DEBUG_VERTS) {
- fprintf(stderr, "Vertex program after native rewrite:\n");
- _mesa_print_program(prog);
- fflush(stdout);
+ if (vp->key.WPosAttr != FRAG_ATTRIB_MAX) {
+ rc_copy_output(&compiler.Base,
+ VERT_RESULT_HPOS,
+ vp->key.WPosAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0);
}
- {
- struct radeon_nqssadce_descr nqssadce = {
- .Init = &nqssadceInit,
- .IsNativeSwizzle = &swizzleIsNative,
- .BuildSwizzle = NULL
- };
- radeonNqssaDce(ctx, prog, &nqssadce);
-
- /* We need this step for reusing temporary registers */
- _mesa_optimize_program(ctx, prog);
-
- if (RADEON_DEBUG & DEBUG_VERTS) {
- fprintf(stderr, "Vertex program after NQSSADCE:\n");
- _mesa_print_program(prog);
- fflush(stdout);
- }
+ if (vp->key.FogAttr != FRAG_ATTRIB_MAX) {
+ rc_move_output(&compiler.Base,
+ VERT_RESULT_FOGC,
+ vp->key.FogAttr - FRAG_ATTRIB_TEX0 + VERT_RESULT_TEX0, WRITEMASK_X);
}
- assert(prog->NumInstructions);
- {
- struct prog_instruction *inst;
- int max, i, tmp;
-
- inst = prog->Instructions;
- max = -1;
- while (inst->Opcode != OPCODE_END) {
- tmp = _mesa_num_inst_src_regs(inst->Opcode);
- for (i = 0; i < tmp; ++i) {
- if (inst->SrcReg[i].File == PROGRAM_TEMPORARY) {
- if ((int) inst->SrcReg[i].Index > max) {
- max = inst->SrcReg[i].Index;
- }
- }
- }
+ r3xx_compile_vertex_program(&compiler);
+ vp->error = compiler.Base.Error;
- if (_mesa_num_inst_dst_regs(inst->Opcode)) {
- if (inst->DstReg.File == PROGRAM_TEMPORARY) {
- if ((int) inst->DstReg.Index > max) {
- max = inst->DstReg.Index;
- }
- }
- }
- ++inst;
- }
+ vp->Base->Base.InputsRead = vp->code.InputsRead;
+ vp->Base->Base.OutputsWritten = vp->code.OutputsWritten;
- /* We actually want highest index of used temporary register,
- * not the number of temporaries used.
- * These values aren't always the same.
- */
- vp->num_temporaries = max + 1;
- }
+ rc_destroy(&compiler.Base);
return vp;
}
-struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)
+struct r300_vertex_program * r300SelectAndTranslateVertexShader(GLcontext *ctx)
{
r300ContextPtr r300 = R300_CONTEXT(ctx);
struct r300_vertex_program_key wanted_key = { 0 };
@@ -1639,7 +299,21 @@ struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)
struct r300_vertex_program *vp;
vpc = (struct r300_vertex_program_cont *)ctx->VertexProgram._Current;
- wanted_key.FpReads = r300->selected_fp->Base->InputsRead;
+
+ 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;
@@ -1664,12 +338,14 @@ struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx)
if(_nc>_p->vpu.count)_p->vpu.count=_nc; \
} while(0)
-static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_vertex_shader_hw_code *code)
+static void r300EmitVertexProgram(r300ContextPtr r300, int dest, struct r300_vertex_program_code *code)
{
int i;
assert((code->length > 0) && (code->length % 4 == 0));
+ R300_STATECHANGE( r300, vap_flush );
+
switch ((dest >> 8) & 0xf) {
case 0:
R300_STATECHANGE(r300, vpi);
@@ -1707,16 +383,17 @@ void r300SetupVertexProgram(r300ContextPtr rmesa)
((drm_r300_cmd_header_t *) rmesa->hw.vpi.cmd)->vpu.count = 0;
((drm_r300_cmd_header_t *) rmesa->hw.vps.cmd)->vpu.count = 0;
+ R300_STATECHANGE(rmesa, vap_flush);
R300_STATECHANGE(rmesa, vpp);
- param_count = r300VertexProgUpdateParams(ctx, prog->Base, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
+ param_count = r300VertexProgUpdateParams(ctx, prog, (float *)&rmesa->hw.vpp.cmd[R300_VPP_PARAM_0]);
bump_vpu_count(rmesa->hw.vpp.cmd, param_count);
param_count /= 4;
- r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->hw_code));
- inst_count = (prog->hw_code.length / 4) - 1;
+ r300EmitVertexProgram(rmesa, R300_PVS_CODE_START, &(prog->code));
+ inst_count = (prog->code.length / 4) - 1;
- r300VapCntl(rmesa, _mesa_bitcount(prog->Base->Base.InputsRead),
- _mesa_bitcount(prog->Base->Base.OutputsWritten), prog->num_temporaries);
+ r300VapCntl(rmesa, _mesa_bitcount(prog->code.InputsRead),
+ _mesa_bitcount(prog->code.OutputsWritten), prog->code.num_temporaries);
R300_STATECHANGE(rmesa, pvs);
rmesa->hw.pvs.cmd[R300_PVS_CNTL_1] = (0 << R300_PVS_FIRST_INST_SHIFT) | (inst_count << R300_PVS_XYZW_VALID_INST_SHIFT) |
diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.h b/src/mesa/drivers/dri/r300/r300_vertprog.h
index 2dab11c337..ccec896be4 100644
--- a/src/mesa/drivers/dri/r300/r300_vertprog.h
+++ b/src/mesa/drivers/dri/r300/r300_vertprog.h
@@ -3,39 +3,9 @@
#include "r300_reg.h"
-#define PVS_OP_DST_OPERAND(opcode, math_inst, macro_inst, reg_index, reg_writemask, reg_class) \
- (((opcode & PVS_DST_OPCODE_MASK) << PVS_DST_OPCODE_SHIFT) \
- | ((math_inst & PVS_DST_MATH_INST_MASK) << PVS_DST_MATH_INST_SHIFT) \
- | ((macro_inst & PVS_DST_MACRO_INST_MASK) << PVS_DST_MACRO_INST_SHIFT) \
- | ((reg_index & PVS_DST_OFFSET_MASK) << PVS_DST_OFFSET_SHIFT) \
- | ((reg_writemask & 0xf) << PVS_DST_WE_X_SHIFT) /* X Y Z W */ \
- | ((reg_class & PVS_DST_REG_TYPE_MASK) << PVS_DST_REG_TYPE_SHIFT))
-
-#define PVS_SRC_OPERAND(in_reg_index, comp_x, comp_y, comp_z, comp_w, reg_class, negate) \
- (((in_reg_index & PVS_SRC_OFFSET_MASK) << PVS_SRC_OFFSET_SHIFT) \
- | ((comp_x & PVS_SRC_SWIZZLE_X_MASK) << PVS_SRC_SWIZZLE_X_SHIFT) \
- | ((comp_y & PVS_SRC_SWIZZLE_Y_MASK) << PVS_SRC_SWIZZLE_Y_SHIFT) \
- | ((comp_z & PVS_SRC_SWIZZLE_Z_MASK) << PVS_SRC_SWIZZLE_Z_SHIFT) \
- | ((comp_w & PVS_SRC_SWIZZLE_W_MASK) << PVS_SRC_SWIZZLE_W_SHIFT) \
- | ((negate & 0xf) << PVS_SRC_MODIFIER_X_SHIFT) /* X Y Z W */ \
- | ((reg_class & PVS_SRC_REG_TYPE_MASK) << PVS_SRC_REG_TYPE_SHIFT))
-
-#if 1
-
-#define VSF_FLAG_X 1
-#define VSF_FLAG_Y 2
-#define VSF_FLAG_Z 4
-#define VSF_FLAG_W 8
-#define VSF_FLAG_XYZ (VSF_FLAG_X | VSF_FLAG_Y | VSF_FLAG_Z)
-#define VSF_FLAG_ALL 0xf
-#define VSF_FLAG_NONE 0
-
-#endif
void r300SetupVertexProgram(r300ContextPtr rmesa);
-struct r300_vertex_program * r300SelectVertexShader(GLcontext *ctx);
-
-void r300TranslateVertexShader(struct r300_vertex_program *vp);
+struct r300_vertex_program * r300SelectAndTranslateVertexShader(GLcontext *ctx);
#endif
diff --git a/src/mesa/drivers/dri/r300/radeon_buffer_objects.c b/src/mesa/drivers/dri/r300/radeon_buffer_objects.c
new file mode 120000
index 0000000000..f6a5f66470
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/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/r300/radeon_buffer_objects.h b/src/mesa/drivers/dri/r300/radeon_buffer_objects.h
new file mode 120000
index 0000000000..2f134fd17b
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/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/r300/radeon_context.h b/src/mesa/drivers/dri/r300/radeon_context.h
index 250570f6b8..da4812d323 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/r300/radeon_debug.c b/src/mesa/drivers/dri/r300/radeon_debug.c
new file mode 120000
index 0000000000..c98c2e074c
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_debug.c
@@ -0,0 +1 @@
+../radeon/radeon_debug.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_debug.h b/src/mesa/drivers/dri/r300/radeon_debug.h
new file mode 120000
index 0000000000..bd8aa28e89
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_debug.h
@@ -0,0 +1 @@
+../radeon/radeon_debug.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_program.c b/src/mesa/drivers/dri/r300/radeon_program.c
deleted file mode 100644
index da5e7aefce..0000000000
--- a/src/mesa/drivers/dri/r300/radeon_program.c
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2008 Nicolai Haehnle.
- *
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial
- * portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
- * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- */
-
-#include "radeon_program.h"
-
-#include "shader/prog_print.h"
-
-
-/**
- * Transform the given clause in the following way:
- * 1. Replace it with an empty clause
- * 2. For every instruction in the original clause, try the given
- * transformations in order.
- * 3. If one of the transformations returns GL_TRUE, assume that it
- * has emitted the appropriate instruction(s) into the new clause;
- * otherwise, copy the instruction verbatim.
- *
- * \note The transformation is currently not recursive; in other words,
- * instructions emitted by transformations are not transformed.
- *
- * \note The transform is called 'local' because it can only look at
- * one instruction at a time.
- */
-void radeonLocalTransform(
- GLcontext *Ctx,
- struct gl_program *program,
- int num_transformations,
- struct radeon_program_transformation* transformations)
-{
- struct radeon_transform_context ctx;
- int ip;
-
- ctx.Ctx = Ctx;
- ctx.Program = program;
- ctx.OldInstructions = program->Instructions;
- ctx.OldNumInstructions = program->NumInstructions;
-
- program->Instructions = 0;
- program->NumInstructions = 0;
-
- for(ip = 0; ip < ctx.OldNumInstructions; ++ip) {
- struct prog_instruction *instr = ctx.OldInstructions + ip;
- int i;
-
- for(i = 0; i < num_transformations; ++i) {
- struct radeon_program_transformation* t = transformations + i;
-
- if (t->function(&ctx, instr, t->userData))
- break;
- }
-
- if (i >= num_transformations) {
- struct prog_instruction* dest = radeonAppendInstructions(program, 1);
- _mesa_copy_instructions(dest, instr, 1);
- }
- }
-
- _mesa_free_instructions(ctx.OldInstructions, ctx.OldNumInstructions);
-}
-
-
-static void scan_instructions(GLboolean* used, const struct prog_instruction* insts, GLuint count)
-{
- GLuint i;
- for (i = 0; i < count; i++) {
- const struct prog_instruction *inst = insts + i;
- const GLuint n = _mesa_num_inst_src_regs(inst->Opcode);
- GLuint k;
-
- for (k = 0; k < n; k++) {
- if (inst->SrcReg[k].File == PROGRAM_TEMPORARY)
- used[inst->SrcReg[k].Index] = GL_TRUE;
- }
- }
-}
-
-GLint radeonFindFreeTemporary(struct radeon_transform_context *t)
-{
- GLboolean used[MAX_PROGRAM_TEMPS];
- GLuint i;
-
- _mesa_memset(used, 0, sizeof(used));
- scan_instructions(used, t->Program->Instructions, t->Program->NumInstructions);
- scan_instructions(used, t->OldInstructions, t->OldNumInstructions);
-
- for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
- if (!used[i])
- return i;
- }
-
- return -1;
-}
-
-
-/**
- * Append the given number of instructions to the program and return a
- * pointer to the first new instruction.
- */
-struct prog_instruction *radeonAppendInstructions(struct gl_program *program, int count)
-{
- int oldnum = program->NumInstructions;
- _mesa_insert_instructions(program, oldnum, count);
- return program->Instructions + oldnum;
-}
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.c b/src/mesa/drivers/dri/r300/radeon_queryobj.c
new file mode 120000
index 0000000000..1d6ebc1c48
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_queryobj.c
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r300/radeon_queryobj.h b/src/mesa/drivers/dri/r300/radeon_queryobj.h
new file mode 120000
index 0000000000..8f6f842b0a
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/radeon_queryobj.h
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/Makefile b/src/mesa/drivers/dri/r600/Makefile
index 5bdc1afbf0..7d5a7b1ab6 100644
--- a/src/mesa/drivers/dri/r600/Makefile
+++ b/src/mesa/drivers/dri/r600/Makefile
@@ -27,16 +27,19 @@ COMMON_SOURCES = \
../common/dri_util.c
RADEON_COMMON_SOURCES = \
- radeon_texture.c \
+ radeon_bo_legacy.c \
radeon_common_context.c \
+ radeon_buffer_objects.c \
radeon_common.c \
+ radeon_cs_legacy.c \
radeon_dma.c \
+ radeon_debug.c \
+ radeon_fbo.c \
radeon_lock.c \
- radeon_bo_legacy.c \
- radeon_cs_legacy.c \
radeon_mipmap_tree.c \
radeon_span.c \
- radeon_fbo.c
+ radeon_texture.c \
+ radeon_queryobj.c
DRIVER_SOURCES = \
radeon_screen.c \
@@ -63,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_cmdbuf.c b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
index 74fec02584..3cfe03a45f 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.c
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.c
@@ -74,12 +74,11 @@ static struct radeon_cs * r600_cs_create(struct radeon_cs_manager *csm,
return cs;
}
-int r600_cs_write_reloc(struct radeon_cs *cs,
- struct radeon_bo *bo,
- uint32_t read_domain,
- uint32_t write_domain,
- uint32_t flags,
- offset_modifiers* poffset_mod)
+static int r600_cs_write_reloc(struct radeon_cs *cs,
+ struct radeon_bo *bo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t flags)
{
struct r600_cs_reloc_legacy *relocs;
int i;
@@ -130,14 +129,10 @@ int r600_cs_write_reloc(struct radeon_cs *cs,
}
relocs[i].indices = indices;
relocs[i].reloc_indices = reloc_indices;
- relocs[i].indices[relocs[i].cindices - 1] = cs->cdw - 1;
- relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->section_cdw;
- cs->section_ndw += 2;
+ relocs[i].indices[relocs[i].cindices - 1] = cs->cdw;
+ relocs[i].reloc_indices[relocs[i].cindices - 1] = cs->cdw;
cs->section_cdw += 2;
-
- relocs[i].offset_mod.shift = poffset_mod->shift;
- relocs[i].offset_mod.shiftbits = poffset_mod->shiftbits;
- relocs[i].offset_mod.mask = poffset_mod->mask;
+ cs->cdw += 2;
return 0;
}
@@ -160,14 +155,11 @@ int r600_cs_write_reloc(struct radeon_cs *cs,
{
return -ENOMEM;
}
- relocs[cs->crelocs].offset_mod.shift = poffset_mod->shift;
- relocs[cs->crelocs].offset_mod.shiftbits = poffset_mod->shiftbits;
- relocs[cs->crelocs].offset_mod.mask = poffset_mod->mask;
- relocs[cs->crelocs].indices[0] = cs->cdw - 1;
- relocs[cs->crelocs].reloc_indices[0] = cs->section_cdw;
- cs->section_ndw += 2;
+ relocs[cs->crelocs].indices[0] = cs->cdw;
+ relocs[cs->crelocs].reloc_indices[0] = cs->cdw;
cs->section_cdw += 2;
+ cs->cdw += 2;
relocs[cs->crelocs].cindices = 1;
cs->relocs_total_size += radeon_bo_legacy_relocs_size(bo);
cs->crelocs++;
@@ -191,11 +183,18 @@ static int r600_cs_begin(struct radeon_cs *cs,
return -EPIPE;
}
- if (cs->cdw + ndw + 32 > cs->ndw) { /* Left 32 DWORD (8 offset+pitch) spare room for reloc indices */
+ cs->section = 1;
+ cs->section_ndw = ndw;
+ cs->section_cdw = 0;
+ cs->section_file = file;
+ cs->section_func = func;
+ cs->section_line = line;
+
+ if (cs->cdw + ndw > cs->ndw) {
uint32_t tmp, *ptr;
- int num = (ndw > 0x3FF) ? ndw : 0x3FF;
+ int num = (ndw > 0x400) ? ndw : 0x400;
- tmp = (cs->cdw + 1 + num) & (~num);
+ tmp = (cs->cdw + num + 0x3FF) & (~0x3FF);
ptr = (uint32_t*)realloc(cs->packets, 4 * tmp);
if (ptr == NULL) {
return -ENOMEM;
@@ -204,13 +203,6 @@ static int r600_cs_begin(struct radeon_cs *cs,
cs->ndw = tmp;
}
- cs->section = 1;
- cs->section_ndw = 0;
- cs->section_cdw = cs->cdw + ndw; /* start of reloc indices. */
- cs->section_file = file;
- cs->section_func = func;
- cs->section_line = line;
-
return 0;
}
@@ -227,8 +219,7 @@ static int r600_cs_end(struct radeon_cs *cs,
}
cs->section = 0;
- if ( (cs->section_ndw + cs->cdw) != cs->section_cdw )
- {
+ if ( cs->section_ndw != cs->section_cdw ) {
fprintf(stderr, "CS section size missmatch start at (%s,%s,%d) %d vs %d\n",
cs->section_file, cs->section_func, cs->section_line, cs->section_ndw, cs->section_cdw);
fprintf(stderr, "cs->section_ndw = %d, cs->cdw = %d, cs->section_cdw = %d \n",
@@ -238,7 +229,14 @@ static int r600_cs_end(struct radeon_cs *cs,
return -EPIPE;
}
- cs->cdw = cs->section_cdw;
+ if (cs->cdw > cs->ndw) {
+ fprintf(stderr, "CS section overflow at (%s,%s,%d) cdw %d ndw %d\n",
+ cs->section_file, cs->section_func, cs->section_line,cs->cdw,cs->ndw);
+ fprintf(stderr, "CS section end at (%s,%s,%d)\n",
+ file, func, line);
+ assert(0);
+ }
+
return 0;
}
@@ -255,65 +253,44 @@ static int r600_cs_process_relocs(struct radeon_cs *cs,
csm = (struct r600_cs_manager_legacy*)cs->csm;
relocs = (struct r600_cs_reloc_legacy *)cs->relocs;
restart:
- for (i = 0; i < cs->crelocs; i++)
- {
- for (j = 0; j < relocs[i].cindices; j++)
- {
+ for (i = 0; i < cs->crelocs; i++) {
uint32_t soffset, eoffset, asicoffset;
r = radeon_bo_legacy_validate(relocs[i].base.bo,
- &soffset, &eoffset);
- if (r == -EAGAIN)
- {
- goto restart;
+ &soffset, &eoffset);
+ if (r == -EAGAIN) {
+ goto restart;
}
- if (r)
- {
- fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
- relocs[i].base.bo, soffset, eoffset);
- return r;
+ if (r) {
+ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
+ relocs[i].base.bo, soffset, eoffset);
+ return r;
}
asicoffset = soffset;
- if (asicoffset >= eoffset)
- {
- /* radeon_bo_debug(relocs[i].base.bo, 12); */
- fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
- relocs[i].base.bo, soffset, eoffset);
- fprintf(stderr, "above end: %p 0x%08X 0x%08X\n",
- relocs[i].base.bo,
- cs->packets[relocs[i].indices[j]],
- eoffset);
- exit(0);
- return -EINVAL;
- }
- /* apply offset operator */
- switch (relocs[i].offset_mod.shift)
- {
- case NO_SHIFT:
- asicoffset = asicoffset & relocs[i].offset_mod.mask;
- break;
- case LEFT_SHIFT:
- asicoffset = (asicoffset << relocs[i].offset_mod.shiftbits) & relocs[i].offset_mod.mask;
- break;
- case RIGHT_SHIFT:
- asicoffset = (asicoffset >> relocs[i].offset_mod.shiftbits) & relocs[i].offset_mod.mask;
- break;
- default:
- break;
- };
-
- /* pkt3 nop header in ib chunk */
- cs->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
-
- /* reloc index in ib chunk */
- cs->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
-
- /* asic offset in reloc chunk */ /* see alex drm r600_nomm_relocate */
- reloc_chunk[offset_dw] = asicoffset;
- reloc_chunk[offset_dw + 3] = 0;
-
- offset_dw += 4;
- }
+
+ for (j = 0; j < relocs[i].cindices; j++) {
+ if (asicoffset >= eoffset) {
+ /* radeon_bo_debug(relocs[i].base.bo, 12); */
+ fprintf(stderr, "validated %p [0x%08X, 0x%08X]\n",
+ relocs[i].base.bo, soffset, eoffset);
+ fprintf(stderr, "above end: %p 0x%08X 0x%08X\n",
+ relocs[i].base.bo,
+ cs->packets[relocs[i].indices[j]],
+ eoffset);
+ exit(0);
+ return -EINVAL;
+ }
+ /* pkt3 nop header in ib chunk */
+ cs->packets[relocs[i].reloc_indices[j]] = 0xC0001000;
+ /* reloc index in ib chunk */
+ cs->packets[relocs[i].reloc_indices[j] + 1] = offset_dw;
+ }
+
+ /* asic offset in reloc chunk */ /* see alex drm r600_nomm_relocate */
+ reloc_chunk[offset_dw] = asicoffset;
+ reloc_chunk[offset_dw + 3] = 0;
+
+ offset_dw += 4;
}
*length_dw_reloc_chunk = offset_dw;
@@ -335,6 +312,7 @@ static int r600_cs_set_age(struct radeon_cs *cs) /* -------------- */
return 0;
}
+#if 0
static void dump_cmdbuf(struct radeon_cs *cs)
{
int i;
@@ -345,61 +323,32 @@ static void dump_cmdbuf(struct radeon_cs *cs)
fprintf(stderr,"--end--\n");
}
+#endif
static int r600_cs_emit(struct radeon_cs *cs)
{
struct r600_cs_manager_legacy *csm = (struct r600_cs_manager_legacy*)cs->csm;
struct drm_radeon_cs cs_cmd;
struct drm_radeon_cs_chunk cs_chunk[2];
- drm_radeon_cmd_buffer_t cmd;
- /* drm_r300_cmd_header_t age; */
uint32_t length_dw_reloc_chunk;
- uint64_t ull;
uint64_t chunk_ptrs[2];
- uint32_t reloc_chunk[128];
+ uint32_t *reloc_chunk;
int r;
int retry = 0;
/* TODO : put chip level things here if need. */
/* csm->ctx->vtbl.emit_cs_header(cs, csm->ctx); */
- BATCH_LOCALS(csm->ctx);
- drm_radeon_getparam_t gp;
- uint32_t current_scratchx_age;
-
- gp.param = RADEON_PARAM_LAST_CLEAR;
- gp.value = (int *)&current_scratchx_age;
- r = drmCommandWriteRead(cs->csm->fd,
- DRM_RADEON_GETPARAM,
- &gp,
- sizeof(gp));
- if (r)
- {
- fprintf(stderr, "%s: drmRadeonGetParam: %d\n", __FUNCTION__, r);
- exit(1);
- }
-
- csm->pending_age = 0;
csm->pending_count = 1;
- current_scratchx_age++;
- csm->pending_age = current_scratchx_age;
-
- BEGIN_BATCH_NO_AUTOSTATE(3);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
- R600_OUT_BATCH((SCRATCH_REG2 - R600_SET_CONFIG_REG_OFFSET) >> 2);
- R600_OUT_BATCH(current_scratchx_age);
- END_BATCH();
- COMMIT_BATCH();
+ reloc_chunk = (uint32_t*)calloc(1, cs->crelocs * 4 * 4);
- //TODO ioctl to get back cs id assigned in drm
- //csm->pending_age = cs_id_back;
-
- r = r600_cs_process_relocs(cs, &(reloc_chunk[0]), &length_dw_reloc_chunk);
+ r = r600_cs_process_relocs(cs, reloc_chunk, &length_dw_reloc_chunk);
if (r) {
+ free(reloc_chunk);
return 0;
}
-
+
/* raw ib chunk */
cs_chunk[0].chunk_id = RADEON_CHUNK_ID_IB;
cs_chunk[0].length_dw = cs->cdw;
@@ -408,7 +357,7 @@ static int r600_cs_emit(struct radeon_cs *cs)
/* reloc chaunk */
cs_chunk[1].chunk_id = RADEON_CHUNK_ID_RELOCS;
cs_chunk[1].length_dw = length_dw_reloc_chunk;
- cs_chunk[1].chunk_data = (unsigned long)&(reloc_chunk[0]);
+ cs_chunk[1].chunk_data = (unsigned long)reloc_chunk;
chunk_ptrs[0] = (uint64_t)(unsigned long)&(cs_chunk[0]);
chunk_ptrs[1] = (uint64_t)(unsigned long)&(cs_chunk[1]);
@@ -426,15 +375,20 @@ static int r600_cs_emit(struct radeon_cs *cs)
} while (r == -EAGAIN && retry < 1000);
if (r) {
+ free(reloc_chunk);
return r;
}
+ csm->pending_age = cs_cmd.cs_id;
+
r600_cs_set_age(cs);
cs->csm->read_used = 0;
cs->csm->vram_write_used = 0;
cs->csm->gart_write_used = 0;
+ free(reloc_chunk);
+
return 0;
}
@@ -513,9 +467,11 @@ struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_cont
void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
{
- radeonContextPtr rmesa = &r600->radeon;
-
- GLuint size;
+ radeonContextPtr rmesa = &r600->radeon;
+ GLuint size;
+
+ r600InitAtoms(r600);
+
/* Initialize command buffer */
size = 256 * driQueryOptioni(&rmesa->optionCache,
"command_buffer_size");
@@ -538,7 +494,10 @@ void r600InitCmdBuf(context_t *r600) /* from rcommonInitCmdBuf */
rmesa->cmdbuf.cs = radeon_cs_create(rmesa->cmdbuf.csm, size);
assert(rmesa->cmdbuf.cs != NULL);
rmesa->cmdbuf.size = size;
-
+
+ radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
+ (void (*)(void *))rmesa->glCtx->Driver.Flush, rmesa->glCtx);
+
if (!rmesa->radeonScreen->kernel_mm) {
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_GTT, rmesa->radeonScreen->gartTextures.size);
diff --git a/src/mesa/drivers/dri/r600/r600_cmdbuf.h b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
index bd1ed7fdff..eba43d37b6 100644
--- a/src/mesa/drivers/dri/r600/r600_cmdbuf.h
+++ b/src/mesa/drivers/dri/r600/r600_cmdbuf.h
@@ -132,54 +132,37 @@ struct r600_cs_reloc_legacy {
uint32_t cindices;
uint32_t *indices;
uint32_t *reloc_indices;
- struct offset_modifiers offset_mod;
};
-extern int r600_cs_write_reloc(struct radeon_cs *cs,
- struct radeon_bo *bo,
- uint32_t read_domain,
- uint32_t write_domain,
- uint32_t flags,
- offset_modifiers* poffset_mod);
-
-static inline void r600_cs_write_dword(struct radeon_cs *cs, uint32_t dword)
-{
- cs->packets[cs->cdw++] = dword;
-}
-
struct radeon_cs_manager * r600_radeon_cs_manager_legacy_ctor(struct radeon_context *ctx);
/**
* Write one dword to the command buffer.
*/
-#define R600_OUT_BATCH(data) \
- do { \
- r600_cs_write_dword(b_l_rmesa->cmdbuf.cs, data);\
- } while(0)
+#define R600_OUT_BATCH(data) \
+do { \
+ radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, data); \
+} while(0)
/**
* Write n dwords from ptr to the command buffer.
*/
-#define R600_OUT_BATCH_TABLE(ptr,n) \
- do { \
- int _i; \
- for (_i=0; _i < n; _i++) {\
- r600_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\
- }\
- } while(0)
+#define R600_OUT_BATCH_TABLE(ptr,n) \
+do { \
+ radeon_cs_write_table(b_l_rmesa->cmdbuf.cs, ptr, n); \
+} while(0)
/**
* Write a relocated dword to the command buffer.
*/
-#define R600_OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags, offset_mod) \
+#define R600_OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \
do { \
if (0 && offset) { \
fprintf(stderr, "(%s:%s:%d) offset : %d\n", \
__FILE__, __FUNCTION__, __LINE__, offset); \
} \
- r600_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \
- r600_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \
- bo, rd, wd, flags, offset_mod); \
+ radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \
+ bo, rd, wd, flags); \
} while(0)
/* R600/R700 */
diff --git a/src/mesa/drivers/dri/r600/r600_context.c b/src/mesa/drivers/dri/r600/r600_context.c
index eacf811282..969144ba12 100644
--- a/src/mesa/drivers/dri/r600/r600_context.c
+++ b/src/mesa/drivers/dri/r600/r600_context.c
@@ -56,8 +56,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "drivers/common/driverfuncs.h"
+#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"
@@ -84,6 +86,7 @@ int hw_tcl_on = 1;
#define need_GL_EXT_framebuffer_object
#define need_GL_EXT_fog_coord
#define need_GL_EXT_gpu_program_parameters
+#define need_GL_EXT_provoking_vertex
#define need_GL_EXT_secondary_color
#define need_GL_EXT_stencil_two_side
#define need_GL_ATI_separate_stencil
@@ -116,6 +119,7 @@ const struct dri_extension card_extensions[] = {
{"GL_EXT_packed_depth_stencil", NULL},
{"GL_EXT_fog_coord", GL_EXT_fog_coord_functions },
{"GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions},
+ {"GL_EXT_provoking_vertex", GL_EXT_provoking_vertex_functions },
{"GL_EXT_secondary_color", GL_EXT_secondary_color_functions},
{"GL_EXT_shadow_funcs", NULL},
{"GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions},
@@ -127,6 +131,7 @@ const struct dri_extension card_extensions[] = {
{"GL_EXT_texture_lod_bias", NULL},
{"GL_EXT_texture_mirror_clamp", NULL},
{"GL_EXT_texture_rectangle", NULL},
+ {"GL_EXT_texture_sRGB", NULL},
{"GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions},
{"GL_ATI_texture_env_combine3", NULL},
{"GL_ATI_texture_mirror_once", NULL},
@@ -185,7 +190,7 @@ static void r600_vtbl_emit_cs_header(struct radeon_cs *cs, radeonContextPtr rmes
static void r600_vtbl_pre_emit_atoms(radeonContextPtr radeon)
{
- /* to be enabled */
+ r700Start3D((context_t *)radeon);
}
static void r600_fallback(GLcontext *ctx, GLuint bit, GLboolean mode)
@@ -225,8 +230,10 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
/* Allocate the R600 context */
r600 = (context_t*) CALLOC(sizeof(*r600));
- if (!r600)
+ if (!r600) {
+ radeon_error("Failed to allocate memory for context.\n");
return GL_FALSE;
+ }
if (!(screen->chip_flags & RADEON_CHIPSET_TCL))
hw_tcl_on = future_hw_tcl_on = 0;
@@ -247,16 +254,16 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
*/
_mesa_init_driver_functions(&functions);
- r700InitChipObject(r600); /* let the eag... */
-
r700InitStateFuncs(&functions);
r600InitTextureFuncs(&functions);
r700InitShaderFuncs(&functions);
r700InitIoctlFuncs(&functions);
+ radeonInitBufferObjectFuncs(&functions);
if (!radeonInitContext(&r600->radeon, &functions,
glVisual, driContextPriv,
sharedContextPrivate)) {
+ radeon_error("Initializing context failed.\n");
FREE(r600);
return GL_FALSE;
}
@@ -279,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;
@@ -325,30 +332,33 @@ 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;
+ radeon_init_debug();
+
driInitExtensions(ctx, card_extensions, GL_TRUE);
if (r600->radeon.radeonScreen->kernel_mm)
driInitExtensions(ctx, mm_extensions, GL_FALSE);
@@ -367,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 );
@@ -377,25 +389,10 @@ GLboolean r600CreateContext(const __GLcontextModes * glVisual,
TNL_CONTEXT(ctx)->Driver.RunPipeline = r600RunPipeline;
if (driQueryOptionb(&r600->radeon.optionCache, "no_rast")) {
- fprintf(stderr, "disabling 3D acceleration\n");
-#if R200_MERGED
- FALLBACK(&r600->radeon, RADEON_FALLBACK_DISABLE, 1);
-#endif
+ radeon_warning("disabling 3D acceleration\n");
}
return GL_TRUE;
}
-/* Clean our own things only, radeonDestroyContext will do every thing else. */
-void
-r600DestroyContext (__DRIcontextPrivate * driContextPriv)
-{
- GET_CURRENT_CONTEXT (ctx);
- context_t *context = ctx ? R700_CONTEXT(ctx) : NULL;
-
- if (context)
- FREE(context->hw.pStateList);
-}
-
-
diff --git a/src/mesa/drivers/dri/r600/r600_context.h b/src/mesa/drivers/dri/r600/r600_context.h
index bcb33e1386..a296ea23fa 100644
--- a/src/mesa/drivers/dri/r600/r600_context.h
+++ b/src/mesa/drivers/dri/r600/r600_context.h
@@ -51,32 +51,13 @@ 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;
-GLboolean r700SendPSState(context_t *context);
-GLboolean r700SendVSState(context_t *context);
-GLboolean r700SendSQConfig(context_t *context);
-
#include "main/mm.h"
-/* 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__){ \
- fprintf(stderr, "*********************************WARN_ONCE*********************************\n"); \
- fprintf(stderr, "File %s function %s line %d\n", \
- __FILE__, __FUNCTION__, __LINE__); \
- fprintf(stderr, a, ## __VA_ARGS__);\
- fprintf(stderr, "***************************************************************************\n"); \
- warn##__LINE__=0;\
- } \
- }
-
/************ DMA BUFFERS **************/
/* The blit width for texture uploads
@@ -105,35 +86,73 @@ 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;
+ struct radeon_state_atom stencil;
+ struct radeon_state_atom db_target;
+ struct radeon_state_atom sc;
+ struct radeon_state_atom scissor;
+ struct radeon_state_atom aa;
+ struct radeon_state_atom cl;
+ struct radeon_state_atom gb;
+ struct radeon_state_atom ucp;
+ struct radeon_state_atom su;
+ struct radeon_state_atom poly;
+ struct radeon_state_atom cb;
+ struct radeon_state_atom clrcmp;
+ struct radeon_state_atom blnd;
+ struct radeon_state_atom blnd_clr;
+ struct radeon_state_atom cb_target;
+ struct radeon_state_atom sx;
+ struct radeon_state_atom vgt;
+ struct radeon_state_atom spi;
+ struct radeon_state_atom vpt;
+
+ struct radeon_state_atom fs;
+ struct radeon_state_atom vs;
+ struct radeon_state_atom ps;
+
+ struct radeon_state_atom vs_consts;
+ struct radeon_state_atom ps_consts;
+
+ struct radeon_state_atom vtx;
+ struct radeon_state_atom tx;
+ struct radeon_state_atom tx_smplr;
+ struct radeon_state_atom tx_brdr_clr;
};
-typedef struct offset_modifiers
+typedef struct StreamDesc
{
- GLuint shift;
- GLuint shiftbits;
- GLuint mask;
-} offset_modifiers;
+ 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.
@@ -144,35 +163,52 @@ struct r600_context {
/* ------ */
R700_CHIP_CONTEXT hw;
+ 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))
#define GL_CONTEXT(context) ((GLcontext *)(context->radeon.glCtx))
-extern void r600DestroyContext(__DRIcontextPrivate * driContextPriv);
extern GLboolean r600CreateContext(const __GLcontextModes * glVisual,
__DRIcontextPrivate * driContextPriv,
void *sharedContextPrivate);
#define R700_CONTEXT_STATES(context) ((R700_CHIP_CONTEXT *)(&context->hw))
-extern GLboolean r700InitChipObject(context_t *context);
-extern GLboolean r700SendContextStates(context_t *context);
-extern GLboolean r700SendViewportState(context_t *context, int id);
-extern GLboolean r700SendRenderTargetState(context_t *context, int id);
-
-extern int r700SetupStreams(GLcontext * ctx);
-extern void r700SetupVTXConstants(GLcontext * ctx,
- unsigned int nStreamID,
- void * pAos,
- unsigned int size, /* number of elements in vector */
- unsigned int stride,
- unsigned int Count); /* number of vectors in stream */
+#define R600_NEWPRIM( rmesa ) \
+do { \
+ if ( rmesa->radeon.dma.flush ) \
+ rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \
+} while (0)
+
+#define R600_STATECHANGE(r600, ATOM) \
+do { \
+ R600_NEWPRIM(r600); \
+ r600->atoms.ATOM.dirty = GL_TRUE; \
+ r600->radeon.hw.is_dirty = GL_TRUE; \
+} while(0)
+
+extern GLboolean r700SyncSurf(context_t *context,
+ struct radeon_bo *pbo,
+ uint32_t read_domain,
+ uint32_t write_domain,
+ uint32_t sync_type);
+
+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_emit.c b/src/mesa/drivers/dri/r600/r600_emit.c
index 685f7fe473..5c250c2418 100644
--- a/src/mesa/drivers/dri/r600/r600_emit.c
+++ b/src/mesa/drivers/dri/r600/r600_emit.c
@@ -49,72 +49,67 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
void r600EmitCacheFlush(context_t *rmesa)
{
- BATCH_LOCALS(&rmesa->radeon);
}
-GLboolean r600EmitShader(GLcontext * ctx,
+GLboolean r600EmitShader(GLcontext * ctx,
void ** shaderbo,
- GLvoid * data,
+ GLvoid * data,
int sizeinDWORD,
- char * szShaderUsage)
+ char * szShaderUsage)
{
- radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
+ radeonContextPtr radeonctx = RADEON_CONTEXT(ctx);
+ struct radeon_bo * pbo;
+ uint32_t *out;
+shader_again_alloc:
+ pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
+ 0,
+ sizeinDWORD * 4,
+ 256,
+ RADEON_GEM_DOMAIN_GTT,
+ 0);
- struct radeon_bo * pbo;
- uint32_t *out;
+ radeon_print(RADEON_SHADER, RADEON_NORMAL, "%s %p size %d: %s\n", __func__, pbo, sizeinDWORD, szShaderUsage);
-shader_again_alloc:
-#ifdef RADEON_DEBUG_BO
- pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
- 0,
- sizeinDWORD * 4,
- 256,
- RADEON_GEM_DOMAIN_GTT,
- 0,
- szShaderUsage);
-#else
- pbo = radeon_bo_open(radeonctx->radeonScreen->bom,
- 0,
- sizeinDWORD * 4,
- 256,
- RADEON_GEM_DOMAIN_GTT,
- 0);
-#endif /* RADEON_DEBUG_BO */
-
- if (!pbo)
- {
+ if (!pbo) {
+ radeon_print(RADEON_MEMORY | RADEON_CS, RADEON_IMPORTANT, "No memory for buffer object. Flushing command buffer.\n");
rcommonFlushCmdBuf(radeonctx, __FUNCTION__);
goto shader_again_alloc;
}
- if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs,
- pbo,
- RADEON_GEM_DOMAIN_GTT, 0))
- fprintf(stderr,"failure to revalidate BOs - badness\n");
+ radeon_cs_space_add_persistent_bo(radeonctx->cmdbuf.cs,
+ pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ if (radeon_cs_space_check_with_bo(radeonctx->cmdbuf.cs,
+ pbo,
+ RADEON_GEM_DOMAIN_GTT, 0)) {
+ radeon_error("failure to revalidate BOs - badness\n");
+ return GL_FALSE;
+ }
radeon_bo_map(pbo, 1);
- radeon_bo_ref(pbo);
+ out = (uint32_t*)(pbo->ptr);
- out = (uint32_t*)(pbo->ptr);
+ memcpy(out, data, sizeinDWORD * 4);
- memcpy(out, data, sizeinDWORD * 4);
+ radeon_bo_unmap(pbo);
- radeon_bo_unmap(pbo);
+ *shaderbo = (void*)pbo;
- *shaderbo = (void*)pbo;
-
- return GL_TRUE;
+ return GL_TRUE;
}
-GLboolean r600DeleteShader(GLcontext * ctx,
- void * shaderbo)
+GLboolean r600DeleteShader(GLcontext * ctx,
+ void * shaderbo)
{
struct radeon_bo * pbo = (struct radeon_bo *)shaderbo;
+ radeon_print(RADEON_SHADER, RADEON_NORMAL, "%s: %p\n", __func__, pbo);
+
if (pbo) {
- radeon_bo_unmap(pbo);
+ if (pbo->ptr)
+ radeon_bo_unmap(pbo);
radeon_bo_unref(pbo); /* when bo->cref <= 0, bo will be bo_free */
}
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 9d5aa3c7e4..edd85b0fac 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/r600_tex.c b/src/mesa/drivers/dri/r600/r600_tex.c
index 43d9f641af..d105b90cd1 100644
--- a/src/mesa/drivers/dri/r600/r600_tex.c
+++ b/src/mesa/drivers/dri/r600/r600_tex.c
@@ -62,12 +62,12 @@ static unsigned int translate_wrap_mode(GLenum wrapmode)
case GL_CLAMP: return SQ_TEX_CLAMP_HALF_BORDER;
case GL_CLAMP_TO_EDGE: return SQ_TEX_CLAMP_LAST_TEXEL;
case GL_CLAMP_TO_BORDER: return SQ_TEX_CLAMP_BORDER;
- case GL_MIRRORED_REPEAT: return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
- case GL_MIRROR_CLAMP_EXT: return SQ_TEX_MIRROR;
- case GL_MIRROR_CLAMP_TO_EDGE_EXT: return SQ_TEX_MIRROR_ONCE_BORDER;
- case GL_MIRROR_CLAMP_TO_BORDER_EXT: return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case GL_MIRRORED_REPEAT: return SQ_TEX_MIRROR;
+ case GL_MIRROR_CLAMP_EXT: return SQ_TEX_MIRROR_ONCE_HALF_BORDER;
+ case GL_MIRROR_CLAMP_TO_EDGE_EXT: return SQ_TEX_MIRROR_ONCE_LAST_TEXEL;
+ case GL_MIRROR_CLAMP_TO_BORDER_EXT: return SQ_TEX_MIRROR_ONCE_BORDER;
default:
- _mesa_problem(NULL, "bad wrap mode in %s", __FUNCTION__);
+ radeon_error("bad wrap mode in %s", __FUNCTION__);
return 0;
}
}
@@ -127,10 +127,18 @@ static void r600SetTexDefaultState(radeonTexObjPtr t)
SETfield(t->SQ_TEX_RESOURCE4, SQ_ENDIAN_NONE,
SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_shift, SQ_TEX_RESOURCE_WORD4_0__ENDIAN_SWAP_mask);
SETfield(t->SQ_TEX_RESOURCE4, 1, REQUEST_SIZE_shift, REQUEST_SIZE_mask);
- t->SQ_TEX_RESOURCE4 |= SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift
- |SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift
- |SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift
- |SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift;
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
SETfield(t->SQ_TEX_RESOURCE4, 0, BASE_LEVEL_shift, BASE_LEVEL_mask); /* mip-maps */
t->SQ_TEX_RESOURCE5 = 0;
@@ -141,26 +149,27 @@ static void r600SetTexDefaultState(radeonTexObjPtr t)
/* Initialize sampler registers */
t->SQ_TEX_SAMPLER0 = 0;
- t->SQ_TEX_SAMPLER0 |=
- SQ_TEX_WRAP << SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift
- |SQ_TEX_WRAP << CLAMP_Y_shift
- |SQ_TEX_WRAP << CLAMP_Z_shift
- |SQ_TEX_XY_FILTER_POINT << XY_MAG_FILTER_shift
- |SQ_TEX_XY_FILTER_POINT << XY_MIN_FILTER_shift
- |SQ_TEX_Z_FILTER_NONE << Z_FILTER_shift
- |SQ_TEX_Z_FILTER_NONE << MIP_FILTER_shift
- |SQ_TEX_BORDER_COLOR_TRANS_BLACK << BORDER_COLOR_TYPE_shift;
-
- t->SQ_TEX_SAMPLER1 = 0x7FF << MAX_LOD_shift;
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_shift,
+ SQ_TEX_SAMPLER_WORD0_0__CLAMP_X_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, CLAMP_Y_shift, CLAMP_Y_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_WRAP, CLAMP_Z_shift, CLAMP_Z_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, XY_MAG_FILTER_shift, XY_MAG_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_XY_FILTER_POINT, XY_MIN_FILTER_shift, XY_MIN_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, Z_FILTER_shift, Z_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_Z_FILTER_NONE, MIP_FILTER_shift, MIP_FILTER_mask);
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_TRANS_BLACK, BORDER_COLOR_TYPE_shift, BORDER_COLOR_TYPE_mask);
+
+ t->SQ_TEX_SAMPLER1 = 0;
+ SETfield(t->SQ_TEX_SAMPLER1, 0x3ff, MAX_LOD_shift, MAX_LOD_mask);
t->SQ_TEX_SAMPLER2 = 0;
SETbit(t->SQ_TEX_SAMPLER2, SQ_TEX_SAMPLER_WORD2_0__TYPE_bit);
}
+#if 0
static GLuint aniso_filter(GLfloat anisotropy)
{
-#if 0
if (anisotropy >= 16.0) {
return R300_TX_MAX_ANISO_16_TO_1;
} else if (anisotropy >= 8.0) {
@@ -172,9 +181,9 @@ static GLuint aniso_filter(GLfloat anisotropy)
} else {
return R300_TX_MAX_ANISO_1_TO_1;
}
-#endif
return 0;
}
+#endif
/**
* Set the texture magnification and minification modes.
@@ -199,8 +208,7 @@ static void r600SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloa
| R300_TX_MIN_FILTER_ANISO
| R300_TX_MIN_FILTER_MIP_LINEAR
| aniso_filter(anisotropy);*/
- if (RADEON_DEBUG & DEBUG_TEXTURE)
- fprintf(stderr, "Using maximum anisotropy of %f\n", anisotropy);
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL, "Using maximum anisotropy of %f\n", anisotropy);
return;
}
@@ -260,14 +268,12 @@ static void r600SetTexFilter(radeonTexObjPtr t, GLenum minf, GLenum magf, GLfloa
static void r600SetTexBorderColor(radeonTexObjPtr t, const GLfloat color[4])
{
-#if 0
- GLubyte c[4];
- CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]);
- CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]);
- CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]);
- CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]);
- t->pp_border_color = PACK_COLOR_8888(c[3], c[0], c[1], c[2]);
-#endif
+ t->TD_PS_SAMPLER0_BORDER_ALPHA = *((uint32_t*)&(color[3]));
+ t->TD_PS_SAMPLER0_BORDER_RED = *((uint32_t*)&(color[2]));
+ t->TD_PS_SAMPLER0_BORDER_GREEN = *((uint32_t*)&(color[1]));
+ t->TD_PS_SAMPLER0_BORDER_BLUE = *((uint32_t*)&(color[0]));
+ SETfield(t->SQ_TEX_SAMPLER0, SQ_TEX_BORDER_COLOR_REGISTER,
+ BORDER_COLOR_TYPE_shift, BORDER_COLOR_TYPE_mask);
}
/**
@@ -281,10 +287,9 @@ static void r600TexParameter(GLcontext * ctx, GLenum target,
{
radeonTexObj* t = radeon_tex_obj(texObj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
- fprintf(stderr, "%s( %s )\n", __FUNCTION__,
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_VERBOSE,
+ "%s( %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(pname));
- }
switch (pname) {
case GL_TEXTURE_MIN_FILTER:
@@ -344,11 +349,10 @@ static void r600DeleteTexture(GLcontext * ctx, struct gl_texture_object *texObj)
context_t* rmesa = R700_CONTEXT(ctx);
radeonTexObj* t = radeon_tex_obj(texObj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
- fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
+ "%s( %p (target = %s) )\n", __FUNCTION__,
(void *)texObj,
_mesa_lookup_enum_by_nr(texObj->Target));
- }
if (rmesa) {
int i;
@@ -386,10 +390,9 @@ static struct gl_texture_object *r600NewTextureObject(GLcontext * ctx,
radeonTexObj* t = CALLOC_STRUCT(radeon_tex_obj);
- if (RADEON_DEBUG & (DEBUG_STATE | DEBUG_TEXTURE)) {
- fprintf(stderr, "%s( %p (target = %s) )\n", __FUNCTION__,
+ radeon_print(RADEON_STATE | RADEON_TEXTURE, RADEON_NORMAL,
+ "%s( %p (target = %s) )\n", __FUNCTION__,
t, _mesa_lookup_enum_by_nr(target));
- }
_mesa_initialize_texture_object(&t->base, name, target);
t->base.MaxAnisotropy = rmesa->radeon.initialMaxAnisotropy;
diff --git a/src/mesa/drivers/dri/r600/r600_texstate.c b/src/mesa/drivers/dri/r600/r600_texstate.c
index 2466aa9595..7d7e77d355 100644
--- a/src/mesa/drivers/dri/r600/r600_texstate.c
+++ b/src/mesa/drivers/dri/r600/r600_texstate.c
@@ -43,11 +43,14 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/teximage.h"
#include "main/texobj.h"
#include "main/enums.h"
+#include "main/simple_list.h"
#include "r600_context.h"
#include "r700_state.h"
#include "radeon_mipmap_tree.h"
#include "r600_tex.h"
+#include "r700_fragprog.h"
+#include "r700_vertprog.h"
void r600UpdateTextureState(GLcontext * ctx);
@@ -59,10 +62,14 @@ void r600UpdateTextureState(GLcontext * ctx)
struct radeon_tex_obj *t;
GLuint unit;
+ R600_STATECHANGE(context, tx);
+ R600_STATECHANGE(context, tx_smplr);
+ R600_STATECHANGE(context, tx_brdr_clr);
+
for (unit = 0; unit < R700_MAX_TEXTURE_UNITS; unit++) {
texUnit = &ctx->Texture.Unit[unit];
t = radeon_tex_obj(ctx->Texture.Unit[unit]._Current);
-
+ r700->textures[unit] = NULL;
if (texUnit->_ReallyEnabled) {
if (!t)
continue;
@@ -75,10 +82,10 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, GLuint mesa_fo
{
radeonTexObj *t = radeon_tex_obj(tObj);
- t->SQ_TEX_RESOURCE4 &= ~( SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask
- |SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask
- |SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask
- |SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask );
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ CLEARfield(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
switch (mesa_format) /* This is mesa format. */
{
@@ -86,163 +93,211 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, GLuint mesa_fo
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGBA8888_REV:
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB8888:
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB8888_REV:
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB888:
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB565:
SETfield(t->SQ_TEX_RESOURCE1, FMT_5_6_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB565_REV:
SETfield(t->SQ_TEX_RESOURCE1, FMT_5_6_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB4444:
SETfield(t->SQ_TEX_RESOURCE1, FMT_4_4_4_4,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB4444_REV:
SETfield(t->SQ_TEX_RESOURCE1, FMT_4_4_4_4,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB1555:
SETfield(t->SQ_TEX_RESOURCE1, FMT_1_5_5_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ARGB1555_REV:
SETfield(t->SQ_TEX_RESOURCE1, FMT_1_5_5_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_AL88:
case MESA_FORMAT_AL88_REV: /* TODO : Check this. */
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB332:
SETfield(t->SQ_TEX_RESOURCE1, FMT_3_3_2,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_A8: /* ZERO, ZERO, ZERO, X */
SETfield(t->SQ_TEX_RESOURCE1, FMT_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_L8: /* X, X, X, ONE */
SETfield(t->SQ_TEX_RESOURCE1, FMT_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_I8: /* X, X, X, X */
case MESA_FORMAT_CI8:
SETfield(t->SQ_TEX_RESOURCE1, FMT_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
/* YUV422 TODO conversion */ /* X, Y, Z, ONE, G8R8_G8B8 */
/*
@@ -272,121 +327,157 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, GLuint mesa_fo
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_32_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGBA_FLOAT16:
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_16_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB_FLOAT32: /* X, Y, Z, ONE */
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_RGB_FLOAT16:
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ALPHA_FLOAT32: /* ZERO, ZERO, ZERO, X */
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_ALPHA_FLOAT16: /* ZERO, ZERO, ZERO, X */
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_LUMINANCE_FLOAT32: /* X, X, X, ONE */
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_LUMINANCE_FLOAT16: /* X, X, X, ONE */
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT32:
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_LUMINANCE_ALPHA_FLOAT16:
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_INTENSITY_FLOAT32: /* X, X, X, X */
SETfield(t->SQ_TEX_RESOURCE1, FMT_32_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_INTENSITY_FLOAT16: /* X, X, X, X */
SETfield(t->SQ_TEX_RESOURCE1, FMT_16_FLOAT,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case MESA_FORMAT_Z16:
case MESA_FORMAT_Z24_S8:
@@ -407,30 +498,82 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, GLuint mesa_fo
};
switch (tObj->DepthMode) {
case GL_LUMINANCE: /* X, X, X, ONE */
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case GL_INTENSITY: /* X, X, X, X */
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
case GL_ALPHA: /* ZERO, ZERO, ZERO, X */
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_0 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_0,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
break;
default:
return GL_FALSE;
}
break;
+ /* EXT_texture_sRGB */
+ case MESA_FORMAT_SRGBA8:
+ SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
+ SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
+ case MESA_FORMAT_SLA8:
+ SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8,
+ SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
+ case MESA_FORMAT_SL8: /* X, X, X, ONE */
+ SETfield(t->SQ_TEX_RESOURCE1, FMT_8,
+ SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
+
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
+ SETbit(t->SQ_TEX_RESOURCE4, SQ_TEX_RESOURCE_WORD4_0__FORCE_DEGAMMA_bit);
+ break;
default:
/* Not supported format */
return GL_FALSE;
@@ -441,7 +584,6 @@ static GLboolean r600GetTexFormat(struct gl_texture_object *tObj, GLuint mesa_fo
void r600SetDepthTexMode(struct gl_texture_object *tObj)
{
- const GLuint *format;
radeonTexObjPtr t;
if (!tObj)
@@ -464,21 +606,23 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
radeonTexObj *t = radeon_tex_obj(texObj);
const struct gl_texture_image *firstImage;
int firstlevel = t->mt ? t->mt->firstLevel : 0;
- GLuint uTexelPitch;
+ GLuint uTexelPitch, row_align;
+
+ if (rmesa->radeon.radeonScreen->driScreen->dri2.enabled &&
+ t->image_override &&
+ t->bo)
+ return;
firstImage = t->base.Image[0][firstlevel];
if (!t->image_override) {
if (!r600GetTexFormat(texObj, firstImage->TexFormat->MesaFormat)) {
- _mesa_problem(NULL, "unexpected texture format in %s",
+ radeon_error("unexpected texture format in %s\n",
__FUNCTION__);
return;
}
}
- if (t->image_override && t->bo)
- return;
-
switch (texObj->Target) {
case GL_TEXTURE_1D:
SETfield(t->SQ_TEX_RESOURCE0, SQ_TEX_DIM_1D, DIM_shift, DIM_mask);
@@ -499,19 +643,30 @@ static void setup_hardware_state(context_t *rmesa, struct gl_texture_object *tex
SETfield(t->SQ_TEX_RESOURCE1, 0, TEX_DEPTH_shift, TEX_DEPTH_mask);
break;
default:
- _mesa_problem(NULL, "unexpected texture target type in %s", __FUNCTION__);
+ radeon_error("unexpected texture target type in %s\n", __FUNCTION__);
return;
}
- uTexelPitch = (firstImage->Width + R700_TEXEL_PITCH_ALIGNMENT_MASK)
+ row_align = rmesa->radeon.texture_row_align - 1;
+ uTexelPitch = ((firstImage->Width * t->mt->bpp + row_align) & ~row_align) / t->mt->bpp;
+ uTexelPitch = (uTexelPitch + R700_TEXEL_PITCH_ALIGNMENT_MASK)
& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+ /* min pitch is 8 */
+ if (uTexelPitch < 8)
+ uTexelPitch = 8;
+
SETfield(t->SQ_TEX_RESOURCE0, (uTexelPitch/8)-1, PITCH_shift, PITCH_mask);
SETfield(t->SQ_TEX_RESOURCE0, firstImage->Width - 1,
TEX_WIDTH_shift, TEX_WIDTH_mask);
SETfield(t->SQ_TEX_RESOURCE1, firstImage->Height - 1,
TEX_HEIGHT_shift, TEX_HEIGHT_mask);
+ if ((t->mt->lastLevel - t->mt->firstLevel) > 0) {
+ t->SQ_TEX_RESOURCE3 = t->mt->levels[0].size / 256;
+ SETfield(t->SQ_TEX_RESOURCE4, t->mt->firstLevel, BASE_LEVEL_shift, BASE_LEVEL_mask);
+ SETfield(t->SQ_TEX_RESOURCE5, t->mt->lastLevel, LAST_LEVEL_shift, LAST_LEVEL_mask);
+ }
}
/**
@@ -542,6 +697,7 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
{
context_t *rmesa = R700_CONTEXT(ctx);
struct radeon_renderbuffer *rrb;
+ struct radeon_bo *pbo;
int i;
int ret;
@@ -570,9 +726,7 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
continue;
if (!r600_validate_texture(ctx, ctx->Texture.Unit[i]._Current)) {
- _mesa_warning(ctx,
- "failed to validate texture for unit %d.\n",
- i);
+ radeon_warning("failed to validate texture for unit %d.\n", i);
}
t = radeon_tex_obj(ctx->Texture.Unit[i]._Current);
if (t->image_override && t->bo)
@@ -585,7 +739,19 @@ GLboolean r600ValidateBuffers(GLcontext * ctx)
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(ctx);
+ if (pbo) {
+ radeon_cs_space_add_persistent_bo(rmesa->radeon.cmdbuf.cs, pbo,
+ RADEON_GEM_DOMAIN_GTT, 0);
+ }
+
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
return GL_FALSE;
return GL_TRUE;
@@ -598,7 +764,7 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
struct gl_texture_object *tObj =
_mesa_lookup_texture(rmesa->radeon.glCtx, texname);
radeonTexObjPtr t = radeon_tex_obj(tObj);
- uint32_t pitch_val;
+ uint32_t pitch_val, size;
if (!tObj)
return;
@@ -608,7 +774,12 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
if (!offset)
return;
- t->bo = NULL;
+ size = pitch;//h * w * (depth / 8);
+ if (t->bo) {
+ radeon_bo_unref(t->bo);
+ t->bo = NULL;
+ }
+ t->bo = radeon_legacy_bo_alloc_fake(rmesa->radeon.radeonScreen->bom, size, offset);
t->override_offset = offset;
pitch_val = pitch;
switch (depth) {
@@ -616,11 +787,14 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
pitch_val /= 4;
break;
case 24:
@@ -628,28 +802,39 @@ void r600SetTexOffset(__DRIcontext * pDRICtx, GLint texname,
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
pitch_val /= 4;
break;
case 16:
SETfield(t->SQ_TEX_RESOURCE1, FMT_5_6_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
pitch_val /= 2;
break;
}
pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+
+ /* min pitch is 8 */
+ if (pitch_val < 8)
+ pitch_val = 8;
+
SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, PITCH_shift, PITCH_mask);
}
@@ -739,20 +924,26 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
} else {
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
}
pitch_val /= 4;
break;
@@ -762,22 +953,28 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
SETfield(t->SQ_TEX_RESOURCE1, FMT_8_8_8_8,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_W << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_W,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
pitch_val /= 4;
break;
case 2:
SETfield(t->SQ_TEX_RESOURCE1, FMT_5_6_5,
SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_shift, SQ_TEX_RESOURCE_WORD1_0__DATA_FORMAT_mask);
- t->SQ_TEX_RESOURCE4 |=
- (SQ_SEL_Z << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift)
- |(SQ_SEL_Y << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift)
- |(SQ_SEL_X << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift)
- |(SQ_SEL_1 << SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Z,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_X_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_Y,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Y_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_X,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_Z_mask);
+ SETfield(t->SQ_TEX_RESOURCE4, SQ_SEL_1,
+ SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_shift, SQ_TEX_RESOURCE_WORD4_0__DST_SEL_W_mask);
pitch_val /= 2;
break;
}
@@ -785,6 +982,10 @@ void r600SetTexBuffer2(__DRIcontext *pDRICtx, GLint target, GLint glx_texture_fo
pitch_val = (pitch_val + R700_TEXEL_PITCH_ALIGNMENT_MASK)
& ~R700_TEXEL_PITCH_ALIGNMENT_MASK;
+ /* min pitch is 8 */
+ if (pitch_val < 8)
+ pitch_val = 8;
+
SETfield(t->SQ_TEX_RESOURCE0, (pitch_val/8)-1, PITCH_shift, PITCH_mask);
SETfield(t->SQ_TEX_RESOURCE0, rb->base.Width - 1,
TEX_WIDTH_shift, TEX_WIDTH_mask);
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c
index 1d41c5cf78..81269350e4 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.c
+++ b/src/mesa/drivers/dri/r600/r700_assembler.c
@@ -33,8 +33,8 @@
#include "main/mtypes.h"
#include "main/imports.h"
+#include "radeon_debug.h"
#include "r600_context.h"
-#include "r700_debug.h"
#include "r700_assembler.h"
@@ -366,8 +366,8 @@ unsigned int r700GetNumOperands(r700_AssemblerBase* pAsm)
case SQ_OP2_INST_COS:
return 1;
- default: r700_error(TODO_ASM_NEEDIMPINST,
- "Need instruction operand number. \n");;
+ default: radeon_error(
+ "Need instruction operand number for %x.\n", pAsm->D.dst.opcode);
};
return 3;
@@ -531,7 +531,7 @@ int check_current_clause(r700_AssemblerBase* pAsm,
case CF_EMPTY_CLAUSE:
break;
default:
- r700_error(ERROR_ASM_VTX_CLAUSE,
+ radeon_error(
"Unknown CF_CLAUSE_TYPE (%d) in check_current_clause. \n", (int) new_clause_type);
return GL_FALSE;
}
@@ -565,7 +565,7 @@ int check_current_clause(r700_AssemblerBase* pAsm,
}
else
{
- r700_error(ERROR_ASM_ALLOCEXPORTCF,
+ radeon_error(
"Error allocating new EXPORT CF instruction in check_current_clause. \n");
return GL_FALSE;
}
@@ -578,7 +578,7 @@ int check_current_clause(r700_AssemblerBase* pAsm,
pAsm->cf_current_clause_type = CF_OTHER_CLAUSE;
break;
default:
- r700_error(ERROR_ASM_UNKOWNCLAUSE,
+ radeon_error(
"Unknown CF_CLAUSE_TYPE (%d) in check_current_clause. \n", (int) new_clause_type);
return GL_FALSE;
}
@@ -611,7 +611,7 @@ GLboolean add_vfetch_instruction(r700_AssemblerBase* pAsm,
}
else
{
- r700_error(ERROR_ASM_ALLOCVTXCF, "Could not allocate a new VFetch CF instruction.");
+ radeon_error("Could not allocate a new VFetch CF instruction.\n");
return GL_FALSE;
}
@@ -661,7 +661,7 @@ GLboolean add_tex_instruction(r700_AssemblerBase* pAsm,
}
else
{
- r700_error(ERROR_ASM_ALLOCTEXCF, "Could not allocate a new TEX CF instruction.");
+ radeon_error("Could not allocate a new TEX CF instruction.\n");
return GL_FALSE;
}
@@ -786,6 +786,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;
@@ -1047,7 +1174,7 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm,
}
break;
default:
- r700_error(ERROR_ASM_SRCARGUMENT, "Invalid source argument type");
+ radeon_error("Invalid source argument type\n");
return GL_FALSE;
}
}
@@ -1094,7 +1221,7 @@ GLboolean assemble_dst(r700_AssemblerBase *pAsm)
}
break;
default:
- r700_error(ERROR_ASM_DSTARGUMENT, "Invalid destination output argument type");
+ radeon_error("Invalid destination output argument type\n");
return GL_FALSE;
}
@@ -1134,7 +1261,7 @@ GLboolean tex_dst(r700_AssemblerBase *pAsm)
}
else
{
- r700_error(ERROR_ASM_DSTARGUMENT, "Invalid destination output argument type");
+ radeon_error("Invalid destination output argument type\n");
return GL_FALSE;
}
@@ -1149,46 +1276,54 @@ 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)
- {
+ switch (pILInst->SrcReg[0].File) {
+ case PROGRAM_CONSTANT:
+ case PROGRAM_LOCAL_PARAM:
+ case PROGRAM_ENV_PARAM:
+ case PROGRAM_STATE_VAR:
+ bValidTexCoord = GL_TRUE;
+ setaddrmode_PVSSRC(&(pAsm->S[0].src), ADDR_ABSOLUTE);
+ pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
+ pAsm->S[0].src.reg = pAsm->aArgSubst[1];
+ break;
case PROGRAM_TEMPORARY:
- bValidTexCoord = GL_TRUE;
-
- pAsm->S[0].src.reg = pILInst->SrcReg[0].Index + pAsm->starting_temp_register_number;
- pAsm->S[0].src.rtype = SRC_REG_TEMPORARY;
-
- break;
+ bValidTexCoord = GL_TRUE;
+ 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;
+ 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
{
- r700_error(ERROR_ASM_BADTEXSRC, "Invalid source texcoord for TEX instruction");
+ radeon_error("Invalid source texcoord for TEX instruction\n");
return GL_FALSE;
}
@@ -1201,11 +1336,11 @@ 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;
}
-GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm)
+GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalized)
{
PVSSRC * texture_coordinate_source;
PVSSRC * texture_unit_source;
@@ -1227,10 +1362,18 @@ GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm)
tex_instruction_ptr->m_Word0.f.resource_id = texture_unit_source->reg;
tex_instruction_ptr->m_Word1.f.lod_bias = 0x0;
- tex_instruction_ptr->m_Word1.f.coord_type_x = SQ_TEX_NORMALIZED;
- tex_instruction_ptr->m_Word1.f.coord_type_y = SQ_TEX_NORMALIZED;
- tex_instruction_ptr->m_Word1.f.coord_type_z = SQ_TEX_NORMALIZED;
- tex_instruction_ptr->m_Word1.f.coord_type_w = SQ_TEX_NORMALIZED;
+ if (normalized) {
+ tex_instruction_ptr->m_Word1.f.coord_type_x = SQ_TEX_NORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_y = SQ_TEX_NORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_z = SQ_TEX_NORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_w = SQ_TEX_NORMALIZED;
+ } else {
+ /* XXX: UNNORMALIZED tex coords have limited wrap modes */
+ tex_instruction_ptr->m_Word1.f.coord_type_x = SQ_TEX_UNNORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_y = SQ_TEX_UNNORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_z = SQ_TEX_UNNORMALIZED;
+ tex_instruction_ptr->m_Word1.f.coord_type_w = SQ_TEX_UNNORMALIZED;
+ }
tex_instruction_ptr->m_Word2.f.offset_x = 0x0;
tex_instruction_ptr->m_Word2.f.offset_y = 0x0;
@@ -1261,7 +1404,7 @@ GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm)
}
else
{
- r700_error(ERROR_ASM_TEXDSTBADTYPE, "Only temp destination registers supported for TEX dest regs.");
+ radeon_error("Only temp destination registers supported for TEX dest regs.\n");
return GL_FALSE;
}
@@ -1354,7 +1497,7 @@ GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
}
else
{
- r700_error(ERROR_ASM_ALUSRCBADTYPE, "Source (%d) register type (%d) not one of TEMP, INPUT, or CONSTANT.",
+ radeon_error("Source (%d) register type (%d) not one of TEMP, INPUT, or CONSTANT.\n",
source_index, pSource->rtype);
return GL_FALSE;
}
@@ -1389,7 +1532,7 @@ GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
src_chan = SQ_CHAN_X;
break;
default:
- r700_error(ERROR_ASM_ALUSRCSELECT, "Unknown source select value (%d) in assemble_alu_src().");
+ radeon_error("Unknown source select value (%d) in assemble_alu_src().\n", channel_swizzle);
return GL_FALSE;
break;
}
@@ -1424,7 +1567,7 @@ GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
alu_instruction_ptr->m_Word1_OP3.f.src2_neg = src_neg;
break;
default:
- r700_error(ERROR_ASM_ALUSRCNUMBER, "Only three sources allowed in ALU opcodes.");
+ radeon_error("Only three sources allowed in ALU opcodes.\n");
return GL_FALSE;
break;
}
@@ -1459,7 +1602,7 @@ GLboolean add_alu_instruction(r700_AssemblerBase* pAsm,
}
else
{
- r700_error(ERROR_ASM_ALLOCALUCF, "Could not allocate a new ALU CF instruction.");
+ radeon_error("Could not allocate a new ALU CF instruction.\n");
return GL_FALSE;
}
@@ -1627,7 +1770,7 @@ GLboolean reserve_cfile(r700_AssemblerBase* pAsm,
}
else
{
- r700_error(ERROR_ASM_CONSTCHANNEL, "All cfile read ports are used, cannot reference C$sel, channel $chan.");
+ radeon_error("All cfile read ports are used, cannot reference C$sel, channel $chan.\n");
return GL_FALSE;
}
return GL_TRUE;
@@ -1641,7 +1784,7 @@ GLboolean reserve_gpr(r700_AssemblerBase* pAsm, GLuint sel, GLuint chan, GLuint
}
else if(pAsm->hw_gpr[cycle][chan] != (int)sel)
{
- r700_error(ERROR_ASM_BADGPRRESERVE, "Another scalar operation has already used GPR read port for given channel");
+ radeon_error("Another scalar operation has already used GPR read port for given channel\n");
return GL_FALSE;
}
@@ -1681,7 +1824,7 @@ GLboolean cycle_for_scalar_bank_swizzle(const int swiz, const int sel, GLuint* p
}
break;
default:
- r700_error(ERROR_ASM_BADSCALARBZ, "Bad Scalar bank swizzle value");
+ radeon_error("Bad Scalar bank swizzle value\n");
break;
}
@@ -1729,7 +1872,7 @@ GLboolean cycle_for_vector_bank_swizzle(const int swiz, const int sel, GLuint* p
}
break;
default:
- r700_error(ERROR_ASM_BADVECTORBZ, "Bad Vec bank swizzle value");
+ radeon_error("Bad Vec bank swizzle value\n");
return GL_FALSE;
break;
}
@@ -2008,7 +2151,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;
@@ -2048,7 +2191,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
}
else
{
- r700_error(ERROR_ASM_ALUDSTBADTYPE, "Only temp destination registers supported for ALU dest regs.");
+ radeon_error("Only temp destination registers supported for ALU dest regs.\n");
return GL_FALSE;
}
@@ -2124,7 +2267,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
alu_instruction_ptr->m_Word1_OP2.f6.write_mask = pAsm->D.dst.writew;
break;
default:
- alu_instruction_ptr->m_Word1_OP2.f6.write_mask = SQ_SEL_MASK;
+ alu_instruction_ptr->m_Word1_OP2.f6.write_mask = 1; //SQ_SEL_MASK;
break;
}
alu_instruction_ptr->m_Word1_OP2.f6.omod = SQ_ALU_OMOD_OFF;
@@ -2153,7 +2296,7 @@ GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm)
alu_instruction_ptr->m_Word1_OP2.f.write_mask = pAsm->D.dst.writew;
break;
default:
- alu_instruction_ptr->m_Word1_OP2.f.write_mask = SQ_SEL_MASK;
+ alu_instruction_ptr->m_Word1_OP2.f.write_mask = 1; //SQ_SEL_MASK;
break;
}
alu_instruction_ptr->m_Word1_OP2.f.omod = SQ_ALU_OMOD_OFF;
@@ -2194,19 +2337,29 @@ GLboolean next_ins(r700_AssemblerBase *pAsm)
{
struct prog_instruction *pILInst = &(pAsm->pILInst[pAsm->uiCurInst]);
- if( GL_TRUE == IsTex(pILInst->Opcode) )
- {
- if( GL_FALSE == assemble_tex_instruction(pAsm) )
- {
- r700_error(ERROR_ASM_TEXINSTRUCTION, "Error assembling TEX instruction");
- return GL_FALSE;
- }
+ if( GL_TRUE == IsTex(pILInst->Opcode) &&
+ /* handle const moves to temp register */
+ !(pAsm->D.dst.opcode == SQ_OP2_INST_MOV) )
+ {
+ if (pILInst->TexSrcTarget == TEXTURE_RECT_INDEX) {
+ if( GL_FALSE == assemble_tex_instruction(pAsm, GL_FALSE) )
+ {
+ radeon_error("Error assembling TEX instruction\n");
+ return GL_FALSE;
+ }
+ } else {
+ if( GL_FALSE == assemble_tex_instruction(pAsm, GL_TRUE) )
+ {
+ radeon_error("Error assembling TEX instruction\n");
+ return GL_FALSE;
+ }
+ }
}
else
{ //ALU
if( GL_FALSE == assemble_alu_instruction(pAsm) )
{
- r700_error(ERROR_ASM_TEXINSTRUCTION, "Error assembling ALU instruction");
+ radeon_error("Error assembling ALU instruction\n");
return GL_FALSE;
}
}
@@ -2351,7 +2504,7 @@ GLboolean assemble_ADD(r700_AssemblerBase *pAsm)
GLboolean assemble_BAD(char *opcode_str)
{
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction (%s)", opcode_str);
+ radeon_error("Not yet implemented instruction (%s)\n", opcode_str);
return GL_FALSE;
}
@@ -2854,6 +3007,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;
@@ -2865,11 +3023,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);
@@ -2883,34 +3036,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;
@@ -2922,29 +3088,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) )
{
@@ -3358,32 +3514,35 @@ 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)
{
- r700_error(TODO_ASM_CONSTTEXADDR, "TODO: Texture coordinates from a constant register not supported.");
- return GL_FALSE;
+ if ( GL_FALSE == mov_temp(pAsm, 0) )
+ return GL_FALSE;
}
- switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
+ switch (pAsm->pILInst[pAsm->uiCurInst].Opcode)
{
case OPCODE_TEX:
- pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
+ pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
break;
- case OPCODE_TXB:
- r700_error(TODO_ASM_TXB, "do not support TXB yet");
+ 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 */
+ case OPCODE_TXP:
+ /* TODO : tex proj version : divid first 3 components by 4th */
pAsm->D.dst.opcode = SQ_TEX_INST_SAMPLE;
break;
default:
- r700_error(ERROR_ASM_BADTEXINST, "Internal error: bad texture op (not TEX)");
+ radeon_error("Internal error: bad texture op (not TEX)\n");
return GL_FALSE;
break;
}
@@ -3402,13 +3561,13 @@ 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 ( GL_FALSE == next_ins(pAsm) )
{
return GL_FALSE;
}
@@ -3565,12 +3724,12 @@ GLboolean AssembleInstr(GLuint uiNumberInsts,
break;
case OPCODE_ARL:
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction OPCODE_ARL ");
+ radeon_error("Not yet implemented instruction OPCODE_ARL \n");
//if ( GL_FALSE == assemble_BAD("ARL") )
return GL_FALSE;
break;
case OPCODE_ARR:
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction OPCODE_ARR ");
+ radeon_error("Not yet implemented instruction OPCODE_ARR \n");
//if ( GL_FALSE == assemble_BAD("ARR") )
return GL_FALSE;
break;
@@ -3601,7 +3760,7 @@ GLboolean AssembleInstr(GLuint uiNumberInsts,
return GL_FALSE;
break;
case OPCODE_EXP:
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction OPCODE_EXP ");
+ radeon_error("Not yet implemented instruction OPCODE_EXP \n");
//if ( GL_FALSE == assemble_BAD("EXP") )
return GL_FALSE;
break; // approx of EX2
@@ -3637,7 +3796,7 @@ GLboolean AssembleInstr(GLuint uiNumberInsts,
return GL_FALSE;
break;
case OPCODE_LOG:
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction OPCODE_LOG ");
+ radeon_error("Not yet implemented instruction OPCODE_LOG \n");
//if ( GL_FALSE == assemble_BAD("LOG") )
return GL_FALSE;
break; // approx of LG2
@@ -3736,7 +3895,7 @@ GLboolean AssembleInstr(GLuint uiNumberInsts,
return GL_FALSE;
break;
case OPCODE_ELSE :
- r700_error(TODO_ASM_NEEDIMPINST, "Not yet implemented instruction OPCODE_ELSE ");
+ radeon_error("Not yet implemented instruction OPCODE_ELSE \n");
//if ( GL_FALSE == assemble_BAD("ELSE") )
return GL_FALSE;
break;
@@ -3758,7 +3917,7 @@ GLboolean AssembleInstr(GLuint uiNumberInsts,
return GL_TRUE;
default:
- r700_error(ERROR_ASM_UNKNOWNILINST, "internal: unknown instruction");
+ radeon_error("internal: unknown instruction\n");
return GL_FALSE;
}
}
@@ -3802,7 +3961,7 @@ GLboolean Process_Export(r700_AssemblerBase* pAsm,
break;
default:
- r700_error(ERROR_ASM_BADEXPORTTYPE, "Unknown export type: %d", type);
+ radeon_error("Unknown export type: %d\n", type);
return GL_FALSE;
break;
}
@@ -3823,6 +3982,9 @@ GLboolean Process_Export(r700_AssemblerBase* pAsm,
if (export_count == 1)
{
ucWriteMask = pAsm->pucOutMask[starting_register_number - pAsm->starting_export_register_number];
+ /* exports Z as a float into Red channel */
+ if (GL_TRUE == is_depth_export)
+ ucWriteMask = 0x1;
if( (ucWriteMask & 0x1) != 0)
{
@@ -4014,6 +4176,22 @@ GLboolean Process_Vertex_Exports(r700_AssemblerBase *pR700AsmCode,
export_starting_index++;
}
+ unBit = 1 << VERT_RESULT_FOGC;
+ if(OutputsWritten & unBit)
+ {
+ if( GL_FALSE == Process_Export(pR700AsmCode,
+ SQ_EXPORT_PARAM,
+ export_starting_index,
+ 1,
+ pR700AsmCode->ucVP_OutputMap[VERT_RESULT_FOGC],
+ GL_FALSE) )
+ {
+ return GL_FALSE;
+ }
+
+ export_starting_index++;
+ }
+
for(i=0; i<8; i++)
{
unBit = 1 << (VERT_RESULT_TEX0 + i);
diff --git a/src/mesa/drivers/dri/r600/r700_assembler.h b/src/mesa/drivers/dri/r600/r700_assembler.h
index e9b21b802e..4e6e20011a 100644
--- a/src/mesa/drivers/dri/r600/r700_assembler.h
+++ b/src/mesa/drivers/dri/r600/r700_assembler.h
@@ -411,6 +411,14 @@ 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);
GLuint gethelpr(r700_AssemblerBase* pAsm);
void resethelpr(r700_AssemblerBase* pAsm);
void checkop_init(r700_AssemblerBase* pAsm);
@@ -424,7 +432,7 @@ GLboolean assemble_src(r700_AssemblerBase *pAsm,
GLboolean assemble_dst(r700_AssemblerBase *pAsm);
GLboolean tex_dst(r700_AssemblerBase *pAsm);
GLboolean tex_src(r700_AssemblerBase *pAsm);
-GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm);
+GLboolean assemble_tex_instruction(r700_AssemblerBase *pAsm, GLboolean normalized);
void initialize(r700_AssemblerBase *pAsm);
GLboolean assemble_alu_src(R700ALUInstruction* alu_instruction_ptr,
int source_index,
diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c
index 635dd58e72..783427a94c 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.c
+++ b/src/mesa/drivers/dri/r600/r700_chip.c
@@ -27,6 +27,7 @@
#include "main/imports.h"
#include "main/glheader.h"
+#include "main/simple_list.h"
#include "r600_context.h"
#include "r600_cmdbuf.h"
@@ -38,256 +39,119 @@
#include "r700_vertprog.h"
#include "r700_ioctl.h"
-#define LINK_STATES(reg) \
-do \
-{ \
- pStateListWork->puiValue = (unsigned int*)&(r700->reg); \
- pStateListWork->unOffset = mm##reg - ASIC_CONTEXT_BASE_INDEX; \
- pStateListWork->pNext = pStateListWork + 1; \
- pStateListWork++; \
-}while(0)
-
-GLboolean r700InitChipObject(context_t *context)
-{
- ContextState * pStateListWork;
-
- R700_CHIP_CONTEXT *r700 = &context->hw;
-
- /* init state list */
- r700->pStateList = (ContextState*) MALLOC (sizeof(ContextState)*sizeof(R700_CHIP_CONTEXT)/sizeof(unsigned int));
- pStateListWork = r700->pStateList;
-
- // misc
- LINK_STATES(TA_CNTL_AUX);
- LINK_STATES(VC_ENHANCE);
- LINK_STATES(SQ_DYN_GPR_CNTL_PS_FLUSH_REQ);
- LINK_STATES(DB_DEBUG);
- LINK_STATES(DB_WATERMARKS);
-
- // SC
- LINK_STATES(PA_SC_SCREEN_SCISSOR_TL);
- LINK_STATES(PA_SC_SCREEN_SCISSOR_BR);
- LINK_STATES(PA_SC_WINDOW_OFFSET);
- LINK_STATES(PA_SC_WINDOW_SCISSOR_TL);
- LINK_STATES(PA_SC_WINDOW_SCISSOR_BR);
- LINK_STATES(PA_SC_CLIPRECT_RULE);
- LINK_STATES(PA_SC_CLIPRECT_0_TL);
- LINK_STATES(PA_SC_CLIPRECT_0_BR);
- LINK_STATES(PA_SC_CLIPRECT_1_TL);
- LINK_STATES(PA_SC_CLIPRECT_1_BR);
- LINK_STATES(PA_SC_CLIPRECT_2_TL);
- LINK_STATES(PA_SC_CLIPRECT_2_BR);
- LINK_STATES(PA_SC_CLIPRECT_3_TL);
- LINK_STATES(PA_SC_CLIPRECT_3_BR);
- LINK_STATES(PA_SC_EDGERULE);
- LINK_STATES(PA_SC_GENERIC_SCISSOR_TL);
- LINK_STATES(PA_SC_GENERIC_SCISSOR_BR);
- LINK_STATES(PA_SC_LINE_STIPPLE);
- LINK_STATES(PA_SC_MPASS_PS_CNTL);
- LINK_STATES(PA_SC_MODE_CNTL);
- LINK_STATES(PA_SC_LINE_CNTL);
- LINK_STATES(PA_SC_AA_CONFIG);
- LINK_STATES(PA_SC_AA_SAMPLE_LOCS_MCTX);
- LINK_STATES(PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX);
- LINK_STATES(PA_SC_AA_MASK);
-
- // SU
- LINK_STATES(PA_SU_POINT_SIZE);
- LINK_STATES(PA_SU_POINT_MINMAX);
- LINK_STATES(PA_SU_LINE_CNTL);
- LINK_STATES(PA_SU_SC_MODE_CNTL);
- LINK_STATES(PA_SU_VTX_CNTL);
- LINK_STATES(PA_SU_POLY_OFFSET_DB_FMT_CNTL);
- LINK_STATES(PA_SU_POLY_OFFSET_CLAMP);
- LINK_STATES(PA_SU_POLY_OFFSET_FRONT_SCALE);
- LINK_STATES(PA_SU_POLY_OFFSET_FRONT_OFFSET);
- LINK_STATES(PA_SU_POLY_OFFSET_BACK_SCALE);
- LINK_STATES(PA_SU_POLY_OFFSET_BACK_OFFSET);
-
- // CL
- LINK_STATES(PA_CL_CLIP_CNTL);
- LINK_STATES(PA_CL_VTE_CNTL);
- LINK_STATES(PA_CL_VS_OUT_CNTL);
- LINK_STATES(PA_CL_NANINF_CNTL);
- LINK_STATES(PA_CL_GB_VERT_CLIP_ADJ);
- LINK_STATES(PA_CL_GB_VERT_DISC_ADJ);
- LINK_STATES(PA_CL_GB_HORZ_CLIP_ADJ);
- LINK_STATES(PA_CL_GB_HORZ_DISC_ADJ);
-
- // CB
- LINK_STATES(CB_CLEAR_RED_R6XX);
- LINK_STATES(CB_CLEAR_GREEN_R6XX);
- LINK_STATES(CB_CLEAR_BLUE_R6XX);
- LINK_STATES(CB_CLEAR_ALPHA_R6XX);
- LINK_STATES(CB_TARGET_MASK);
- LINK_STATES(CB_SHADER_MASK);
- LINK_STATES(CB_BLEND_RED);
- LINK_STATES(CB_BLEND_GREEN);
- LINK_STATES(CB_BLEND_BLUE);
- LINK_STATES(CB_BLEND_ALPHA);
- LINK_STATES(CB_FOG_RED_R6XX);
- LINK_STATES(CB_FOG_GREEN_R6XX);
- LINK_STATES(CB_FOG_BLUE_R6XX);
- LINK_STATES(CB_SHADER_CONTROL);
- LINK_STATES(CB_COLOR_CONTROL);
- LINK_STATES(CB_CLRCMP_CONTROL);
- LINK_STATES(CB_CLRCMP_SRC);
- LINK_STATES(CB_CLRCMP_DST);
- LINK_STATES(CB_CLRCMP_MSK);
- LINK_STATES(CB_BLEND_CONTROL);
-
- // SX
- LINK_STATES(SX_MISC);
- LINK_STATES(SX_ALPHA_TEST_CONTROL);
- LINK_STATES(SX_ALPHA_REF);
-
- // VGT
- LINK_STATES(VGT_MAX_VTX_INDX);
- LINK_STATES(VGT_MIN_VTX_INDX);
- LINK_STATES(VGT_INDX_OFFSET);
- LINK_STATES(VGT_MULTI_PRIM_IB_RESET_INDX);
- LINK_STATES(VGT_OUTPUT_PATH_CNTL);
- LINK_STATES(VGT_HOS_CNTL);
- LINK_STATES(VGT_HOS_MAX_TESS_LEVEL);
- LINK_STATES(VGT_HOS_MIN_TESS_LEVEL);
- LINK_STATES(VGT_HOS_REUSE_DEPTH);
- LINK_STATES(VGT_GROUP_PRIM_TYPE);
- LINK_STATES(VGT_GROUP_FIRST_DECR);
- LINK_STATES(VGT_GROUP_DECR);
- LINK_STATES(VGT_GROUP_VECT_0_CNTL);
- LINK_STATES(VGT_GROUP_VECT_1_CNTL);
- LINK_STATES(VGT_GROUP_VECT_0_FMT_CNTL);
- LINK_STATES(VGT_GROUP_VECT_1_FMT_CNTL);
- LINK_STATES(VGT_GS_MODE);
- LINK_STATES(VGT_PRIMITIVEID_EN);
- LINK_STATES(VGT_DMA_NUM_INSTANCES);
- LINK_STATES(VGT_MULTI_PRIM_IB_RESET_EN);
- LINK_STATES(VGT_INSTANCE_STEP_RATE_0);
- LINK_STATES(VGT_INSTANCE_STEP_RATE_1);
- LINK_STATES(VGT_STRMOUT_EN);
- LINK_STATES(VGT_REUSE_OFF);
- LINK_STATES(VGT_VTX_CNT_EN);
- LINK_STATES(VGT_STRMOUT_BUFFER_EN);
-
- LINK_STATES(SQ_VTX_SEMANTIC_0);
- LINK_STATES(SQ_VTX_SEMANTIC_1);
- LINK_STATES(SQ_VTX_SEMANTIC_2);
- LINK_STATES(SQ_VTX_SEMANTIC_3);
- LINK_STATES(SQ_VTX_SEMANTIC_4);
- LINK_STATES(SQ_VTX_SEMANTIC_5);
- LINK_STATES(SQ_VTX_SEMANTIC_6);
- LINK_STATES(SQ_VTX_SEMANTIC_7);
- LINK_STATES(SQ_VTX_SEMANTIC_8);
- LINK_STATES(SQ_VTX_SEMANTIC_9);
- LINK_STATES(SQ_VTX_SEMANTIC_10);
- LINK_STATES(SQ_VTX_SEMANTIC_11);
- LINK_STATES(SQ_VTX_SEMANTIC_12);
- LINK_STATES(SQ_VTX_SEMANTIC_13);
- LINK_STATES(SQ_VTX_SEMANTIC_14);
- LINK_STATES(SQ_VTX_SEMANTIC_15);
- LINK_STATES(SQ_VTX_SEMANTIC_16);
- LINK_STATES(SQ_VTX_SEMANTIC_17);
- LINK_STATES(SQ_VTX_SEMANTIC_18);
- LINK_STATES(SQ_VTX_SEMANTIC_19);
- LINK_STATES(SQ_VTX_SEMANTIC_20);
- LINK_STATES(SQ_VTX_SEMANTIC_21);
- LINK_STATES(SQ_VTX_SEMANTIC_22);
- LINK_STATES(SQ_VTX_SEMANTIC_23);
- LINK_STATES(SQ_VTX_SEMANTIC_24);
- LINK_STATES(SQ_VTX_SEMANTIC_25);
- LINK_STATES(SQ_VTX_SEMANTIC_26);
- LINK_STATES(SQ_VTX_SEMANTIC_27);
- LINK_STATES(SQ_VTX_SEMANTIC_28);
- LINK_STATES(SQ_VTX_SEMANTIC_29);
- LINK_STATES(SQ_VTX_SEMANTIC_30);
- LINK_STATES(SQ_VTX_SEMANTIC_31);
-
- // SPI
- LINK_STATES(SPI_VS_OUT_ID_0);
- LINK_STATES(SPI_VS_OUT_ID_1);
- LINK_STATES(SPI_VS_OUT_ID_2);
- LINK_STATES(SPI_VS_OUT_ID_3);
- LINK_STATES(SPI_VS_OUT_ID_4);
- LINK_STATES(SPI_VS_OUT_ID_5);
- LINK_STATES(SPI_VS_OUT_ID_6);
- LINK_STATES(SPI_VS_OUT_ID_7);
- LINK_STATES(SPI_VS_OUT_ID_8);
- LINK_STATES(SPI_VS_OUT_ID_9);
-
- LINK_STATES(SPI_PS_INPUT_CNTL_0);
- LINK_STATES(SPI_PS_INPUT_CNTL_1);
- LINK_STATES(SPI_PS_INPUT_CNTL_2);
- LINK_STATES(SPI_PS_INPUT_CNTL_3);
- LINK_STATES(SPI_PS_INPUT_CNTL_4);
- LINK_STATES(SPI_PS_INPUT_CNTL_5);
- LINK_STATES(SPI_PS_INPUT_CNTL_6);
- LINK_STATES(SPI_PS_INPUT_CNTL_7);
- LINK_STATES(SPI_PS_INPUT_CNTL_8);
- LINK_STATES(SPI_PS_INPUT_CNTL_9);
- LINK_STATES(SPI_PS_INPUT_CNTL_10);
- LINK_STATES(SPI_PS_INPUT_CNTL_11);
- LINK_STATES(SPI_PS_INPUT_CNTL_12);
- LINK_STATES(SPI_PS_INPUT_CNTL_13);
- LINK_STATES(SPI_PS_INPUT_CNTL_14);
- LINK_STATES(SPI_PS_INPUT_CNTL_15);
- LINK_STATES(SPI_PS_INPUT_CNTL_16);
- LINK_STATES(SPI_PS_INPUT_CNTL_17);
- LINK_STATES(SPI_PS_INPUT_CNTL_18);
- LINK_STATES(SPI_PS_INPUT_CNTL_19);
- LINK_STATES(SPI_PS_INPUT_CNTL_20);
- LINK_STATES(SPI_PS_INPUT_CNTL_21);
- LINK_STATES(SPI_PS_INPUT_CNTL_22);
- LINK_STATES(SPI_PS_INPUT_CNTL_23);
- LINK_STATES(SPI_PS_INPUT_CNTL_24);
- LINK_STATES(SPI_PS_INPUT_CNTL_25);
- LINK_STATES(SPI_PS_INPUT_CNTL_26);
- LINK_STATES(SPI_PS_INPUT_CNTL_27);
- LINK_STATES(SPI_PS_INPUT_CNTL_28);
- LINK_STATES(SPI_PS_INPUT_CNTL_29);
- LINK_STATES(SPI_PS_INPUT_CNTL_30);
- LINK_STATES(SPI_PS_INPUT_CNTL_31);
-
- LINK_STATES(SPI_VS_OUT_CONFIG);
- LINK_STATES(SPI_THREAD_GROUPING);
- LINK_STATES(SPI_PS_IN_CONTROL_0);
- LINK_STATES(SPI_PS_IN_CONTROL_1);
- LINK_STATES(SPI_INTERP_CONTROL_0);
- LINK_STATES(SPI_INPUT_Z);
- LINK_STATES(SPI_FOG_CNTL);
- LINK_STATES(SPI_FOG_FUNC_SCALE);
- LINK_STATES(SPI_FOG_FUNC_BIAS);
-
- // SQ
- LINK_STATES(SQ_ESGS_RING_ITEMSIZE);
- LINK_STATES(SQ_GSVS_RING_ITEMSIZE);
- LINK_STATES(SQ_ESTMP_RING_ITEMSIZE);
- LINK_STATES(SQ_GSTMP_RING_ITEMSIZE);
- LINK_STATES(SQ_VSTMP_RING_ITEMSIZE);
- LINK_STATES(SQ_PSTMP_RING_ITEMSIZE);
- LINK_STATES(SQ_FBUF_RING_ITEMSIZE);
- LINK_STATES(SQ_REDUC_RING_ITEMSIZE);
- //LINK_STATES(SQ_GS_VERT_ITEMSIZE);
-
- pStateListWork->puiValue = (unsigned int*)&(r700->SQ_GS_VERT_ITEMSIZE);
- pStateListWork->unOffset = mmSQ_GS_VERT_ITEMSIZE - ASIC_CONTEXT_BASE_INDEX;
- pStateListWork->pNext = NULL; /* END OF STATE LIST */
-
- return GL_TRUE;
-}
-
-void r700SetupVTXConstants(GLcontext * ctx,
- unsigned int nStreamID,
- void * pAos,
- unsigned int size, /* number of elements in vector */
- unsigned int stride,
- unsigned int count) /* number of vectors in stream */
+#include "radeon_mipmap_tree.h"
+
+static void r700SendTexState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ struct radeon_bo *bo = NULL;
+ unsigned int i;
+ BATCH_LOCALS(&context->radeon);
+
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = r700->textures[i];
+ if (t) {
+ if (!t->image_override)
+ bo = t->mt->bo;
+ else
+ bo = t->bo;
+ if (bo) {
+
+ r700SyncSurf(context, bo,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
+ 0, TC_ACTION_ENA_bit);
+
+ BEGIN_BATCH_NO_AUTOSTATE(9 + 4);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
+ R600_OUT_BATCH(i * 7);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE2);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE3);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
+ R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
+ bo,
+ 0,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
+ bo,
+ r700->textures[i]->SQ_TEX_RESOURCE3,
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ END_BATCH();
+ COMMIT_BATCH();
+ }
+ }
+ }
+ }
+}
+
+static void r700SendTexSamplerState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ unsigned int i;
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = r700->textures[i];
+ if (t) {
+ BEGIN_BATCH_NO_AUTOSTATE(5);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
+ R600_OUT_BATCH(i * 3);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
+ R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
+ END_BATCH();
+ COMMIT_BATCH();
+ }
+ }
+ }
+}
+
+static void r700SendTexBorderColorState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ unsigned int i;
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = r700->textures[i];
+ if (t) {
+ BEGIN_BATCH_NO_AUTOSTATE(2 + 4);
+ R600_OUT_BATCH_REGSEQ((TD_PS_SAMPLER0_BORDER_RED + (i * 16)), 4);
+ R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_RED);
+ R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_GREEN);
+ R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_BLUE);
+ R600_OUT_BATCH(r700->textures[i]->TD_PS_SAMPLER0_BORDER_ALPHA);
+ END_BATCH();
+ COMMIT_BATCH();
+ }
+ }
+ }
+}
+
+static void r700SetupVTXConstants(GLcontext * ctx,
+ unsigned int nStreamID,
+ void * pAos,
+ unsigned int size, /* number of elements in vector */
+ unsigned int stride,
+ unsigned int count) /* number of vectors in stream */
{
context_t *context = R700_CONTEXT(ctx);
- uint32_t *dest;
struct radeon_aos * paos = (struct radeon_aos *)pAos;
- offset_modifiers offset_mod = {NO_SHIFT, 0, 0xFFFFFFFF};
-
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
unsigned int uSQ_VTX_CONSTANT_WORD0_0;
unsigned int uSQ_VTX_CONSTANT_WORD1_0;
@@ -295,9 +159,13 @@ void r700SetupVTXConstants(GLcontext * ctx,
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
@@ -306,55 +174,153 @@ void r700SetupVTXConstants(GLcontext * ctx,
uSQ_VTX_CONSTANT_WORD0_0 = paos->offset;
uSQ_VTX_CONSTANT_WORD1_0 = count * (size * 4) - 1;
- uSQ_VTX_CONSTANT_WORD2_0 |= 0 << BASE_ADDRESS_HI_shift /* TODO */
- |stride << SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift
- |GetSurfaceFormat(GL_FLOAT, size, NULL) << SQ_VTX_CONSTANT_WORD2_0__DATA_FORMAT_shift /* TODO : trace back api for initial data type, not only GL_FLOAT */
- |SQ_NUM_FORMAT_SCALED << SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift
- |SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit;
-
- uSQ_VTX_CONSTANT_WORD3_0 |= 1 << MEM_REQUEST_SIZE_shift;
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, 0, BASE_ADDRESS_HI_shift, BASE_ADDRESS_HI_mask); /* TODO */
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, stride, SQ_VTX_CONSTANT_WORD2_0__STRIDE_shift,
+ SQ_VTX_CONSTANT_WORD2_0__STRIDE_mask);
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, GetSurfaceFormat(GL_FLOAT, 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 */
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED,
+ SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ SETbit(uSQ_VTX_CONSTANT_WORD2_0, SQ_VTX_CONSTANT_WORD2_0__FORMAT_COMP_ALL_bit);
- uSQ_VTX_CONSTANT_WORD6_0 |= SQ_TEX_VTX_VALID_BUFFER << SQ_TEX_RESOURCE_WORD6_0__TYPE_shift;
+ 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);
+ BEGIN_BATCH_NO_AUTOSTATE(9 + 2);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
R600_OUT_BATCH((nStreamID + 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, &offset_mod);
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
+ END_BATCH();
+ COMMIT_BATCH();
+
+}
+
+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 */
+ SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED,
+ SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask);
+ 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();
}
-int r700SetupStreams(GLcontext * ctx)
+void r700SetupStreams(GLcontext *ctx)
{
context_t *context = R700_CONTEXT(ctx);
-
- BATCH_LOCALS(&context->radeon);
-
- 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;
+ struct vertex_buffer *vb = &tnl->vb;
+ unsigned int i, j = 0;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ R600_STATECHANGE(context, vtx);
+
+ for(i=0; i<VERT_ATTRIB_MAX; i++) {
+ if(vp->mesa_program->Base.InputsRead & (1 << i)) {
+ rcommon_emit_vector(ctx,
+ &context->radeon.tcl.aos[j],
+ vb->AttribPtr[i]->data,
+ vb->AttribPtr[i]->size,
+ vb->AttribPtr[i]->stride,
+ vb->Count);
+ j++;
+ }
+ }
+ context->radeon.tcl.aos_count = j;
+}
- unsigned int unBit;
+static void r700SendVTXState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ 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__);
+
+ if (context->radeon.tcl.aos_count == 0)
+ return;
BEGIN_BATCH_NO_AUTOSTATE(6);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
- R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
+ R600_OUT_BATCH(mmSQ_VTX_BASE_VTX_LOC - ASIC_CTL_CONST_BASE_INDEX);
R600_OUT_BATCH(0);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CTL_CONST, 1));
@@ -363,168 +329,188 @@ int r700SetupStreams(GLcontext * ctx)
END_BATCH();
COMMIT_BATCH();
- context->radeon.tcl.aos_count = 0;
- for(i=0; i<VERT_ATTRIB_MAX; i++)
- {
- unBit = 1 << i;
- if(vpc->mesa_program.Base.InputsRead & unBit)
- {
- rcommon_emit_vector(ctx,
- &context->radeon.tcl.aos[j],
- vb->AttribPtr[i]->data,
- vb->AttribPtr[i]->size,
- vb->AttribPtr[i]->stride,
- vb->Count);
-
- /* currently aos are packed */
- r700SetupVTXConstants(ctx,
+ for(i=0; i<VERT_ATTRIB_MAX; i++) {
+ 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);
- j++;
- context->radeon.tcl.aos_count++;
- }
- }
+ }
+ else
+ { /* context->selected_vp->uiVersion == 2 : aos not always packed */
+ r700SetupVTXConstants2(ctx,
+ (void*)(&context->radeon.tcl.aos[j]),
+ &(context->stream_desc[j]));
+ }
+ j++;
+ }
+ }
+}
- return R600_FALLBACK_NONE;
+static void r700SetRenderTarget(context_t *context, int id)
+{
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
+ struct radeon_renderbuffer *rrb;
+ unsigned int nPitchInPixel;
+
+ rrb = radeon_get_colorbuffer(&context->radeon);
+ if (!rrb || !rrb->bo) {
+ return;
+ }
+
+ R600_STATECHANGE(context, cb_target);
+
+ /* color buffer */
+ r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset;
+
+ nPitchInPixel = rrb->pitch/rrb->cpp;
+ SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, (nPitchInPixel/8)-1,
+ PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask);
+ SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1,
+ SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask);
+ r700->render_target[id].CB_COLOR0_BASE.u32All = 0;
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask);
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ARRAY_LINEAR_GENERAL,
+ CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask);
+ if(4 == rrb->cpp)
+ {
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, COLOR_8_8_8_8,
+ CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, SWAP_ALT, COMP_SWAP_shift, COMP_SWAP_mask);
+ }
+ else
+ {
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, COLOR_5_6_5,
+ CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, SWAP_ALT_REV,
+ COMP_SWAP_shift, COMP_SWAP_mask);
+ }
+ SETbit(r700->render_target[id].CB_COLOR0_INFO.u32All, SOURCE_FORMAT_bit);
+ SETbit(r700->render_target[id].CB_COLOR0_INFO.u32All, BLEND_CLAMP_bit);
+ SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask);
+
+ r700->render_target[id].enabled = GL_TRUE;
}
-GLboolean r700SendContextStates(context_t *context)
+static void r700SetDepthTarget(context_t *context)
{
- BATCH_LOCALS(&context->radeon);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
- R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ struct radeon_renderbuffer *rrb;
+ unsigned int nPitchInPixel;
- ContextState * pState = r700->pStateList;
- ContextState * pInit;
- unsigned int toSend;
- unsigned int ui;
+ rrb = radeon_get_depthbuffer(&context->radeon);
+ if (!rrb)
+ return;
- while(NULL != pState)
- {
- toSend = 1;
-
- pInit = pState;
-
- while(NULL != pState->pNext)
- {
- if ((pState->pNext->unOffset - pState->unOffset) > 1)
- {
- break;
- }
- else
- {
- pState = pState->pNext;
- toSend++;
- }
- }
+ R600_STATECHANGE(context, db_target);
- pState = pState->pNext;
+ /* depth buf */
+ r700->DB_DEPTH_SIZE.u32All = 0;
+ r700->DB_DEPTH_BASE.u32All = 0;
+ r700->DB_DEPTH_INFO.u32All = 0;
+ r700->DB_DEPTH_VIEW.u32All = 0;
- BEGIN_BATCH_NO_AUTOSTATE(toSend + 2);
- R600_OUT_BATCH_REGSEQ(((pInit->unOffset + ASIC_CONTEXT_BASE_INDEX)<<2), toSend);
- for(ui=0; ui<toSend; ui++)
- {
- R600_OUT_BATCH(*(pInit->puiValue));
- pInit = pInit->pNext;
- };
- END_BATCH();
- };
- COMMIT_BATCH();
+ nPitchInPixel = rrb->pitch/rrb->cpp;
- return GL_TRUE;
-}
+ SETfield(r700->DB_DEPTH_SIZE.u32All, (nPitchInPixel/8)-1,
+ PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask);
+ SETfield(r700->DB_DEPTH_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1,
+ SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); /* size in pixel / 64 - 1 */
+ if(4 == rrb->cpp)
+ {
+ SETfield(r700->DB_DEPTH_INFO.u32All, DEPTH_8_24,
+ DB_DEPTH_INFO__FORMAT_shift, DB_DEPTH_INFO__FORMAT_mask);
+ }
+ else
+ {
+ 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_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. */
+}
-GLboolean r700SendDepthTargetState(context_t *context, int id)
+static void r700SendDepthTargetState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_renderbuffer *rrb;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
rrb = radeon_get_depthbuffer(&context->radeon);
if (!rrb || !rrb->bo) {
fprintf(stderr, "no rrb\n");
- return GL_FALSE;
+ return;
}
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
+ r700SetDepthTarget(context);
- BEGIN_BATCH_NO_AUTOSTATE(9);
+ BEGIN_BATCH_NO_AUTOSTATE(8 + 2);
R600_OUT_BATCH_REGSEQ(DB_DEPTH_SIZE, 2);
R600_OUT_BATCH(r700->DB_DEPTH_SIZE.u32All);
R600_OUT_BATCH(r700->DB_DEPTH_VIEW.u32All);
- R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 3);
+ R600_OUT_BATCH_REGSEQ(DB_DEPTH_BASE, 2);
+ R600_OUT_BATCH(r700->DB_DEPTH_BASE.u32All);
+ R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All);
R600_OUT_BATCH_RELOC(r700->DB_DEPTH_BASE.u32All,
rrb->bo,
r700->DB_DEPTH_BASE.u32All,
- 0, RADEON_GEM_DOMAIN_VRAM, 0, &offset_mod);
- R600_OUT_BATCH(r700->DB_DEPTH_INFO.u32All);
- R600_OUT_BATCH(r700->DB_HTILE_DATA_BASE.u32All);
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
- BEGIN_BATCH_NO_AUTOSTATE(24);
- R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
- R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
- R600_OUT_BATCH(r700->DB_DEPTH_CLEAR.u32All);
-
- R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
- R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
- R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
-
- R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, r700->DB_DEPTH_CONTROL.u32All);
- R600_OUT_BATCH_REGVAL(DB_SHADER_CONTROL, r700->DB_SHADER_CONTROL.u32All);
-
- R600_OUT_BATCH_REGSEQ(DB_RENDER_CONTROL, 2);
- R600_OUT_BATCH(r700->DB_RENDER_CONTROL.u32All);
- R600_OUT_BATCH(r700->DB_RENDER_OVERRIDE.u32All);
-
- R600_OUT_BATCH_REGVAL(DB_HTILE_SURFACE, r700->DB_HTILE_SURFACE.u32All);
- R600_OUT_BATCH_REGVAL(DB_ALPHA_TO_MASK, r700->DB_ALPHA_TO_MASK.u32All);
- END_BATCH();
+ if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) &&
+ (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)) {
+ BEGIN_BATCH_NO_AUTOSTATE(2);
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_BASE_UPDATE, 0));
+ R600_OUT_BATCH(1 << 0);
+ END_BATCH();
+ }
COMMIT_BATCH();
- r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
- DB_ACTION_ENA_bit | DB_DEST_BASE_ENA_bit);
-
- return GL_TRUE;
}
-GLboolean r700SendRenderTargetState(context_t *context, int id)
+static void r700SendRenderTargetState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
struct radeon_renderbuffer *rrb;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ int id = 0;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
rrb = radeon_get_colorbuffer(&context->radeon);
if (!rrb || !rrb->bo) {
fprintf(stderr, "no rrb\n");
- return GL_FALSE;
+ return;
}
+ r700SetRenderTarget(context, 0);
+
if (id > R700_MAX_RENDER_TARGETS)
- return GL_FALSE;
+ return;
if (!r700->render_target[id].enabled)
- return GL_FALSE;
-
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
+ return;
- BEGIN_BATCH_NO_AUTOSTATE(3);
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
R600_OUT_BATCH_REGSEQ(CB_COLOR0_BASE + (4 * id), 1);
+ R600_OUT_BATCH(r700->render_target[id].CB_COLOR0_BASE.u32All);
R600_OUT_BATCH_RELOC(r700->render_target[id].CB_COLOR0_BASE.u32All,
rrb->bo,
r700->render_target[id].CB_COLOR0_BASE.u32All,
- 0, RADEON_GEM_DOMAIN_VRAM, 0, &offset_mod);
+ 0, RADEON_GEM_DOMAIN_VRAM, 0);
END_BATCH();
if ((context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) &&
@@ -544,42 +530,32 @@ GLboolean r700SendRenderTargetState(context_t *context, int id)
R600_OUT_BATCH_REGVAL(CB_COLOR0_MASK + (4 * id), r700->render_target[id].CB_COLOR0_MASK.u32All);
END_BATCH();
- if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
- BEGIN_BATCH_NO_AUTOSTATE(3);
- R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * id), r700->render_target[id].CB_BLEND0_CONTROL.u32All);
- END_BATCH();
- }
-
COMMIT_BATCH();
- r700SyncSurf(context, rrb->bo, 0, RADEON_GEM_DOMAIN_VRAM,
- CB_ACTION_ENA_bit | (1 << (id + 6)));
-
- return GL_TRUE;
}
-GLboolean r700SendPSState(context_t *context)
+static void r700SendPSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
- struct radeon_renderbuffer *rrb;
struct radeon_bo * pbo;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
pbo = (struct radeon_bo *)r700GetActiveFpShaderBo(GL_CONTEXT(context));
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
+ if (!pbo)
+ return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
- BEGIN_BATCH_NO_AUTOSTATE(3);
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
R600_OUT_BATCH_REGSEQ(SQ_PGM_START_PS, 1);
+ R600_OUT_BATCH(r700->ps.SQ_PGM_START_PS.u32All);
R600_OUT_BATCH_RELOC(r700->ps.SQ_PGM_START_PS.u32All,
pbo,
r700->ps.SQ_PGM_START_PS.u32All,
- RADEON_GEM_DOMAIN_GTT, 0, 0, &offset_mod);
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(9);
@@ -590,31 +566,30 @@ GLboolean r700SendPSState(context_t *context)
COMMIT_BATCH();
- return GL_TRUE;
}
-GLboolean r700SendVSState(context_t *context)
+static void r700SendVSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
- struct radeon_renderbuffer *rrb;
struct radeon_bo * pbo;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
pbo = (struct radeon_bo *)r700GetActiveVpShaderBo(GL_CONTEXT(context));
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
+ if (!pbo)
+ return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
- BEGIN_BATCH_NO_AUTOSTATE(3);
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
R600_OUT_BATCH_REGSEQ(SQ_PGM_START_VS, 1);
+ R600_OUT_BATCH(r700->vs.SQ_PGM_START_VS.u32All);
R600_OUT_BATCH_RELOC(r700->vs.SQ_PGM_START_VS.u32All,
pbo,
r700->vs.SQ_PGM_START_VS.u32All,
- RADEON_GEM_DOMAIN_GTT, 0, 0, &offset_mod);
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(6);
@@ -623,17 +598,15 @@ GLboolean r700SendVSState(context_t *context)
END_BATCH();
COMMIT_BATCH();
-
- return GL_TRUE;
}
-GLboolean r700SendFSState(context_t *context)
+static void r700SendFSState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
- struct radeon_renderbuffer *rrb;
struct radeon_bo * pbo;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
/* XXX fixme
* R6xx chips require a FS be emitted, even if it's not used.
@@ -646,18 +619,18 @@ GLboolean r700SendFSState(context_t *context)
r700->fs.SQ_PGM_CF_OFFSET_FS.u32All = 0;
/* XXX */
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
+ if (!pbo)
+ return;
r700SyncSurf(context, pbo, RADEON_GEM_DOMAIN_GTT, 0, SH_ACTION_ENA_bit);
- BEGIN_BATCH_NO_AUTOSTATE(3);
+ BEGIN_BATCH_NO_AUTOSTATE(3 + 2);
R600_OUT_BATCH_REGSEQ(SQ_PGM_START_FS, 1);
+ R600_OUT_BATCH(r700->fs.SQ_PGM_START_FS.u32All);
R600_OUT_BATCH_RELOC(r700->fs.SQ_PGM_START_FS.u32All,
pbo,
r700->fs.SQ_PGM_START_FS.u32All,
- RADEON_GEM_DOMAIN_GTT, 0, 0, &offset_mod);
+ RADEON_GEM_DOMAIN_GTT, 0, 0);
END_BATCH();
BEGIN_BATCH_NO_AUTOSTATE(6);
@@ -667,21 +640,21 @@ GLboolean r700SendFSState(context_t *context)
COMMIT_BATCH();
- return GL_TRUE;
}
-GLboolean r700SendViewportState(context_t *context, int id)
+static void r700SendViewportState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
- struct radeon_renderbuffer *rrb;
- offset_modifiers offset_mod;
BATCH_LOCALS(&context->radeon);
+ int id = 0;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
if (id > R700_MAX_VIEWPORTS)
- return GL_FALSE;
+ return;
if (!r700->viewport[id].enabled)
- return GL_FALSE;
+ return;
BEGIN_BATCH_NO_AUTOSTATE(16);
R600_OUT_BATCH_REGSEQ(PA_SC_VPORT_SCISSOR_0_TL + (8 * id), 2);
@@ -701,15 +674,16 @@ GLboolean r700SendViewportState(context_t *context, int id)
COMMIT_BATCH();
- return GL_TRUE;
}
-GLboolean r700SendSQConfig(context_t *context)
+static void r700SendSQConfig(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
- BEGIN_BATCH_NO_AUTOSTATE(8);
+ BEGIN_BATCH_NO_AUTOSTATE(34);
R600_OUT_BATCH_REGSEQ(SQ_CONFIG, 6);
R600_OUT_BATCH(r700->sq_config.SQ_CONFIG.u32All);
R600_OUT_BATCH(r700->sq_config.SQ_GPR_RESOURCE_MGMT_1.u32All);
@@ -717,17 +691,35 @@ GLboolean r700SendSQConfig(context_t *context)
R600_OUT_BATCH(r700->sq_config.SQ_THREAD_RESOURCE_MGMT.u32All);
R600_OUT_BATCH(r700->sq_config.SQ_STACK_RESOURCE_MGMT_1.u32All);
R600_OUT_BATCH(r700->sq_config.SQ_STACK_RESOURCE_MGMT_2.u32All);
+
+ R600_OUT_BATCH_REGVAL(TA_CNTL_AUX, r700->TA_CNTL_AUX.u32All);
+ R600_OUT_BATCH_REGVAL(VC_ENHANCE, r700->VC_ENHANCE.u32All);
+ R600_OUT_BATCH_REGVAL(R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ, r700->SQ_DYN_GPR_CNTL_PS_FLUSH_REQ.u32All);
+ R600_OUT_BATCH_REGVAL(DB_DEBUG, r700->DB_DEBUG.u32All);
+ R600_OUT_BATCH_REGVAL(DB_WATERMARKS, r700->DB_WATERMARKS.u32All);
+
+ R600_OUT_BATCH_REGSEQ(SQ_ESGS_RING_ITEMSIZE, 9);
+ R600_OUT_BATCH(r700->SQ_ESGS_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_GSVS_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_ESTMP_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_GSTMP_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_VSTMP_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_PSTMP_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_FBUF_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_REDUC_RING_ITEMSIZE.u32All);
+ R600_OUT_BATCH(r700->SQ_GS_VERT_ITEMSIZE.u32All);
END_BATCH();
- COMMIT_BATCH();
- return GL_TRUE;
+ COMMIT_BATCH();
}
-GLboolean r700SendUCPState(context_t *context)
+static void r700SendUCPState(GLcontext *ctx, struct radeon_state_atom *atom)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
BATCH_LOCALS(&context->radeon);
int i;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
for (i = 0; i < R700_MAX_UCP; i++) {
if (r700->ucp[i].enabled) {
@@ -741,7 +733,626 @@ GLboolean r700SendUCPState(context_t *context)
COMMIT_BATCH();
}
}
+}
+
+static void r700SendSPIState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ unsigned int ui;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(59 + R700_MAX_SHADER_EXPORTS);
+
+ R600_OUT_BATCH_REGSEQ(SQ_VTX_SEMANTIC_0, 32);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_0.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_1.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_2.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_3.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_4.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_5.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_6.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_7.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_8.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_9.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_10.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_11.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_12.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_13.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_14.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_15.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_16.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_17.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_18.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_19.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_20.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_21.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_22.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_23.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_24.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_25.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_26.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_27.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_28.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_29.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_30.u32All);
+ R600_OUT_BATCH(r700->SQ_VTX_SEMANTIC_31.u32All);
+
+ R600_OUT_BATCH_REGSEQ(SPI_VS_OUT_ID_0, 10);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_0.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_1.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_2.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_3.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_4.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_5.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_6.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_7.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_8.u32All);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_ID_9.u32All);
+
+ R600_OUT_BATCH_REGSEQ(SPI_VS_OUT_CONFIG, 9);
+ R600_OUT_BATCH(r700->SPI_VS_OUT_CONFIG.u32All);
+ R600_OUT_BATCH(r700->SPI_THREAD_GROUPING.u32All);
+ R600_OUT_BATCH(r700->SPI_PS_IN_CONTROL_0.u32All);
+ R600_OUT_BATCH(r700->SPI_PS_IN_CONTROL_1.u32All);
+ R600_OUT_BATCH(r700->SPI_INTERP_CONTROL_0.u32All);
+ R600_OUT_BATCH(r700->SPI_INPUT_Z.u32All);
+ R600_OUT_BATCH(r700->SPI_FOG_CNTL.u32All);
+ R600_OUT_BATCH(r700->SPI_FOG_FUNC_SCALE.u32All);
+ R600_OUT_BATCH(r700->SPI_FOG_FUNC_BIAS.u32All);
+
+ R600_OUT_BATCH_REGSEQ(SPI_PS_INPUT_CNTL_0, R700_MAX_SHADER_EXPORTS);
+ for(ui = 0; ui < R700_MAX_SHADER_EXPORTS; ui++)
+ R600_OUT_BATCH(r700->SPI_PS_INPUT_CNTL[ui].u32All);
+
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendVGTState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(41);
+
+ R600_OUT_BATCH_REGSEQ(VGT_MAX_VTX_INDX, 4);
+ R600_OUT_BATCH(r700->VGT_MAX_VTX_INDX.u32All);
+ R600_OUT_BATCH(r700->VGT_MIN_VTX_INDX.u32All);
+ R600_OUT_BATCH(r700->VGT_INDX_OFFSET.u32All);
+ R600_OUT_BATCH(r700->VGT_MULTI_PRIM_IB_RESET_INDX.u32All);
+
+ R600_OUT_BATCH_REGSEQ(VGT_OUTPUT_PATH_CNTL, 13);
+ R600_OUT_BATCH(r700->VGT_OUTPUT_PATH_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_HOS_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_HOS_MAX_TESS_LEVEL.u32All);
+ R600_OUT_BATCH(r700->VGT_HOS_MIN_TESS_LEVEL.u32All);
+ R600_OUT_BATCH(r700->VGT_HOS_REUSE_DEPTH.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_PRIM_TYPE.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_FIRST_DECR.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_DECR.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_VECT_0_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_VECT_1_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_VECT_0_FMT_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_GROUP_VECT_1_FMT_CNTL.u32All);
+ R600_OUT_BATCH(r700->VGT_GS_MODE.u32All);
+
+ R600_OUT_BATCH_REGVAL(VGT_PRIMITIVEID_EN, r700->VGT_PRIMITIVEID_EN.u32All);
+ R600_OUT_BATCH_REGVAL(VGT_MULTI_PRIM_IB_RESET_EN, r700->VGT_MULTI_PRIM_IB_RESET_EN.u32All);
+ R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_0, r700->VGT_INSTANCE_STEP_RATE_0.u32All);
+ R600_OUT_BATCH_REGVAL(VGT_INSTANCE_STEP_RATE_1, r700->VGT_INSTANCE_STEP_RATE_1.u32All);
+
+ R600_OUT_BATCH_REGSEQ(VGT_STRMOUT_EN, 3);
+ R600_OUT_BATCH(r700->VGT_STRMOUT_EN.u32All);
+ R600_OUT_BATCH(r700->VGT_REUSE_OFF.u32All);
+ R600_OUT_BATCH(r700->VGT_VTX_CNT_EN.u32All);
+
+ R600_OUT_BATCH_REGVAL(VGT_STRMOUT_BUFFER_EN, r700->VGT_STRMOUT_BUFFER_EN.u32All);
+
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendSXState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(9);
+ R600_OUT_BATCH_REGVAL(SX_MISC, r700->SX_MISC.u32All);
+ R600_OUT_BATCH_REGVAL(SX_ALPHA_TEST_CONTROL, r700->SX_ALPHA_TEST_CONTROL.u32All);
+ R600_OUT_BATCH_REGVAL(SX_ALPHA_REF, r700->SX_ALPHA_REF.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendDBState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(23);
+ R600_OUT_BATCH_REGVAL(DB_HTILE_DATA_BASE, r700->DB_HTILE_DATA_BASE.u32All);
+
+ R600_OUT_BATCH_REGSEQ(DB_STENCIL_CLEAR, 2);
+ R600_OUT_BATCH(r700->DB_STENCIL_CLEAR.u32All);
+ R600_OUT_BATCH(r700->DB_DEPTH_CLEAR.u32All);
+
+ R600_OUT_BATCH_REGVAL(DB_DEPTH_CONTROL, r700->DB_DEPTH_CONTROL.u32All);
+ R600_OUT_BATCH_REGVAL(DB_SHADER_CONTROL, r700->DB_SHADER_CONTROL.u32All);
+
+ R600_OUT_BATCH_REGSEQ(DB_RENDER_CONTROL, 2);
+ R600_OUT_BATCH(r700->DB_RENDER_CONTROL.u32All);
+ R600_OUT_BATCH(r700->DB_RENDER_OVERRIDE.u32All);
+
+ R600_OUT_BATCH_REGVAL(DB_HTILE_SURFACE, r700->DB_HTILE_SURFACE.u32All);
+ R600_OUT_BATCH_REGVAL(DB_ALPHA_TO_MASK, r700->DB_ALPHA_TO_MASK.u32All);
+
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendStencilState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ R600_OUT_BATCH_REGSEQ(DB_STENCILREFMASK, 2);
+ R600_OUT_BATCH(r700->DB_STENCILREFMASK.u32All);
+ R600_OUT_BATCH(r700->DB_STENCILREFMASK_BF.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendCBState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) {
+ BEGIN_BATCH_NO_AUTOSTATE(11);
+ R600_OUT_BATCH_REGSEQ(CB_CLEAR_RED, 4);
+ R600_OUT_BATCH(r700->CB_CLEAR_RED_R6XX.u32All);
+ R600_OUT_BATCH(r700->CB_CLEAR_GREEN_R6XX.u32All);
+ R600_OUT_BATCH(r700->CB_CLEAR_BLUE_R6XX.u32All);
+ R600_OUT_BATCH(r700->CB_CLEAR_ALPHA_R6XX.u32All);
+ R600_OUT_BATCH_REGSEQ(CB_FOG_RED, 3);
+ R600_OUT_BATCH(r700->CB_FOG_RED_R6XX.u32All);
+ R600_OUT_BATCH(r700->CB_FOG_GREEN_R6XX.u32All);
+ R600_OUT_BATCH(r700->CB_FOG_BLUE_R6XX.u32All);
+ END_BATCH();
+ }
+
+ BEGIN_BATCH_NO_AUTOSTATE(7);
+ R600_OUT_BATCH_REGSEQ(CB_TARGET_MASK, 2);
+ R600_OUT_BATCH(r700->CB_TARGET_MASK.u32All);
+ R600_OUT_BATCH(r700->CB_SHADER_MASK.u32All);
+ R600_OUT_BATCH_REGVAL(R7xx_CB_SHADER_CONTROL, r700->CB_SHADER_CONTROL.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendCBCLRCMPState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ R600_OUT_BATCH_REGSEQ(CB_CLRCMP_CONTROL, 4);
+ R600_OUT_BATCH(r700->CB_CLRCMP_CONTROL.u32All);
+ R600_OUT_BATCH(r700->CB_CLRCMP_SRC.u32All);
+ R600_OUT_BATCH(r700->CB_CLRCMP_DST.u32All);
+ R600_OUT_BATCH(r700->CB_CLRCMP_MSK.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendCBBlendState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ unsigned int ui;
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770) {
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH_REGVAL(CB_BLEND_CONTROL, r700->CB_BLEND_CONTROL.u32All);
+ END_BATCH();
+ }
+
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH_REGVAL(CB_COLOR_CONTROL, r700->CB_COLOR_CONTROL.u32All);
+ END_BATCH();
+
+ if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
+ for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
+ if (r700->render_target[ui].enabled) {
+ BEGIN_BATCH_NO_AUTOSTATE(3);
+ R600_OUT_BATCH_REGVAL(CB_BLEND0_CONTROL + (4 * ui),
+ r700->render_target[ui].CB_BLEND0_CONTROL.u32All);
+ END_BATCH();
+ }
+ }
+ }
+
+ COMMIT_BATCH();
+}
+
+static void r700SendCBBlendColorState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ R600_OUT_BATCH_REGSEQ(CB_BLEND_RED, 4);
+ R600_OUT_BATCH(r700->CB_BLEND_RED.u32All);
+ R600_OUT_BATCH(r700->CB_BLEND_GREEN.u32All);
+ R600_OUT_BATCH(r700->CB_BLEND_BLUE.u32All);
+ R600_OUT_BATCH(r700->CB_BLEND_ALPHA.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendSUState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(9);
+ R600_OUT_BATCH_REGVAL(PA_SU_SC_MODE_CNTL, r700->PA_SU_SC_MODE_CNTL.u32All);
+ R600_OUT_BATCH_REGSEQ(PA_SU_POINT_SIZE, 4);
+ R600_OUT_BATCH(r700->PA_SU_POINT_SIZE.u32All);
+ R600_OUT_BATCH(r700->PA_SU_POINT_MINMAX.u32All);
+ R600_OUT_BATCH(r700->PA_SU_LINE_CNTL.u32All);
+ R600_OUT_BATCH(r700->PA_SU_VTX_CNTL.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+
+}
+
+static void r700SendPolyState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(10);
+ R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_DB_FMT_CNTL, 2);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_DB_FMT_CNTL.u32All);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_CLAMP.u32All);
+ R600_OUT_BATCH_REGSEQ(PA_SU_POLY_OFFSET_FRONT_SCALE, 4);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_SCALE.u32All);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_FRONT_OFFSET.u32All);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_SCALE.u32All);
+ R600_OUT_BATCH(r700->PA_SU_POLY_OFFSET_BACK_OFFSET.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+
+}
+
+static void r700SendCLState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(12);
+ R600_OUT_BATCH_REGVAL(PA_CL_CLIP_CNTL, r700->PA_CL_CLIP_CNTL.u32All);
+ R600_OUT_BATCH_REGVAL(PA_CL_VTE_CNTL, r700->PA_CL_VTE_CNTL.u32All);
+ R600_OUT_BATCH_REGVAL(PA_CL_VS_OUT_CNTL, r700->PA_CL_VS_OUT_CNTL.u32All);
+ R600_OUT_BATCH_REGVAL(PA_CL_NANINF_CNTL, r700->PA_CL_NANINF_CNTL.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendGBState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(6);
+ R600_OUT_BATCH_REGSEQ(PA_CL_GB_VERT_CLIP_ADJ, 4);
+ R600_OUT_BATCH(r700->PA_CL_GB_VERT_CLIP_ADJ.u32All);
+ R600_OUT_BATCH(r700->PA_CL_GB_VERT_DISC_ADJ.u32All);
+ R600_OUT_BATCH(r700->PA_CL_GB_HORZ_CLIP_ADJ.u32All);
+ R600_OUT_BATCH(r700->PA_CL_GB_HORZ_DISC_ADJ.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendScissorState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(22);
+ R600_OUT_BATCH_REGSEQ(PA_SC_SCREEN_SCISSOR_TL, 2);
+ R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_SCREEN_SCISSOR_BR.u32All);
+
+ R600_OUT_BATCH_REGSEQ(PA_SC_WINDOW_OFFSET, 12);
+ R600_OUT_BATCH(r700->PA_SC_WINDOW_OFFSET.u32All);
+ R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_WINDOW_SCISSOR_BR.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_RULE.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_0_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_0_BR.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_1_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_1_BR.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_2_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_2_BR.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_CLIPRECT_3_BR.u32All);
+
+ R600_OUT_BATCH_REGSEQ(PA_SC_GENERIC_SCISSOR_TL, 2);
+ R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_TL.u32All);
+ R600_OUT_BATCH(r700->PA_SC_GENERIC_SCISSOR_BR.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendSCState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ BEGIN_BATCH_NO_AUTOSTATE(15);
+ R600_OUT_BATCH_REGVAL(R7xx_PA_SC_EDGERULE, r700->PA_SC_EDGERULE.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_LINE_STIPPLE, r700->PA_SC_LINE_STIPPLE.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_MPASS_PS_CNTL, r700->PA_SC_MPASS_PS_CNTL.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_MODE_CNTL, r700->PA_SC_MODE_CNTL.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_LINE_CNTL, r700->PA_SC_LINE_CNTL.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendAAState(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ BATCH_LOCALS(&context->radeon);
+
+ BEGIN_BATCH_NO_AUTOSTATE(12);
+ R600_OUT_BATCH_REGVAL(PA_SC_AA_CONFIG, r700->PA_SC_AA_CONFIG.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_MCTX.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX, r700->PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX.u32All);
+ R600_OUT_BATCH_REGVAL(PA_SC_AA_MASK, r700->PA_SC_AA_MASK.u32All);
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendPSConsts(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ int i;
+ BATCH_LOCALS(&context->radeon);
+
+ if (r700->ps.num_consts == 0)
+ return;
+
+ BEGIN_BATCH_NO_AUTOSTATE(2 + (r700->ps.num_consts * 4));
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, (r700->ps.num_consts * 4)));
+ /* assembler map const from very beginning. */
+ R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
+ for (i = 0; i < r700->ps.num_consts; i++) {
+ R600_OUT_BATCH(r700->ps.consts[i][0].u32All);
+ R600_OUT_BATCH(r700->ps.consts[i][1].u32All);
+ R600_OUT_BATCH(r700->ps.consts[i][2].u32All);
+ R600_OUT_BATCH(r700->ps.consts[i][3].u32All);
+ }
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static void r700SendVSConsts(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = R700_CONTEXT_STATES(context);
+ int i;
+ BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s\n", __func__);
+
+ if (r700->vs.num_consts == 0)
+ return;
+
+ BEGIN_BATCH_NO_AUTOSTATE(2 + (r700->vs.num_consts * 4));
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, (r700->vs.num_consts * 4)));
+ /* assembler map const from very beginning. */
+ R600_OUT_BATCH(SQ_ALU_CONSTANT_VS_OFFSET * 4);
+ for (i = 0; i < r700->vs.num_consts; i++) {
+ R600_OUT_BATCH(r700->vs.consts[i][0].u32All);
+ R600_OUT_BATCH(r700->vs.consts[i][1].u32All);
+ R600_OUT_BATCH(r700->vs.consts[i][2].u32All);
+ R600_OUT_BATCH(r700->vs.consts[i][3].u32All);
+ }
+ END_BATCH();
+ COMMIT_BATCH();
+}
+
+static int check_always(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ return atom->cmd_size;
+}
+
+static int check_cb(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ int count = 7;
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ count += 11;
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+
+ return count;
+}
+
+static int check_blnd(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ unsigned int ui;
+ int count = 3;
+
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ count += 3;
+
+ if (context->radeon.radeonScreen->chip_family > CHIP_FAMILY_R600) {
+ for (ui = 0; ui < R700_MAX_RENDER_TARGETS; ui++) {
+ if (r700->render_target[ui].enabled)
+ count += 3;
+ }
+ }
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+
+ return count;
+}
- return GL_TRUE;
+static int check_ucp(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ int i;
+ int count = 0;
+
+ for (i = 0; i < R700_MAX_UCP; i++) {
+ if (r700->ucp[i].enabled)
+ count += 6;
+ }
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+ return count;
}
+static int check_vtx(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ int count = context->radeon.tcl.aos_count * 18;
+
+ if (count)
+ count += 6;
+
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+ return count;
+}
+
+static int check_tx(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ unsigned int i, count = 0;
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+
+ for (i = 0; i < R700_TEXTURE_NUMBERUNITS; i++) {
+ if (ctx->Texture.Unit[i]._ReallyEnabled) {
+ radeonTexObj *t = r700->textures[i];
+ if (t)
+ count++;
+ }
+ }
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+ return count * 31;
+}
+
+static int check_ps_consts(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ int count = r700->ps.num_consts * 4;
+
+ if (count)
+ count += 2;
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+
+ return count;
+}
+
+static int check_vs_consts(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ int count = r700->vs.num_consts * 4;
+
+ if (count)
+ count += 2;
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s %d\n", __func__, count);
+
+ return count;
+}
+
+#define ALLOC_STATE( ATOM, CHK, SZ, EMIT ) \
+do { \
+ context->atoms.ATOM.cmd_size = (SZ); \
+ context->atoms.ATOM.cmd = NULL; \
+ context->atoms.ATOM.name = #ATOM; \
+ context->atoms.ATOM.idx = 0; \
+ context->atoms.ATOM.check = check_##CHK; \
+ context->atoms.ATOM.dirty = GL_FALSE; \
+ context->atoms.ATOM.emit = (EMIT); \
+ context->radeon.hw.max_state_size += (SZ); \
+ insert_at_tail(&context->radeon.hw.atomlist, &context->atoms.ATOM); \
+} while (0)
+
+void r600InitAtoms(context_t *context)
+{
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %p\n", __func__, context);
+ context->radeon.hw.max_state_size = 10 + 5 + 14; /* start 3d, idle, cb/db flush */
+
+ /* Setup the atom linked list */
+ make_empty_list(&context->radeon.hw.atomlist);
+ context->radeon.hw.atomlist.name = "atom-list";
+
+ ALLOC_STATE(sq, always, 34, r700SendSQConfig);
+ ALLOC_STATE(db, always, 23, r700SendDBState);
+ ALLOC_STATE(stencil, always, 4, r700SendStencilState);
+ ALLOC_STATE(db_target, always, 12, r700SendDepthTargetState);
+ ALLOC_STATE(sc, always, 15, r700SendSCState);
+ ALLOC_STATE(scissor, always, 22, r700SendScissorState);
+ ALLOC_STATE(aa, always, 12, r700SendAAState);
+ ALLOC_STATE(cl, always, 12, r700SendCLState);
+ ALLOC_STATE(gb, always, 6, r700SendGBState);
+ ALLOC_STATE(ucp, ucp, (R700_MAX_UCP * 6), r700SendUCPState);
+ ALLOC_STATE(su, always, 9, r700SendSUState);
+ ALLOC_STATE(poly, always, 10, r700SendPolyState);
+ ALLOC_STATE(cb, cb, 18, r700SendCBState);
+ ALLOC_STATE(clrcmp, always, 6, r700SendCBCLRCMPState);
+ ALLOC_STATE(blnd, blnd, (6 + (R700_MAX_RENDER_TARGETS * 3)), r700SendCBBlendState);
+ ALLOC_STATE(blnd_clr, always, 6, r700SendCBBlendColorState);
+ ALLOC_STATE(cb_target, always, 25, r700SendRenderTargetState);
+ ALLOC_STATE(sx, always, 9, r700SendSXState);
+ ALLOC_STATE(vgt, always, 41, r700SendVGTState);
+ ALLOC_STATE(spi, always, (59 + R700_MAX_SHADER_EXPORTS), r700SendSPIState);
+ ALLOC_STATE(vpt, always, 16, r700SendViewportState);
+ ALLOC_STATE(fs, always, 18, r700SendFSState);
+ ALLOC_STATE(vs, always, 18, r700SendVSState);
+ ALLOC_STATE(ps, always, 21, r700SendPSState);
+ ALLOC_STATE(vs_consts, vs_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendVSConsts);
+ ALLOC_STATE(ps_consts, ps_consts, (2 + (R700_MAX_DX9_CONSTS * 4)), r700SendPSConsts);
+ ALLOC_STATE(vtx, vtx, (6 + (VERT_ATTRIB_MAX * 18)), r700SendVTXState);
+ ALLOC_STATE(tx, tx, (R700_TEXTURE_NUMBERUNITS * 20), r700SendTexState);
+ ALLOC_STATE(tx_smplr, tx, (R700_TEXTURE_NUMBERUNITS * 5), r700SendTexSamplerState);
+ ALLOC_STATE(tx_brdr_clr, tx, (R700_TEXTURE_NUMBERUNITS * 6), r700SendTexBorderColorState);
+
+ context->radeon.hw.is_dirty = GL_TRUE;
+ context->radeon.hw.all_dirty = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/r600/r700_chip.h b/src/mesa/drivers/dri/r600/r700_chip.h
index fa419aa499..ae249e15fd 100644
--- a/src/mesa/drivers/dri/r600/r700_chip.h
+++ b/src/mesa/drivers/dri/r600/r700_chip.h
@@ -46,6 +46,7 @@
#define R700_MAX_VIEWPORTS 16
#define R700_MAX_SHADER_EXPORTS 32
#define R700_MAX_UCP 6
+#define R700_MAX_DX9_CONSTS 256
/* Enum not show in r600_*.h */
@@ -188,6 +189,7 @@ typedef struct _RENDER_TARGET_STATE_STRUCT
union UINT_FLOAT CB_COLOR0_MASK; /* 0xA040 */
union UINT_FLOAT CB_BLEND0_CONTROL; /* 0xA1E0 */
GLboolean enabled;
+ GLboolean dirty;
} RENDER_TARGET_STATE_STRUCT;
typedef struct _VIEWPORT_STATE_STRUCT
@@ -203,6 +205,7 @@ typedef struct _VIEWPORT_STATE_STRUCT
union UINT_FLOAT PA_CL_VPORT_ZSCALE; /* 0xA113 */
union UINT_FLOAT PA_CL_VPORT_ZOFFSET; /* 0xA114 */
GLboolean enabled;
+ GLboolean dirty;
} VIEWPORT_STATE_STRUCT;
typedef struct _UCP_STATE_STRUCT
@@ -212,6 +215,7 @@ typedef struct _UCP_STATE_STRUCT
union UINT_FLOAT PA_CL_UCP_0_Z;
union UINT_FLOAT PA_CL_UCP_0_W;
GLboolean enabled;
+ GLboolean dirty;
} UCP_STATE_STRUCT;
typedef struct _PS_STATE_STRUCT
@@ -220,6 +224,9 @@ typedef struct _PS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_RESOURCES_PS ; /* 0xA214 */
union UINT_FLOAT SQ_PGM_EXPORTS_PS ; /* 0xA215 */
union UINT_FLOAT SQ_PGM_CF_OFFSET_PS ; /* 0xA233 */
+ GLboolean dirty;
+ int num_consts;
+ union UINT_FLOAT consts[R700_MAX_DX9_CONSTS][4];
} PS_STATE_STRUCT;
typedef struct _VS_STATE_STRUCT
@@ -227,6 +234,9 @@ typedef struct _VS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_START_VS ; /* 0xA216 */
union UINT_FLOAT SQ_PGM_RESOURCES_VS ; /* 0xA21A */
union UINT_FLOAT SQ_PGM_CF_OFFSET_VS ; /* 0xA234 */
+ GLboolean dirty;
+ int num_consts;
+ union UINT_FLOAT consts[R700_MAX_DX9_CONSTS][4];
} VS_STATE_STRUCT;
typedef struct _GS_STATE_STRUCT
@@ -234,6 +244,7 @@ typedef struct _GS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_START_GS ; /* 0xA21B */
union UINT_FLOAT SQ_PGM_RESOURCES_GS ; /* 0xA21F */
union UINT_FLOAT SQ_PGM_CF_OFFSET_GS ; /* 0xA235 */
+ GLboolean dirty;
} GS_STATE_STRUCT;
typedef struct _ES_STATE_STRUCT
@@ -241,6 +252,7 @@ typedef struct _ES_STATE_STRUCT
union UINT_FLOAT SQ_PGM_START_ES ; /* 0xA220 */
union UINT_FLOAT SQ_PGM_RESOURCES_ES ; /* 0xA224 */
union UINT_FLOAT SQ_PGM_CF_OFFSET_ES ; /* 0xA236 */
+ GLboolean dirty;
} ES_STATE_STRUCT;
typedef struct _FS_STATE_STRUCT
@@ -248,6 +260,7 @@ typedef struct _FS_STATE_STRUCT
union UINT_FLOAT SQ_PGM_START_FS ; /* 0xA225 */
union UINT_FLOAT SQ_PGM_RESOURCES_FS ; /* 0xA229 */
union UINT_FLOAT SQ_PGM_CF_OFFSET_FS ; /* 0xA237 */
+ GLboolean dirty;
} FS_STATE_STRUCT;
typedef struct _SQ_CONFIG_STRUCT
@@ -260,27 +273,14 @@ typedef struct _SQ_CONFIG_STRUCT
union UINT_FLOAT SQ_STACK_RESOURCE_MGMT_2 ; /* 0x2305 */
} SQ_CONFIG_STRUCT;
-typedef struct ContextState
-{
- unsigned int * puiValue;
- unsigned int unOffset;
- struct ContextState * pNext;
-} ContextState;
-
typedef struct _R700_CHIP_CONTEXT
{
- // misc
- union UINT_FLOAT TA_CNTL_AUX ; /* 0x2542 */
- union UINT_FLOAT VC_ENHANCE ; /* 0x25C5 */
- union UINT_FLOAT SQ_DYN_GPR_CNTL_PS_FLUSH_REQ; /* 0x2363 */
- union UINT_FLOAT DB_DEBUG ; /* 0x260C */
- union UINT_FLOAT DB_WATERMARKS ; /* 0x260E */
-
// DB
union UINT_FLOAT DB_DEPTH_SIZE ; /* 0xA000 */
union UINT_FLOAT DB_DEPTH_VIEW ; /* 0xA001 */
union UINT_FLOAT DB_DEPTH_BASE ; /* 0xA003 */
union UINT_FLOAT DB_DEPTH_INFO ; /* 0xA004 */
+ GLboolean db_target_dirty;
union UINT_FLOAT DB_HTILE_DATA_BASE ; /* 0xA005 */
union UINT_FLOAT DB_STENCIL_CLEAR ; /* 0xA00A */
union UINT_FLOAT DB_DEPTH_CLEAR ; /* 0xA00B */
@@ -292,6 +292,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT DB_ALPHA_TO_MASK ; /* 0xA351 */
union UINT_FLOAT DB_DEPTH_CONTROL ; /* 0xA200 */
union UINT_FLOAT DB_SHADER_CONTROL ; /* 0xA203 */
+ GLboolean db_dirty;
// SC
union UINT_FLOAT PA_SC_SCREEN_SCISSOR_TL ; /* 0xA00C */
@@ -311,6 +312,8 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT PA_SC_EDGERULE ; /* 0xA08C */
union UINT_FLOAT PA_SC_GENERIC_SCISSOR_TL ; /* 0xA090 */
union UINT_FLOAT PA_SC_GENERIC_SCISSOR_BR ; /* 0xA091 */
+ GLboolean scissor_dirty;
+
union UINT_FLOAT PA_SC_LINE_STIPPLE ; /* 0xA283 */
union UINT_FLOAT PA_SC_LINE_CNTL ; /* 0xA300 */
union UINT_FLOAT PA_SC_AA_CONFIG ; /* 0xA301 */
@@ -319,6 +322,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_MCTX ; /* 0xA307 */
union UINT_FLOAT PA_SC_AA_SAMPLE_LOCS_8S_WD1_MCTX; /* 0xA308 */
union UINT_FLOAT PA_SC_AA_MASK ; /* 0xA312 */
+ GLboolean sc_dirty;
// CL
union UINT_FLOAT PA_CL_CLIP_CNTL ; /* 0xA204 */
@@ -329,6 +333,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT PA_CL_GB_VERT_DISC_ADJ ; /* 0xA304 */
union UINT_FLOAT PA_CL_GB_HORZ_CLIP_ADJ ; /* 0xA305 */
union UINT_FLOAT PA_CL_GB_HORZ_DISC_ADJ ; /* 0xA306 */
+ GLboolean cl_dirty;
// SU
union UINT_FLOAT PA_SU_SC_MODE_CNTL ; /* 0xA205 */
@@ -342,6 +347,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT PA_SU_POLY_OFFSET_FRONT_OFFSET; /* 0xA381 */
union UINT_FLOAT PA_SU_POLY_OFFSET_BACK_SCALE; /* 0xA382 */
union UINT_FLOAT PA_SU_POLY_OFFSET_BACK_OFFSET; /* 0xA383 */
+ GLboolean su_dirty;
VIEWPORT_STATE_STRUCT viewport[R700_MAX_VIEWPORTS];
UCP_STATE_STRUCT ucp[R700_MAX_UCP];
@@ -367,12 +373,14 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT CB_CLRCMP_DST ; /* 0xA30E */
union UINT_FLOAT CB_CLRCMP_MSK ; /* 0xA30F */
union UINT_FLOAT CB_BLEND_CONTROL ; /* 0xABD0 */
+ GLboolean cb_dirty;
RENDER_TARGET_STATE_STRUCT render_target[R700_MAX_RENDER_TARGETS];
// SX
union UINT_FLOAT SX_MISC ; /* 0xA0D4 */
union UINT_FLOAT SX_ALPHA_TEST_CONTROL ; /* 0xA104 */
union UINT_FLOAT SX_ALPHA_REF ; /* 0xA10E */
+ GLboolean sx_dirty;
// VGT
union UINT_FLOAT VGT_MAX_VTX_INDX ; /* 0xA100 */
@@ -393,7 +401,6 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT VGT_GROUP_VECT_1_FMT_CNTL ; /* 0xA28F */
union UINT_FLOAT VGT_GS_MODE ; /* 0xA290 */
union UINT_FLOAT VGT_PRIMITIVEID_EN ; /* 0xA2A1 */
- union UINT_FLOAT VGT_DMA_NUM_INSTANCES ; /* 0xA2A2 */
union UINT_FLOAT VGT_MULTI_PRIM_IB_RESET_EN; /* 0xA2A5 */
union UINT_FLOAT VGT_INSTANCE_STEP_RATE_0 ; /* 0xA2A8 */
union UINT_FLOAT VGT_INSTANCE_STEP_RATE_1 ; /* 0xA2A9 */
@@ -401,6 +408,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT VGT_REUSE_OFF ; /* 0xA2AD */
union UINT_FLOAT VGT_VTX_CNT_EN ; /* 0xA2AE */
union UINT_FLOAT VGT_STRMOUT_BUFFER_EN ; /* 0xA2C8 */
+ GLboolean vgt_dirty;
// SPI
union UINT_FLOAT SPI_VS_OUT_ID_0 ; /* 0xA185 */
@@ -455,39 +463,8 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT SQ_VTX_SEMANTIC_29 ; /* 0xA0FD */
union UINT_FLOAT SQ_VTX_SEMANTIC_30 ; /* 0xA0FE */
union UINT_FLOAT SQ_VTX_SEMANTIC_31 ; /* 0xA0FF */
-
- union UINT_FLOAT SPI_PS_INPUT_CNTL_0 ; /* 0xA191 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_1 ; /* 0xA192 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_2 ; /* 0xA193 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_3 ; /* 0xA194 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_4 ; /* 0xA195 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_5 ; /* 0xA196 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_6 ; /* 0xA197 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_7 ; /* 0xA198 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_8 ; /* 0xA199 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_9 ; /* 0xA19A */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_10 ; /* 0xA19B */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_11 ; /* 0xA19C */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_12 ; /* 0xA19D */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_13 ; /* 0xA19E */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_14 ; /* 0xA19F */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_15 ; /* 0xA1A0 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_16 ; /* 0xA1A1 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_17 ; /* 0xA1A2 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_18 ; /* 0xA1A3 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_19 ; /* 0xA1A4 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_20 ; /* 0xA1A5 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_21 ; /* 0xA1A6 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_22 ; /* 0xA1A7 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_23 ; /* 0xA1A8 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_24 ; /* 0xA1A9 */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_25 ; /* 0xA1AA */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_26 ; /* 0xA1AB */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_27 ; /* 0xA1AC */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_28 ; /* 0xA1AD */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_29 ; /* 0xA1AE */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_30 ; /* 0xA1AF */
- union UINT_FLOAT SPI_PS_INPUT_CNTL_31 ; /* 0xA1B0 */
+ union UINT_FLOAT SPI_PS_INPUT_CNTL[R700_MAX_SHADER_EXPORTS];
+ GLboolean spi_dirty;
// shaders
PS_STATE_STRUCT ps;
@@ -498,7 +475,12 @@ typedef struct _R700_CHIP_CONTEXT
// SQ CONFIG
SQ_CONFIG_STRUCT sq_config;
-
+ // misc
+ union UINT_FLOAT TA_CNTL_AUX ; /* 0x2542 */
+ union UINT_FLOAT VC_ENHANCE ; /* 0x25C5 */
+ union UINT_FLOAT SQ_DYN_GPR_CNTL_PS_FLUSH_REQ; /* 0x2363 */
+ union UINT_FLOAT DB_DEBUG ; /* 0x260C */
+ union UINT_FLOAT DB_WATERMARKS ; /* 0x260E */
// SQ
union UINT_FLOAT SQ_ESGS_RING_ITEMSIZE ; /* 0xA22A */
union UINT_FLOAT SQ_GSVS_RING_ITEMSIZE ; /* 0xA22B */
@@ -509,8 +491,7 @@ typedef struct _R700_CHIP_CONTEXT
union UINT_FLOAT SQ_FBUF_RING_ITEMSIZE ; /* 0xA230 */
union UINT_FLOAT SQ_REDUC_RING_ITEMSIZE ; /* 0xA231 */
union UINT_FLOAT SQ_GS_VERT_ITEMSIZE ; /* 0xA232 */
-
- ContextState* pStateList;
+ GLboolean sq_dirty;
radeonTexObj* textures[R700_TEXTURE_NUMBERUNITS];
diff --git a/src/mesa/drivers/dri/r600/r700_clear.c b/src/mesa/drivers/dri/r600/r700_clear.c
index e84be38622..c6546ab00c 100644
--- a/src/mesa/drivers/dri/r600/r700_clear.c
+++ b/src/mesa/drivers/dri/r600/r700_clear.c
@@ -31,6 +31,7 @@
#include "main/imports.h"
#include "main/mtypes.h"
#include "main/enums.h"
+#include "swrast/swrast.h"
#include "radeon_lock.h"
#include "r600_context.h"
@@ -45,12 +46,6 @@ static GLboolean r700ClearFast(context_t *context, GLbitfield mask)
return GL_FALSE;
}
-#define R600_NEWPRIM( rmesa ) \
- do { \
- if ( rmesa->radeon.dma.flush ) \
- rmesa->radeon.dma.flush( rmesa->radeon.glCtx ); \
- } while (0)
-
void r700Clear(GLcontext * ctx, GLbitfield mask)
{
context_t *context = R700_CONTEXT(ctx);
@@ -60,6 +55,8 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
int i;
struct gl_framebuffer *fb = ctx->DrawBuffer;
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE, "%s %x\n", __func__, mask);
+
if( GL_TRUE == r700ClearFast(context, mask) )
{
return;
@@ -111,8 +108,7 @@ void r700Clear(GLcontext * ctx, GLbitfield mask)
}
if (swrast_mask) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
- fprintf(stderr, "%s: swrast clear, mask: %x\n",
+ radeon_print(RADEON_FALLBACKS, RADEON_IMPORTANT, "%s: swrast clear, mask: %x\n",
__FUNCTION__, swrast_mask);
_swrast_Clear(ctx, swrast_mask);
}
diff --git a/src/mesa/drivers/dri/r600/r700_debug.c b/src/mesa/drivers/dri/r600/r700_debug.c
index ecdb75ad48..cd1ba9eca3 100644
--- a/src/mesa/drivers/dri/r600/r700_debug.c
+++ b/src/mesa/drivers/dri/r600/r700_debug.c
@@ -25,31 +25,8 @@
* CooperYuan <cooper.yuan@amd.com>, <cooperyuan@gmail.com>
*/
-#include <stdio.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "main/glheader.h"
-
#include "r700_debug.h"
-#include "r600_context.h"
-
-void NormalizeLogErrorCode(int nError)
-{
- //TODO
-}
-
-void r700_error(int nLocalError, char* fmt, ...)
-{
- va_list args;
-
- NormalizeLogErrorCode(nLocalError);
-
- va_start(args, fmt);
- fprintf(stderr, fmt, args);
- va_end(args);
-}
+#include "radeon_debug.h"
void DumpHwBinary(int type, void *addr, int size)
{
@@ -61,21 +38,21 @@ void DumpHwBinary(int type, void *addr, int size)
switch (type)
{
case DUMP_PIXEL_SHADER:
- DEBUGF("Pixel Shader\n");
+ radeon_print(RADEON_SHADER, RADEON_TRACE, "Pixel Shader\n");
break;
case DUMP_VERTEX_SHADER:
- DEBUGF("Vertex Shader\n");
+ radeon_print(RADEON_SHADER, RADEON_TRACE, "Vertex Shader\n");
break;
case DUMP_FETCH_SHADER:
- DEBUGF("Fetch Shader\n");
+ radeon_print(RADEON_SHADER, RADEON_TRACE, "Fetch Shader\n");
break;
}
for (i = 0; i < size; i++)
{
- DEBUGP("0x%08x,\t", *pHw);
+ radeon_print(RADEON_SHADER, RADEON_TRACE, "0x%08x,\t", *pHw);
if (i%4 == 3)
- DEBUGP("\n", *pHw);
+ radeon_print(RADEON_SHADER, RADEON_TRACE, "0x%08x\n", *pHw);
pHw++;
}
diff --git a/src/mesa/drivers/dri/r600/r700_debug.h b/src/mesa/drivers/dri/r600/r700_debug.h
index e810e6da08..c0921bf610 100644
--- a/src/mesa/drivers/dri/r600/r700_debug.h
+++ b/src/mesa/drivers/dri/r600/r700_debug.h
@@ -27,67 +27,13 @@
#ifndef _R700_DEBUG_H_
#define _R700_DEBUG_H_
-
-enum R700_ERROR
-{
- ERROR_ASM_VTX_CLAUSE = 0x1000,
- ERROR_ASM_UNKOWNCLAUSE = 0x1001,
- ERROR_ASM_ALLOCEXPORTCF = 0x1002,
- ERROR_ASM_ALLOCVTXCF = 0x1003,
- ERROR_ASM_ALLOCTEXCF = 0x1004,
- ERROR_ASM_ALLOCALUCF = 0x1005,
- ERROR_ASM_UNKNOWNILINST = 0x1006,
- ERROR_ASM_SRCARGUMENT = 0x1007,
- ERROR_ASM_DSTARGUMENT = 0x1008,
- ERROR_ASM_TEXINSTRUCTION = 0x1009,
- ERROR_ASM_ALUINSTRUCTION = 0x100A,
- ERROR_ASM_INSTDSTTRACK = 0x100B,
- ERROR_ASM_TEXDSTBADTYPE = 0x100C,
- ERROR_ASM_ALUSRCBADTYPE = 0x100D,
- ERROR_ASM_ALUSRCSELECT = 0x100E,
- ERROR_ASM_ALUSRCNUMBER = 0x100F,
- ERROR_ASM_ALUDSTBADTYPE = 0x1010,
- ERROR_ASM_CONSTCHANNEL = 0x1011,
- ERROR_ASM_BADSCALARBZ = 0x1012,
- ERROR_ASM_BADGPRRESERVE = 0x1013,
- ERROR_ASM_BADVECTORBZ = 0x1014,
- ERROR_ASM_BADTEXINST = 0x1015,
- ERROR_ASM_BADTEXSRC = 0x1016,
- ERROR_ASM_BADEXPORTTYPE = 0x1017,
-
-
- TODO_ASM_CONSTTEXADDR = 0x8000,
- TODO_ASM_NEEDIMPINST = 0x8001,
- TODO_ASM_TXB = 0x8002,
- TODO_ASM_TXP = 0x8003
-};
-
enum R700_DUMP_TYPE
{
- DUMP_VERTEX_SHADER = 0x1,
- DUMP_PIXEL_SHADER = 0x2,
- DUMP_FETCH_SHADER = 0x4,
+ DUMP_VERTEX_SHADER = 0x1,
+ DUMP_PIXEL_SHADER = 0x2,
+ DUMP_FETCH_SHADER = 0x4,
};
-#define DEBUGF printf
-#define DEBUGP printf
-
-void NormalizeLogErrorCode(int nError);
-/*NormalizeLogErrorCode(nLocalError); */
-void r700_error(int nLocalError, char *fmt, ...);
extern void DumpHwBinary(int, void *, int);
-#ifdef STANDALONE_COMPILER
-#ifdef __cplusplus
-extern "C"
-{
-#endif //__cplusplus
-
-void LogString(char* szStr);
-
-#ifdef __cplusplus
-}
-#endif //__cplusplus
-#endif /*STANDALONE_COMPILER*/
-
#endif /*_R700_DEBUG_H_*/
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.c b/src/mesa/drivers/dri/r600/r700_fragprog.c
index 44de2aebee..78ce3ae436 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.c
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.c
@@ -55,6 +55,12 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm,
//Input mapping : mesa_fp->Base.InputsRead set the flag, set in
//The flags parsed in parse_attrib_binding. FRAG_ATTRIB_COLx, FRAG_ATTRIB_TEXx, ...
//MUST match order in Map_Vertex_Output
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS] = pAsm->number_used_registers++;
+ }
+
unBit = 1 << FRAG_ATTRIB_COL0;
if(mesa_fp->Base.InputsRead & unBit)
{
@@ -67,6 +73,12 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm,
pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1] = pAsm->number_used_registers++;
}
+ unBit = 1 << FRAG_ATTRIB_FOGC;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC] = pAsm->number_used_registers++;
+ }
+
for(i=0; i<8; i++)
{
unBit = 1 << (FRAG_ATTRIB_TEX0 + i);
@@ -106,15 +118,16 @@ void Map_Fragment_Program(r700_AssemblerBase *pAsm,
pAsm->uiFP_OutputMap[FRAG_RESULT_DEPTH] = pAsm->number_used_registers++;
pAsm->number_of_exports++;
pAsm->number_of_colorandz_exports++;
+ pAsm->pR700Shader->depthIsExported = 1;
}
- pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
+ pAsm->pucOutMask = (unsigned char*) MALLOC(pAsm->number_of_exports);
for(ui=0; ui<pAsm->number_of_exports; ui++)
{
pAsm->pucOutMask[ui] = 0x0;
}
-
- pAsm->uFirstHelpReg = pAsm->number_used_registers;
+
+ pAsm->uFirstHelpReg = pAsm->number_used_registers;
}
GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp,
@@ -245,6 +258,20 @@ GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
return GL_TRUE;
}
+void r700SelectFragmentShader(GLcontext *ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_fragment_program *fp = (struct r700_fragment_program *)
+ (ctx->FragmentProgram._Current);
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ {
+ fp->r700AsmCode.bR6xx = 1;
+ }
+
+ if (GL_FALSE == fp->translated)
+ r700TranslateFragmentShader(fp, &(fp->mesa_program));
+}
+
void * r700GetActiveFpShaderBo(GLcontext * ctx)
{
struct r700_fragment_program *fp = (struct r700_fragment_program *)
@@ -255,33 +282,32 @@ void * r700GetActiveFpShaderBo(GLcontext * ctx)
GLboolean r700SetupFragmentProgram(GLcontext * ctx)
{
- context_t *context = R700_CONTEXT(ctx);
- BATCH_LOCALS(&context->radeon);
-
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
struct r700_fragment_program *fp = (struct r700_fragment_program *)
(ctx->FragmentProgram._Current);
-
+ r700_AssemblerBase *pAsm = &(fp->r700AsmCode);
+ struct gl_fragment_program *mesa_fp = &(fp->mesa_program);
struct gl_program_parameter_list *paramList;
unsigned int unNumParamData;
- unsigned int ui;
-
+ unsigned int ui, i;
unsigned int unNumOfReg;
-
+ unsigned int unBit;
+ GLuint exportCount;
+
if(GL_FALSE == fp->loaded)
{
- if(fp->r700Shader.bNeedsAssembly == GL_TRUE)
+ if(fp->r700Shader.bNeedsAssembly == GL_TRUE)
{
Assemble( &(fp->r700Shader) );
}
/* Load fp to gpu */
- r600EmitShader(ctx,
- &(fp->shaderbo),
+ r600EmitShader(ctx,
+ &(fp->shaderbo),
(GLvoid *)(fp->r700Shader.pProgram),
fp->r700Shader.uShaderBinaryDWORDSize,
- "FS");
+ "FS");
fp->loaded = GL_TRUE;
}
@@ -293,16 +319,33 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
(context->chipobj.MemUse)(context, fp->shadercode.buf->id);
*/
+ R600_STATECHANGE(context, ps);
+
+ r700->ps.SQ_PGM_RESOURCES_PS.u32All = 0;
+ SETbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
+
r700->ps.SQ_PGM_START_PS.u32All = 0; /* set from buffer obj */
+ R600_STATECHANGE(context, spi);
+
unNumOfReg = fp->r700Shader.nRegs + 1;
ui = (r700->SPI_PS_IN_CONTROL_0.u32All & NUM_INTERP_mask) / (1 << NUM_INTERP_shift);
- ui = ui ? ui : unNumOfReg;
+ /* PS uses fragment.position */
+ if (mesa_fp->Base.InputsRead & (1 << FRAG_ATTRIB_WPOS))
+ {
+ ui += 1;
+ SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, ui, NUM_INTERP_shift, NUM_INTERP_mask);
+ SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, CENTERS_ONLY, BARYC_SAMPLE_CNTL_shift, BARYC_SAMPLE_CNTL_mask);
+ SETbit(r700->SPI_PS_IN_CONTROL_0.u32All, POSITION_ENA_bit);
+ SETbit(r700->SPI_INPUT_Z.u32All, PROVIDE_Z_TO_SPI_bit);
+ }
+
+ ui = (unNumOfReg < ui) ? ui : unNumOfReg;
+
+ SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
- SETfield(r700->ps.SQ_PGM_RESOURCES_PS.u32All, ui, NUM_GPRS_shift, NUM_GPRS_mask);
-
CLEARbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, UNCACHED_FIRST_INST_bit);
if(fp->r700Shader.uStackSize) /* we don't use branch for now, it should be zero. */
@@ -314,6 +357,8 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
SETfield(r700->ps.SQ_PGM_EXPORTS_PS.u32All, fp->r700Shader.exportMode,
EXPORT_MODE_shift, EXPORT_MODE_mask);
+ R600_STATECHANGE(context, db);
+
if(fp->r700Shader.killIsUsed)
{
SETbit(r700->DB_SHADER_CONTROL.u32All, KILL_ENABLE_bit);
@@ -325,45 +370,107 @@ GLboolean r700SetupFragmentProgram(GLcontext * ctx)
if(fp->r700Shader.depthIsExported)
{
- SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
+ SETbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
}
else
{
CLEARbit(r700->DB_SHADER_CONTROL.u32All, Z_EXPORT_ENABLE_bit);
}
- /* sent out shader constants. */
+ // emit ps input map
+ unBit = 1 << FRAG_ATTRIB_WPOS;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_WPOS];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
- paramList = fp->mesa_program.Base.Parameters;
+ unBit = 1 << FRAG_ATTRIB_COL0;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL0];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ unBit = 1 << FRAG_ATTRIB_COL1;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_COL1];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+
+ unBit = 1 << FRAG_ATTRIB_FOGC;
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_FOGC];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ if (r700->SPI_INTERP_CONTROL_0.u32All & FLAT_SHADE_ENA_bit)
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ else
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
- if(NULL != paramList)
+ for(i=0; i<8; i++)
{
- _mesa_load_state_parameters(ctx, paramList);
+ unBit = 1 << (FRAG_ATTRIB_TEX0 + i);
+ if(mesa_fp->Base.InputsRead & unBit)
+ {
+ ui = pAsm->uiFP_AttributeMap[FRAG_ATTRIB_TEX0 + i];
+ SETbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, SEL_CENTROID_bit);
+ SETfield(r700->SPI_PS_INPUT_CNTL[ui].u32All, ui,
+ SEMANTIC_shift, SEMANTIC_mask);
+ CLEARbit(r700->SPI_PS_INPUT_CNTL[ui].u32All, FLAT_SHADE_bit);
+ }
+ }
- unNumParamData = paramList->NumParameters * 4;
+ R600_STATECHANGE(context, cb);
+ exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
+ r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
- BEGIN_BATCH_NO_AUTOSTATE(2 + unNumParamData);
-
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
+ /* sent out shader constants. */
+ paramList = fp->mesa_program.Base.Parameters;
- /* assembler map const from very beginning. */
- R600_OUT_BATCH(SQ_ALU_CONSTANT_PS_OFFSET * 4);
+ if(NULL != paramList) {
+ _mesa_load_state_parameters(ctx, paramList);
- unNumParamData = paramList->NumParameters;
+ if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
+ return GL_FALSE;
- for(ui=0; ui<unNumParamData; ui++)
- {
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
- }
- END_BATCH();
- COMMIT_BATCH();
- }
+ R600_STATECHANGE(context, ps_consts);
- return GL_TRUE;
-}
+ r700->ps.num_consts = paramList->NumParameters;
+ unNumParamData = paramList->NumParameters;
+ for(ui=0; ui<unNumParamData; ui++) {
+ r700->ps.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+ r700->ps.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+ r700->ps.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+ r700->ps.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+ }
+ } else
+ r700->ps.num_consts = 0;
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/r600/r700_fragprog.h b/src/mesa/drivers/dri/r600/r700_fragprog.h
index 9c7813e908..cbb108d212 100644
--- a/src/mesa/drivers/dri/r600/r700_fragprog.h
+++ b/src/mesa/drivers/dri/r600/r700_fragprog.h
@@ -49,13 +49,16 @@ struct r700_fragment_program
/* Internal */
void Map_Fragment_Program(r700_AssemblerBase *pAsm,
- struct gl_fragment_program *mesa_fp);
+ struct gl_fragment_program *mesa_fp);
GLboolean Find_Instruction_Dependencies_fp(struct r700_fragment_program *fp,
- struct gl_fragment_program *mesa_fp);
+ struct gl_fragment_program *mesa_fp);
+
+GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
+ struct gl_fragment_program *mesa_vp);
/* Interface */
-extern GLboolean r700TranslateFragmentShader(struct r700_fragment_program *fp,
- struct gl_fragment_program *mesa_vp);
+extern void r700SelectFragmentShader(GLcontext *ctx);
+
extern GLboolean r700SetupFragmentProgram(GLcontext * ctx);
extern void * r700GetActiveFpShaderBo(GLcontext * ctx);
diff --git a/src/mesa/drivers/dri/r600/r700_ioctl.c b/src/mesa/drivers/dri/r600/r700_ioctl.c
index c479532001..72a8978976 100644
--- a/src/mesa/drivers/dri/r600/r700_ioctl.c
+++ b/src/mesa/drivers/dri/r600/r700_ioctl.c
@@ -31,6 +31,7 @@
#include "main/imports.h"
#include "main/macros.h"
#include "main/context.h"
+#include "main/simple_list.h"
#include "swrast/swrast.h"
#include "radeon_common.h"
@@ -40,34 +41,10 @@
#include "r700_ioctl.h"
#include "r700_clear.h"
-static void r700Flush(GLcontext *ctx)
-{
- radeonContextPtr radeon = RADEON_CONTEXT(ctx);
- context_t * context = R700_CONTEXT(ctx);
-
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw);
-
- /* okay if we have no cmds in the buffer &&
- we have no DMA flush &&
- we have no DMA buffer allocated.
- then no point flushing anything at all.
- */
- if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current)
- return;
-
- if (radeon->dma.flush)
- radeon->dma.flush( ctx );
-
- r700SendContextStates(context);
-
- if (radeon->cmdbuf.cs->cdw)
- rcommonFlushCmdBuf(radeon, __FUNCTION__);
-}
void r700InitIoctlFuncs(struct dd_function_table *functions)
{
functions->Clear = r700Clear;
functions->Finish = radeonFinish;
- functions->Flush = r700Flush;
+ functions->Flush = radeonFlush;
}
diff --git a/src/mesa/drivers/dri/r600/r700_oglprog.c b/src/mesa/drivers/dri/r600/r700_oglprog.c
index 36de143b1a..5290ef31be 100644
--- a/src/mesa/drivers/dri/r600/r700_oglprog.c
+++ b/src/mesa/drivers/dri/r600/r700_oglprog.c
@@ -33,6 +33,7 @@
#include "tnl/tnl.h"
#include "r600_context.h"
+#include "r600_emit.h"
#include "r700_oglprog.h"
#include "r700_fragprog.h"
@@ -45,23 +46,21 @@ 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,
+ "%s %u, %u\n", __func__, target, id);
+
switch (target)
{
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:
@@ -85,22 +84,31 @@ 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;
- context_t *context = R700_CONTEXT(ctx);
+
+ radeon_print(RADEON_SHADER, RADEON_VERBOSE,
+ "%s %p\n", __func__, prog);
switch (prog->Target)
{
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 77cbe3cfd0..b58859b6ba 100644
--- a/src/mesa/drivers/dri/r600/r700_render.c
+++ b/src/mesa/drivers/dri/r600/r700_render.c
@@ -43,8 +43,8 @@
#include "tnl/t_context.h"
#include "tnl/t_vertex.h"
#include "tnl/t_pipeline.h"
+#include "vbo/vbo_context.h"
-#include "radeon_mipmap_tree.h"
#include "r600_context.h"
#include "r600_cmdbuf.h"
@@ -54,11 +54,13 @@
#include "r700_fragprog.h"
#include "r700_state.h"
+#include "radeon_buffer_objects.h"
+#include "radeon_common_context.h"
+
void r700WaitForIdle(context_t *context);
void r700WaitForIdleClean(context_t *context);
-void r700Start3D(context_t *context);
GLboolean r700SendTextureState(context_t *context);
-unsigned int r700PrimitiveType(int prim);
+static unsigned int r700PrimitiveType(int prim);
void r600UpdateTextureState(GLcontext * ctx);
GLboolean r700SyncSurf(context_t *context,
struct radeon_bo *pbo,
@@ -69,6 +71,7 @@ GLboolean r700SyncSurf(context_t *context,
void r700WaitForIdle(context_t *context)
{
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_RENDER | RADEON_STATE, RADEON_TRACE, "%s\n", __func__);
BEGIN_BATCH_NO_AUTOSTATE(3);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_CONFIG_REG, 1));
@@ -82,6 +85,7 @@ void r700WaitForIdle(context_t *context)
void r700WaitForIdleClean(context_t *context)
{
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_RENDER | RADEON_STATE, RADEON_TRACE, "%s\n", __func__);
BEGIN_BATCH_NO_AUTOSTATE(5);
R600_OUT_BATCH(CP_PACKET3(R600_IT_EVENT_WRITE, 0));
@@ -98,6 +102,7 @@ void r700WaitForIdleClean(context_t *context)
void r700Start3D(context_t *context)
{
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_RENDER | RADEON_STATE, RADEON_TRACE, "%s\n", __func__);
if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
{
BEGIN_BATCH_NO_AUTOSTATE(2);
@@ -117,83 +122,6 @@ void r700Start3D(context_t *context)
r700WaitForIdleClean(context);
}
-static GLboolean r700SetupShaders(GLcontext * ctx)
-{
- context_t *context = R700_CONTEXT(ctx);
-
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
- GLuint exportCount;
-
- r700->ps.SQ_PGM_RESOURCES_PS.u32All = 0;
- r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
-
- SETbit(r700->ps.SQ_PGM_RESOURCES_PS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
- SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
-
- r700SetupVertexProgram(ctx);
-
- r700SetupFragmentProgram(ctx);
-
- exportCount = (r700->ps.SQ_PGM_EXPORTS_PS.u32All & EXPORT_MODE_mask) / (1 << EXPORT_MODE_shift);
- r700->CB_SHADER_CONTROL.u32All = (1 << exportCount) - 1;
-
- return GL_TRUE;
-}
-
-GLboolean r700SendTextureState(context_t *context)
-{
- unsigned int i;
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
- offset_modifiers offset_mod = {NO_SHIFT, 0, 0xFFFFFFFF};
- struct radeon_bo *bo = NULL;
- BATCH_LOCALS(&context->radeon);
-
- for (i=0; i<R700_TEXTURE_NUMBERUNITS; i++) {
- radeonTexObj *t = r700->textures[i];
- if (t) {
- if (!t->image_override)
- bo = t->mt->bo;
- else
- bo = t->bo;
- if (bo) {
-
- r700SyncSurf(context, bo,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM,
- 0, TC_ACTION_ENA_bit);
-
- BEGIN_BATCH_NO_AUTOSTATE(9);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_RESOURCE, 7));
- R600_OUT_BATCH(i * 7);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE0);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE1);
- R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE2,
- bo,
- 0,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0, &offset_mod);
- R600_OUT_BATCH_RELOC(r700->textures[i]->SQ_TEX_RESOURCE3,
- bo,
- 0,
- RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0, &offset_mod);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE4);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE5);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_RESOURCE6);
- END_BATCH();
-
- BEGIN_BATCH_NO_AUTOSTATE(5);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_SAMPLER, 3));
- R600_OUT_BATCH(i * 3);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER0);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER1);
- R600_OUT_BATCH(r700->textures[i]->SQ_TEX_SAMPLER2);
- END_BATCH();
- COMMIT_BATCH();
- }
- }
- }
- return GL_TRUE;
-}
-
GLboolean r700SyncSurf(context_t *context,
struct radeon_bo *pbo,
uint32_t read_domain,
@@ -201,35 +129,34 @@ GLboolean r700SyncSurf(context_t *context,
uint32_t sync_type)
{
BATCH_LOCALS(&context->radeon);
+ radeon_print(RADEON_RENDER | RADEON_STATE, RADEON_TRACE, "%s\n", __func__);
uint32_t cp_coher_size;
- offset_modifiers offset_mod;
+
+ if (!pbo)
+ return GL_FALSE;
if (pbo->size == 0xffffffff)
cp_coher_size = 0xffffffff;
else
cp_coher_size = ((pbo->size + 255) >> 8);
- offset_mod.shift = NO_SHIFT;
- offset_mod.shiftbits = 0;
- offset_mod.mask = 0xFFFFFFFF;
-
- BEGIN_BATCH_NO_AUTOSTATE(5);
+ BEGIN_BATCH_NO_AUTOSTATE(5 + 2);
R600_OUT_BATCH(CP_PACKET3(R600_IT_SURFACE_SYNC, 3));
R600_OUT_BATCH(sync_type);
R600_OUT_BATCH(cp_coher_size);
+ R600_OUT_BATCH(0);
+ R600_OUT_BATCH(10);
R600_OUT_BATCH_RELOC(0,
pbo,
0,
- read_domain, write_domain, 0, &offset_mod); // ???
- R600_OUT_BATCH(10);
-
+ read_domain, write_domain, 0);
END_BATCH();
COMMIT_BATCH();
return GL_TRUE;
}
-unsigned int r700PrimitiveType(int prim)
+static unsigned int r700PrimitiveType(int prim)
{
switch (prim & PRIM_MODE_MASK)
{
@@ -270,120 +197,253 @@ unsigned int r700PrimitiveType(int prim)
}
}
-static GLboolean r700RunRender(GLcontext * ctx,
- struct tnl_pipeline_stage *stage)
+static int r700NumVerts(int num_verts, int prim)
{
- context_t *context = R700_CONTEXT(ctx);
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
- int lastIndex = 0;
-#if 1
- BATCH_LOCALS(&context->radeon);
-
- unsigned int i, j;
- TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *vb = &tnl->vb;
+ int verts_off = 0;
+
+ switch (prim & PRIM_MODE_MASK) {
+ case GL_POINTS:
+ verts_off = 0;
+ break;
+ case GL_LINES:
+ verts_off = num_verts % 2;
+ break;
+ case GL_LINE_STRIP:
+ if (num_verts < 2)
+ verts_off = num_verts;
+ break;
+ case GL_LINE_LOOP:
+ if (num_verts < 2)
+ verts_off = num_verts;
+ break;
+ case GL_TRIANGLES:
+ verts_off = num_verts % 3;
+ break;
+ case GL_TRIANGLE_STRIP:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ case GL_TRIANGLE_FAN:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ case GL_QUADS:
+ verts_off = num_verts % 4;
+ break;
+ case GL_QUAD_STRIP:
+ if (num_verts < 4)
+ verts_off = num_verts;
+ else
+ verts_off = num_verts % 2;
+ break;
+ case GL_POLYGON:
+ if (num_verts < 3)
+ verts_off = num_verts;
+ break;
+ default:
+ assert(0);
+ return -1;
+ break;
+ }
+
+ return num_verts - verts_off;
+}
- struct r700_fragment_program *fp = (struct r700_fragment_program *)
- (ctx->FragmentProgram._Current);
- if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
- {
- fp->r700AsmCode.bR6xx = 1;
- }
+static void r700RunRenderPrimitive(GLcontext * ctx, int start, int end, int prim)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ BATCH_LOCALS(&context->radeon);
+ int type, i, total_emit;
+ int num_indices;
+ uint32_t vgt_draw_initiator = 0;
+ uint32_t vgt_index_type = 0;
+ uint32_t vgt_primitive_type = 0;
+ uint32_t vgt_num_indices = 0;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *vb = &tnl->vb;
+
+ type = r700PrimitiveType(prim);
+ num_indices = r700NumVerts(end - start, prim);
+
+ radeon_print(RADEON_RENDER, RADEON_TRACE,
+ "%s type %x num_indices %d\n",
+ __func__, type, num_indices);
+
+ if (type < 0 || num_indices <= 0)
+ return;
+
+ total_emit = 3 /* VGT_PRIMITIVE_TYPE */
+ + 2 /* VGT_INDEX_TYPE */
+ + 2 /* NUM_INSTANCES */
+ + num_indices + 3; /* DRAW_INDEX_IMMD */
+
+ 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);
- r700Start3D(context); /* TODO : this is too much. */
+ // 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);
- r700SendSQConfig(context);
+ // num instances
+ R600_OUT_BATCH(CP_PACKET3(R600_IT_NUM_INSTANCES, 0));
+ R600_OUT_BATCH(1);
- r700UpdateShaders(ctx);
+ // draw packet
+ vgt_num_indices = num_indices;
+ 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);
- r700SetScissor(context);
- r700SetRenderTarget(context, 0);
- r700SetDepthTarget(context);
+ 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(r700SetupStreams(ctx))
+ if(NULL == context->ind_buf.bo)
{
- return GL_TRUE;
+ for (i = start; i < (start + num_indices); i++) {
+ if(vb->Elts)
+ {
+ R600_OUT_BATCH(vb->Elts[i]);
+ }
+ else
+ R600_OUT_BATCH(i);
+ }
}
-
- r600UpdateTextureState(ctx);
- r700SendTextureState(context);
-
- if(GL_FALSE == fp->translated)
- {
- if( GL_FALSE == r700TranslateFragmentShader(fp, &(fp->mesa_program)) )
+ else
+ {
+ if(GL_TRUE == context->ind_buf.bHostIb)
{
- return GL_TRUE;
+ 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++;
+ }
+ }
+ }
+ else
+ {
+ /* TODO : hw ib draw */
}
}
- r700SetupShaders(ctx);
-
- r700SendFSState(context); // FIXME just a place holder for now
- r700SendPSState(context);
- r700SendVSState(context);
-
- r700SendUCPState(context);
- r700SendContextStates(context);
- r700SendViewportState(context, 0);
- r700SendRenderTargetState(context, 0);
- r700SendDepthTargetState(context);
+ END_BATCH();
+ COMMIT_BATCH();
+}
- /* richard test code */
- for (i = 0; i < vb->PrimitiveCount; i++)
- {
- GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
- GLuint start = vb->Primitive[i].start;
- GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
- GLuint numIndices = vb->Primitive[i].count;
- GLuint numEntires;
+/* start 3d, idle, cb/db flush */
+#define PRE_EMIT_STATE_BUFSZ 10 + 5 + 14
- unsigned int VGT_DRAW_INITIATOR = 0;
- unsigned int VGT_INDEX_TYPE = 0;
- unsigned int VGT_PRIMITIVE_TYPE = 0;
- unsigned int VGT_NUM_INDICES = 0;
-
- numEntires = 2 /* VGT_INDEX_TYPE */
- + 3 /* VGT_PRIMITIVE_TYPE */
- + numIndices + 3; /* DRAW_INDEX_IMMD */
-
- BEGIN_BATCH_NO_AUTOSTATE(numEntires);
+static GLuint r700PredictRenderSize(GLcontext* ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct r700_vertex_program *vp = context->selected_vp;
+ struct vertex_buffer *vb = &tnl->vb;
+ GLboolean flushed;
+ GLuint dwords, i;
+ GLuint state_size;
+ /* pre calculate aos count so state prediction works */
+ 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;
+ state_size = radeonCountStateEmitSize(&context->radeon);
+ flushed = rcommonEnsureCmdBufSpace(&context->radeon,
+ dwords + state_size, __FUNCTION__);
+
+ if (flushed)
+ dwords += radeonCountStateEmitSize(&context->radeon);
+ else
+ dwords += state_size;
- VGT_INDEX_TYPE |= DI_INDEX_SIZE_32_BIT << INDEX_TYPE_shift;
+ radeon_print(RADEON_RENDER, RADEON_VERBOSE,
+ "%s: total prediction size is %d.\n", __FUNCTION__, dwords);
+ return dwords;
+}
- R600_OUT_BATCH(CP_PACKET3(R600_IT_INDEX_TYPE, 0));
- R600_OUT_BATCH(VGT_INDEX_TYPE);
+static GLboolean r700RunRender(GLcontext * ctx,
+ struct tnl_pipeline_stage *stage)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ radeonContextPtr radeon = &context->radeon;
+ unsigned int i, id = 0;
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *vb = &tnl->vb;
+ struct radeon_renderbuffer *rrb;
- VGT_NUM_INDICES = numIndices;
+ radeon_print(RADEON_RENDER, RADEON_NORMAL, "%s: cs begin at %d\n",
+ __func__, context->radeon.cmdbuf.cs->cdw);
- VGT_PRIMITIVE_TYPE |= r700PrimitiveType(prim) << VGT_PRIMITIVE_TYPE__PRIM_TYPE_shift;
- 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);
+ /* 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);
- VGT_DRAW_INITIATOR |= DI_SRC_SEL_IMMEDIATE << SOURCE_SELECT_shift;
- VGT_DRAW_INITIATOR |= DI_MAJOR_MODE_0 << MAJOR_MODE_shift;
+ r700SetScissor(context);
+ r700SetupVertexProgram(ctx);
+ r700SetupFragmentProgram(ctx);
+ r600UpdateTextureState(ctx);
- R600_OUT_BATCH(CP_PACKET3(R600_IT_DRAW_INDEX_IMMD, (numIndices + 1)));
- R600_OUT_BATCH(VGT_NUM_INDICES);
- R600_OUT_BATCH(VGT_DRAW_INITIATOR);
+ GLuint emit_end = r700PredictRenderSize(ctx)
+ + context->radeon.cmdbuf.cs->cdw;
+ r700SetupStreams(ctx);
- for (j = lastIndex; j < lastIndex + numIndices; j++)
- {
- R600_OUT_BATCH(j);
- }
- lastIndex += numIndices;
+ radeonEmitState(radeon);
- END_BATCH();
- COMMIT_BATCH();
+ radeon_debug_add_indent();
+ /* richard test code */
+ for (i = 0; i < vb->PrimitiveCount; i++) {
+ GLuint prim = _tnl_translate_prim(&vb->Primitive[i]);
+ GLuint start = vb->Primitive[i].start;
+ GLuint end = vb->Primitive[i].start + vb->Primitive[i].count;
+ r700RunRenderPrimitive(ctx, start, end, prim);
}
+ radeon_debug_remove_indent();
/* Flush render op cached for last several quads. */
r700WaitForIdleClean(context);
- radeonReleaseArrays(ctx, 0);
+ 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);
-#endif //0
- rcommonFlushCmdBuf( &context->radeon, __FUNCTION__ );
+ radeonReleaseArrays(ctx, ~0);
+
+ radeon_print(RADEON_RENDER, RADEON_TRACE, "%s: cs end at %d\n",
+ __func__, context->radeon.cmdbuf.cs->cdw);
+
+ 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_FALSE;
}
@@ -403,7 +463,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))
@@ -411,10 +474,6 @@ static GLboolean r700RunTCLRender(GLcontext * ctx, /*----------------------*/
return GL_TRUE;
}
- context_t *context = R700_CONTEXT(ctx);
-
- r700UpdateShaders(ctx);
-
bRet = r700RunRender(ctx, stage);
return bRet;
@@ -456,4 +515,585 @@ 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, &r300->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_TRUE;
+
+#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;
+ GLboolean bValidedbuffer;
+ struct radeon_renderbuffer *rrb;
+
+ if (ctx->NewState)
+ {
+ _mesa_update_state( ctx );
+ }
+
+ bValidedbuffer = r600ValidateBuffers(ctx);
+
+ /* 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);
+
+ _tnl_UpdateFixedFunctionProgram(ctx);
+ r700SetVertexFormat(ctx, arrays, max_index + 1);
+ r700SetupStreams2(ctx, arrays, max_index + 1);
+ r700UpdateShaders2(ctx);
+
+ r700SetScissor(context);
+
+ r700SetupVertexProgram(ctx);
+
+ r700SetupFragmentProgram(ctx);
+
+ r600UpdateTextureState(ctx);
+
+ GLuint emit_end = r700PredictRenderSize(ctx)
+ + context->radeon.cmdbuf.cs->cdw;
+
+ r700SetupIndexBuffer(ctx, ib);
+
+ radeonEmitState(radeon);
+
+ for (i = 0; i < nr_prims; ++i)
+ {
+ r700RunRenderPrimitive(ctx,
+ prim[i].start,
+ prim[i].start + prim[i].count,
+ prim[i].mode);
+ }
+
+ /* 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);
+
+ 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 b4fd51c137..955ea4e4e1 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 bfd01e1a93..997cb05aaf 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_shaderinst.c b/src/mesa/drivers/dri/r600/r700_shaderinst.c
index c1bffee91f..f120d9f941 100644
--- a/src/mesa/drivers/dri/r600/r700_shaderinst.c
+++ b/src/mesa/drivers/dri/r600/r700_shaderinst.c
@@ -27,7 +27,7 @@
#include "main/mtypes.h"
-#include "r700_debug.h"
+#include "radeon_debug.h"
#include "r700_shaderinst.h"
void Init_R700ControlFlowGenericClause(R700ControlFlowGenericClause* pInst)
@@ -208,16 +208,16 @@ unsigned int GetCFMaxInstructions(ShaderInstType instType)
GLboolean LinkVertexInstruction(R700ControlFlowGenericClause *pCFGeneric,
R700VertexInstruction *pVTXInstruction)
{
- if (pCFGeneric->m_pLinkedTEXInstruction != 0)
- {
- r700_error(ERROR_ASM_VTX_CLAUSE, "This instruction is already linked to a texture instruction");
- return GL_FALSE;
+ if (pCFGeneric->m_pLinkedTEXInstruction != 0)
+ {
+ radeon_error("This instruction is already linked to a texture instruction.\n");
+ return GL_FALSE;
}
pCFGeneric->m_pLinkedVTXInstruction = pVTXInstruction;
- pVTXInstruction->m_pLinkedGenericClause = pCFGeneric;
+ pVTXInstruction->m_pLinkedGenericClause = pCFGeneric;
- return GL_TRUE;
+ return GL_TRUE;
}
diff --git a/src/mesa/drivers/dri/r600/r700_state.c b/src/mesa/drivers/dri/r600/r700_state.c
index a2ddebb1ce..1043eabb14 100644
--- a/src/mesa/drivers/dri/r600/r700_state.c
+++ b/src/mesa/drivers/dri/r600/r700_state.c
@@ -61,57 +61,58 @@ static void r700UpdatePolygonMode(GLcontext * ctx);
static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state);
static void r700SetStencilState(GLcontext * ctx, GLboolean state);
-void r700SetDefaultStates(context_t *context) //--------------------
-{
-
-}
-
void r700UpdateShaders (GLcontext * ctx) //----------------------------------
{
context_t *context = R700_CONTEXT(ctx);
-
GLvector4f dummy_attrib[_TNL_ATTRIB_MAX];
GLvector4f *temp_attrib[_TNL_ATTRIB_MAX];
+ int i;
- struct r700_vertex_program *vp;
- int i;
+ /* 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;
+ }
- if (context->radeon.NewGLState)
- {
- context->radeon.NewGLState = 0;
+ r700SelectFragmentShader(ctx);
- for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++)
- {
- /* mat states from state var not array for sw */
- dummy_attrib[i].stride = 0;
+ if (context->radeon.NewGLState) {
+ for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+ /* mat states from state var not array for sw */
+ dummy_attrib[i].stride = 0;
+ temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
+ TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &(dummy_attrib[i]);
+ }
- temp_attrib[i] = TNL_CONTEXT(ctx)->vb.AttribPtr[i];
- TNL_CONTEXT(ctx)->vb.AttribPtr[i] = &(dummy_attrib[i]);
- }
+ _tnl_UpdateFixedFunctionProgram(ctx);
- _tnl_UpdateFixedFunctionProgram(ctx);
+ for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++) {
+ TNL_CONTEXT(ctx)->vb.AttribPtr[i] = temp_attrib[i];
+ }
+ }
- for (i = _TNL_FIRST_MAT; i <= _TNL_LAST_MAT; i++)
- {
- TNL_CONTEXT(ctx)->vb.AttribPtr[i] = temp_attrib[i];
- }
+ r700SelectVertexShader(ctx, 1);
+ r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ context->radeon.NewGLState = 0;
+}
- r700SelectVertexShader(ctx);
- vp = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+void r700UpdateShaders2(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
- if (vp->translated == GL_FALSE)
- {
- // TODO
- //fprintf(stderr, "Failing back to sw-tcl\n");
- //hw_tcl_on = future_hw_tcl_on = 0;
- //r300ResetHwState(rmesa);
- //
- r700UpdateStateParameters(ctx, _NEW_PROGRAM);
- return;
- }
+ /* 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;
}
- r700UpdateStateParameters(ctx, _NEW_PROGRAM);
+ r700SelectFragmentShader(ctx);
+
+ r700SelectVertexShader(ctx, 2);
+ r700UpdateStateParameters(ctx, _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS);
+ context->radeon.NewGLState = 0;
}
/*
@@ -130,76 +131,38 @@ void r700UpdateViewportOffset(GLcontext * ctx) //------------------
GLfloat tx = v[MAT_TX] + xoffset;
GLfloat ty = (-v[MAT_TY]) + yoffset;
- r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
- r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
-
- radeonUpdateScissor(ctx);
-}
-
-/**
- * Tell the card where to render (offset, pitch).
- * Effected by glDrawBuffer, etc
- */
-void r700UpdateDrawBuffer(GLcontext * ctx) /* TODO */ //---------------------
-{
-#if 0 /* to be enabled */
- context_t *context = R700_CONTEXT(ctx);
-
- switch (ctx->DrawBuffer->_ColorDrawBufferIndexes[0])
- {
- case BUFFER_FRONT_LEFT:
- context->target.rt = context->screen->frontBuffer;
- break;
- case BUFFER_BACK_LEFT:
- context->target.rt = context->screen->backBuffer;
- break;
- default:
- memset (&context->target.rt, sizeof(context->target.rt), 0);
+ if (r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All != tx ||
+ r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All != ty) {
+ /* Note: this should also modify whatever data the context reset
+ * code uses...
+ */
+ R600_STATECHANGE(context, vpt);
+ r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
+ r700->viewport[id].PA_CL_VPORT_YOFFSET.f32All = ty;
}
-#endif /* to be enabled */
-}
-
-static void r700FetchStateParameter(GLcontext * ctx,
- const gl_state_index state[STATE_LENGTH],
- GLfloat * value)
-{
- context_t *context = R700_CONTEXT(ctx);
- /* TODO */
+ radeonUpdateScissor(ctx);
}
void r700UpdateStateParameters(GLcontext * ctx, GLuint new_state) //--------------------
{
- struct r700_fragment_program *fp;
+ struct r700_fragment_program *fp =
+ (struct r700_fragment_program *)ctx->FragmentProgram._Current;
struct gl_program_parameter_list *paramList;
- GLuint i;
- if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM)))
+ if (!(new_state & (_NEW_BUFFERS | _NEW_PROGRAM | _NEW_PROGRAM_CONSTANTS)))
return;
- fp = (struct r700_fragment_program *)ctx->FragmentProgram._Current;
- if (!fp)
- {
+ if (!ctx->FragmentProgram._Current || !fp)
return;
- }
- paramList = fp->mesa_program.Base.Parameters;
+ paramList = ctx->FragmentProgram._Current->Base.Parameters;
if (!paramList)
- {
return;
- }
- for (i = 0; i < paramList->NumParameters; i++)
- {
- if (paramList->Parameters[i].Type == PROGRAM_STATE_VAR)
- {
- r700FetchStateParameter(ctx,
- paramList->Parameters[i].
- StateIndexes,
- paramList->ParameterValues[i]);
- }
- }
+ _mesa_load_state_parameters(ctx, paramList);
+
}
/**
@@ -212,21 +175,32 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
_swrast_InvalidateState(ctx, new_state);
- _swsetup_InvalidateState(ctx, new_state);
- _vbo_InvalidateState(ctx, new_state);
- _tnl_InvalidateState(ctx, new_state);
- _ae_invalidate_state(ctx, new_state);
+ _swsetup_InvalidateState(ctx, new_state);
+ _vbo_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+ _ae_invalidate_state(ctx, new_state);
+
+ if (new_state & _NEW_BUFFERS) {
+ _mesa_update_framebuffer(ctx);
+ /* this updates the DrawBuffer's Width/Height if it's a FBO */
+ _mesa_update_draw_buffer_bounds(ctx);
+
+ R600_STATECHANGE(context, cb_target);
+ R600_STATECHANGE(context, db_target);
+ }
- if (new_state & (_NEW_BUFFERS | _NEW_COLOR | _NEW_PIXEL))
- {
- _mesa_update_framebuffer(ctx);
- /* this updates the DrawBuffer's Width/Height if it's a FBO */
- _mesa_update_draw_buffer_bounds(ctx);
+ if (new_state & (_NEW_LIGHT)) {
+ R600_STATECHANGE(context, su);
+ if (ctx->Light.ProvokingVertex == GL_LAST_VERTEX_CONVENTION)
+ SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+ else
+ CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, PROVOKING_VTX_LAST_bit);
+ }
- r700UpdateDrawBuffer(ctx);
- }
+ r700UpdateStateParameters(ctx, new_state);
- r700UpdateStateParameters(ctx, new_state);
+ R600_STATECHANGE(context, cl);
+ R600_STATECHANGE(context, spi);
if(GL_TRUE == r700->bEnablePerspective)
{
@@ -251,14 +225,15 @@ static void r700InvalidateState(GLcontext * ctx, GLuint new_state) //-----------
SETbit(r700->SPI_PS_IN_CONTROL_0.u32All, LINEAR_GRADIENT_ENA_bit);
}
- context->radeon.NewGLState |= new_state;
+ context->radeon.NewGLState |= new_state;
}
static void r700SetDepthState(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, db);
if (ctx->Depth.Test)
{
@@ -326,6 +301,8 @@ static void r700SetAlphaState(GLcontext * ctx)
uint32_t alpha_func = REF_ALWAYS;
GLboolean really_enabled = ctx->Color.AlphaEnabled;
+ R600_STATECHANGE(context, sx);
+
switch (ctx->Color.AlphaFunc) {
case GL_NEVER:
alpha_func = REF_NEVER;
@@ -378,6 +355,8 @@ static void r700BlendColor(GLcontext * ctx, const GLfloat cf[4]) //-------------
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, blnd_clr);
+
r700->CB_BLEND_RED.f32All = cf[0];
r700->CB_BLEND_GREEN.f32All = cf[1];
r700->CB_BLEND_BLUE.f32All = cf[2];
@@ -446,6 +425,8 @@ static void r700SetBlendState(GLcontext * ctx)
int id = 0;
uint32_t blend_reg = 0, eqn, eqnA;
+ R600_STATECHANGE(context, blnd);
+
if (RGBA_LOGICOP_ENABLED(ctx) || !ctx->Color.BlendEnabled) {
SETfield(blend_reg,
BLEND_ONE, COLOR_SRCBLEND_shift, COLOR_SRCBLEND_mask);
@@ -584,14 +565,46 @@ static void r700BlendFuncSeparate(GLcontext * ctx,
/**
* Translate LogicOp enums into hardware representation.
- * Both use a very logical bit-wise layout, but unfortunately the order
- * of bits is reversed.
*/
static GLuint translate_logicop(GLenum logicop)
{
- GLuint bits = logicop - GL_CLEAR;
- bits = ((bits & 1) << 3) | ((bits & 2) << 1) | ((bits & 4) >> 1) | ((bits & 8) >> 3);
- return bits;
+ switch (logicop) {
+ case GL_CLEAR:
+ return 0x00;
+ case GL_SET:
+ return 0xff;
+ case GL_COPY:
+ return 0xcc;
+ case GL_COPY_INVERTED:
+ return 0x33;
+ case GL_NOOP:
+ return 0xaa;
+ case GL_INVERT:
+ return 0x55;
+ case GL_AND:
+ return 0x88;
+ case GL_NAND:
+ return 0x77;
+ case GL_OR:
+ return 0xee;
+ case GL_NOR:
+ return 0x11;
+ case GL_XOR:
+ return 0x66;
+ case GL_EQUIV:
+ return 0xaa;
+ case GL_AND_REVERSE:
+ return 0x44;
+ case GL_AND_INVERTED:
+ return 0x22;
+ case GL_OR_REVERSE:
+ return 0xdd;
+ case GL_OR_INVERTED:
+ return 0xbb;
+ default:
+ fprintf(stderr, "unknown blend logic operation %x\n", logicop);
+ return 0xcc;
+ }
}
/**
@@ -600,8 +613,11 @@ static GLuint translate_logicop(GLenum logicop)
*/
static void r700SetLogicOpState(GLcontext *ctx)
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+ R600_STATECHANGE(context, blnd);
+
if (RGBA_LOGICOP_ENABLED(ctx))
SETfield(r700->CB_COLOR_CONTROL.u32All,
translate_logicop(ctx->Color.LogicOp), ROP3_shift, ROP3_mask);
@@ -621,7 +637,10 @@ static void r700LogicOpcode(GLcontext *ctx, GLenum logicop)
static void r700UpdateCulling(GLcontext * ctx)
{
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+
+ R600_STATECHANGE(context, su);
CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, FACE_bit);
CLEARbit(r700->PA_SU_SC_MODE_CNTL.u32All, CULL_FRONT_bit);
@@ -666,7 +685,11 @@ static void r700UpdateCulling(GLcontext * ctx)
static void r700UpdateLineStipple(GLcontext * ctx)
{
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
+
+ R600_STATECHANGE(context, sc);
+
if (ctx->Line.StippleFlag)
{
SETbit(r700->PA_SC_MODE_CNTL.u32All, LINE_STIPPLE_ENABLE_bit);
@@ -741,14 +764,17 @@ static void r700Enable(GLcontext * ctx, GLenum cap, GLboolean state) //---------
static void r700ColorMask(GLcontext * ctx,
GLboolean r, GLboolean g, GLboolean b, GLboolean a) //------------------
{
+ context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&R700_CONTEXT(ctx)->hw);
unsigned int mask = ((r ? 1 : 0) |
(g ? 2 : 0) |
(b ? 4 : 0) |
(a ? 8 : 0));
- if (mask != r700->CB_SHADER_MASK.u32All)
+ if (mask != r700->CB_SHADER_MASK.u32All) {
+ R600_STATECHANGE(context, cb);
SETfield(r700->CB_SHADER_MASK.u32All, mask, OUTPUT0_ENABLE_shift, OUTPUT0_ENABLE_mask);
+ }
}
/**
@@ -804,6 +830,8 @@ static void r700ShadeModel(GLcontext * ctx, GLenum mode) //--------------------
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, spi);
+
/* also need to set/clear FLAT_SHADE bit per param in SPI_PS_INPUT_CNTL_[0-31] */
switch (mode) {
case GL_FLAT:
@@ -825,6 +853,8 @@ static void r700PointSize(GLcontext * ctx, GLfloat size)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, su);
+
/* We need to clamp to user defined range here, because
* the HW clamping happens only for per vertex point size. */
size = CLAMP(size, ctx->Point.MinSize, ctx->Point.MaxSize);
@@ -833,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);
}
@@ -845,14 +875,16 @@ static void r700PointParameter(GLcontext * ctx, GLenum pname, const GLfloat * pa
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, su);
+
/* 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:
@@ -919,9 +951,6 @@ static void r700SetStencilState(GLcontext * ctx, GLboolean state)
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
GLboolean hw_stencil = GL_FALSE;
- //fixme
- //r300CatchStencilFallback(ctx);
-
if (ctx->DrawBuffer) {
struct radeon_renderbuffer *rrbStencil
= radeon_get_renderbuffer(ctx->DrawBuffer, BUFFER_STENCIL);
@@ -929,9 +958,11 @@ static void r700SetStencilState(GLcontext * ctx, GLboolean state)
}
if (hw_stencil) {
- if (state)
+ R600_STATECHANGE(context, db);
+ if (state) {
SETbit(r700->DB_DEPTH_CONTROL.u32All, STENCIL_ENABLE_bit);
- else
+ SETbit(r700->DB_DEPTH_CONTROL.u32All, BACKFACE_ENABLE_bit);
+ } else
CLEARbit(r700->DB_DEPTH_CONTROL.u32All, STENCIL_ENABLE_bit);
}
}
@@ -943,8 +974,8 @@ static void r700StencilFuncSeparate(GLcontext * ctx, GLenum face,
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
const unsigned back = ctx->Stencil._BackFace;
- //fixme
- //r300CatchStencilFallback(ctx);
+ R600_STATECHANGE(context, stencil);
+ R600_STATECHANGE(context, db);
//front
SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.Ref[0],
@@ -972,8 +1003,7 @@ static void r700StencilMaskSeparate(GLcontext * ctx, GLenum face, GLuint mask) /
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
const unsigned back = ctx->Stencil._BackFace;
- //fixme
- //r300CatchStencilFallback(ctx);
+ R600_STATECHANGE(context, stencil);
// front
SETfield(r700->DB_STENCILREFMASK.u32All, ctx->Stencil.WriteMask[0],
@@ -992,8 +1022,7 @@ static void r700StencilOpSeparate(GLcontext * ctx, GLenum face,
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
const unsigned back = ctx->Stencil._BackFace;
- //fixme
- //r300CatchStencilFallback(ctx);
+ R600_STATECHANGE(context, db);
SETfield(r700->DB_DEPTH_CONTROL.u32All, translate_stencil_op(ctx->Stencil.FailFunc[0]),
STENCILFAIL_shift, STENCILFAIL_mask);
@@ -1037,7 +1066,7 @@ static void r700UpdateWindow(GLcontext * ctx, int id) //--------------------
GLfloat sz = v[MAT_SZ] * depthScale;
GLfloat tz = v[MAT_TZ] * depthScale;
- /* TODO : Need DMA flush as well. */
+ R600_STATECHANGE(context, vpt);
r700->viewport[id].PA_CL_VPORT_XSCALE.f32All = sx;
r700->viewport[id].PA_CL_VPORT_XOFFSET.f32All = tx;
@@ -1075,10 +1104,13 @@ static void r700LineWidth(GLcontext * ctx, GLfloat widthf) //---------------
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
uint32_t lineWidth = (uint32_t)((widthf * 0.5) * (1 << 4));
+
+ R600_STATECHANGE(context, su);
+
if (lineWidth > 0xFFFF)
- lineWidth = 0xFFFF;
+ lineWidth = 0xFFFF;
SETfield(r700->PA_SU_LINE_CNTL.u32All,(uint16_t)lineWidth,
- PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
+ PA_SU_LINE_CNTL__WIDTH_shift, PA_SU_LINE_CNTL__WIDTH_mask);
}
static void r700LineStipple(GLcontext *ctx, GLint factor, GLushort pattern)
@@ -1086,6 +1118,8 @@ static void r700LineStipple(GLcontext *ctx, GLint factor, GLushort pattern)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, sc);
+
SETfield(r700->PA_SC_LINE_STIPPLE.u32All, pattern, LINE_PATTERN_shift, LINE_PATTERN_mask);
SETfield(r700->PA_SC_LINE_STIPPLE.u32All, (factor-1), REPEAT_COUNT_shift, REPEAT_COUNT_mask);
SETfield(r700->PA_SC_LINE_STIPPLE.u32All, 1, AUTO_RESET_CNTL_shift, AUTO_RESET_CNTL_mask);
@@ -1096,6 +1130,8 @@ static void r700SetPolygonOffsetState(GLcontext * ctx, GLboolean state)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, su);
+
if (state) {
SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_FRONT_ENABLE_bit);
SETbit(r700->PA_SU_SC_MODE_CNTL.u32All, POLY_OFFSET_BACK_ENABLE_bit);
@@ -1112,18 +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;
-
+ 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;
@@ -1135,6 +1178,8 @@ static void r700UpdatePolygonMode(GLcontext * ctx)
context_t *context = R700_CONTEXT(ctx);
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ R600_STATECHANGE(context, su);
+
SETfield(r700->PA_SU_SC_MODE_CNTL.u32All, X_DISABLE_POLY_MODE, POLY_MODE_shift, POLY_MODE_mask);
/* Only do something if a polygon mode is wanted, default is GL_FILL */
@@ -1210,6 +1255,8 @@ static void r700ClipPlane( GLcontext *ctx, GLenum plane, const GLfloat *eq )
p = (GLint) plane - (GLint) GL_CLIP_PLANE0;
ip = (GLint *)ctx->Transform._ClipUserPlane[p];
+ R600_STATECHANGE(context, ucp);
+
r700->ucp[p].PA_CL_UCP_0_X.u32All = ip[0];
r700->ucp[p].PA_CL_UCP_0_Y.u32All = ip[1];
r700->ucp[p].PA_CL_UCP_0_Z.u32All = ip[2];
@@ -1223,6 +1270,9 @@ static void r700SetClipPlaneState(GLcontext * ctx, GLenum cap, GLboolean state)
GLuint p;
p = cap - GL_CLIP_PLANE0;
+
+ R600_STATECHANGE(context, cl);
+
if (state) {
r700->PA_CL_CLIP_CNTL.u32All |= (UCP_ENA_0_bit << p);
r700->ucp[p].enabled = GL_TRUE;
@@ -1247,15 +1297,36 @@ void r700SetScissor(context_t *context) //---------------
if (context->radeon.state.scissor.enabled) {
x1 = context->radeon.state.scissor.rect.x1;
y1 = context->radeon.state.scissor.rect.y1;
- x2 = context->radeon.state.scissor.rect.x2 - 1;
- y2 = context->radeon.state.scissor.rect.y2 - 1;
+ x2 = context->radeon.state.scissor.rect.x2;
+ y2 = context->radeon.state.scissor.rect.y2;
} else {
- x1 = rrb->dPriv->x;
- y1 = rrb->dPriv->y;
- x2 = rrb->dPriv->x + rrb->dPriv->w;
- y2 = rrb->dPriv->y + rrb->dPriv->h;
+ if (context->radeon.radeonScreen->driScreen->dri2.enabled) {
+ x1 = 0;
+ y1 = 0;
+ x2 = rrb->base.Width;
+ y2 = rrb->base.Height;
+ } else {
+ x1 = rrb->dPriv->x;
+ y1 = rrb->dPriv->y;
+ x2 = rrb->dPriv->x + rrb->dPriv->w;
+ y2 = rrb->dPriv->y + rrb->dPriv->h;
+ }
}
+ R600_STATECHANGE(context, scissor);
+
+ /* screen */
+ SETbit(r700->PA_SC_SCREEN_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
+ SETfield(r700->PA_SC_SCREEN_SCISSOR_TL.u32All, x1,
+ PA_SC_SCREEN_SCISSOR_TL__TL_X_shift, PA_SC_SCREEN_SCISSOR_TL__TL_X_mask);
+ SETfield(r700->PA_SC_SCREEN_SCISSOR_TL.u32All, y1,
+ PA_SC_SCREEN_SCISSOR_TL__TL_Y_shift, PA_SC_SCREEN_SCISSOR_TL__TL_Y_mask);
+
+ SETfield(r700->PA_SC_SCREEN_SCISSOR_BR.u32All, x2,
+ PA_SC_SCREEN_SCISSOR_BR__BR_X_shift, PA_SC_SCREEN_SCISSOR_BR__BR_X_mask);
+ SETfield(r700->PA_SC_SCREEN_SCISSOR_BR.u32All, y2,
+ PA_SC_SCREEN_SCISSOR_BR__BR_Y_shift, PA_SC_SCREEN_SCISSOR_BR__BR_Y_mask);
+
/* window */
SETbit(r700->PA_SC_WINDOW_SCISSOR_TL.u32All, WINDOW_OFFSET_DISABLE_bit);
SETfield(r700->PA_SC_WINDOW_SCISSOR_TL.u32All, x1,
@@ -1311,120 +1382,6 @@ void r700SetScissor(context_t *context) //---------------
r700->viewport[id].enabled = GL_TRUE;
}
-void r700SetRenderTarget(context_t *context, int id)
-{
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
- struct radeon_renderbuffer *rrb;
- unsigned int nPitchInPixel;
-
- /* screen/window/view */
- SETfield(r700->CB_TARGET_MASK.u32All, 0xF, (4 * id), TARGET0_ENABLE_mask);
-
- rrb = radeon_get_colorbuffer(&context->radeon);
- if (!rrb || !rrb->bo) {
- fprintf(stderr, "no rrb\n");
- return;
- }
-
- /* color buffer */
- r700->render_target[id].CB_COLOR0_BASE.u32All = context->radeon.state.color.draw_offset;
-
- nPitchInPixel = rrb->pitch/rrb->cpp;
- SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, (nPitchInPixel/8)-1,
- PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask);
- SETfield(r700->render_target[id].CB_COLOR0_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1,
- SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask);
- r700->render_target[id].CB_COLOR0_BASE.u32All = 0;
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ENDIAN_NONE, ENDIAN_shift, ENDIAN_mask);
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, ARRAY_LINEAR_GENERAL,
- CB_COLOR0_INFO__ARRAY_MODE_shift, CB_COLOR0_INFO__ARRAY_MODE_mask);
- if(4 == rrb->cpp)
- {
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, COLOR_8_8_8_8,
- CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, SWAP_ALT, COMP_SWAP_shift, COMP_SWAP_mask);
- }
- else
- {
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, COLOR_5_6_5,
- CB_COLOR0_INFO__FORMAT_shift, CB_COLOR0_INFO__FORMAT_mask);
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, SWAP_ALT_REV,
- COMP_SWAP_shift, COMP_SWAP_mask);
- }
- SETbit(r700->render_target[id].CB_COLOR0_INFO.u32All, SOURCE_FORMAT_bit);
- SETbit(r700->render_target[id].CB_COLOR0_INFO.u32All, BLEND_CLAMP_bit);
- SETfield(r700->render_target[id].CB_COLOR0_INFO.u32All, NUMBER_UNORM, NUMBER_TYPE_shift, NUMBER_TYPE_mask);
-
- r700->render_target[id].enabled = GL_TRUE;
-}
-
-void r700SetDepthTarget(context_t *context)
-{
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
-
- struct radeon_renderbuffer *rrb;
- unsigned int nPitchInPixel;
-
- /* depth buf */
- r700->DB_DEPTH_SIZE.u32All = 0;
- r700->DB_DEPTH_BASE.u32All = 0;
- r700->DB_DEPTH_INFO.u32All = 0;
-
- r700->DB_DEPTH_CLEAR.u32All = 0x3F800000;
- r700->DB_DEPTH_VIEW.u32All = 0;
- r700->DB_RENDER_CONTROL.u32All = 0;
- SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
- SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
- r700->DB_RENDER_OVERRIDE.u32All = 0;
- if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
- SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
- SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
-
- r700->DB_ALPHA_TO_MASK.u32All = 0;
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET1_shift, ALPHA_TO_MASK_OFFSET1_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET2_shift, ALPHA_TO_MASK_OFFSET2_mask);
- SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET3_shift, ALPHA_TO_MASK_OFFSET3_mask);
-
- rrb = radeon_get_depthbuffer(&context->radeon);
- if (!rrb)
- return;
-
- nPitchInPixel = rrb->pitch/rrb->cpp;
-
- SETfield(r700->DB_DEPTH_SIZE.u32All, (nPitchInPixel/8)-1,
- PITCH_TILE_MAX_shift, PITCH_TILE_MAX_mask);
- SETfield(r700->DB_DEPTH_SIZE.u32All, ( (nPitchInPixel * context->radeon.radeonScreen->driScreen->fbHeight)/64 )-1,
- SLICE_TILE_MAX_shift, SLICE_TILE_MAX_mask); /* size in pixel / 64 - 1 */
-
- if(4 == rrb->cpp)
- {
- switch (GL_CONTEXT(context)->Visual.depthBits)
- {
- case 16:
- case 24:
- SETfield(r700->DB_DEPTH_INFO.u32All, DEPTH_8_24,
- DB_DEPTH_INFO__FORMAT_shift, DB_DEPTH_INFO__FORMAT_mask);
- break;
- default:
- fprintf(stderr, "Error: Unsupported depth %d... exiting\n",
- GL_CONTEXT(context)->Visual.depthBits);
- _mesa_exit(-1);
- }
- }
- else
- {
- 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,
- 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. */
-}
-
static void r700InitSQConfig(GLcontext * ctx)
{
context_t *context = R700_CONTEXT(ctx);
@@ -1447,6 +1404,8 @@ static void r700InitSQConfig(GLcontext * ctx)
int num_gs_stack_entries;
int num_es_stack_entries;
+ R600_STATECHANGE(context, sq);
+
// SQ
ps_prio = 0;
vs_prio = 1;
@@ -1487,6 +1446,7 @@ static void r700InitSQConfig(GLcontext * ctx)
case CHIP_FAMILY_RV610:
case CHIP_FAMILY_RV620:
case CHIP_FAMILY_RS780:
+ case CHIP_FAMILY_RS880:
default:
num_ps_gprs = 84;
num_vs_gprs = 36;
@@ -1569,6 +1529,7 @@ static void r700InitSQConfig(GLcontext * ctx)
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))
CLEARbit(r700->sq_config.SQ_CONFIG.u32All, VC_ENABLE_bit);
else
@@ -1622,8 +1583,10 @@ static void r700InitSQConfig(GLcontext * ctx)
void r700InitState(GLcontext * ctx) //-------------------
{
context_t *context = R700_CONTEXT(ctx);
-
R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ int id = 0;
+
+ radeon_firevertices(&context->radeon);
r700->TA_CNTL_AUX.u32All = 0;
SETfield(r700->TA_CNTL_AUX.u32All, 28, TD_FIFO_CREDIT_shift, TD_FIFO_CREDIT_mask);
@@ -1653,31 +1616,16 @@ void r700InitState(GLcontext * ctx) //-------------------
r700->VGT_MIN_VTX_INDX.u32All = 0;
r700->VGT_INDX_OFFSET.u32All = 0;
- /* Specify the number of instances */
- r700->VGT_DMA_NUM_INSTANCES.u32All = 1;
-
/* default shader connections. */
r700->SPI_VS_OUT_ID_0.u32All = 0x03020100;
r700->SPI_VS_OUT_ID_1.u32All = 0x07060504;
-
- r700->SPI_PS_INPUT_CNTL_0.u32All = 0x00000800;
- r700->SPI_PS_INPUT_CNTL_1.u32All = 0x00000801;
- r700->SPI_PS_INPUT_CNTL_2.u32All = 0x00000802;
+ r700->SPI_VS_OUT_ID_2.u32All = 0x0b0a0908;
+ r700->SPI_VS_OUT_ID_3.u32All = 0x0f0e0d0c;
r700->SPI_THREAD_GROUPING.u32All = 0;
if (context->radeon.radeonScreen->chip_family >= CHIP_FAMILY_RV770)
SETfield(r700->SPI_THREAD_GROUPING.u32All, 1, PS_GROUPING_shift, PS_GROUPING_mask);
- /* screen */
- r700->PA_SC_SCREEN_SCISSOR_TL.u32All = 0x0;
-
- SETfield(r700->PA_SC_SCREEN_SCISSOR_BR.u32All,
- ((RADEONDRIPtr)(context->radeon.radeonScreen->driScreen->pDevPriv))->width,
- PA_SC_SCREEN_SCISSOR_BR__BR_X_shift, PA_SC_SCREEN_SCISSOR_BR__BR_X_mask);
- SETfield(r700->PA_SC_SCREEN_SCISSOR_BR.u32All,
- ((RADEONDRIPtr)(context->radeon.radeonScreen->driScreen->pDevPriv))->height,
- PA_SC_SCREEN_SCISSOR_BR__BR_Y_shift, PA_SC_SCREEN_SCISSOR_BR__BR_Y_mask);
-
/* 4 clip rectangles */ /* TODO : set these clip rects according to context->currentDraw->numClipRects */
r700->PA_SC_CLIPRECT_RULE.u32All = 0;
SETfield(r700->PA_SC_CLIPRECT_RULE.u32All, CLIP_RULE_mask, CLIP_RULE_shift, CLIP_RULE_mask);
@@ -1747,6 +1695,24 @@ void r700InitState(GLcontext * ctx) //-------------------
r700DepthFunc(ctx, ctx->Depth.Func);
SETbit(r700->DB_SHADER_CONTROL.u32All, DUAL_EXPORT_ENABLE_bit);
+ r700->DB_DEPTH_CLEAR.u32All = 0x3F800000;
+
+ r700->DB_RENDER_CONTROL.u32All = 0;
+ SETbit(r700->DB_RENDER_CONTROL.u32All, STENCIL_COMPRESS_DISABLE_bit);
+ SETbit(r700->DB_RENDER_CONTROL.u32All, DEPTH_COMPRESS_DISABLE_bit);
+ r700->DB_RENDER_OVERRIDE.u32All = 0;
+ if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
+ SETbit(r700->DB_RENDER_OVERRIDE.u32All, FORCE_SHADER_Z_ORDER_bit);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIZ_ENABLE_shift, FORCE_HIZ_ENABLE_mask);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE0_shift, FORCE_HIS_ENABLE0_mask);
+ SETfield(r700->DB_RENDER_OVERRIDE.u32All, FORCE_DISABLE, FORCE_HIS_ENABLE1_shift, FORCE_HIS_ENABLE1_mask);
+
+ r700->DB_ALPHA_TO_MASK.u32All = 0;
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET0_shift, ALPHA_TO_MASK_OFFSET0_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET1_shift, ALPHA_TO_MASK_OFFSET1_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET2_shift, ALPHA_TO_MASK_OFFSET2_mask);
+ SETfield(r700->DB_ALPHA_TO_MASK.u32All, 2, ALPHA_TO_MASK_OFFSET3_shift, ALPHA_TO_MASK_OFFSET3_mask);
+
/* stencil */
r700Enable(ctx, GL_STENCIL_TEST, ctx->Stencil._Enabled);
r700StencilMaskSeparate(ctx, 0, ctx->Stencil.WriteMask[0]);
@@ -1812,6 +1778,11 @@ void r700InitState(GLcontext * ctx) //-------------------
/* Set up color compare mask */
r700->CB_CLRCMP_MSK.u32All = 0xFFFFFFFF;
+ /* screen/window/view */
+ SETfield(r700->CB_TARGET_MASK.u32All, 0xF, (4 * id), TARGET0_ENABLE_mask);
+
+ context->radeon.hw.all_dirty = GL_TRUE;
+
}
void r700InitStateFuncs(struct dd_function_table *functions) //-----------------
diff --git a/src/mesa/drivers/dri/r600/r700_state.h b/src/mesa/drivers/dri/r600/r700_state.h
index 23246367db..209189d8d7 100644
--- a/src/mesa/drivers/dri/r600/r700_state.h
+++ b/src/mesa/drivers/dri/r600/r700_state.h
@@ -35,17 +35,13 @@
extern void r700UpdateStateParameters(GLcontext * ctx, GLuint new_state);
extern void r700UpdateShaders (GLcontext * ctx);
+extern void r700UpdateShaders2(GLcontext * ctx);
extern void r700UpdateViewportOffset(GLcontext * ctx);
-extern void r700UpdateDrawBuffer (GLcontext * ctx);
extern void r700InitState (GLcontext * ctx);
extern void r700InitStateFuncs (struct dd_function_table *functions);
-extern void r700SetRenderTarget(context_t *context, int id);
-extern void r700SetDefaultStates(context_t * context);
-
-void r700SetScissor(context_t *context);
-void r700SetDepthTarget(context_t *context);
+extern void r700SetScissor(context_t *context);
#endif /* _R600_SCREEN_H */
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c
index 172e6ee501..e7a209be9d 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.c
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.c
@@ -35,11 +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"
@@ -52,7 +55,7 @@ unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm,
unsigned int unBit;
unsigned int unTotal = unStart;
- //!!!!!!! THE ORDER MATCH FS INPUT
+ //!!!!!!! THE ORDER MATCH FS INPUT
unBit = 1 << VERT_RESULT_HPOS;
if(mesa_vp->Base.OutputsWritten & unBit)
@@ -73,17 +76,17 @@ unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm,
}
//TODO : dealing back face.
- //unBit = 1 << VERT_RESULT_BFC0;
- //if(mesa_vp->Base.OutputsWritten & unBit)
- //{
- // pAsm->ucVP_OutputMap[VERT_RESULT_COL0] = unTotal++;
- //}
-
- //unBit = 1 << VERT_RESULT_BFC1;
- //if(mesa_vp->Base.OutputsWritten & unBit)
- //{
- // pAsm->ucVP_OutputMap[VERT_RESULT_COL1] = unTotal++;
- //}
+ unBit = 1 << VERT_RESULT_BFC0;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_BFC0] = unTotal++;
+ }
+
+ unBit = 1 << VERT_RESULT_BFC1;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_BFC1] = unTotal++;
+ }
//TODO : dealing fog.
unBit = 1 << VERT_RESULT_FOGC;
@@ -93,11 +96,11 @@ unsigned int Map_Vertex_Output(r700_AssemblerBase *pAsm,
}
//TODO : dealing point size.
- //unBit = 1 << VERT_RESULT_PSIZ;
- //if(mesa_vp->Base.OutputsWritten & unBit)
- //{
- // pAsm->ucVP_OutputMap[VERT_RESULT_PSIZ] = unTotal++;
- //}
+ unBit = 1 << VERT_RESULT_PSIZ;
+ if(mesa_vp->Base.OutputsWritten & unBit)
+ {
+ pAsm->ucVP_OutputMap[VERT_RESULT_PSIZ] = unTotal++;
+ }
for(i=0; i<8; i++)
{
@@ -156,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;
@@ -172,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) )
- {
- r700_error(ERROR_ASM_VTX_CLAUSE, "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);
@@ -257,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
@@ -288,79 +363,229 @@ 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;
- if (context->radeon.radeonScreen->chip_family < CHIP_FAMILY_RV770)
- {
- vpc->r700AsmCode.bR6xx = 1;
- }
-
+ struct r700_vertex_program_cont *vpc;
+ struct r700_vertex_program *vp;
TNLcontext *tnl = TNL_CONTEXT(ctx);
- struct vertex_buffer *vb = &tnl->vb;
-
+ struct vertex_buffer *vb = &tnl->vb;
unsigned int unBit;
unsigned int i;
+ GLboolean match;
+ GLbitfield InputsRead;
+
+ vpc = (struct r700_vertex_program_cont *)ctx->VertexProgram._Current;
+
+ InputsRead = vpc->mesa_program.Base.InputsRead;
+ if (vpc->mesa_program.IsPositionInvariant)
+ {
+ 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;
+ }
+ }
- if(GL_FALSE == vpc->translated)
+ vp = r700TranslateVertexShader(ctx, &(vpc->mesa_program), nVersion);
+ if(!vp)
{
- r700TranslateVertexShader(vpc,
- &(vpc->mesa_program) );
+ radeon_error("Failed to translate vertex shader. \n");
+ return;
}
+ vp->next = vpc->progs;
+ vpc->progs = vp;
+ context->selected_vp = vp;
+ return;
}
-void * r700GetActiveVpShaderBo(GLcontext * ctx)
+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)
{
- struct r700_vertex_program *vp
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+ 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;
- return vp->shaderbo;
+ 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;
+ }
+ }
+
+ 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++;
}
-GLboolean r700SetupVertexProgram(GLcontext * ctx)
+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;
- BATCH_LOCALS(&context->radeon);
+ 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;
- R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ while(unBit)
+ {
+ if(unBit & 1)
+ {
+ r700TranslateAttrib(ctx, unLoc, count, arrays[unLoc]);
+ }
+
+ unBit >>= 1;
+ ++unLoc;
+ }
+}
+
+void * r700GetActiveVpShaderBo(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ struct r700_vertex_program *vp = context->selected_vp;;
+
+ if (vp)
+ return vp->shaderbo;
+ else
+ return NULL;
+}
- struct r700_vertex_program *vp
- = (struct r700_vertex_program *)ctx->VertexProgram._Current;
+GLboolean r700SetupVertexProgram(GLcontext * ctx)
+{
+ context_t *context = R700_CONTEXT(ctx);
+ R700_CHIP_CONTEXT *r700 = (R700_CHIP_CONTEXT*)(&context->hw);
+ struct r700_vertex_program *vp = context->selected_vp;
struct gl_program_parameter_list *paramList;
unsigned int unNumParamData;
-
unsigned int ui;
if(GL_FALSE == vp->loaded)
{
- if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
+ if(vp->r700Shader.bNeedsAssembly == GL_TRUE)
{
Assemble( &(vp->r700Shader) );
}
/* Load vp to gpu */
- r600EmitShader(ctx,
- &(vp->shaderbo),
+ r600EmitShader(ctx,
+ &(vp->shaderbo),
(GLvoid *)(vp->r700Shader.pProgram),
- vp->r700Shader.uShaderBinaryDWORDSize,
- "VS");
+ vp->r700Shader.uShaderBinaryDWORDSize,
+ "VS");
vp->loaded = GL_TRUE;
}
@@ -372,8 +597,14 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
(context->chipobj.MemUse)(context, vp->shadercode.buf->id);
*/
- r700->vs.SQ_PGM_START_VS.u32All = 0; /* set from buffer object. */
-
+ R600_STATECHANGE(context, vs);
+ R600_STATECHANGE(context, fs); /* hack */
+
+ r700->vs.SQ_PGM_RESOURCES_VS.u32All = 0;
+ SETbit(r700->vs.SQ_PGM_RESOURCES_VS.u32All, PGM_RESOURCES__PRIME_CACHE_ON_DRAW_bit);
+
+ r700->vs.SQ_PGM_START_VS.u32All = 0; /* set from buffer object. */
+
SETfield(r700->vs.SQ_PGM_RESOURCES_VS.u32All, vp->r700Shader.nRegs + 1,
NUM_GPRS_shift, NUM_GPRS_mask);
@@ -383,9 +614,12 @@ GLboolean r700SetupVertexProgram(GLcontext * ctx)
STACK_SIZE_shift, STACK_SIZE_mask);
}
- SETfield(r700->SPI_VS_OUT_CONFIG.u32All, vp->r700Shader.nParamExports ? (vp->r700Shader.nParamExports - 1) : 0,
+ R600_STATECHANGE(context, spi);
+
+ SETfield(r700->SPI_VS_OUT_CONFIG.u32All,
+ vp->r700Shader.nParamExports ? (vp->r700Shader.nParamExports - 1) : 0,
VS_EXPORT_COUNT_shift, VS_EXPORT_COUNT_mask);
- SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, vp->r700Shader.nParamExports,
+ SETfield(r700->SPI_PS_IN_CONTROL_0.u32All, vp->r700Shader.nParamExports,
NUM_INTERP_shift, NUM_INTERP_mask);
/*
@@ -394,37 +628,28 @@ 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);
- if(NULL != paramList)
- {
- _mesa_load_state_parameters(ctx, paramList);
+ if (paramList->NumParameters > R700_MAX_DX9_CONSTS)
+ return GL_FALSE;
- unNumParamData = paramList->NumParameters * 4;
+ R600_STATECHANGE(context, vs_consts);
- BEGIN_BATCH_NO_AUTOSTATE(unNumParamData + 2);
-
- R600_OUT_BATCH(CP_PACKET3(R600_IT_SET_ALU_CONST, unNumParamData));
- /* assembler map const from very beginning. */
- R600_OUT_BATCH(SQ_ALU_CONSTANT_VS_OFFSET * 4);
+ r700->vs.num_consts = paramList->NumParameters;
- unNumParamData = paramList->NumParameters;
+ unNumParamData = paramList->NumParameters;
- for(ui=0; ui<unNumParamData; ui++)
- {
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][0])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][1])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][2])));
- R600_OUT_BATCH(*((unsigned int*)&(paramList->ParameterValues[ui][3])));
- }
- END_BATCH();
- COMMIT_BATCH();
- }
+ for(ui=0; ui<unNumParamData; ui++) {
+ r700->vs.consts[ui][0].f32All = paramList->ParameterValues[ui][0];
+ r700->vs.consts[ui][1].f32All = paramList->ParameterValues[ui][1];
+ r700->vs.consts[ui][2].f32All = paramList->ParameterValues[ui][2];
+ r700->vs.consts[ui][3].f32All = paramList->ParameterValues[ui][3];
+ }
+ } else
+ r700->vs.num_consts = 0;
return GL_TRUE;
}
-
-
-
-
diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.h b/src/mesa/drivers/dri/r600/r700_vertprog.h
index 6a9726a3d0..f9a3e395ee 100644
--- a/src/mesa/drivers/dri/r600/r700_vertprog.h
+++ b/src/mesa/drivers/dri/r600/r700_vertprog.h
@@ -43,46 +43,61 @@ 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;
+ struct r700_vertex_program *next;
r700_AssemblerBase r700AsmCode;
R700_Shader r700Shader;
- GLboolean translated;
+ GLboolean translated;
GLboolean loaded;
+ GLint uiVersion;
- /* ... */
-
void * shaderbo;
- ArrayDesc aos_desc[VERT_ATTRIB_MAX];
+ 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,
- unsigned int unStart);
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart);
unsigned int Map_Vertex_Input(r700_AssemblerBase *pAsm,
- struct gl_vertex_program *mesa_vp,
- unsigned int unStart);
+ struct gl_vertex_program *mesa_vp,
+ unsigned int unStart);
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,
- struct gl_vertex_program *mesa_vp);
+ struct r700_vertex_program *vp,
+ struct gl_vertex_program *mesa_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);
+ struct gl_vertex_program *mesa_vp);
-/* Interface */
-extern 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);
-extern void r700SelectVertexShader(GLcontext *ctx);
+/* Interface */
+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 0000000000..f6a5f66470
--- /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 0000000000..2f134fd17b
--- /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/r600/radeon_debug.c b/src/mesa/drivers/dri/r600/radeon_debug.c
new file mode 120000
index 0000000000..c98c2e074c
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_debug.c
@@ -0,0 +1 @@
+../radeon/radeon_debug.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_debug.h b/src/mesa/drivers/dri/r600/radeon_debug.h
new file mode 120000
index 0000000000..bd8aa28e89
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_debug.h
@@ -0,0 +1 @@
+../radeon/radeon_debug.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_queryobj.c b/src/mesa/drivers/dri/r600/radeon_queryobj.c
new file mode 120000
index 0000000000..1d6ebc1c48
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_queryobj.c
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.c \ No newline at end of file
diff --git a/src/mesa/drivers/dri/r600/radeon_queryobj.h b/src/mesa/drivers/dri/r600/radeon_queryobj.h
new file mode 120000
index 0000000000..8f6f842b0a
--- /dev/null
+++ b/src/mesa/drivers/dri/r600/radeon_queryobj.h
@@ -0,0 +1 @@
+../radeon/radeon_queryobj.h \ No newline at end of file
diff --git a/src/mesa/drivers/dri/radeon/Makefile b/src/mesa/drivers/dri/radeon/Makefile
index b59ad68f44..b1efc72872 100644
--- a/src/mesa/drivers/dri/radeon/Makefile
+++ b/src/mesa/drivers/dri/radeon/Makefile
@@ -15,16 +15,18 @@ CS_SOURCES = radeon_cs_space_drm.c
endif
RADEON_COMMON_SOURCES = \
- radeon_texture.c \
+ radeon_bo_legacy.c \
radeon_common_context.c \
radeon_common.c \
+ radeon_cs_legacy.c \
radeon_dma.c \
+ radeon_debug.c \
+ radeon_fbo.c \
radeon_lock.c \
- radeon_bo_legacy.c \
- radeon_cs_legacy.c \
radeon_mipmap_tree.c \
+ radeon_queryobj.c \
radeon_span.c \
- radeon_fbo.c
+ radeon_texture.c
DRIVER_SOURCES = \
radeon_context.c \
@@ -45,7 +47,7 @@ C_SOURCES = \
$(DRIVER_SOURCES) \
$(CS_SOURCES)
-DRIVER_DEFINES = -DRADEON_COMMON=0
+DRIVER_DEFINES = -DRADEON_R100 -Wall
DRI_LIB_DEPS += $(RADEON_LDFLAGS)
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
index 8eeaea1cb2..7141371633 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_drm.h
@@ -34,10 +34,6 @@
#include <stdint.h>
//#include "radeon_track.h"
-#ifndef RADEON_DEBUG_BO
-#define RADEON_DEBUG_BO 0
-#endif
-
/* bo object */
#define RADEON_BO_FLAGS_MACRO_TILE 1
#define RADEON_BO_FLAGS_MICRO_TILE 2
@@ -61,28 +57,23 @@ struct radeon_bo {
/* bo functions */
struct radeon_bo_funcs {
-#ifdef RADEON_DEBUG_BO
- struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
- uint32_t handle,
- uint32_t size,
- uint32_t alignment,
- uint32_t domains,
- uint32_t flags,
- char * szBufUsage);
-#else
struct radeon_bo *(*bo_open)(struct radeon_bo_manager *bom,
uint32_t handle,
uint32_t size,
uint32_t alignment,
uint32_t domains,
uint32_t flags);
-#endif /* RADEON_DEBUG_BO */
void (*bo_ref)(struct radeon_bo *bo);
struct radeon_bo *(*bo_unref)(struct radeon_bo *bo);
int (*bo_map)(struct radeon_bo *bo, int write);
int (*bo_unmap)(struct radeon_bo *bo);
int (*bo_wait)(struct radeon_bo *bo);
int (*bo_is_static)(struct radeon_bo *bo);
+ int (*bo_set_tiling)(struct radeon_bo *bo, uint32_t tiling_flags,
+ uint32_t pitch);
+ int (*bo_get_tiling)(struct radeon_bo *bo, uint32_t *tiling_flags,
+ uint32_t *pitch);
+ int (*bo_is_busy)(struct radeon_bo *bo, uint32_t *domain);
};
struct radeon_bo_manager {
@@ -110,20 +101,13 @@ static inline struct radeon_bo *_radeon_bo_open(struct radeon_bo_manager *bom,
uint32_t alignment,
uint32_t domains,
uint32_t flags,
-#ifdef RADEON_DEBUG_BO
- char * szBufUsage,
-#endif /* RADEON_DEBUG_BO */
const char *file,
const char *func,
int line)
{
struct radeon_bo *bo;
-#ifdef RADEON_DEBUG_BO
- bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags, szBufUsage);
-#else
bo = bom->funcs->bo_open(bom, handle, size, alignment, domains, flags);
-#endif /* RADEON_DEBUG_BO */
#ifdef RADEON_BO_TRACK
if (bo) {
@@ -187,6 +171,27 @@ static inline int _radeon_bo_wait(struct radeon_bo *bo,
return bo->bom->funcs->bo_wait(bo);
}
+static inline int _radeon_bo_is_busy(struct radeon_bo *bo,
+ uint32_t *domain,
+ const char *file,
+ const char *func,
+ int line)
+{
+ return bo->bom->funcs->bo_is_busy(bo, domain);
+}
+
+static inline int radeon_bo_set_tiling(struct radeon_bo *bo,
+ uint32_t tiling_flags, uint32_t pitch)
+{
+ return bo->bom->funcs->bo_set_tiling(bo, tiling_flags, pitch);
+}
+
+static inline int radeon_bo_get_tiling(struct radeon_bo *bo,
+ uint32_t *tiling_flags, uint32_t *pitch)
+{
+ return bo->bom->funcs->bo_get_tiling(bo, tiling_flags, pitch);
+}
+
static inline int radeon_bo_is_static(struct radeon_bo *bo)
{
if (bo->bom->funcs->bo_is_static)
@@ -194,13 +199,8 @@ static inline int radeon_bo_is_static(struct radeon_bo *bo)
return 0;
}
-#ifdef RADEON_DEBUG_BO
-#define radeon_bo_open(bom, h, s, a, d, f, u)\
- _radeon_bo_open(bom, h, s, a, d, f, u, __FILE__, __FUNCTION__, __LINE__)
-#else
#define radeon_bo_open(bom, h, s, a, d, f)\
_radeon_bo_open(bom, h, s, a, d, f, __FILE__, __FUNCTION__, __LINE__)
-#endif /* RADEON_DEBUG_BO */
#define radeon_bo_ref(bo)\
_radeon_bo_ref(bo, __FILE__, __FUNCTION__, __LINE__)
#define radeon_bo_unref(bo)\
@@ -213,5 +213,7 @@ static inline int radeon_bo_is_static(struct radeon_bo *bo)
_radeon_bo_debug(bo, opcode, __FILE__, __FUNCTION__, __LINE__)
#define radeon_bo_wait(bo) \
_radeon_bo_wait(bo, __FILE__, __func__, __LINE__)
+#define radeon_bo_is_busy(bo, domain) \
+ _radeon_bo_is_busy(bo, domain, __FILE__, __func__, __LINE__)
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
index 992eb4611b..3e7547d2f9 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.c
@@ -69,9 +69,6 @@ struct bo_legacy {
void *ptr;
struct bo_legacy *next, *prev;
struct bo_legacy *pnext, *pprev;
-#ifdef RADEON_DEBUG_BO
- char szBufUsage[16];
-#endif /* RADEON_DEBUG_BO */
};
struct bo_manager_legacy {
@@ -238,8 +235,9 @@ static int legacy_wait_pending(struct radeon_bo *bo)
return 0;
}
-static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
+void legacy_track_pending(struct radeon_bo_manager *bom, int debug)
{
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy*) bom;
struct bo_legacy *bo_legacy;
struct bo_legacy *next;
@@ -247,8 +245,8 @@ static void legacy_track_pending(struct bo_manager_legacy *boml, int debug)
bo_legacy = boml->pending_bos.pnext;
while (bo_legacy) {
if (debug)
- fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
- boml->current_age, bo_legacy->pending);
+ fprintf(stderr,"pending %p %d %d %d\n", bo_legacy, bo_legacy->base.size,
+ boml->current_age, bo_legacy->pending);
next = bo_legacy->pnext;
if (legacy_is_pending(&(bo_legacy->base))) {
}
@@ -289,12 +287,7 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
uint32_t size,
uint32_t alignment,
uint32_t domains,
-#ifdef RADEON_DEBUG_BO
- uint32_t flags,
- char * szBufUsage)
-#else
uint32_t flags)
-#endif /* RADEON_DEBUG_BO */
{
struct bo_legacy *bo_legacy;
static int pgsize;
@@ -327,10 +320,6 @@ static struct bo_legacy *bo_allocate(struct bo_manager_legacy *boml,
bo_legacy->next->prev = bo_legacy;
}
-#ifdef RADEON_DEBUG_BO
- sprintf(bo_legacy->szBufUsage, "%s", szBufUsage);
-#endif /* RADEON_DEBUG_BO */
-
return bo_legacy;
}
@@ -429,12 +418,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
uint32_t size,
uint32_t alignment,
uint32_t domains,
-#ifdef RADEON_DEBUG_BO
- uint32_t flags,
- char * szBufUsage)
-#else
uint32_t flags)
-#endif /* RADEON_DEBUG_BO */
{
struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
struct bo_legacy *bo_legacy;
@@ -451,11 +435,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
}
return NULL;
}
-#ifdef RADEON_DEBUG_BO
- bo_legacy = bo_allocate(boml, size, alignment, domains, flags, szBufUsage);
-#else
bo_legacy = bo_allocate(boml, size, alignment, domains, flags);
-#endif /* RADEON_DEBUG_BO */
bo_legacy->static_bo = 0;
r = legacy_new_handle(boml, &bo_legacy->base.handle);
if (r) {
@@ -465,7 +445,7 @@ static struct radeon_bo *bo_open(struct radeon_bo_manager *bom,
if (bo_legacy->base.domains & RADEON_GEM_DOMAIN_GTT)
{
retry:
- legacy_track_pending(boml, 0);
+ legacy_track_pending(&boml->base, 0);
/* dma buffers */
r = bo_dma_alloc(&(bo_legacy->base));
@@ -562,6 +542,18 @@ static int bo_unmap(struct radeon_bo *bo)
return 0;
}
+static int bo_is_busy(struct radeon_bo *bo, uint32_t *domain)
+{
+ *domain = 0;
+ if (bo->domains & RADEON_GEM_DOMAIN_GTT)
+ *domain = RADEON_GEM_DOMAIN_GTT;
+ else
+ *domain = RADEON_GEM_DOMAIN_CPU;
+ if (legacy_is_pending(bo))
+ return -EBUSY;
+ else
+ return 0;
+}
static int bo_is_static(struct radeon_bo *bo)
{
@@ -577,6 +569,9 @@ static struct radeon_bo_funcs bo_legacy_funcs = {
bo_unmap,
NULL,
bo_is_static,
+ NULL,
+ NULL,
+ bo_is_busy
};
static int bo_vram_validate(struct radeon_bo *bo,
@@ -599,7 +594,7 @@ static int bo_vram_validate(struct radeon_bo *bo,
if (r) {
pending_retry = 0;
while(boml->cpendings && pending_retry++ < 10000) {
- legacy_track_pending(boml, 0);
+ legacy_track_pending(&boml->base, 0);
retry_count++;
if (retry_count > 2) {
free(bo_legacy->tobj);
@@ -622,12 +617,34 @@ static int bo_vram_validate(struct radeon_bo *bo,
if (bo_legacy->dirty || bo_legacy->tobj->base.dirty_images[0]) {
if (IS_R600_CLASS(boml->screen)) {
- char *src = bo_legacy->ptr;
- char *dst = (char *) boml->screen->driScreen->pFB +
- (bo_legacy->offset - boml->fb_location);
+ drm_radeon_texture_t tex;
+ drm_radeon_tex_image_t tmp;
+ int ret;
+
+ tex.offset = bo_legacy->offset;
+ tex.image = &tmp;
+ assert(!(tex.offset & 1023));
- /* FIXME: alignment, pitch, etc. */
- memcpy(dst, src, bo->size);
+ tmp.x = 0;
+ tmp.y = 0;
+ tmp.width = bo->size;
+ tmp.height = 1;
+ tmp.data = bo_legacy->ptr;
+ tex.format = RADEON_TXFORMAT_ARGB8888;
+ tex.width = tmp.width;
+ tex.height = tmp.height;
+ tex.pitch = bo->size;
+ do {
+ ret = drmCommandWriteRead(bo->bom->fd,
+ DRM_RADEON_TEXTURE,
+ &tex,
+ sizeof(drm_radeon_texture_t));
+ if (ret) {
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
+ usleep(1);
+ }
+ } while (ret == -EAGAIN);
} else {
/* Copy to VRAM using a blit.
* All memory is 4K aligned. We're using 1024 pixels wide blits.
@@ -660,7 +677,7 @@ static int bo_vram_validate(struct radeon_bo *bo,
&tex,
sizeof(drm_radeon_texture_t));
if (ret) {
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "DRM_RADEON_TEXTURE: again!\n");
usleep(1);
}
@@ -689,14 +706,8 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
int retries = 0;
if (bo_legacy->map_count) {
-#ifdef RADEON_DEBUG_BO
- fprintf(stderr, "bo(%p, %d, %s) is mapped (%d) can't valide it.\n",
- bo, bo->size, bo_legacy->szBufUsage, bo_legacy->map_count);
-#else
fprintf(stderr, "bo(%p, %d) is mapped (%d) can't valide it.\n",
bo, bo->size, bo_legacy->map_count);
-#endif /* RADEON_DEBUG_BO */
-
return -EINVAL;
}
if (bo_legacy->static_bo || bo_legacy->validated) {
@@ -709,7 +720,7 @@ int radeon_bo_legacy_validate(struct radeon_bo *bo,
r = bo_vram_validate(bo, soffset, eoffset);
if (r) {
- legacy_track_pending(boml, 0);
+ legacy_track_pending(&boml->base, 0);
legacy_kick_all_buffers(boml);
retries++;
if (retries == 2) {
@@ -768,21 +779,13 @@ void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom)
}
static struct bo_legacy *radeon_legacy_bo_alloc_static(struct bo_manager_legacy *bom,
- int size,
-#ifdef RADEON_DEBUG_BO
- uint32_t offset,
- char * szBufUsage)
-#else
- uint32_t offset)
-#endif /* RADEON_DEBUG_BO */
+ int size,
+ uint32_t offset)
{
struct bo_legacy *bo;
-#ifdef RADEON_DEBUG_BO
- bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0, szBufUsage);
-#else
bo = bo_allocate(bom, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
-#endif /* RADEON_DEBUG_BO */
+
if (bo == NULL)
return NULL;
bo->static_bo = 1;
@@ -843,11 +846,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
size = 4096*4096*4;
/* allocate front */
-#ifdef RADEON_DEBUG_BO
- bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset, "FRONT BUF");
-#else
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->frontOffset);
-#endif /* RADEON_DEBUG_BO */
+
if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
@@ -857,11 +857,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
}
/* allocate back */
-#ifdef RADEON_DEBUG_BO
- bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset, "BACK BUF");
-#else
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->backOffset);
-#endif /* RADEON_DEBUG_BO */
+
if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
@@ -871,11 +868,8 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
}
/* allocate depth */
-#ifdef RADEON_DEBUG_BO
- bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset, "Z BUF");
-#else
bo = radeon_legacy_bo_alloc_static(bom, size, bom->screen->depthOffset);
-#endif /* RADEON_DEBUG_BO */
+
if (!bo) {
radeon_bo_manager_legacy_dtor((struct radeon_bo_manager*)bom);
return NULL;
@@ -904,3 +898,29 @@ unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo)
return bo->size;
}
+/*
+ * Fake up a bo for things like texture image_override.
+ * bo->offset already includes fb_location
+ */
+struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
+ int size,
+ uint32_t offset)
+{
+ struct bo_manager_legacy *boml = (struct bo_manager_legacy *)bom;
+ struct bo_legacy *bo;
+
+ bo = bo_allocate(boml, size, 0, RADEON_GEM_DOMAIN_VRAM, 0);
+
+ if (bo == NULL)
+ return NULL;
+ bo->static_bo = 1;
+ bo->offset = offset;
+ bo->base.handle = bo->offset;
+ bo->ptr = boml->screen->driScreen->pFB + (offset - boml->fb_location);
+ if (bo->base.handle > boml->nhandle) {
+ boml->nhandle = bo->base.handle + 1;
+ }
+ radeon_bo_ref(&(bo->base));
+ return &(bo->base);
+}
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
index 0db817cab0..2cf15dfaff 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bo_legacy.h
@@ -42,5 +42,9 @@ struct radeon_bo_manager *radeon_bo_manager_legacy_ctor(struct radeon_screen *sc
void radeon_bo_manager_legacy_dtor(struct radeon_bo_manager *bom);
void radeon_bo_legacy_texture_age(struct radeon_bo_manager *bom);
unsigned radeon_bo_legacy_relocs_size(struct radeon_bo *bo);
+struct radeon_bo *radeon_legacy_bo_alloc_fake(struct radeon_bo_manager *bom,
+ int size,
+ uint32_t offset);
+void legacy_track_pending(struct radeon_bo_manager *bom, int debug);
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
index e0c70dd9a1..4520a7d7d4 100644
--- a/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
+++ b/src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h
@@ -15,6 +15,12 @@
#define RADEON_GEM_DOMAIN_GTT 0x2 // GTT or cache flushed
#define RADEON_GEM_DOMAIN_VRAM 0x4 // VRAM domain
+#define RADEON_TILING_MACRO 0x1
+#define RADEON_TILING_MICRO 0x2
+#define RADEON_TILING_SWAP 0x4
+#define RADEON_TILING_SURFACE 0x8 /* this object requires a surface
+ * when mapped - i.e. front buffer */
+
/* to be used to build locally in mesa with no libdrm bits */
#include "../radeon/radeon_bo_drm.h"
#include "../radeon/radeon_cs_drm.h"
@@ -39,6 +45,10 @@ struct drm_radeon_info {
#define RADEON_PARAM_DEVICE_ID 16
#endif
+#ifndef RADEON_PARAM_NUM_Z_PIPES
+#define RADEON_PARAM_NUM_Z_PIPES 17
+#endif
+
#ifndef RADEON_INFO_DEVICE_ID
#define RADEON_INFO_DEVICE_ID 0
#endif
@@ -46,6 +56,10 @@ struct drm_radeon_info {
#define RADEON_INFO_NUM_GB_PIPES 0
#endif
+#ifndef RADEON_INFO_NUM_Z_PIPES
+#define RADEON_INFO_NUM_Z_PIPES 0
+#endif
+
#ifndef DRM_RADEON_INFO
#define DRM_RADEON_INFO 0x1
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
new file mode 100644
index 0000000000..8fac5c6c51
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.c
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include "radeon_buffer_objects.h"
+
+#include "main/imports.h"
+#include "main/mtypes.h"
+#include "main/bufferobj.h"
+
+#include "radeon_common.h"
+
+struct radeon_buffer_object *
+get_radeon_buffer_object(struct gl_buffer_object *obj)
+{
+ return (struct radeon_buffer_object *) obj;
+}
+
+static struct gl_buffer_object *
+radeonNewBufferObject(GLcontext * ctx,
+ GLuint name,
+ GLenum target)
+{
+ struct radeon_buffer_object *obj = CALLOC_STRUCT(radeon_buffer_object);
+
+ _mesa_initialize_buffer_object(&obj->Base, name, target);
+
+ obj->bo = NULL;
+
+ return &obj->Base;
+}
+
+/**
+ * Called via glDeleteBuffersARB().
+ */
+static void
+radeonDeleteBufferObject(GLcontext * ctx,
+ struct gl_buffer_object *obj)
+{
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ if (obj->Pointer) {
+ radeon_bo_unmap(radeon_obj->bo);
+ }
+
+ if (radeon_obj->bo) {
+ radeon_bo_unref(radeon_obj->bo);
+ }
+
+ _mesa_free(radeon_obj);
+}
+
+
+/**
+ * Allocate space for and store data in a buffer object. Any data that was
+ * previously stored in the buffer object is lost. If data is NULL,
+ * memory will be allocated, but no copy will occur.
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
+ */
+static GLboolean
+radeonBufferData(GLcontext * ctx,
+ GLenum target,
+ GLsizeiptrARB size,
+ const GLvoid * data,
+ GLenum usage,
+ struct gl_buffer_object *obj)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ radeon_obj->Base.Size = size;
+ radeon_obj->Base.Usage = usage;
+
+ if (radeon_obj->bo != NULL) {
+ radeon_bo_unref(radeon_obj->bo);
+ radeon_obj->bo = NULL;
+ }
+
+ if (size != 0) {
+ radeon_obj->bo = radeon_bo_open(radeon->radeonScreen->bom,
+ 0,
+ size,
+ 32,
+ RADEON_GEM_DOMAIN_GTT,
+ 0);
+
+ if (!radeon_obj->bo)
+ return GL_FALSE;
+
+ if (data != NULL) {
+ radeon_bo_map(radeon_obj->bo, GL_TRUE);
+
+ _mesa_memcpy(radeon_obj->bo->ptr, data, size);
+
+ radeon_bo_unmap(radeon_obj->bo);
+ }
+ }
+ return GL_TRUE;
+}
+
+/**
+ * Replace data in a subrange of buffer object. If the data range
+ * specified by size + offset extends beyond the end of the buffer or
+ * if data is NULL, no copy is performed.
+ * Called via glBufferSubDataARB().
+ */
+static void
+radeonBufferSubData(GLcontext * ctx,
+ GLenum target,
+ GLintptrARB offset,
+ GLsizeiptrARB size,
+ const GLvoid * data,
+ struct gl_buffer_object *obj)
+{
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ radeon_bo_map(radeon_obj->bo, GL_TRUE);
+
+ _mesa_memcpy(radeon_obj->bo->ptr + offset, data, size);
+
+ radeon_bo_unmap(radeon_obj->bo);
+}
+
+/**
+ * Called via glGetBufferSubDataARB()
+ */
+static void
+radeonGetBufferSubData(GLcontext * ctx,
+ GLenum target,
+ GLintptrARB offset,
+ GLsizeiptrARB size,
+ GLvoid * data,
+ struct gl_buffer_object *obj)
+{
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ radeon_bo_map(radeon_obj->bo, GL_FALSE);
+
+ _mesa_memcpy(data, radeon_obj->bo->ptr + offset, size);
+
+ radeon_bo_unmap(radeon_obj->bo);
+}
+
+/**
+ * Called via glMapBufferARB()
+ */
+static void *
+radeonMapBuffer(GLcontext * ctx,
+ GLenum target,
+ GLenum access,
+ struct gl_buffer_object *obj)
+{
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ if (access == GL_WRITE_ONLY_ARB) {
+ ctx->Driver.Flush(ctx);
+ }
+
+ if (radeon_obj->bo == NULL) {
+ obj->Pointer = NULL;
+ return NULL;
+ }
+
+ radeon_bo_map(radeon_obj->bo, access == GL_WRITE_ONLY_ARB);
+
+ obj->Pointer = radeon_obj->bo->ptr;
+ obj->Length = obj->Size;
+ obj->Offset = 0;
+
+ return obj->Pointer;
+}
+
+
+/**
+ * Called via glUnmapBufferARB()
+ */
+static GLboolean
+radeonUnmapBuffer(GLcontext * ctx,
+ GLenum target,
+ struct gl_buffer_object *obj)
+{
+ struct radeon_buffer_object *radeon_obj = get_radeon_buffer_object(obj);
+
+ if (radeon_obj->bo != NULL) {
+ radeon_bo_unmap(radeon_obj->bo);
+ }
+
+ obj->Pointer = NULL;
+ obj->Offset = 0;
+ obj->Length = 0;
+
+ return GL_TRUE;
+}
+
+void
+radeonInitBufferObjectFuncs(struct dd_function_table *functions)
+{
+ functions->NewBufferObject = radeonNewBufferObject;
+ functions->DeleteBuffer = radeonDeleteBufferObject;
+ functions->BufferData = radeonBufferData;
+ functions->BufferSubData = radeonBufferSubData;
+ functions->GetBufferSubData = radeonGetBufferSubData;
+ functions->MapBuffer = radeonMapBuffer;
+ functions->UnmapBuffer = radeonUnmapBuffer;
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_buffer_objects.h b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.h
new file mode 100644
index 0000000000..d681960825
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_buffer_objects.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef RADEON_BUFFER_OBJECTS_H
+#define RADEON_BUFFER_OBJECTS_H
+
+#include "main/mtypes.h"
+
+struct radeon_bo;
+
+/**
+ * Radeon vertex/pixel buffer object, derived from Mesa's gl_buffer_object.
+ */
+struct radeon_buffer_object
+{
+ struct gl_buffer_object Base;
+ struct radeon_bo *bo;
+};
+
+struct radeon_buffer_object *
+get_radeon_buffer_object(struct gl_buffer_object *obj);
+
+/**
+ * Hook the bufferobject implementation into mesa:
+ */
+void radeonInitBufferObjectFuncs(struct dd_function_table *functions);
+
+#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_chipset.h b/src/mesa/drivers/dri/radeon/radeon_chipset.h
index 0a6a2df35b..46a9cd5ff8 100644
--- a/src/mesa/drivers/dri/radeon/radeon_chipset.h
+++ b/src/mesa/drivers/dri/radeon/radeon_chipset.h
@@ -335,9 +335,16 @@
#define PCI_CHIP_RS780_9615 0x9615
#define PCI_CHIP_RS780_9616 0x9616
+#define PCI_CHIP_RS880_9710 0x9710
+#define PCI_CHIP_RS880_9711 0x9711
+#define PCI_CHIP_RS880_9712 0x9712
+#define PCI_CHIP_RS880_9713 0x9713
+#define PCI_CHIP_RS880_9714 0x9714
+
#define PCI_CHIP_RV770_9440 0x9440
#define PCI_CHIP_RV770_9441 0x9441
#define PCI_CHIP_RV770_9442 0x9442
+#define PCI_CHIP_RV770_9443 0x9443
#define PCI_CHIP_RV770_9444 0x9444
#define PCI_CHIP_RV770_9446 0x9446
#define PCI_CHIP_RV770_944A 0x944A
@@ -356,11 +363,14 @@
#define PCI_CHIP_RV770_947A 0x947A
#define PCI_CHIP_RV770_947B 0x947B
+#define PCI_CHIP_RV730_9480 0x9480
#define PCI_CHIP_RV730_9487 0x9487
+#define PCI_CHIP_RV730_9488 0x9488
#define PCI_CHIP_RV730_9489 0x9489
#define PCI_CHIP_RV730_948F 0x948F
#define PCI_CHIP_RV730_9490 0x9490
#define PCI_CHIP_RV730_9491 0x9491
+#define PCI_CHIP_RV730_9495 0x9495
#define PCI_CHIP_RV730_9498 0x9498
#define PCI_CHIP_RV730_949C 0x949C
#define PCI_CHIP_RV730_949E 0x949E
@@ -374,12 +384,16 @@
#define PCI_CHIP_RV710_9552 0x9552
#define PCI_CHIP_RV710_9553 0x9553
#define PCI_CHIP_RV710_9555 0x9555
+#define PCI_CHIP_RV710_9557 0x9557
#define PCI_CHIP_RV740_94A0 0x94A0
#define PCI_CHIP_RV740_94A1 0x94A1
+#define PCI_CHIP_RV740_94A3 0x94A3
#define PCI_CHIP_RV740_94B1 0x94B1
#define PCI_CHIP_RV740_94B3 0x94B3
+#define PCI_CHIP_RV740_94B4 0x94B4
#define PCI_CHIP_RV740_94B5 0x94B5
+#define PCI_CHIP_RV740_94B9 0x94B9
enum {
CHIP_FAMILY_R100,
@@ -414,6 +428,7 @@ enum {
CHIP_FAMILY_RV620,
CHIP_FAMILY_RV635,
CHIP_FAMILY_RS780,
+ CHIP_FAMILY_RS880,
CHIP_FAMILY_RV770,
CHIP_FAMILY_RV730,
CHIP_FAMILY_RV710,
diff --git a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h
index abb023c7de..6fcd1ce7ca 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cmdbuf.h
@@ -3,7 +3,7 @@
#include "radeon_bocs_wrapper.h"
-void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
+GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller);
int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller);
int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller);
void rcommonInitCmdBuf(radeonContextPtr rmesa);
@@ -54,11 +54,12 @@ void rcommonBeginBatch(radeonContextPtr rmesa,
*/
#define OUT_BATCH_RELOC(data, bo, offset, rd, wd, flags) \
do { \
- if (0 && offset) { \
+ int __offset = (offset); \
+ if (0 && __offset) { \
fprintf(stderr, "(%s:%s:%d) offset : %d\n", \
- __FILE__, __FUNCTION__, __LINE__, offset); \
+ __FILE__, __FUNCTION__, __LINE__, __offset); \
} \
- radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, offset); \
+ radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, __offset); \
radeon_cs_write_reloc(b_l_rmesa->cmdbuf.cs, \
bo, rd, wd, flags); \
if (!b_l_rmesa->radeonScreen->kernel_mm) \
@@ -71,10 +72,7 @@ void rcommonBeginBatch(radeonContextPtr rmesa,
*/
#define OUT_BATCH_TABLE(ptr,n) \
do { \
- int _i; \
- for (_i=0; _i < n; _i++) {\
- radeon_cs_write_dword(b_l_rmesa->cmdbuf.cs, ptr[_i]);\
- }\
+ radeon_cs_write_table(b_l_rmesa->cmdbuf.cs, (ptr), (n));\
} while(0)
/**
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.c b/src/mesa/drivers/dri/radeon/radeon_common.c
index dde615a4d9..264392b327 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common.c
@@ -45,46 +45,26 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/glheader.h"
#include "main/imports.h"
#include "main/context.h"
-#include "main/arrayobj.h"
-#include "main/api_arrayelt.h"
#include "main/enums.h"
-#include "main/colormac.h"
-#include "main/light.h"
#include "main/framebuffer.h"
-#include "main/simple_list.h"
#include "main/renderbuffer.h"
-#include "swrast/swrast.h"
-#include "vbo/vbo.h"
-#include "tnl/tnl.h"
-#include "tnl/t_pipeline.h"
-#include "swrast_setup/swrast_setup.h"
-
-#include "main/blend.h"
-#include "main/bufferobj.h"
-#include "main/buffers.h"
-#include "main/depth.h"
-#include "main/polygon.h"
-#include "main/shaders.h"
-#include "main/texstate.h"
-#include "main/varray.h"
-#include "glapi/dispatch.h"
-#include "swrast/swrast.h"
-#include "main/stencil.h"
-#include "main/matrix.h"
-#include "main/attrib.h"
-#include "main/enable.h"
-#include "main/viewport.h"
-
-#include "dri_util.h"
+#include "drivers/common/meta.h"
+
#include "vblank.h"
#include "radeon_common.h"
#include "radeon_bocs_wrapper.h"
#include "radeon_lock.h"
#include "radeon_drm.h"
-#include "radeon_mipmap_tree.h"
+#include "radeon_queryobj.h"
-#define DEBUG_CMDBUF 0
+/**
+ * Enable verbose debug output for emit code.
+ * 0 no output
+ * 1 most output
+ * 2 also print state alues
+ */
+#define RADEON_CMDBUF 0
/* =============================================================
* Scissoring
@@ -147,6 +127,9 @@ void radeonRecalcScissorRects(radeonContextPtr radeon)
out++;
}
}
+
+ if (radeon->vtbl.update_scissor)
+ radeon->vtbl.update_scissor(radeon->glCtx);
}
void radeon_get_cliprects(radeonContextPtr radeon,
@@ -221,26 +204,48 @@ void radeonSetCliprects(radeonContextPtr radeon)
void radeonUpdateScissor( GLcontext *ctx )
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
+ GLint x = ctx->Scissor.X, y = ctx->Scissor.Y;
+ GLsizei w = ctx->Scissor.Width, h = ctx->Scissor.Height;
+ int x1, y1, x2, y2;
+ int min_x, min_y, max_x, max_y;
- if ( !ctx->DrawBuffer->Name ) {
- __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
-
- int x = ctx->Scissor.X;
- int y = dPriv->h - ctx->Scissor.Y - ctx->Scissor.Height;
- int w = ctx->Scissor.X + ctx->Scissor.Width - 1;
- int h = dPriv->h - ctx->Scissor.Y - 1;
+ if (!ctx->DrawBuffer)
+ return;
+ min_x = min_y = 0;
+ max_x = ctx->DrawBuffer->Width - 1;
+ max_y = ctx->DrawBuffer->Height - 1;
- rmesa->state.scissor.rect.x1 = x + dPriv->x;
- rmesa->state.scissor.rect.y1 = y + dPriv->y;
- rmesa->state.scissor.rect.x2 = w + dPriv->x + 1;
- rmesa->state.scissor.rect.y2 = h + dPriv->y + 1;
+ if ( !ctx->DrawBuffer->Name ) {
+ x1 = x;
+ y1 = ctx->DrawBuffer->Height - (y + h);
+ x2 = x + w - 1;
+ y2 = y1 + h - 1;
} else {
- rmesa->state.scissor.rect.x1 = ctx->Scissor.X;
- rmesa->state.scissor.rect.y1 = ctx->Scissor.Y;
- rmesa->state.scissor.rect.x2 = ctx->Scissor.X + ctx->Scissor.Width;
- rmesa->state.scissor.rect.y2 = ctx->Scissor.Y + ctx->Scissor.Height;
+ x1 = x;
+ y1 = y;
+ x2 = x + w - 1;
+ y2 = y + h - 1;
+
+ }
+ if (!rmesa->radeonScreen->kernel_mm) {
+ /* Fix scissors for dri 1 */
+
+ __DRIdrawablePrivate *dPriv = radeon_get_drawable(rmesa);
+ x1 += dPriv->x;
+ x2 += dPriv->x + 1;
+ min_x += dPriv->x;
+ max_x += dPriv->x + 1;
+ y1 += dPriv->y;
+ y2 += dPriv->y + 1;
+ min_y += dPriv->y;
+ max_y += dPriv->y + 1;
}
+ rmesa->state.scissor.rect.x1 = CLAMP(x1, min_x, max_x);
+ rmesa->state.scissor.rect.y1 = CLAMP(y1, min_y, max_y);
+ rmesa->state.scissor.rect.x2 = CLAMP(x2, min_x, max_x);
+ rmesa->state.scissor.rect.y2 = CLAMP(y2, min_y, max_y);
+
radeonRecalcScissorRects( rmesa );
}
@@ -258,6 +263,28 @@ void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h)
}
}
+void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask )
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ GLuint i;
+ drm_radeon_stipple_t stipple;
+
+ /* Must flip pattern upside down.
+ */
+ for ( i = 0 ; i < 32 ; i++ ) {
+ stipple.mask[31 - i] = ((GLuint *) mask)[i];
+ }
+
+ /* TODO: push this into cmd mechanism
+ */
+ radeon_firevertices(radeon);
+ LOCK_HARDWARE( radeon );
+
+ drmCommandWrite( radeon->dri.fd, DRM_RADEON_STIPPLE,
+ &stipple, sizeof(stipple) );
+ UNLOCK_HARDWARE( radeon );
+}
+
/* ================================================================
* SwapBuffers with client-side throttling
@@ -442,7 +469,7 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
rfb = dPriv->driverPrivate;
- if ( RADEON_DEBUG & DEBUG_IOCTL ) {
+ if ( RADEON_DEBUG & RADEON_IOCTL ) {
fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, (void *) rmesa->glCtx );
}
@@ -481,32 +508,6 @@ void radeonCopyBuffer( __DRIdrawablePrivate *dPriv,
if (!n)
continue;
- if (IS_R600_CLASS(rmesa->radeonScreen)) {
- int cpp = rmesa->radeonScreen->cpp;
- int src_pitch = rmesa->radeonScreen->backPitch * cpp;
- int dst_pitch = rmesa->radeonScreen->frontPitch * cpp;
- char *src = (char *)rmesa->radeonScreen->driScreen->pFB + rmesa->radeonScreen->backOffset;
- char *dst = (char *)rmesa->radeonScreen->driScreen->pFB + rmesa->radeonScreen->frontOffset;
- int j;
- drm_clip_rect_t *pb = rmesa->sarea->boxes;
-
- for (j = 0; j < n; j++) {
- int x = pb[j].x1;
- int y = pb[j].y1;
- int w = pb[j].x2 - x;
- int h = pb[j].y2 - y;
-
- src += (y * src_pitch) + (x * cpp);
- dst += (y * dst_pitch) + (x * cpp);
-
- while (h--) {
- memcpy(dst, src, w * cpp);
- src += src_pitch;
- dst += dst_pitch;
- }
- }
- }
-
ret = drmCommandNone( rmesa->dri.fd, DRM_RADEON_SWAP );
if ( ret ) {
@@ -562,7 +563,7 @@ static GLboolean radeonPageFlip( __DRIdrawablePrivate *dPriv )
LOCK_HARDWARE(radeon);
- if ( RADEON_DEBUG & DEBUG_IOCTL ) {
+ if ( RADEON_DEBUG & RADEON_IOCTL ) {
fprintf(stderr, "%s: pfCurrentPage: %d %d\n", __FUNCTION__,
radeon->sarea->pfCurrentPage, radeon->sarea->pfState);
}
@@ -822,7 +823,7 @@ void radeon_draw_buffer(GLcontext *ctx, struct gl_framebuffer *fb)
*/
void radeonDrawBuffer( GLcontext *ctx, GLenum mode )
{
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "%s %s\n", __FUNCTION__,
_mesa_lookup_enum_by_nr( mode ));
@@ -887,10 +888,11 @@ void radeonUpdatePageFlipping(radeonContextPtr radeon)
void radeon_window_moved(radeonContextPtr radeon)
{
+ /* Cliprects has to be updated before doing anything else */
+ radeonSetCliprects(radeon);
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
radeonUpdatePageFlipping(radeon);
}
- radeonSetCliprects(radeon);
}
void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height)
@@ -905,7 +907,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he
if (!radeon->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
if (radeon->is_front_buffer_rendering) {
- radeonFlush(ctx);
+ ctx->Driver.Flush(ctx);
}
radeon_update_renderbuffers(driContext, driContext->driDrawablePriv);
if (driContext->driDrawablePriv != driContext->driReadablePriv)
@@ -919,7 +921,7 @@ void radeon_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei he
ctx->Driver.Viewport = old_viewport;
}
-static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
+static void radeon_print_state_atom_prekmm(radeonContextPtr radeon, struct radeon_state_atom *state)
{
int i, j, reg;
int dwords = (*state->check) (radeon->glCtx, state);
@@ -927,7 +929,10 @@ static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state
fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
- if (RADEON_DEBUG & DEBUG_VERBOSE) {
+ if (radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) {
+ if (dwords > state->cmd_size)
+ dwords = state->cmd_size;
+
for (i = 0; i < dwords;) {
cmd = *((drm_r300_cmd_header_t *) &state->cmd[i]);
reg = (cmd.packet0.reghi << 8) | cmd.packet0.reglo;
@@ -944,15 +949,26 @@ static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state
}
}
-static void radeon_print_state_atom_kmm(radeonContextPtr radeon, struct radeon_state_atom *state)
+static void radeon_print_state_atom(radeonContextPtr radeon, struct radeon_state_atom *state)
{
int i, j, reg, count;
- int dwords = (*state->check) (radeon->glCtx, state);
+ int dwords;
uint32_t packet0;
+ if (!radeon_is_debug_enabled(RADEON_STATE, RADEON_VERBOSE) )
+ return;
+
+ if (!radeon->radeonScreen->kernel_mm) {
+ radeon_print_state_atom_prekmm(radeon, state);
+ return;
+ }
+
+ dwords = (*state->check) (radeon->glCtx, state);
fprintf(stderr, " emit %s %d/%d\n", state->name, dwords, state->cmd_size);
- if (RADEON_DEBUG & DEBUG_VERBOSE) {
+ if (radeon_is_debug_enabled(RADEON_STATE, RADEON_TRACE)) {
+ if (dwords > state->cmd_size)
+ dwords = state->cmd_size;
for (i = 0; i < dwords;) {
packet0 = state->cmd[i];
reg = (packet0 & 0x1FFF) << 2;
@@ -970,40 +986,81 @@ static void radeon_print_state_atom_kmm(radeonContextPtr radeon, struct radeon_s
}
}
-static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean dirty)
+/**
+ * Count total size for next state emit.
+ **/
+GLuint radeonCountStateEmitSize(radeonContextPtr radeon)
{
- BATCH_LOCALS(radeon);
struct radeon_state_atom *atom;
+ GLuint dwords = 0;
+ /* check if we are going to emit full state */
+
+ if (radeon->cmdbuf.cs->cdw && !radeon->hw.all_dirty) {
+ if (!radeon->hw.is_dirty)
+ goto out;
+ foreach(atom, &radeon->hw.atomlist) {
+ if (atom->dirty) {
+ const GLuint atom_size = atom->check(radeon->glCtx, atom);
+ dwords += atom_size;
+ if (RADEON_CMDBUF && atom_size) {
+ radeon_print_state_atom(radeon, atom);
+ }
+ }
+ }
+ } else {
+ foreach(atom, &radeon->hw.atomlist) {
+ const GLuint atom_size = atom->check(radeon->glCtx, atom);
+ dwords += atom_size;
+ if (RADEON_CMDBUF && atom_size) {
+ radeon_print_state_atom(radeon, atom);
+ }
+
+ }
+ }
+out:
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s %u\n", __func__, dwords);
+ return dwords;
+}
+
+static INLINE void radeon_emit_atom(radeonContextPtr radeon, struct radeon_state_atom *atom)
+{
+ BATCH_LOCALS(radeon);
int dwords;
+ dwords = (*atom->check) (radeon->glCtx, atom);
+ if (dwords) {
+
+ radeon_print_state_atom(radeon, atom);
+
+ if (atom->emit) {
+ (*atom->emit)(radeon->glCtx, atom);
+ } else {
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(atom->cmd, dwords);
+ END_BATCH();
+ }
+ } else {
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, " skip state %s\n", atom->name);
+ }
+ atom->dirty = GL_FALSE;
+
+}
+
+static INLINE void radeonEmitAtoms(radeonContextPtr radeon, GLboolean emitAll)
+{
+ struct radeon_state_atom *atom;
+
if (radeon->vtbl.pre_emit_atoms)
radeon->vtbl.pre_emit_atoms(radeon);
/* Emit actual atoms */
- foreach(atom, &radeon->hw.atomlist) {
- if ((atom->dirty || radeon->hw.all_dirty) == dirty) {
- dwords = (*atom->check) (radeon->glCtx, atom);
- if (dwords) {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- if (radeon->radeonScreen->kernel_mm)
- radeon_print_state_atom_kmm(radeon, atom);
- else
- radeon_print_state_atom(radeon, atom);
- }
- if (atom->emit) {
- (*atom->emit)(radeon->glCtx, atom);
- } else {
- BEGIN_BATCH_NO_AUTOSTATE(dwords);
- OUT_BATCH_TABLE(atom->cmd, dwords);
- END_BATCH();
- }
- atom->dirty = GL_FALSE;
- } else {
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_STATE) {
- fprintf(stderr, " skip state %s\n",
- atom->name);
- }
- }
+ if (radeon->hw.all_dirty || emitAll) {
+ foreach(atom, &radeon->hw.atomlist)
+ radeon_emit_atom( radeon, atom );
+ } else {
+ foreach(atom, &radeon->hw.atomlist) {
+ if ( atom->dirty )
+ radeon_emit_atom( radeon, atom );
}
}
@@ -1023,8 +1080,7 @@ static GLboolean radeon_revalidate_bos(GLcontext *ctx)
void radeonEmitState(radeonContextPtr radeon)
{
- if (RADEON_DEBUG & (DEBUG_STATE|DEBUG_PRIMS))
- fprintf(stderr, "%s\n", __FUNCTION__);
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s\n", __FUNCTION__);
if (radeon->vtbl.pre_emit_state)
radeon->vtbl.pre_emit_state(radeon);
@@ -1033,33 +1089,28 @@ void radeonEmitState(radeonContextPtr radeon)
if (radeon->cmdbuf.cs->cdw && !radeon->hw.is_dirty && !radeon->hw.all_dirty)
return;
- /* To avoid going across the entire set of states multiple times, just check
- * for enough space for the case of emitting all state, and inline the
- * radeonAllocCmdBuf code here without all the checks.
- */
- rcommonEnsureCmdBufSpace(radeon, radeon->hw.max_state_size, __FUNCTION__);
-
if (!radeon->cmdbuf.cs->cdw) {
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "Begin reemit state\n");
+ radeonEmitAtoms(radeon, GL_TRUE);
+ } else {
+
+ if (RADEON_DEBUG & RADEON_STATE)
+ fprintf(stderr, "Begin dirty state\n");
+
radeonEmitAtoms(radeon, GL_FALSE);
}
- if (RADEON_DEBUG & DEBUG_STATE)
- fprintf(stderr, "Begin dirty state\n");
-
- radeonEmitAtoms(radeon, GL_TRUE);
radeon->hw.is_dirty = GL_FALSE;
radeon->hw.all_dirty = GL_FALSE;
-
}
void radeonFlush(GLcontext *ctx)
{
radeonContextPtr radeon = RADEON_CONTEXT(ctx);
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s %d\n", __FUNCTION__, radeon->cmdbuf.cs->cdw);
/* okay if we have no cmds in the buffer &&
@@ -1067,7 +1118,7 @@ void radeonFlush(GLcontext *ctx)
we have no DMA buffer allocated.
then no point flushing anything at all.
*/
- if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && !radeon->dma.current)
+ if (!radeon->dma.flush && !radeon->cmdbuf.cs->cdw && is_empty_list(&radeon->dma.reserved))
return;
if (radeon->dma.flush)
@@ -1092,11 +1143,14 @@ void radeonFlush(GLcontext *ctx)
* each of N places that do rendering. This has worse performances,
* but it is much easier to get correct.
*/
- if (radeon->is_front_buffer_rendering) {
+ if (!radeon->is_front_buffer_rendering) {
radeon->front_buffer_dirty = GL_FALSE;
}
}
}
+
+ make_empty_list(&radeon->query.not_flushed_head);
+
}
/* Make sure all commands have been sent to the hardware and have
@@ -1148,11 +1202,13 @@ int rcommonFlushCmdBufLocked(radeonContextPtr rmesa, const char *caller)
}
rmesa->cmdbuf.flushing = 1;
- if (RADEON_DEBUG & DEBUG_IOCTL) {
+ if (RADEON_DEBUG & RADEON_IOCTL) {
fprintf(stderr, "%s from %s - %i cliprects\n",
__FUNCTION__, caller, rmesa->numClipRects);
}
+ radeonEmitQueryEnd(rmesa->glCtx);
+
if (rmesa->cmdbuf.cs->cdw) {
ret = radeon_cs_emit(rmesa->cmdbuf.cs);
rmesa->hw.all_dirty = GL_TRUE;
@@ -1171,14 +1227,16 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
{
int ret;
- radeonReleaseDmaRegion(rmesa);
+ radeonReleaseDmaRegions(rmesa);
LOCK_HARDWARE(rmesa);
ret = rcommonFlushCmdBufLocked(rmesa, caller);
UNLOCK_HARDWARE(rmesa);
if (ret) {
- fprintf(stderr, "drmRadeonCmdBuffer: %d\n", ret);
+ fprintf(stderr, "drmRadeonCmdBuffer: %d. Kernel failed to "
+ "parse or rejected command stream. See dmesg "
+ "for more info.\n", ret);
_mesa_exit(ret);
}
@@ -1191,12 +1249,16 @@ int rcommonFlushCmdBuf(radeonContextPtr rmesa, const char *caller)
*
* \param dwords The number of dwords we need to be free on the command buffer
*/
-void rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
+GLboolean rcommonEnsureCmdBufSpace(radeonContextPtr rmesa, int dwords, const char *caller)
{
- if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size ||
- radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
- rcommonFlushCmdBuf(rmesa, caller);
- }
+ if ((rmesa->cmdbuf.cs->cdw + dwords + 128) > rmesa->cmdbuf.size
+ || radeon_cs_need_flush(rmesa->cmdbuf.cs)) {
+ /* If we try to flush empty buffer there is too big rendering operation. */
+ assert(rmesa->cmdbuf.cs->cdw);
+ rcommonFlushCmdBuf(rmesa, caller);
+ return GL_TRUE;
+ }
+ return GL_FALSE;
}
void rcommonInitCmdBuf(radeonContextPtr rmesa)
@@ -1211,15 +1273,13 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa)
if (size > 64 * 256)
size = 64 * 256;
- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA)) {
- fprintf(stderr, "sizeof(drm_r300_cmd_header_t)=%zd\n",
- sizeof(drm_r300_cmd_header_t));
- fprintf(stderr, "sizeof(drm_radeon_cmd_buffer_t)=%zd\n",
- sizeof(drm_radeon_cmd_buffer_t));
- fprintf(stderr,
+ radeon_print(RADEON_CS, RADEON_VERBOSE,
+ "sizeof(drm_r300_cmd_header_t)=%zd\n", sizeof(drm_r300_cmd_header_t));
+ radeon_print(RADEON_CS, RADEON_VERBOSE,
+ "sizeof(drm_radeon_cmd_buffer_t)=%zd\n", sizeof(drm_radeon_cmd_buffer_t));
+ radeon_print(RADEON_CS, RADEON_VERBOSE,
"Allocating %d bytes command buffer (max state is %d bytes)\n",
size * 4, rmesa->hw.max_state_size * 4);
- }
if (rmesa->radeonScreen->kernel_mm) {
int fd = rmesa->radeonScreen->driScreen->fd;
@@ -1236,7 +1296,7 @@ void rcommonInitCmdBuf(radeonContextPtr rmesa)
rmesa->cmdbuf.size = size;
radeon_cs_space_set_flush(rmesa->cmdbuf.cs,
- (void (*)(void *))radeonFlush, rmesa->glCtx);
+ (void (*)(void *))rmesa->glCtx->Driver.Flush, rmesa->glCtx);
if (!rmesa->radeonScreen->kernel_mm) {
radeon_cs_set_limit(rmesa->cmdbuf.cs, RADEON_GEM_DOMAIN_VRAM, rmesa->radeonScreen->texSize[0]);
@@ -1271,22 +1331,19 @@ void rcommonBeginBatch(radeonContextPtr rmesa, int n,
const char *function,
int line)
{
- rcommonEnsureCmdBufSpace(rmesa, n, function);
if (!rmesa->cmdbuf.cs->cdw && dostate) {
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "Reemit state after flush (from %s)\n", function);
+ radeon_print(RADEON_STATE, RADEON_NORMAL,
+ "Reemit state after flush (from %s)\n", function);
radeonEmitState(rmesa);
}
radeon_cs_begin(rmesa->cmdbuf.cs, n, file, function, line);
- if (DEBUG_CMDBUF && RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
+ radeon_print(RADEON_CS, RADEON_VERBOSE, "BEGIN_BATCH(%d) at %d, from %s:%i\n",
n, rmesa->cmdbuf.cs->cdw, function, line);
}
void radeonUserClear(GLcontext *ctx, GLuint mask)
{
- radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- meta_clear_tris(&rmesa->meta, mask);
+ _mesa_meta_Clear(ctx, mask);
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_common.h b/src/mesa/drivers/dri/radeon/radeon_common.h
index cebae18b2d..f3201911ac 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common.h
@@ -10,6 +10,7 @@ void radeonRecalcScissorRects(radeonContextPtr radeon);
void radeonSetCliprects(radeonContextPtr radeon);
void radeonUpdateScissor( GLcontext *ctx );
void radeonScissor(GLcontext* ctx, GLint x, GLint y, GLsizei w, GLsizei h);
+void radeonPolygonStipplePreKMS( GLcontext *ctx, const GLubyte *mask );
void radeonWaitForIdleLocked(radeonContextPtr radeon);
extern uint32_t radeonGetAge(radeonContextPtr radeon);
@@ -24,6 +25,7 @@ void radeonUpdatePageFlipping(radeonContextPtr rmesa);
void radeonFlush(GLcontext *ctx);
void radeonFinish(GLcontext * ctx);
void radeonEmitState(radeonContextPtr radeon);
+GLuint radeonCountStateEmitSize(radeonContextPtr radeon);
void radeon_clear_tris(GLcontext *ctx, GLbitfield mask);
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.c b/src/mesa/drivers/dri/radeon/radeon_common_context.c
index 285e015c92..6b9b1e3c5e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.c
@@ -37,6 +37,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "utils.h"
#include "vblank.h"
#include "drirenderbuffer.h"
+#include "drivers/common/meta.h"
#include "main/context.h"
#include "main/framebuffer.h"
#include "main/renderbuffer.h"
@@ -46,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
@@ -85,6 +86,18 @@ static const char* get_chip_family_name(int chip_family)
case CHIP_FAMILY_R580: return "R580";
case CHIP_FAMILY_RV560: return "RV560";
case CHIP_FAMILY_RV570: return "RV570";
+ case CHIP_FAMILY_R600: return "R600";
+ case CHIP_FAMILY_RV610: return "RV610";
+ case CHIP_FAMILY_RV630: return "RV630";
+ case CHIP_FAMILY_RV670: return "RV670";
+ case CHIP_FAMILY_RV620: return "RV620";
+ case CHIP_FAMILY_RV635: return "RV635";
+ case CHIP_FAMILY_RS780: return "RS780";
+ case CHIP_FAMILY_RS880: return "RS880";
+ case CHIP_FAMILY_RV770: return "RV770";
+ case CHIP_FAMILY_RV730: return "RV730";
+ case CHIP_FAMILY_RV710: return "RV710";
+ case CHIP_FAMILY_RV740: return "RV740";
default: return "unknown";
}
}
@@ -195,11 +208,15 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
driContextPriv->driverPrivate = radeon;
meta_init_metaops(ctx, &radeon->meta);
+
+ _mesa_meta_init(ctx);
+
/* DRI fields */
radeon->dri.context = driContextPriv;
radeon->dri.screen = sPriv;
radeon->dri.hwContext = driContextPriv->hHWContext;
radeon->dri.hwLock = &sPriv->pSAREA->lock;
+ radeon->dri.hwLockCount = 0;
radeon->dri.fd = sPriv->fd;
radeon->dri.drmMinor = sPriv->drm_version.minor;
@@ -210,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);
@@ -230,7 +244,29 @@ GLboolean radeonInitContext(radeonContextPtr radeon,
radeon->texture_depth = ( glVisual->rgbBits > 16 ) ?
DRI_CONF_TEXTURE_DEPTH_32 : DRI_CONF_TEXTURE_DEPTH_16;
- radeon->texture_row_align = 32;
+ if (IS_R600_CLASS(radeon->radeonScreen)) {
+ radeon->texture_row_align = 256;
+ radeon->texture_rect_row_align = 256;
+ radeon->texture_compressed_row_align = 256;
+ } else if (IS_R200_CLASS(radeon->radeonScreen) ||
+ IS_R100_CLASS(radeon->radeonScreen)) {
+ radeon->texture_row_align = 32;
+ radeon->texture_rect_row_align = 64;
+ radeon->texture_compressed_row_align = 32;
+ } else { /* R300 - not sure this is all correct */
+ int chip_family = radeon->radeonScreen->chip_family;
+ if (chip_family == CHIP_FAMILY_RS600 ||
+ chip_family == CHIP_FAMILY_RS690 ||
+ chip_family == CHIP_FAMILY_RS740)
+ radeon->texture_row_align = 64;
+ else
+ radeon->texture_row_align = 32;
+ radeon->texture_rect_row_align = 64;
+ radeon->texture_compressed_row_align = 64;
+ }
+
+ make_empty_list(&radeon->query.not_flushed_head);
+ radeon_init_dma(radeon);
return GL_TRUE;
}
@@ -265,63 +301,48 @@ void radeonDestroyContext(__DRIcontextPrivate *driContextPriv )
radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
radeonContextPtr current = ctx ? RADEON_CONTEXT(ctx) : NULL;
- /* +r6/r7 */
- __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
- radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
- /* --------- */
+ assert(radeon);
+
+ _mesa_meta_free(radeon->glCtx);
if (radeon == current) {
radeon_firevertices(radeon);
_mesa_make_current(NULL, NULL, NULL);
}
- assert(radeon);
- if (radeon)
- {
-
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
- if (IS_R600_CLASS(screen))
- {
- r600DestroyContext(driContextPriv);
- }
-#endif
-
- if (radeon->dma.current) {
- rcommonFlushCmdBuf( radeon, __FUNCTION__ );
- }
-
- radeonReleaseArrays(radeon->glCtx, ~0);
- meta_destroy_metaops(&radeon->meta);
- if (radeon->vtbl.free_context)
- radeon->vtbl.free_context(radeon->glCtx);
- _swsetup_DestroyContext( radeon->glCtx );
- _tnl_DestroyContext( radeon->glCtx );
- _vbo_DestroyContext( radeon->glCtx );
- _swrast_DestroyContext( radeon->glCtx );
-
- /* free atom list */
- /* free the Mesa context */
- _mesa_destroy_context(radeon->glCtx);
-
- /* _mesa_destroy_context() might result in calls to functions that
- * depend on the DriverCtx, so don't set it to NULL before.
- *
- * radeon->glCtx->DriverCtx = NULL;
- */
- /* free the option cache */
- driDestroyOptionCache(&radeon->optionCache);
-
- rcommonDestroyCmdBuf(radeon);
-
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600) /* +r6/r7 */
- if (!IS_R600_CLASS(screen))
-#endif
- radeon_destroy_atom_list(radeon);
+ if (!is_empty_list(&radeon->dma.reserved)) {
+ rcommonFlushCmdBuf( radeon, __FUNCTION__ );
+ }
- if (radeon->state.scissor.pClipRects) {
- FREE(radeon->state.scissor.pClipRects);
- radeon->state.scissor.pClipRects = 0;
- }
+ radeonFreeDmaRegions(radeon);
+ radeonReleaseArrays(radeon->glCtx, ~0);
+ meta_destroy_metaops(&radeon->meta);
+ if (radeon->vtbl.free_context)
+ radeon->vtbl.free_context(radeon->glCtx);
+ _swsetup_DestroyContext( radeon->glCtx );
+ _tnl_DestroyContext( radeon->glCtx );
+ _vbo_DestroyContext( radeon->glCtx );
+ _swrast_DestroyContext( radeon->glCtx );
+
+ /* free atom list */
+ /* free the Mesa context */
+ _mesa_destroy_context(radeon->glCtx);
+
+ /* _mesa_destroy_context() might result in calls to functions that
+ * depend on the DriverCtx, so don't set it to NULL before.
+ *
+ * radeon->glCtx->DriverCtx = NULL;
+ */
+ /* free the option cache */
+ driDestroyOptionCache(&radeon->optionCache);
+
+ rcommonDestroyCmdBuf(radeon);
+
+ radeon_destroy_atom_list(radeon);
+
+ if (radeon->state.scissor.pClipRects) {
+ FREE(radeon->state.scissor.pClipRects);
+ radeon->state.scissor.pClipRects = 0;
}
#ifdef RADEON_BO_TRACK
track = fopen("/tmp/tracklog", "w");
@@ -339,7 +360,7 @@ GLboolean radeonUnbindContext(__DRIcontextPrivate * driContextPriv)
{
radeonContextPtr radeon = (radeonContextPtr) driContextPriv->driverPrivate;
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "%s ctx %p\n", __FUNCTION__,
radeon->glCtx);
@@ -356,88 +377,48 @@ radeon_make_kernel_renderbuffer_current(radeonContextPtr radeon,
if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->frontOffset,
- 0,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Front Buf");
-#else
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->frontOffset,
0,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->backOffset,
0,
0,
RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Back Buf");
-#else
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->backOffset,
- 0,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->depthOffset,
- 0,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Z Buf");
-#else
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset,
0,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->depthOffset,
- 0,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Stencil Buf");
-#else
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset,
0,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
@@ -460,16 +441,6 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
if ((rb = (void *)draw->base.Attachment[BUFFER_FRONT_LEFT].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->frontOffset +
- radeon->radeonScreen->fbLocation,
- size,
- 4096,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Front Buf");
-#else
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->frontOffset +
radeon->radeonScreen->fbLocation,
@@ -477,23 +448,12 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
4096,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->frontPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_BACK_LEFT].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->backOffset +
- radeon->radeonScreen->fbLocation,
- size,
- 4096,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Back Buf");
-#else
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->backOffset +
radeon->radeonScreen->fbLocation,
@@ -501,55 +461,32 @@ radeon_make_renderbuffer_current(radeonContextPtr radeon,
4096,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->backPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_DEPTH].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset +
radeon->radeonScreen->fbLocation,
size,
4096,
RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Z Buf");
-#else
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->depthOffset +
- radeon->radeonScreen->fbLocation,
- size,
- 4096,
- RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
}
if ((rb = (void *)draw->base.Attachment[BUFFER_STENCIL].Renderbuffer)) {
if (!rb->bo) {
-#ifdef RADEON_DEBUG_BO
rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
radeon->radeonScreen->depthOffset +
radeon->radeonScreen->fbLocation,
size,
4096,
RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Stencil Buf");
-#else
- rb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- radeon->radeonScreen->depthOffset +
- radeon->radeonScreen->fbLocation,
- size,
- 4096,
- RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
}
rb->cpp = radeon->radeonScreen->cpp;
rb->pitch = radeon->radeonScreen->depthPitch * rb->cpp;
@@ -587,7 +524,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
char *regname;
struct radeon_bo *depth_bo = NULL, *bo;
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "enter %s, drawable %p\n", __func__, drawable);
draw = drawable->driverPrivate;
@@ -714,7 +651,7 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
continue;
}
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr,
"attaching buffer %s, %d, at %d, cpp %d, pitch %d\n",
regname, buffers[i].name, buffers[i].attachment,
@@ -727,33 +664,34 @@ radeon_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable)
rb->has_surface = 0;
if (buffers[i].attachment == __DRI_BUFFER_STENCIL && depth_bo) {
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "(reusing depth buffer as stencil)\n");
bo = depth_bo;
radeon_bo_ref(bo);
} else {
-#ifdef RADEON_DEBUG_BO
- bo = radeon_bo_open(radeon->radeonScreen->bom,
- buffers[i].name,
- 0,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
- buffers[i].flags,
- regname);
-#else
+ uint32_t tiling_flags = 0, pitch = 0;
+ int ret;
+
bo = radeon_bo_open(radeon->radeonScreen->bom,
buffers[i].name,
0,
0,
RADEON_GEM_DOMAIN_VRAM,
buffers[i].flags);
-#endif /* RADEON_DEBUG_BO */
+
if (bo == NULL) {
fprintf(stderr, "failed to attach %s %d\n",
regname, buffers[i].name);
}
+
+ ret = radeon_bo_get_tiling(bo, &tiling_flags, &pitch);
+ if (tiling_flags & RADEON_TILING_MACRO)
+ bo->flags |= RADEON_BO_FLAGS_MACRO_TILE;
+ if (tiling_flags & RADEON_TILING_MICRO)
+ bo->flags |= RADEON_BO_FLAGS_MICRO_TILE;
+
}
if (buffers[i].attachment == __DRI_BUFFER_DEPTH) {
@@ -799,7 +737,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
struct gl_framebuffer *readfb;
if (!driContextPriv) {
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "%s ctx is null\n", __FUNCTION__);
_mesa_make_current(NULL, NULL, NULL);
return GL_TRUE;
@@ -821,7 +759,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
radeon_make_renderbuffer_current(radeon, drfb);
}
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "%s ctx %p dfb %p rfb %p\n", __FUNCTION__, radeon->glCtx, drfb, readfb);
driUpdateFramebufferSize(radeon->glCtx, driDrawPriv);
@@ -856,7 +794,7 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
}
- if (RADEON_DEBUG & DEBUG_DRI)
+ if (RADEON_DEBUG & RADEON_DRI)
fprintf(stderr, "End %s\n", __FUNCTION__);
return GL_TRUE;
diff --git a/src/mesa/drivers/dri/radeon/radeon_common_context.h b/src/mesa/drivers/dri/radeon/radeon_common_context.h
index e4a8da0596..0309345393 100644
--- a/src/mesa/drivers/dri/radeon/radeon_common_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_common_context.h
@@ -8,6 +8,7 @@
#include "tnl/t_context.h"
#include "main/colormac.h"
+#include "radeon_debug.h"
#include "radeon_screen.h"
#include "radeon_drm.h"
#include "dri_util.h"
@@ -142,10 +143,6 @@ struct radeon_stencilbuffer_state {
GLuint clear; /* rb3d_stencilrefmask value */
};
-struct radeon_stipple_state {
- GLuint mask[32];
-};
-
struct radeon_state_atom {
struct radeon_state_atom *next, *prev;
const char *name; /* for debug */
@@ -163,6 +160,7 @@ struct radeon_hw_state {
/* Head of the linked list of state atoms. */
struct radeon_state_atom atomlist;
int max_state_size; /* Number of bytes necessary for a full state emit. */
+ int max_post_flush_size; /* Number of bytes necessary for post flushing emits */
GLboolean is_dirty, all_dirty;
};
@@ -239,6 +237,11 @@ struct radeon_tex_obj {
GLuint SQ_TEX_SAMPLER1;
GLuint SQ_TEX_SAMPLER2;
+ GLuint TD_PS_SAMPLER0_BORDER_RED;
+ GLuint TD_PS_SAMPLER0_BORDER_GREEN;
+ GLuint TD_PS_SAMPLER0_BORDER_BLUE;
+ GLuint TD_PS_SAMPLER0_BORDER_ALPHA;
+
GLboolean border_fallback;
@@ -249,6 +252,17 @@ static INLINE radeonTexObj* radeon_tex_obj(struct gl_texture_object *texObj)
return (radeonTexObj*)texObj;
}
+/* occlusion query */
+struct radeon_query_object {
+ struct gl_query_object Base;
+ struct radeon_bo *bo;
+ int curr_offset;
+ GLboolean emitted_begin;
+
+ /* Double linked list of not flushed query objects */
+ struct radeon_query_object *prev, *next;
+};
+
/* Need refcounting on dma buffers:
*/
struct radeon_dma_buffer {
@@ -264,14 +278,25 @@ struct radeon_aos {
int count; /** Number of vertices */
};
+#define DMA_BO_FREE_TIME 100
+
+struct radeon_dma_bo {
+ struct radeon_dma_bo *next, *prev;
+ struct radeon_bo *bo;
+ int expire_counter;
+};
+
struct radeon_dma {
/* Active dma region. Allocations for vertices and retained
* regions come from here. Also used for emitting random vertices,
* these may be flushed by calling flush_current();
*/
- struct radeon_bo *current; /** Buffer that DMA memory is allocated from */
- int current_used; /** Number of bytes allocated and forgotten about */
- int current_vertexptr; /** End of active vertex region */
+ struct radeon_dma_bo free;
+ struct radeon_dma_bo wait;
+ struct radeon_dma_bo reserved;
+ size_t current_used; /** Number of bytes allocated and forgotten about */
+ size_t current_vertexptr; /** End of active vertex region */
+ size_t minimum_size;
/**
* If current_vertexptr != current_used then flush must be non-zero.
@@ -279,12 +304,6 @@ struct radeon_dma {
* performed.
*/
void (*flush) (GLcontext *);
-
- /* Number of "in-flight" DMA buffers, i.e. the number of buffers
- * for which a DISCARD command is currently queued in the command buffer
-.
- */
- GLuint nr_released_bufs;
};
/* radeon_swtcl.c
@@ -304,6 +323,7 @@ struct radeon_swtcl_info {
struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX];
GLuint vertex_attr_count;
+ GLuint emit_prediction;
};
#define RADEON_MAX_AOS_ARRAYS 16
@@ -316,7 +336,8 @@ struct radeon_tcl_info {
struct radeon_ioctl {
GLuint vertex_offset;
- struct radeon_bo *bo;
+ GLuint vertex_max;
+ struct radeon_bo *bo;
GLuint vertex_size;
};
@@ -360,27 +381,11 @@ struct radeon_dri_mirror {
drm_context_t hwContext;
drm_hw_lock_t *hwLock;
+ int hwLockCount;
int fd;
int drmMinor;
};
-#define DEBUG_TEXTURE 0x001
-#define DEBUG_STATE 0x002
-#define DEBUG_IOCTL 0x004
-#define DEBUG_PRIMS 0x008
-#define DEBUG_VERTS 0x010
-#define DEBUG_FALLBACKS 0x020
-#define DEBUG_VFMT 0x040
-#define DEBUG_CODEGEN 0x080
-#define DEBUG_VERBOSE 0x100
-#define DEBUG_DRI 0x200
-#define DEBUG_DMA 0x400
-#define DEBUG_SANITY 0x800
-#define DEBUG_SYNC 0x1000
-#define DEBUG_PIXEL 0x2000
-#define DEBUG_MEMORY 0x4000
-
-
typedef void (*radeon_tri_func) (radeonContextPtr,
radeonVertex *,
radeonVertex *, radeonVertex *);
@@ -424,6 +429,8 @@ struct radeon_context {
int texture_depth;
float initialMaxAnisotropy;
uint32_t texture_row_align;
+ uint32_t texture_rect_row_align;
+ uint32_t texture_compressed_row_align;
struct radeon_dma dma;
struct radeon_hw_state hw;
@@ -438,7 +445,6 @@ struct radeon_context {
GLuint numClipRects; /* Cliprects for the draw buffer */
drm_clip_rect_t *pClipRects;
unsigned int lastStamp;
- GLboolean lost_context;
drm_radeon_sarea_t *sarea; /* Private SAREA data */
/* Mirrors of some DRI state */
@@ -461,6 +467,8 @@ struct radeon_context {
struct radeon_cmdbuf cmdbuf;
+ struct radeon_debug debug;
+
drm_clip_rect_t fboRect;
GLboolean constant_cliprect; /* use for FBO or DRI2 rendering */
GLboolean front_cliprects;
@@ -493,6 +501,12 @@ struct radeon_context {
struct dri_metaops meta;
struct {
+ struct radeon_query_object *current;
+ struct radeon_query_object not_flushed_head;
+ struct radeon_state_atom queryobj;
+ } query;
+
+ struct {
void (*get_lock)(radeonContextPtr radeon);
void (*update_viewport_offset)(GLcontext *ctx);
void (*emit_cs_header)(struct radeon_cs *cs, radeonContextPtr rmesa);
@@ -501,6 +515,8 @@ struct radeon_context {
void (*pre_emit_state)(radeonContextPtr rmesa);
void (*fallback)(GLcontext *ctx, GLuint bit, GLboolean mode);
void (*free_context)(GLcontext *ctx);
+ void (*emit_query_finish)(radeonContextPtr radeon);
+ void (*update_scissor)(GLcontext *ctx);
} vtbl;
};
@@ -516,7 +532,6 @@ static inline __DRIdrawablePrivate* radeon_get_readable(radeonContextPtr radeon)
return radeon->dri.context->driReadablePriv;
}
-
/**
* This function takes a float and packs it into a uint32_t
*/
@@ -576,21 +591,4 @@ GLboolean radeonMakeCurrent(__DRIcontextPrivate * driContextPriv,
__DRIdrawablePrivate * driReadPriv);
extern void radeonDestroyContext(__DRIcontextPrivate * driContextPriv);
-/* ================================================================
- * Debugging:
- */
-#define DO_DEBUG 1
-
-#if DO_DEBUG
-extern int RADEON_DEBUG;
-#else
-#define RADEON_DEBUG 0
-#endif
-
-#ifndef HAVE_LIBDRM_RADEON
-#ifndef RADEON_DEBUG_BO
-#define RADEON_DEBUG_BO 1
-#endif
-#endif
-
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.c b/src/mesa/drivers/dri/radeon/radeon_context.c
index c457fb654e..8f4485aee7 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.c
+++ b/src/mesa/drivers/dri/radeon/radeon_context.c
@@ -62,7 +62,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_swtcl.h"
#include "radeon_tcl.h"
#include "radeon_maos.h"
+#include "radeon_queryobj.h"
+#define need_GL_ARB_occlusion_query
#define need_GL_EXT_blend_minmax
#define need_GL_EXT_fog_coord
#define need_GL_EXT_secondary_color
@@ -80,6 +82,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
const struct dri_extension card_extensions[] =
{
{ "GL_ARB_multitexture", NULL },
+ { "GL_ARB_occlusion_query", GL_ARB_occlusion_query_functions},
{ "GL_ARB_texture_border_clamp", NULL },
{ "GL_ARB_texture_env_add", NULL },
{ "GL_ARB_texture_env_combine", NULL },
@@ -134,25 +137,6 @@ static const struct tnl_pipeline_stage *radeon_pipeline[] = {
NULL,
};
-static const struct dri_debug_control debug_control[] =
-{
- { "fall", DEBUG_FALLBACKS },
- { "tex", DEBUG_TEXTURE },
- { "ioctl", DEBUG_IOCTL },
- { "prim", DEBUG_PRIMS },
- { "vert", DEBUG_VERTS },
- { "state", DEBUG_STATE },
- { "code", DEBUG_CODEGEN },
- { "vfmt", DEBUG_VFMT },
- { "vtxf", DEBUG_VFMT },
- { "verb", DEBUG_VERBOSE },
- { "dri", DEBUG_DRI },
- { "dma", DEBUG_DMA },
- { "san", DEBUG_SANITY },
- { "sync", DEBUG_SYNC },
- { NULL, 0 }
-};
-
static void r100_get_lock(radeonContextPtr radeon)
{
r100ContextPtr rmesa = (r100ContextPtr)radeon;
@@ -194,6 +178,20 @@ static void r100_vtbl_free_context(GLcontext *ctx)
_mesa_vector4f_free( &rmesa->tcl.ObjClean );
}
+static void r100_emit_query_finish(radeonContextPtr radeon)
+{
+ BATCH_LOCALS(radeon);
+ struct radeon_query_object *query = radeon->query.current;
+
+ BEGIN_BATCH_NO_AUTOSTATE(4);
+ OUT_BATCH(CP_PACKET0(RADEON_RB3D_ZPASS_ADDR, 0));
+ OUT_BATCH_RELOC(0, query->bo, query->curr_offset, 0, RADEON_GEM_DOMAIN_GTT, 0);
+ END_BATCH();
+ query->curr_offset += sizeof(uint32_t);
+ assert(query->curr_offset < RADEON_QUERY_PAGE_SIZE);
+ query->emitted_begin = GL_FALSE;
+}
+
static void r100_init_vtbl(radeonContextPtr radeon)
{
radeon->vtbl.get_lock = r100_get_lock;
@@ -202,6 +200,8 @@ static void r100_init_vtbl(radeonContextPtr radeon)
radeon->vtbl.swtcl_flush = r100_swtcl_flush;
radeon->vtbl.pre_emit_state = r100_vtbl_pre_emit_state;
radeon->vtbl.fallback = radeonFallback;
+ radeon->vtbl.free_context = r100_vtbl_free_context;
+ radeon->vtbl.emit_query_finish = r100_emit_query_finish;
}
/* Create the device specific context.
@@ -258,6 +258,7 @@ r100CreateContext( const __GLcontextModes *glVisual,
*/
_mesa_init_driver_functions( &functions );
radeonInitTextureFuncs( &functions );
+ radeonInitQueryObjFunctions(&functions);
if (!radeonInitContext(&rmesa->radeon, &functions,
glVisual, driContextPriv,
@@ -368,11 +369,14 @@ r100CreateContext( const __GLcontextModes *glVisual,
if (rmesa->radeon.radeonScreen->kernel_mm || rmesa->radeon.dri.drmMinor >= 9)
_mesa_enable_extension( ctx, "GL_NV_texture_rectangle");
+ if (!rmesa->radeon.radeonScreen->kernel_mm)
+ _mesa_disable_extension(ctx, "GL_ARB_occlusion_query");
+
/* XXX these should really go right after _mesa_init_driver_functions() */
radeon_fbo_init(&rmesa->radeon);
radeonInitSpanFuncs( ctx );
radeonInitIoctlFuncs( ctx );
- radeonInitStateFuncs( ctx );
+ radeonInitStateFuncs( ctx , rmesa->radeon.radeonScreen->kernel_mm );
radeonInitState( rmesa );
radeonInitSwtcl( ctx );
diff --git a/src/mesa/drivers/dri/radeon/radeon_context.h b/src/mesa/drivers/dri/radeon/radeon_context.h
index 1795d8bdb6..4e2c52c835 100644
--- a/src/mesa/drivers/dri/radeon/radeon_context.h
+++ b/src/mesa/drivers/dri/radeon/radeon_context.h
@@ -295,6 +295,15 @@ struct radeon_texture_state {
#define SHN_SHININESS 1
#define SHN_STATE_SIZE 2
+#define R100_QUERYOBJ_CMD_0 0
+#define R100_QUERYOBJ_DATA_0 1
+#define R100_QUERYOBJ_CMDSIZE 2
+
+#define STP_CMD_0 0
+#define STP_DATA_0 1
+#define STP_CMD_1 2
+#define STP_STATE_SIZE 35
+
struct r100_hw_state {
/* Hardware state, stored as cmdbuf commands:
* -- Need to doublebuffer for
@@ -319,12 +328,11 @@ struct r100_hw_state {
struct radeon_state_atom fog;
struct radeon_state_atom glt;
struct radeon_state_atom txr[3]; /* for NPOT */
-
+ struct radeon_state_atom stp;
};
struct r100_state {
- struct radeon_stipple_state stipple;
struct radeon_texture_state texture;
};
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
index ee403d173c..ab4eca31a3 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_drm.h
@@ -201,6 +201,15 @@ static inline void radeon_cs_write_qword(struct radeon_cs *cs, uint64_t qword)
}
}
+static inline void radeon_cs_write_table(struct radeon_cs *cs, void *data, uint32_t size)
+{
+ memcpy(cs->packets + cs->cdw, data, size * 4);
+ cs->cdw += size;
+ if (cs->section) {
+ cs->section_cdw += size;
+ }
+}
+
static inline void radeon_cs_space_set_flush(struct radeon_cs *cs, void (*fn)(void *), void *data)
{
cs->space_flush_fn = fn;
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
index 4f1065ebcf..f1addb299e 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.c
@@ -32,6 +32,7 @@
#include <errno.h>
#include "radeon_bocs_wrapper.h"
+#include "radeon_common.h"
struct cs_manager_legacy {
struct radeon_cs_manager base;
@@ -317,7 +318,7 @@ static int cs_emit(struct radeon_cs *cs)
if ((!IS_R300_CLASS(csm->ctx->radeonScreen)) &&
(!IS_R600_CLASS(csm->ctx->radeonScreen))) { /* +r6/r7 : No irq for r6/r7 yet. */
drm_radeon_irq_emit_t emit_cmd;
- emit_cmd.irq_seq = &csm->pending_age;
+ emit_cmd.irq_seq = (int*)&csm->pending_age;
r = drmCommandWrite(cs->csm->fd, DRM_RADEON_IRQ_EMIT, &emit_cmd, sizeof(emit_cmd));
if (r) {
return r;
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
index e177b4bafe..cafbc9e576 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_legacy.h
@@ -32,7 +32,7 @@
#ifndef RADEON_CS_LEGACY_H
#define RADEON_CS_LEGACY_H
-#include "radeon_common.h"
+struct radeon_context;
struct radeon_cs_manager *radeon_cs_manager_legacy_ctor(struct radeon_context *ctx);
void radeon_cs_manager_legacy_dtor(struct radeon_cs_manager *csm);
diff --git a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
index 5a8df7bb8c..89cbbb5a6b 100644
--- a/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
+++ b/src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c
@@ -82,7 +82,7 @@ static inline int radeon_cs_setup_bo(struct radeon_cs_space_check *sc, struct ra
if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
sizes->op_read -= bo->size;
sizes->op_vram_write += bo->size;
- } else if (write_domain == RADEON_GEM_DOMAIN_VRAM) {
+ } else if (write_domain == RADEON_GEM_DOMAIN_GTT) {
sizes->op_read -= bo->size;
sizes->op_gart_write += bo->size;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.c b/src/mesa/drivers/dri/radeon/radeon_debug.c
new file mode 100644
index 0000000000..413000b6c0
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_debug.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright © 2009 Pauli Nieminen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ */
+/*
+ * Authors:
+ * Pauli Nieminen <suokkos@gmail.com>
+ */
+
+#include "utils.h"
+
+#include "radeon_debug.h"
+#include "radeon_common_context.h"
+
+#include <stdarg.h>
+#include <stdio.h>
+
+static const struct dri_debug_control debug_control[] = {
+ {"fall", RADEON_FALLBACKS},
+ {"tex", RADEON_TEXTURE},
+ {"ioctl", RADEON_IOCTL},
+ {"verts", RADEON_VERTS},
+ {"render", RADEON_RENDER},
+ {"swrender", RADEON_SWRENDER},
+ {"state", RADEON_STATE},
+ {"shader", RADEON_SHADER},
+ {"vfmt", RADEON_VFMT},
+ {"vtxf", RADEON_VFMT},
+ {"dri", RADEON_DRI},
+ {"dma", RADEON_DMA},
+ {"sanity", RADEON_SANITY},
+ {"sync", RADEON_SYNC},
+ {"pixel", RADEON_PIXEL},
+ {"mem", RADEON_MEMORY},
+ {"cs", RADEON_CS},
+ {"allmsg", ~RADEON_SYNC}, /* avoid the term "sync" because the parser uses strstr */
+ {NULL, 0}
+};
+
+radeon_debug_type_t radeon_enabled_debug_types;
+
+void radeon_init_debug(void)
+{
+ radeon_enabled_debug_types = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
+
+ radeon_enabled_debug_types |= RADEON_GENERAL;
+}
+
+void _radeon_debug_add_indent(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ const size_t length = sizeof(radeon->debug.indent)
+ / sizeof(radeon->debug.indent[0]);
+ if (radeon->debug.indent_depth < length - 1) {
+ radeon->debug.indent[radeon->debug.indent_depth] = '\t';
+ ++radeon->debug.indent_depth;
+ };
+}
+
+void _radeon_debug_remove_indent(void)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ if (radeon->debug.indent_depth > 0) {
+ radeon->debug.indent[radeon->debug.indent_depth] = '\0';
+ --radeon->debug.indent_depth;
+ }
+}
+
+void _radeon_print(const radeon_debug_type_t type,
+ const radeon_debug_level_t level,
+ const char* message,
+ ...)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ if (ctx) {
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ // FIXME: Make this multi thread safe
+ if (radeon->debug.indent_depth)
+ fprintf(stderr, "%s", radeon->debug.indent);
+ }
+ va_list values;
+ va_start( values, message );
+ vfprintf(stderr, message, values);
+ va_end( values );
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_debug.h b/src/mesa/drivers/dri/radeon/radeon_debug.h
new file mode 100644
index 0000000000..26da31c1c4
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_debug.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright © 2009 Pauli Nieminen
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and 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.
+ */
+/*
+ * Authors:
+ * Pauli Nieminen <suokkos@gmail.com>
+ */
+
+#ifndef RADEON_DEBUG_H_INCLUDED
+#define RADEON_DEBUG_H_INCLUDED
+
+#include <stdlib.h>
+
+typedef enum radeon_debug_levels {
+ RADEON_CRITICAL = 0, /* Only errors */
+ RADEON_IMPORTANT = 1, /* Important warnings and messages */
+ RADEON_NORMAL = 2, /* Normal log messages usefull for debugging */
+ RADEON_VERBOSE = 3, /* Extra details to debugging */
+ RADEON_TRACE = 4 /* Log about everything that happens */
+} radeon_debug_level_t;
+
+/**
+ * Compile time option to change level of debugging compiled to dri driver.
+ * Selecting critical level is not recommended because perfromance gains are
+ * going to minimal but you will lose a lot of important warnings in case of
+ * errors.
+ */
+#ifndef RADEON_DEBUG_LEVEL
+#define RADEON_DEBUG_LEVEL RADEON_VERBOSE
+#endif
+
+typedef enum radeon_debug_types {
+ RADEON_TEXTURE = 0x00001,
+ RADEON_STATE = 0x00002,
+ RADEON_IOCTL = 0x00004,
+ RADEON_RENDER = 0x00008,
+ RADEON_SWRENDER = 0x00010,
+ RADEON_FALLBACKS = 0x00020,
+ RADEON_VFMT = 0x00040,
+ RADEON_SHADER = 0x00080,
+ RADEON_CS = 0x00100,
+ RADEON_DRI = 0x00200,
+ RADEON_DMA = 0x00400,
+ RADEON_SANITY = 0x00800,
+ RADEON_SYNC = 0x01000,
+ RADEON_PIXEL = 0x02000,
+ RADEON_MEMORY = 0x04000,
+ RADEON_VERTS = 0x08000,
+ RADEON_GENERAL = 0x10000 /* Used for errors and warnings */
+} radeon_debug_type_t;
+
+#define RADEON_MAX_INDENT 5
+
+struct radeon_debug {
+ size_t indent_depth;
+ char indent[RADEON_MAX_INDENT];
+};
+
+extern radeon_debug_type_t radeon_enabled_debug_types;
+
+/**
+ * Compabibility layer for old debug code
+ **/
+#define RADEON_DEBUG radeon_enabled_debug_types
+
+static inline int radeon_is_debug_enabled(const radeon_debug_type_t type,
+ const radeon_debug_level_t level)
+{
+ return RADEON_DEBUG_LEVEL >= level
+ && (type & radeon_enabled_debug_types);
+}
+/*
+ * define macro for gcc specific __attribute__ if using alternative compiler
+ */
+#ifndef __GNUC__
+#define __attribute__(x) /*empty*/
+#endif
+
+
+extern void _radeon_print(const radeon_debug_type_t type,
+ const radeon_debug_level_t level,
+ const char* message,
+ ...) __attribute__((format(printf,3,4)));
+/**
+ * Print out debug message if channel specified by type is enabled
+ * and compile time debugging level is at least as high as level parameter
+ */
+#define radeon_print(type, level, message, ...) do { \
+ const radeon_debug_level_t _debug_level = (level); \
+ const radeon_debug_type_t _debug_type = (type); \
+ /* Compile out if level of message is too high */ \
+ if (radeon_is_debug_enabled(type, level)) { \
+ _radeon_print(_debug_type, _debug_level, \
+ (message), ## __VA_ARGS__); \
+ } \
+} while(0)
+
+/**
+ * printf style function for writing error messages.
+ */
+#define radeon_error(message, ...) do { \
+ radeon_print(RADEON_GENERAL, RADEON_CRITICAL, \
+ (message), ## __VA_ARGS__); \
+} while(0)
+
+/**
+ * printf style function for writing warnings.
+ */
+#define radeon_warning(message, ...) do { \
+ radeon_print(RADEON_GENERAL, RADEON_IMPORTANT, \
+ (message), ## __VA_ARGS__); \
+} while(0)
+
+extern void radeon_init_debug(void);
+extern void _radeon_debug_add_indent(void);
+extern void _radeon_debug_remove_indent(void);
+
+static inline void radeon_debug_add_indent(void)
+{
+ if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
+ _radeon_debug_add_indent();
+ }
+}
+static inline void radeon_debug_remove_indent(void)
+{
+ if (RADEON_DEBUG_LEVEL >= RADEON_VERBOSE) {
+ _radeon_debug_remove_indent();
+ }
+}
+
+
+/* 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, ...) 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_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 48114a0012..c6edbae9a1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.c
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.c
@@ -30,7 +30,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
**************************************************************************/
+#include <errno.h>
#include "radeon_common.h"
+#include "main/simple_list.h"
#if defined(USE_X86_ASM)
#define COPY_DWORDS( dst, src, nr ) \
@@ -52,11 +54,11 @@ do { \
} while (0)
#endif
-static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
+void radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
__FUNCTION__, count, stride, (void *)out, (void *)data);
@@ -70,11 +72,11 @@ static void radeonEmitVec4(uint32_t *out, GLvoid * data, int stride, int count)
}
}
-void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
+void radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
__FUNCTION__, count, stride, (void *)out, (void *)data);
@@ -89,11 +91,11 @@ void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count)
}
}
-void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
+void radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
__FUNCTION__, count, stride, (void *)out, (void *)data);
@@ -110,11 +112,11 @@ void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count)
}
}
-static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
+void radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d out %p data %p\n",
__FUNCTION__, count, stride, (void *)out, (void *)data);
@@ -132,7 +134,7 @@ static void radeonEmitVec16(uint32_t *out, GLvoid * data, int stride, int count)
}
void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
- GLvoid * data, int size, int stride, int count)
+ const GLvoid * data, int size, int stride, int count)
{
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
uint32_t *out;
@@ -161,61 +163,68 @@ void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
}
}
+void radeon_init_dma(radeonContextPtr rmesa)
+{
+ make_empty_list(&rmesa->dma.free);
+ make_empty_list(&rmesa->dma.wait);
+ make_empty_list(&rmesa->dma.reserved);
+ rmesa->dma.minimum_size = MAX_DMA_BUF_SZ;
+}
+
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size)
{
+ struct radeon_dma_bo *dma_bo = NULL;
+ /* we set minimum sizes to at least requested size
+ aligned to next 16 bytes. */
+ if (size > rmesa->dma.minimum_size)
+ rmesa->dma.minimum_size = (size + 15) & (~15);
- size = MAX2(size, MAX_DMA_BUF_SZ);
+ radeon_print(RADEON_DMA, RADEON_NORMAL, "%s size %d minimum_size %d\n",
+ __FUNCTION__, size, rmesa->dma.minimum_size);
- if (RADEON_DEBUG & (DEBUG_IOCTL | DEBUG_DMA))
- fprintf(stderr, "%s\n", __FUNCTION__);
- if (rmesa->dma.flush) {
- rmesa->dma.flush(rmesa->glCtx);
- }
+ /* unmap old reserved bo */
+ if (!is_empty_list(&rmesa->dma.reserved))
+ radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
- if (rmesa->dma.nr_released_bufs > 4) {
- rcommonFlushCmdBuf(rmesa, __FUNCTION__);
- rmesa->dma.nr_released_bufs = 0;
- }
-
- if (rmesa->dma.current) {
- radeon_bo_unmap(rmesa->dma.current);
- radeon_bo_unref(rmesa->dma.current);
- rmesa->dma.current = 0;
- }
+ if (is_empty_list(&rmesa->dma.free)
+ || last_elem(&rmesa->dma.free)->bo->size < size) {
+ dma_bo = CALLOC_STRUCT(radeon_dma_bo);
+ assert(dma_bo);
again_alloc:
-#ifdef RADEON_DEBUG_BO
- rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
- 0, size, 4, RADEON_GEM_DOMAIN_GTT,
- 0, "dma.current");
-#else
- rmesa->dma.current = radeon_bo_open(rmesa->radeonScreen->bom,
- 0, size, 4, RADEON_GEM_DOMAIN_GTT,
- 0);
-#endif /* RADEON_DEBUG_BO */
-
- if (!rmesa->dma.current) {
- rcommonFlushCmdBuf(rmesa, __FUNCTION__);
- rmesa->dma.nr_released_bufs = 0;
- goto again_alloc;
+ dma_bo->bo = radeon_bo_open(rmesa->radeonScreen->bom,
+ 0, rmesa->dma.minimum_size, 4,
+ RADEON_GEM_DOMAIN_GTT, 0);
+
+ if (!dma_bo->bo) {
+ rcommonFlushCmdBuf(rmesa, __FUNCTION__);
+ goto again_alloc;
+ }
+ insert_at_head(&rmesa->dma.reserved, dma_bo);
+ } else {
+ /* We push and pop buffers from end of list so we can keep
+ counter on unused buffers for later freeing them from
+ begin of list */
+ dma_bo = last_elem(&rmesa->dma.free);
+ remove_from_list(dma_bo);
+ insert_at_head(&rmesa->dma.reserved, dma_bo);
}
rmesa->dma.current_used = 0;
rmesa->dma.current_vertexptr = 0;
if (radeon_cs_space_check_with_bo(rmesa->cmdbuf.cs,
- rmesa->dma.current,
+ first_elem(&rmesa->dma.reserved)->bo,
RADEON_GEM_DOMAIN_GTT, 0))
fprintf(stderr,"failure to revalidate BOs - badness\n");
- if (!rmesa->dma.current) {
+ if (is_empty_list(&rmesa->dma.reserved)) {
/* Cmd buff have been flushed in radeon_revalidate_bos */
- rmesa->dma.nr_released_bufs = 0;
goto again_alloc;
}
- radeon_bo_map(rmesa->dma.current, 1);
+ radeon_bo_map(first_elem(&rmesa->dma.reserved)->bo, 1);
}
/* Allocates a region from rmesa->dma.current. If there isn't enough
@@ -225,7 +234,7 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa,
struct radeon_bo **pbo, int *poffset,
int bytes, int alignment)
{
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s %d\n", __FUNCTION__, bytes);
if (rmesa->dma.flush)
@@ -236,30 +245,154 @@ void radeonAllocDmaRegion(radeonContextPtr rmesa,
alignment--;
rmesa->dma.current_used = (rmesa->dma.current_used + alignment) & ~alignment;
- if (!rmesa->dma.current || rmesa->dma.current_used + bytes > rmesa->dma.current->size)
- radeonRefillCurrentDmaRegion(rmesa, (bytes + 15) & ~15);
+ if (is_empty_list(&rmesa->dma.reserved)
+ || rmesa->dma.current_used + bytes > first_elem(&rmesa->dma.reserved)->bo->size)
+ radeonRefillCurrentDmaRegion(rmesa, bytes);
*poffset = rmesa->dma.current_used;
- *pbo = rmesa->dma.current;
+ *pbo = first_elem(&rmesa->dma.reserved)->bo;
radeon_bo_ref(*pbo);
/* Always align to at least 16 bytes */
rmesa->dma.current_used = (rmesa->dma.current_used + bytes + 15) & ~15;
rmesa->dma.current_vertexptr = rmesa->dma.current_used;
- assert(rmesa->dma.current_used <= rmesa->dma.current->size);
+ assert(rmesa->dma.current_used <= first_elem(&rmesa->dma.reserved)->bo->size);
}
-void radeonReleaseDmaRegion(radeonContextPtr rmesa)
+void radeonFreeDmaRegions(radeonContextPtr rmesa)
{
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s %p\n", __FUNCTION__, rmesa->dma.current);
- if (rmesa->dma.current) {
- rmesa->dma.nr_released_bufs++;
- radeon_bo_unmap(rmesa->dma.current);
- radeon_bo_unref(rmesa->dma.current);
+ struct radeon_dma_bo *dma_bo;
+ struct radeon_dma_bo *temp;
+ if (RADEON_DEBUG & RADEON_DMA)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+
+ foreach_s(dma_bo, temp, &rmesa->dma.free) {
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ FREE(dma_bo);
+ }
+
+ foreach_s(dma_bo, temp, &rmesa->dma.wait) {
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ FREE(dma_bo);
+ }
+
+ foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
+ remove_from_list(dma_bo);
+ radeon_bo_unmap(dma_bo->bo);
+ radeon_bo_unref(dma_bo->bo);
+ FREE(dma_bo);
}
- rmesa->dma.current = NULL;
+}
+
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes)
+{
+ if (is_empty_list(&rmesa->dma.reserved))
+ return;
+
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "%s %d\n", __FUNCTION__, return_bytes);
+ rmesa->dma.current_used -= return_bytes;
+ rmesa->dma.current_vertexptr = rmesa->dma.current_used;
+}
+
+static int radeon_bo_is_idle(struct radeon_bo* bo)
+{
+ uint32_t domain;
+ int ret = radeon_bo_is_busy(bo, &domain);
+ if (ret == -EINVAL) {
+ 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;
+}
+
+void radeonReleaseDmaRegions(radeonContextPtr rmesa)
+{
+ struct radeon_dma_bo *dma_bo;
+ struct radeon_dma_bo *temp;
+ const int expire_at = ++rmesa->dma.free.expire_counter + DMA_BO_FREE_TIME;
+ const int time = rmesa->dma.free.expire_counter;
+
+ if (RADEON_DEBUG & RADEON_DMA) {
+ size_t free = 0,
+ wait = 0,
+ reserved = 0;
+ foreach(dma_bo, &rmesa->dma.free)
+ ++free;
+
+ foreach(dma_bo, &rmesa->dma.wait)
+ ++wait;
+
+ foreach(dma_bo, &rmesa->dma.reserved)
+ ++reserved;
+
+ fprintf(stderr, "%s: free %zu, wait %zu, reserved %zu, minimum_size: %zu\n",
+ __FUNCTION__, free, wait, reserved, rmesa->dma.minimum_size);
+ }
+
+ if (!rmesa->radeonScreen->driScreen->dri2.enabled) {
+ /* request updated cs processing information from kernel */
+ legacy_track_pending(rmesa->radeonScreen->bom, 0);
+ }
+ /* move waiting bos to free list.
+ wait list provides gpu time to handle data before reuse */
+ foreach_s(dma_bo, temp, &rmesa->dma.wait) {
+ if (dma_bo->expire_counter == time) {
+ WARN_ONCE("Leaking dma buffer object!\n");
+ /* 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;
+ }
+ /* free objects that are too small to be used because of large request */
+ if (dma_bo->bo->size < rmesa->dma.minimum_size) {
+ radeon_bo_unref(dma_bo->bo);
+ remove_from_list(dma_bo);
+ FREE(dma_bo);
+ continue;
+ }
+ if (!radeon_bo_is_idle(dma_bo->bo))
+ continue;
+ remove_from_list(dma_bo);
+ dma_bo->expire_counter = expire_at;
+ insert_at_tail(&rmesa->dma.free, dma_bo);
+ }
+
+ /* unmap the last dma region */
+ if (!is_empty_list(&rmesa->dma.reserved))
+ radeon_bo_unmap(first_elem(&rmesa->dma.reserved)->bo);
+ /* move reserved to wait list */
+ foreach_s(dma_bo, temp, &rmesa->dma.reserved) {
+ /* free objects that are too small to be used because of large request */
+ if (dma_bo->bo->size < rmesa->dma.minimum_size) {
+ radeon_bo_unref(dma_bo->bo);
+ remove_from_list(dma_bo);
+ FREE(dma_bo);
+ continue;
+ }
+ remove_from_list(dma_bo);
+ dma_bo->expire_counter = expire_at;
+ insert_at_tail(&rmesa->dma.wait, dma_bo);
+ }
+
+ /* free bos that have been unused for some time */
+ foreach_s(dma_bo, temp, &rmesa->dma.free) {
+ if (dma_bo->expire_counter != time)
+ break;
+ remove_from_list(dma_bo);
+ radeon_bo_unref(dma_bo->bo);
+ FREE(dma_bo);
+ }
+
}
@@ -271,11 +404,11 @@ void rcommon_flush_last_swtcl_prim( GLcontext *ctx )
struct radeon_dma *dma = &rmesa->dma;
- if (RADEON_DEBUG & DEBUG_IOCTL)
- fprintf(stderr, "%s %p\n", __FUNCTION__, dma->current);
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
dma->flush = NULL;
- if (dma->current) {
+ if (!is_empty_list(&dma->reserved)) {
GLuint current_offset = dma->current_used;
assert (dma->current_used +
@@ -297,19 +430,21 @@ rcommonAllocDmaLowVerts( radeonContextPtr rmesa, int nverts, int vsize )
{
GLuint bytes = vsize * nverts;
void *head;
-restart:
- if (!rmesa->dma.current || rmesa->dma.current_vertexptr + bytes > rmesa->dma.current->size) {
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
+ if(is_empty_list(&rmesa->dma.reserved)
+ ||rmesa->dma.current_vertexptr + bytes > first_elem(&rmesa->dma.reserved)->bo->size) {
+ if (rmesa->dma.flush) {
+ rmesa->dma.flush(rmesa->glCtx);
+ }
+
radeonRefillCurrentDmaRegion(rmesa, bytes);
+
+ return NULL;
}
if (!rmesa->dma.flush) {
- /* make sure we have enough space to use this in cmdbuf */
- rcommonEnsureCmdBufSpace(rmesa,
- rmesa->hw.max_state_size + (20*sizeof(int)),
- __FUNCTION__);
/* if cmdbuf flushed DMA restart */
- if (!rmesa->dma.current)
- goto restart;
rmesa->glCtx->Driver.NeedFlush |= FLUSH_STORED_VERTICES;
rmesa->dma.flush = rcommon_flush_last_swtcl_prim;
}
@@ -320,7 +455,7 @@ restart:
rmesa->swtcl.numverts * rmesa->swtcl.vertex_size * 4 ==
rmesa->dma.current_vertexptr );
- head = (rmesa->dma.current->ptr + rmesa->dma.current_vertexptr);
+ head = (first_elem(&rmesa->dma.reserved)->bo->ptr + rmesa->dma.current_vertexptr);
rmesa->dma.current_vertexptr += bytes;
rmesa->swtcl.numverts += nverts;
return head;
@@ -330,18 +465,17 @@ void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs )
{
radeonContextPtr radeon = RADEON_CONTEXT( ctx );
int i;
+ if (RADEON_DEBUG & RADEON_IOCTL)
+ fprintf(stderr, "%s\n", __FUNCTION__);
if (radeon->dma.flush) {
radeon->dma.flush(radeon->glCtx);
}
- if (radeon->tcl.elt_dma_bo) {
- radeon_bo_unref(radeon->tcl.elt_dma_bo);
- radeon->tcl.elt_dma_bo = NULL;
- }
for (i = 0; i < radeon->tcl.aos_count; i++) {
if (radeon->tcl.aos[i].bo) {
radeon_bo_unref(radeon->tcl.aos[i].bo);
radeon->tcl.aos[i].bo = NULL;
+
}
}
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_dma.h b/src/mesa/drivers/dri/radeon/radeon_dma.h
index 06e388fc1d..74e653fd18 100644
--- a/src/mesa/drivers/dri/radeon/radeon_dma.h
+++ b/src/mesa/drivers/dri/radeon/radeon_dma.h
@@ -33,20 +33,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#ifndef RADEON_DMA_H
#define RADEON_DMA_H
-void radeonEmitVec8(uint32_t *out, GLvoid * data, int stride, int count);
-void radeonEmitVec12(uint32_t *out, GLvoid * data, int stride, int count);
+void radeonEmitVec4(uint32_t *out, const GLvoid * data, int stride, int count);
+void radeonEmitVec8(uint32_t *out, const GLvoid * data, int stride, int count);
+void radeonEmitVec12(uint32_t *out, const GLvoid * data, int stride, int count);
+void radeonEmitVec16(uint32_t *out, const GLvoid * data, int stride, int count);
void rcommon_emit_vector(GLcontext * ctx, struct radeon_aos *aos,
- GLvoid * data, int size, int stride, int count);
+ const GLvoid * data, int size, int stride, int count);
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes);
void radeonRefillCurrentDmaRegion(radeonContextPtr rmesa, int size);
+void radeon_init_dma(radeonContextPtr rmesa);
+void radeonReturnDmaRegion(radeonContextPtr rmesa, int return_bytes);
void radeonAllocDmaRegion(radeonContextPtr rmesa,
struct radeon_bo **pbo, int *poffset,
int bytes, int alignment);
-void radeonReleaseDmaRegion(radeonContextPtr rmesa);
+void radeonReleaseDmaRegions(radeonContextPtr rmesa);
void rcommon_flush_last_swtcl_prim(GLcontext *ctx);
void *rcommonAllocDmaLowVerts(radeonContextPtr rmesa, int nverts, int vsize);
+void radeonFreeDmaRegions(radeonContextPtr rmesa);
void radeonReleaseArrays( GLcontext *ctx, GLuint newinputs );
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_fbo.c b/src/mesa/drivers/dri/radeon/radeon_fbo.c
index f28efa33e9..7ac53ec0ca 100644
--- a/src/mesa/drivers/dri/radeon/radeon_fbo.c
+++ b/src/mesa/drivers/dri/radeon/radeon_fbo.c
@@ -35,11 +35,12 @@
#include "main/context.h"
#include "main/texformat.h"
#include "main/texrender.h"
+#include "drivers/common/meta.h"
#include "radeon_common.h"
#include "radeon_mipmap_tree.h"
-#define FILE_DEBUG_FLAG DEBUG_TEXTURE
+#define FILE_DEBUG_FLAG RADEON_TEXTURE
#define DBG(...) do { \
if (RADEON_DEBUG & FILE_DEBUG_FLAG) \
_mesa_printf(__VA_ARGS__); \
@@ -177,30 +178,21 @@ radeon_alloc_renderbuffer_storage(GLcontext * ctx, struct gl_renderbuffer *rb,
width, height);
}
else {
- uint32_t size = width * height * cpp;
+ uint32_t size;
uint32_t pitch = ((cpp * width + 63) & ~63) / cpp;
fprintf(stderr,"Allocating %d x %d radeon RBO (pitch %d)\n", width,
height, pitch);
+ size = pitch * height * cpp;
rrb->pitch = pitch * cpp;
rrb->cpp = cpp;
-#ifdef RADEON_DEBUG_BO
- rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
- 0,
- size,
- 0,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "Radeon RBO");
-#else
rrb->bo = radeon_bo_open(radeon->radeonScreen->bom,
0,
size,
0,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
rb->Width = width;
rb->Height = height;
return GL_TRUE;
@@ -291,7 +283,7 @@ radeon_create_renderbuffer(GLenum format, __DRIdrawablePrivate *driDrawPriv)
rrb->base.RedBits = 8;
rrb->base.GreenBits = 8;
rrb->base.BlueBits = 8;
- rrb->base.AlphaBits = 8;
+ rrb->base.AlphaBits = 0;
rrb->base.DataType = GL_UNSIGNED_BYTE;
break;
case GL_RGBA8:
@@ -407,7 +399,7 @@ restart:
rrb->cpp = 2;
rrb->base._ActualFormat = GL_RGB5;
rrb->base._BaseFormat = GL_RGB;
- rrb->base.DataType = GL_UNSIGNED_SHORT;
+ rrb->base.DataType = GL_UNSIGNED_BYTE;
DBG("Render to RGB5 texture OK\n");
}
else if (texImage->TexFormat == &_mesa_texformat_argb1555) {
@@ -581,14 +573,6 @@ radeon_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
}
-static void
-radeon_blit_framebuffer(GLcontext *ctx,
- GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
- GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLbitfield mask, GLenum filter)
-{
-}
-
void radeon_fbo_init(struct radeon_context *radeon)
{
radeon->glCtx->Driver.NewFramebuffer = radeon_new_framebuffer;
@@ -599,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 = radeon_blit_framebuffer;
+ radeon->glCtx->Driver.BlitFramebuffer = _mesa_meta_BlitFramebuffer;
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.c b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
index a5e4df7941..a0106d00fa 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.c
@@ -113,7 +113,7 @@ void radeonSetUpAtomList( r100ContextPtr rmesa )
insert_at_tail(&rmesa->radeon.hw.atomlist, &rmesa->hw.glt);
}
-void radeonEmitScissor(r100ContextPtr rmesa)
+static void radeonEmitScissor(r100ContextPtr rmesa)
{
BATCH_LOCALS(&rmesa->radeon);
if (!rmesa->radeon.radeonScreen->kernel_mm) {
@@ -127,8 +127,8 @@ void radeonEmitScissor(r100ContextPtr rmesa)
OUT_BATCH((rmesa->radeon.state.scissor.rect.y1 << 16) |
rmesa->radeon.state.scissor.rect.x1);
OUT_BATCH(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
- OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2 - 1) << 16) |
- (rmesa->radeon.state.scissor.rect.x2 - 1));
+ OUT_BATCH(((rmesa->radeon.state.scissor.rect.y2) << 16) |
+ (rmesa->radeon.state.scissor.rect.x2));
END_BATCH();
} else {
BEGIN_BATCH(2);
@@ -200,7 +200,7 @@ void radeonFlushElts( GLcontext *ctx )
uint32_t *cmd = (uint32_t *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_start);
int dwords = (rmesa->radeon.cmdbuf.cs->section_ndw - rmesa->radeon.cmdbuf.cs->section_cdw);
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
assert( rmesa->radeon.dma.flush == radeonFlushElts );
@@ -236,7 +236,7 @@ void radeonFlushElts( GLcontext *ctx )
END_BATCH();
- if (RADEON_DEBUG & DEBUG_SYNC) {
+ if (RADEON_DEBUG & RADEON_SYNC) {
fprintf(stderr, "%s: Syncing\n", __FUNCTION__);
radeonFinish( rmesa->radeon.glCtx );
}
@@ -252,7 +252,7 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
int align_min_nr;
BATCH_LOCALS(&rmesa->radeon);
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s %d prim %x\n", __FUNCTION__, min_nr, primitive);
assert((primitive & RADEON_CP_VC_CNTL_PRIM_WALK_IND));
@@ -273,7 +273,7 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
} else {
OUT_BATCH(rmesa->ioctl.vertex_offset);
}
- OUT_BATCH(0xffff);
+ OUT_BATCH(rmesa->ioctl.vertex_max);
OUT_BATCH(vertex_format);
OUT_BATCH(primitive |
RADEON_CP_VC_CNTL_PRIM_WALK_IND |
@@ -296,7 +296,7 @@ GLushort *radeonAllocEltsOpenEnded( r100ContextPtr rmesa,
retval = (GLushort *)(rmesa->radeon.cmdbuf.cs->packets + rmesa->tcl.elt_cmd_offset);
- if (RADEON_DEBUG & DEBUG_PRIMS)
+ if (RADEON_DEBUG & RADEON_RENDER)
fprintf(stderr, "%s: header prim %x \n",
__FUNCTION__, primitive);
@@ -318,7 +318,7 @@ void radeonEmitVertexAOS( r100ContextPtr rmesa,
#else
BATCH_LOCALS(&rmesa->radeon);
- if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_IOCTL))
+ if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_IOCTL))
fprintf(stderr, "%s: vertex_size 0x%x offset 0x%x \n",
__FUNCTION__, vertex_size, offset);
@@ -342,6 +342,7 @@ void radeonEmitAOS( r100ContextPtr rmesa,
rmesa->ioctl.bo = rmesa->radeon.tcl.aos[0].bo;
rmesa->ioctl.vertex_offset =
(rmesa->radeon.tcl.aos[0].offset + offset * rmesa->radeon.tcl.aos[0].stride * 4);
+ rmesa->ioctl.vertex_max = rmesa->radeon.tcl.aos[0].count;
#else
BATCH_LOCALS(&rmesa->radeon);
uint32_t voffset;
@@ -349,7 +350,7 @@ void radeonEmitAOS( r100ContextPtr rmesa,
int sz = 1 + (nr >> 1) * 3 + (nr & 1) * 2;
int i;
- if (RADEON_DEBUG & DEBUG_IOCTL)
+ if (RADEON_DEBUG & RADEON_IOCTL)
fprintf(stderr, "%s\n", __FUNCTION__);
BEGIN_BATCH(sz+2+(nr * 2));
@@ -574,7 +575,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
GLuint color_mask = 0;
GLuint orig_mask = mask;
- if ( RADEON_DEBUG & DEBUG_IOCTL ) {
+ if ( RADEON_DEBUG & RADEON_IOCTL ) {
fprintf( stderr, "radeonClear\n");
}
@@ -610,7 +611,7 @@ static void radeonClear( GLcontext *ctx, GLbitfield mask )
}
if ( mask ) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "%s: swrast clear, mask: %x\n", __FUNCTION__, mask);
_swrast_Clear( ctx, mask );
}
diff --git a/src/mesa/drivers/dri/radeon/radeon_ioctl.h b/src/mesa/drivers/dri/radeon/radeon_ioctl.h
index 18805d4c57..deb53ae313 100644
--- a/src/mesa/drivers/dri/radeon/radeon_ioctl.h
+++ b/src/mesa/drivers/dri/radeon/radeon_ioctl.h
@@ -132,16 +132,18 @@ static INLINE int RADEON_DB_STATECHANGE(r100ContextPtr rmesa,
* r200EmitState is called from within r200EmitVbufPrim and r200FlushElts.
*/
#if RADEON_OLD_PACKETS
-#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
+#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2))+nr*2)
#define VERT_AOS_BUFSZ (0)
#define ELTS_BUFSZ(nr) (24 + nr * 2)
-#define VBUF_BUFSZ (6 * sizeof(int))
+#define VBUF_BUFSZ (8)
#else
-#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2)) * sizeof(int))
-#define VERT_AOS_BUFSZ (5 * sizeof(int))
+#define AOS_BUFSZ(nr) ((3 + ((nr / 2) * 3) + ((nr & 1) * 2) + nr*2))
+#define VERT_AOS_BUFSZ (5)
#define ELTS_BUFSZ(nr) (16 + nr * 2)
-#define VBUF_BUFSZ (4 * sizeof(int))
+#define VBUF_BUFSZ (4)
#endif
+#define SCISSOR_BUFSZ (8)
+#define INDEX_BUFSZ (7)
static inline uint32_t cmdpacket3(int cmd_type)
diff --git a/src/mesa/drivers/dri/radeon/radeon_lighting.c b/src/mesa/drivers/dri/radeon/radeon_lighting.c
index ac3b94e4a6..ba444f2b10 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lighting.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lighting.c
@@ -195,7 +195,7 @@ void radeonUpdateMaterial( GLcontext *ctx )
if (ctx->Light.ColorMaterialEnabled)
mask &= ~ctx->Light.ColorMaterialBitmask;
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -234,7 +234,7 @@ void radeonUpdateMaterial( GLcontext *ctx )
check_twoside_fallback( ctx );
update_global_ambient( ctx );
}
- else if (RADEON_DEBUG & (DEBUG_PRIMS|DEBUG_STATE))
+ else if (RADEON_DEBUG & (RADEON_PRIMS|DEBUG_STATE))
fprintf(stderr, "%s: Elided noop material call\n", __FUNCTION__);
}
@@ -624,7 +624,7 @@ static void radeonLightingSpaceChange( GLcontext *ctx )
GLboolean tmp;
RADEON_STATECHANGE( rmesa, tcl );
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s %d\n", __FUNCTION__, ctx->_NeedEyeCoords);
if (ctx->_NeedEyeCoords)
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.c b/src/mesa/drivers/dri/radeon/radeon_lock.c
index 5774f7ebcf..02de8e5fd1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.c
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.c
@@ -85,11 +85,35 @@ void radeonGetLock(radeonContextPtr rmesa, GLuint flags)
}
rmesa->vtbl.get_lock(rmesa);
-
- rmesa->lost_context = GL_TRUE;
}
-
-void radeon_lock_hardware(radeonContextPtr radeon)
+#ifndef NDEBUG
+struct lock_debug {
+ const char* function;
+ const char* file;
+ int line;
+};
+
+static struct lock_debug ldebug = {0};
+#endif
+
+#if 0
+/** TODO: use atomic operations for reference counting **/
+/** gcc 4.2 has builtin functios for this **/
+#define ATOMIC_INC_AND_FETCH(atomic) __sync_add_and_fetch(&atomic, 1)
+#define ATOMIC_DEC_AND_FETCH(atomic) __sync_sub_and_fetch(&atomic, 1)
+#else
+#define ATOMIC_INC_AND_FETCH(atomic) (++atomic)
+#define ATOMIC_DEC_AND_FETCH(atomic) (--atomic)
+#endif
+
+
+void radeon_lock_hardware(radeonContextPtr radeon
+#ifndef NDEBUG
+ ,const char* function
+ ,const char* file
+ ,const int line
+#endif
+ )
{
char ret = 0;
struct radeon_framebuffer *rfb = NULL;
@@ -104,16 +128,39 @@ void radeon_lock_hardware(radeonContextPtr radeon)
}
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ if (ATOMIC_INC_AND_FETCH(radeon->dri.hwLockCount) > 1)
+ {
+#ifndef NDEBUG
+ if ( RADEON_DEBUG & RADEON_SANITY )
+ fprintf(stderr, "*** %d times of recursive call to %s ***\n"
+ "Original call was from %s (file: %s line: %d)\n"
+ "Now call is coming from %s (file: %s line: %d)\n"
+ , radeon->dri.hwLockCount, __FUNCTION__
+ , ldebug.function, ldebug.file, ldebug.line
+ , function, file, line
+ );
+#endif
+ return;
+ }
DRM_CAS(radeon->dri.hwLock, radeon->dri.hwContext,
(DRM_LOCK_HELD | radeon->dri.hwContext), ret );
if (ret)
radeonGetLock(radeon, 0);
+#ifndef NDEBUG
+ ldebug.function = function;
+ ldebug.file = file;
+ ldebug.line = line;
+#endif
}
}
void radeon_unlock_hardware(radeonContextPtr radeon)
{
if (!radeon->radeonScreen->driScreen->dri2.enabled) {
+ if (ATOMIC_DEC_AND_FETCH(radeon->dri.hwLockCount) > 0)
+ {
+ return;
+ }
DRM_UNLOCK( radeon->dri.fd,
radeon->dri.hwLock,
radeon->dri.hwContext );
diff --git a/src/mesa/drivers/dri/radeon/radeon_lock.h b/src/mesa/drivers/dri/radeon/radeon_lock.h
index 2817709eed..da5a5b4371 100644
--- a/src/mesa/drivers/dri/radeon/radeon_lock.h
+++ b/src/mesa/drivers/dri/radeon/radeon_lock.h
@@ -48,12 +48,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
extern void radeonGetLock(radeonContextPtr rmesa, GLuint flags);
-void radeon_lock_hardware(radeonContextPtr rmesa);
+void radeon_lock_hardware(radeonContextPtr rmesa
+#ifndef NDEBUG
+ ,const char* function
+ ,const char* file
+ ,const int line
+#endif
+ );
void radeon_unlock_hardware(radeonContextPtr rmesa);
/* Lock the hardware and validate our state.
*/
+#ifdef NDEBUG
#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa)
+#else
+#define LOCK_HARDWARE( rmesa ) radeon_lock_hardware(rmesa, __FUNCTION__, __FILE__, __LINE__)
+#endif
#define UNLOCK_HARDWARE( rmesa ) radeon_unlock_hardware(rmesa)
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
index 7c6ea0530e..08e1c5d00d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_arrays.c
@@ -56,7 +56,7 @@ static void emit_vecfog(GLcontext *ctx, struct radeon_aos *aos,
int size = 1;
radeonContextPtr rmesa = RADEON_CONTEXT(ctx);
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d\n",
__FUNCTION__, count, stride);
@@ -87,7 +87,7 @@ static void emit_vecfog(GLcontext *ctx, struct radeon_aos *aos,
static void emit_s0_vec(uint32_t *out, GLvoid *data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d\n",
__FUNCTION__, count, stride);
@@ -103,7 +103,7 @@ static void emit_stq_vec(uint32_t *out, GLvoid *data, int stride, int count)
{
int i;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s count %d stride %d\n",
__FUNCTION__, count, stride);
@@ -126,7 +126,7 @@ static void emit_tex_vector(GLcontext *ctx, struct radeon_aos *aos,
int emitsize;
uint32_t *out;
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
fprintf(stderr, "%s %d/%d\n", __FUNCTION__, count, size);
switch (size) {
@@ -188,7 +188,7 @@ void radeonEmitArrays( GLcontext *ctx, GLuint inputs )
GLuint vtx, unit;
#if 0
- if (RADEON_DEBUG & DEBUG_VERTS)
+ if (RADEON_DEBUG & RADEON_VERTS)
_tnl_print_vert_flags( __FUNCTION__, inputs );
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
index 034cda8a65..515783135d 100644
--- a/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
+++ b/src/mesa/drivers/dri/radeon/radeon_maos_vbtmp.h
@@ -54,8 +54,7 @@ static void TAG(emit)( GLcontext *ctx,
union emit_union *v = (union emit_union *)dest;
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf(stderr, "%s\n", __FUNCTION__);
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE, "%s\n", __FUNCTION__);
coord = (GLuint (*)[4])VB->ObjPtr->data;
coord_stride = VB->ObjPtr->stride;
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
index f04a07fecd..38db305e2a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.c
@@ -90,16 +90,18 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
GLuint face, GLuint level, GLuint* curOffset)
{
radeon_mipmap_level *lvl = &mt->levels[level];
- uint32_t row_align = rmesa->texture_row_align - 1;
+ uint32_t row_align;
/* Find image size in bytes */
if (mt->compressed) {
/* TODO: Is this correct? Need test cases for compressed textures! */
- lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
+ row_align = rmesa->texture_compressed_row_align - 1;
+ lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = radeon_compressed_texture_size(mt->radeon->glCtx,
lvl->width, lvl->height, lvl->depth, mt->compressed);
} else if (mt->target == GL_TEXTURE_RECTANGLE_NV) {
- lvl->rowstride = (lvl->width * mt->bpp + 63) & ~63;
+ row_align = rmesa->texture_rect_row_align - 1;
+ lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = lvl->rowstride * lvl->height;
} else if (mt->tilebits & RADEON_TXO_MICRO_TILE) {
/* tile pattern is 16 bytes x2. mipmaps stay 32 byte aligned,
@@ -108,6 +110,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
lvl->rowstride = (lvl->width * mt->bpp * 2 + 31) & ~31;
lvl->size = lvl->rowstride * ((lvl->height + 1) / 2) * lvl->depth;
} else {
+ row_align = rmesa->texture_row_align - 1;
lvl->rowstride = (lvl->width * mt->bpp + row_align) & ~row_align;
lvl->size = lvl->rowstride * lvl->height * lvl->depth;
}
@@ -118,7 +121,7 @@ static void compute_tex_image_offset(radeonContextPtr rmesa, radeon_mipmap_tree
lvl->faces[face].offset = *curOffset;
*curOffset += lvl->size;
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr,
"level %d, face %d: rs:%d %dx%d at %d\n",
level, face, lvl->rowstride, lvl->width, lvl->height, lvl->faces[face].offset);
@@ -187,13 +190,14 @@ static void calculate_miptree_layout_r300(radeonContextPtr rmesa, radeon_mipmap_
* Create a new mipmap tree, calculate its layout and allocate memory.
*/
radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
- GLenum target, GLuint firstLevel, GLuint lastLevel,
+ GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
GLuint width0, GLuint height0, GLuint depth0,
GLuint bpp, GLuint tilebits, GLuint compressed)
{
radeon_mipmap_tree *mt = CALLOC_STRUCT(_radeon_mipmap_tree);
mt->radeon = rmesa;
+ mt->internal_format = internal_format;
mt->refcount = 1;
mt->t = t;
mt->target = target;
@@ -212,18 +216,10 @@ radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *
else
calculate_miptree_layout_r100(rmesa, mt);
-#ifdef RADEON_DEBUG_BO
- mt->bo = radeon_bo_open(rmesa->radeonScreen->bom,
- 0, mt->totalsize, 1024,
- RADEON_GEM_DOMAIN_VRAM,
- 0,
- "MIPMAP TREE");
-#else
mt->bo = radeon_bo_open(rmesa->radeonScreen->bom,
0, mt->totalsize, 1024,
RADEON_GEM_DOMAIN_VRAM,
0);
-#endif /* RADEON_DEBUG_BO */
return mt;
}
@@ -323,7 +319,8 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
if (face >= mt->faces || level < mt->firstLevel || level > mt->lastLevel)
return GL_FALSE;
- if (texImage->IsCompressed != mt->compressed)
+ if (texImage->InternalFormat != mt->internal_format ||
+ texImage->IsCompressed != mt->compressed)
return GL_FALSE;
if (!texImage->IsCompressed &&
@@ -363,8 +360,8 @@ GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_textu
mt->width0 == firstImage->Width &&
mt->height0 == firstImage->Height &&
mt->depth0 == firstImage->Depth &&
- mt->bpp == firstImage->TexFormat->TexelBytes &&
- mt->compressed == compressed);
+ mt->compressed == compressed &&
+ (!mt->compressed ? (mt->bpp == firstImage->TexFormat->TexelBytes) : 1));
}
@@ -373,9 +370,9 @@ GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_textu
* given image in the given position.
*/
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
- struct gl_texture_image *texImage, GLuint face, GLuint level)
+ radeon_texture_image *image, GLuint face, GLuint level)
{
- GLuint compressed = texImage->IsCompressed ? texImage->TexFormat->MesaFormat : 0;
+ GLuint compressed = image->base.IsCompressed ? image->base.TexFormat->MesaFormat : 0;
GLuint numfaces = 1;
GLuint firstLevel, lastLevel;
@@ -389,9 +386,10 @@ void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
return;
t->mt = radeon_miptree_create(rmesa, t, t->base.Target,
+ image->base.InternalFormat,
firstLevel, lastLevel,
- texImage->Width, texImage->Height, texImage->Depth,
- texImage->TexFormat->TexelBytes, t->tile_bits, compressed);
+ image->base.Width, image->base.Height, image->base.Depth,
+ image->base.TexFormat->TexelBytes, t->tile_bits, compressed);
}
/* Although we use the image_offset[] array to store relative offsets
diff --git a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
index 7ece688493..db28252da3 100644
--- a/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
+++ b/src/mesa/drivers/dri/radeon/radeon_mipmap_tree.h
@@ -67,6 +67,7 @@ struct _radeon_mipmap_tree {
GLuint totalsize; /** total size of the miptree, in bytes */
GLenum target; /** GL_TEXTURE_xxx */
+ GLenum internal_format;
GLuint faces; /** # of faces: 6 for cubemaps, 1 otherwise */
GLuint firstLevel; /** First mip level stored in this mipmap tree */
GLuint lastLevel; /** Last mip level stored in this mipmap tree */
@@ -83,7 +84,7 @@ struct _radeon_mipmap_tree {
};
radeon_mipmap_tree* radeon_miptree_create(radeonContextPtr rmesa, radeonTexObj *t,
- GLenum target, GLuint firstLevel, GLuint lastLevel,
+ GLenum target, GLenum internal_format, GLuint firstLevel, GLuint lastLevel,
GLuint width0, GLuint height0, GLuint depth0,
GLuint bpp, GLuint tilebits, GLuint compressed);
void radeon_miptree_reference(radeon_mipmap_tree *mt);
@@ -93,7 +94,7 @@ GLboolean radeon_miptree_matches_image(radeon_mipmap_tree *mt,
struct gl_texture_image *texImage, GLuint face, GLuint level);
GLboolean radeon_miptree_matches_texture(radeon_mipmap_tree *mt, struct gl_texture_object *texObj);
void radeon_try_alloc_miptree(radeonContextPtr rmesa, radeonTexObj *t,
- struct gl_texture_image *texImage, GLuint face, GLuint level);
+ radeon_texture_image *texImage, GLuint face, GLuint level);
GLuint radeon_miptree_image_offset(radeon_mipmap_tree *mt,
GLuint face, GLuint level);
void radeon_miptree_depth_offsets(radeon_mipmap_tree *mt, GLuint level, GLuint *offsets);
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.c b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
new file mode 100644
index 0000000000..b79d864ba2
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright © 2008-2009 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Maciej Cencora <m.cencora@gmail.com>
+ *
+ */
+#include "radeon_common.h"
+#include "radeon_queryobj.h"
+#include "radeon_debug.h"
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+
+static int radeonQueryIsFlushed(GLcontext *ctx, struct gl_query_object *q)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_query_object *tmp, *query = (struct radeon_query_object *)q;
+
+ foreach(tmp, &radeon->query.not_flushed_head) {
+ if (tmp == query) {
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+static void radeonQueryGetResult(GLcontext *ctx, struct gl_query_object *q)
+{
+ struct radeon_query_object *query = (struct radeon_query_object *)q;
+ uint32_t *result;
+ int i;
+
+ radeon_print(RADEON_STATE, RADEON_VERBOSE,
+ "%s: query id %d, result %d\n",
+ __FUNCTION__, query->Base.Id, (int) query->Base.Result);
+
+ radeon_bo_map(query->bo, GL_FALSE);
+
+ result = query->bo->ptr;
+
+ query->Base.Result = 0;
+ for (i = 0; i < query->curr_offset/sizeof(uint32_t); ++i) {
+ query->Base.Result += result[i];
+ radeon_print(RADEON_STATE, RADEON_TRACE, "result[%d] = %d\n", i, result[i]);
+ }
+
+ radeon_bo_unmap(query->bo);
+}
+
+static struct gl_query_object * radeonNewQueryObject(GLcontext *ctx, GLuint id)
+{
+ struct radeon_query_object *query;
+
+ query = _mesa_calloc(sizeof(struct radeon_query_object));
+
+ query->Base.Id = id;
+ query->Base.Result = 0;
+ query->Base.Active = GL_FALSE;
+ query->Base.Ready = GL_TRUE;
+
+ radeon_print(RADEON_STATE, RADEON_VERBOSE,"%s: query id %d\n", __FUNCTION__, query->Base.Id);
+
+ return &query->Base;
+}
+
+static void radeonDeleteQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+ struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+ if (query->bo) {
+ radeon_bo_unref(query->bo);
+ }
+
+ _mesa_free(query);
+}
+
+static void radeonWaitQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+ struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+ /* If the cmdbuf with packets for this query hasn't been flushed yet, do it now */
+ if (!radeonQueryIsFlushed(ctx, q))
+ ctx->Driver.Flush(ctx);
+
+ radeon_print(RADEON_STATE, RADEON_VERBOSE, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, q->Id, query->bo, query->curr_offset);
+
+ radeonQueryGetResult(ctx, q);
+
+ query->Base.Ready = GL_TRUE;
+}
+
+
+static void radeonBeginQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_query_object *query = (struct radeon_query_object *)q;
+
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+ assert(radeon->query.current == NULL);
+
+ if (radeon->dma.flush)
+ radeon->dma.flush(radeon->glCtx);
+
+ if (!query->bo) {
+ query->bo = radeon_bo_open(radeon->radeonScreen->bom, 0, RADEON_QUERY_PAGE_SIZE, RADEON_QUERY_PAGE_SIZE, RADEON_GEM_DOMAIN_GTT, 0);
+ }
+ query->curr_offset = 0;
+
+ radeon->query.current = query;
+
+ radeon->query.queryobj.dirty = GL_TRUE;
+ radeon->hw.is_dirty = GL_TRUE;
+ insert_at_tail(&radeon->query.not_flushed_head, query);
+
+}
+
+void radeonEmitQueryEnd(GLcontext *ctx)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_query_object *query = radeon->query.current;
+
+ if (!query)
+ return;
+
+ if (query->emitted_begin == GL_FALSE)
+ return;
+
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d, bo %p, offset %d\n", __FUNCTION__, query->Base.Id, query->bo, query->curr_offset);
+
+ radeon_cs_space_check_with_bo(radeon->cmdbuf.cs,
+ query->bo,
+ 0, RADEON_GEM_DOMAIN_GTT);
+
+ radeon->vtbl.emit_query_finish(radeon);
+}
+
+static void radeonEndQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+ radeon_print(RADEON_STATE, RADEON_NORMAL, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+ if (radeon->dma.flush)
+ radeon->dma.flush(radeon->glCtx);
+ radeonEmitQueryEnd(ctx);
+
+ radeon->query.current = NULL;
+}
+
+static void radeonCheckQuery(GLcontext *ctx, struct gl_query_object *q)
+{
+ radeon_print(RADEON_STATE, RADEON_TRACE, "%s: query id %d\n", __FUNCTION__, q->Id);
+
+#ifdef DRM_RADEON_GEM_BUSY
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+
+ if (radeon->radeonScreen->kernel_mm) {
+ struct radeon_query_object *query = (struct radeon_query_object *)q;
+ uint32_t domain;
+
+ /* Need to perform a flush, as per ARB_occlusion_query spec */
+ if (!radeonQueryIsFlushed(ctx, q)) {
+ ctx->Driver.Flush(ctx);
+ }
+
+ if (radeon_bo_is_busy(query->bo, &domain) == 0) {
+ radeonQueryGetResult(ctx, q);
+ query->Base.Ready = GL_TRUE;
+ }
+ } else {
+ radeonWaitQuery(ctx, q);
+ }
+#else
+ radeonWaitQuery(ctx, q);
+#endif
+}
+
+void radeonInitQueryObjFunctions(struct dd_function_table *functions)
+{
+ functions->NewQueryObject = radeonNewQueryObject;
+ functions->DeleteQuery = radeonDeleteQuery;
+ functions->BeginQuery = radeonBeginQuery;
+ functions->EndQuery = radeonEndQuery;
+ functions->CheckQuery = radeonCheckQuery;
+ functions->WaitQuery = radeonWaitQuery;
+}
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ struct radeon_query_object *query = radeon->query.current;
+
+ if (!query || query->emitted_begin)
+ return 0;
+ return atom->cmd_size;
+}
+
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ radeonContextPtr radeon = RADEON_CONTEXT(ctx);
+ BATCH_LOCALS(radeon);
+ int dwords;
+
+ dwords = (*atom->check) (ctx, atom);
+
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
+ OUT_BATCH_TABLE(atom->cmd, dwords);
+ END_BATCH();
+
+ radeon->query.current->emitted_begin = GL_TRUE;
+}
diff --git a/src/mesa/drivers/dri/radeon/radeon_queryobj.h b/src/mesa/drivers/dri/radeon/radeon_queryobj.h
new file mode 100644
index 0000000000..19374dc76b
--- /dev/null
+++ b/src/mesa/drivers/dri/radeon/radeon_queryobj.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2008 Maciej Cencora <m.cencora@gmail.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ * Authors:
+ * Maciej Cencora <m.cencora@gmail.com>
+ *
+ */
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "radeon_common_context.h"
+
+extern void radeonEmitQueryBegin(GLcontext *ctx);
+extern void radeonEmitQueryEnd(GLcontext *ctx);
+
+extern void radeonInitQueryObjFunctions(struct dd_function_table *functions);
+
+#define RADEON_QUERY_PAGE_SIZE 4096
+
+int radeon_check_query_active(GLcontext *ctx, struct radeon_state_atom *atom);
+void radeon_emit_queryobj(GLcontext *ctx, struct radeon_state_atom *atom);
+
+static inline void radeon_init_query_stateobj(radeonContextPtr radeon, int SZ)
+{
+ radeon->query.queryobj.cmd_size = (SZ);
+ radeon->query.queryobj.cmd = (uint32_t*)CALLOC((SZ) * sizeof(uint32_t));
+ radeon->query.queryobj.name = "queryobj";
+ radeon->query.queryobj.idx = 0;
+ radeon->query.queryobj.check = radeon_check_query_active;
+ radeon->query.queryobj.dirty = GL_FALSE;
+ radeon->query.queryobj.emit = radeon_emit_queryobj;
+
+ radeon->hw.max_state_size += (SZ);
+ insert_at_tail(&radeon->hw.atomlist, &radeon->query.queryobj);
+}
+
diff --git a/src/mesa/drivers/dri/radeon/radeon_sanity.c b/src/mesa/drivers/dri/radeon/radeon_sanity.c
index bbed838b59..1ab570f507 100644
--- a/src/mesa/drivers/dri/radeon/radeon_sanity.c
+++ b/src/mesa/drivers/dri/radeon/radeon_sanity.c
@@ -44,11 +44,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#define MORE_VERBOSE 1
#if MORE_VERBOSE
-#define VERBOSE (RADEON_DEBUG & DEBUG_VERBOSE)
+#define VERBOSE (RADEON_DEBUG & RADEON_VERBOSE)
#define NORMAL (1)
#else
#define VERBOSE 0
-#define NORMAL (RADEON_DEBUG & DEBUG_VERBOSE)
+#define NORMAL (RADEON_DEBUG & RADEON_VERBOSE)
#endif
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c
index 290ef2394d..573eb6c9c1 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.c
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.c
@@ -48,18 +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_fragprog.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 */
@@ -83,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
@@ -110,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
@@ -148,7 +147,10 @@ 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
/* TODO: integrate these into xmlpool.h! */
#define DRI_CONF_MAX_TEXTURE_IMAGE_UNITS(def,min,max) \
@@ -218,31 +220,7 @@ static const GLuint __driNConfigOptions = 17;
extern const struct dri_extension gl_20_extension[];
-#ifndef RADEON_DEBUG
-
-static const struct dri_debug_control debug_control[] = {
- {"fall", DEBUG_FALLBACKS},
- {"tex", DEBUG_TEXTURE},
- {"ioctl", DEBUG_IOCTL},
- {"prim", DEBUG_PRIMS},
- {"vert", DEBUG_VERTS},
- {"state", DEBUG_STATE},
- {"code", DEBUG_CODEGEN},
- {"vfmt", DEBUG_VFMT},
- {"vtxf", DEBUG_VFMT},
- {"verb", DEBUG_VERBOSE},
- {"dri", DEBUG_DRI},
- {"dma", DEBUG_DMA},
- {"san", DEBUG_SANITY},
- {"sync", DEBUG_SYNC},
- {"pix", DEBUG_PIXEL},
- {"mem", DEBUG_MEMORY},
- {"allmsg", ~DEBUG_SYNC}, /* avoid the term "sync" because the parser uses strstr */
- {NULL, 0}
-};
-#endif /* RADEON_DEBUG */
-
-#endif /* RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) */
+#endif
extern const struct dri_extension card_extensions[];
extern const struct dri_extension mm_extensions[];
@@ -257,7 +235,7 @@ radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value)
struct drm_radeon_info info = { 0 };
if (sPriv->drm_version.major >= 2) {
- info.value = (uint64_t)value;
+ info.value = (uint64_t)(uintptr_t)value;
switch (param) {
case RADEON_PARAM_DEVICE_ID:
info.request = RADEON_INFO_DEVICE_ID;
@@ -265,6 +243,9 @@ radeonGetParam(__DRIscreenPrivate *sPriv, int param, void *value)
case RADEON_PARAM_NUM_GB_PIPES:
info.request = RADEON_INFO_NUM_GB_PIPES;
break;
+ case RADEON_PARAM_NUM_Z_PIPES:
+ info.request = RADEON_INFO_NUM_Z_PIPES;
+ break;
default:
return -EINVAL;
}
@@ -356,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,
@@ -369,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,
@@ -389,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,
@@ -402,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 */
@@ -851,10 +832,19 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
screen->chip_family = CHIP_FAMILY_RS780;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
+ case PCI_CHIP_RS880_9710:
+ case PCI_CHIP_RS880_9711:
+ case PCI_CHIP_RS880_9712:
+ case PCI_CHIP_RS880_9713:
+ case PCI_CHIP_RS880_9714:
+ screen->chip_family = CHIP_FAMILY_RS880;
+ screen->chip_flags = RADEON_CHIPSET_TCL;
+ break;
case PCI_CHIP_RV770_9440:
case PCI_CHIP_RV770_9441:
case PCI_CHIP_RV770_9442:
+ case PCI_CHIP_RV770_9443:
case PCI_CHIP_RV770_9444:
case PCI_CHIP_RV770_9446:
case PCI_CHIP_RV770_944A:
@@ -876,11 +866,14 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
+ case PCI_CHIP_RV730_9480:
case PCI_CHIP_RV730_9487:
+ case PCI_CHIP_RV730_9488:
case PCI_CHIP_RV730_9489:
case PCI_CHIP_RV730_948F:
case PCI_CHIP_RV730_9490:
case PCI_CHIP_RV730_9491:
+ case PCI_CHIP_RV730_9495:
case PCI_CHIP_RV730_9498:
case PCI_CHIP_RV730_949C:
case PCI_CHIP_RV730_949E:
@@ -897,15 +890,19 @@ static int radeon_set_screen_flags(radeonScreenPtr screen, int device_id)
case PCI_CHIP_RV710_9552:
case PCI_CHIP_RV710_9553:
case PCI_CHIP_RV710_9555:
+ case PCI_CHIP_RV710_9557:
screen->chip_family = CHIP_FAMILY_RV710;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
case PCI_CHIP_RV740_94A0:
case PCI_CHIP_RV740_94A1:
+ case PCI_CHIP_RV740_94A3:
case PCI_CHIP_RV740_94B1:
case PCI_CHIP_RV740_94B3:
+ case PCI_CHIP_RV740_94B4:
case PCI_CHIP_RV740_94B5:
+ case PCI_CHIP_RV740_94B9:
screen->chip_family = CHIP_FAMILY_RV740;
screen->chip_flags = RADEON_CHIPSET_TCL;
break;
@@ -945,9 +942,8 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
return NULL;
}
-#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
- RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
-#endif
+ radeon_init_debug();
+
/* parse information in __driConfigOptions */
driParseOptionInfo (&screen->optionCache,
__driConfigOptions, __driNConfigOptions);
@@ -990,6 +986,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
screen->drmSupportsPointSprites = (sPriv->drm_version.minor >= 13);
screen->drmSupportsCubeMapsR100 = (sPriv->drm_version.minor >= 15);
screen->drmSupportsVertexProgram = (sPriv->drm_version.minor >= 25);
+ screen->drmSupportsOcclusionQueries = (sPriv->drm_version.minor >= 30);
}
ret = radeon_set_screen_flags(screen, dri_priv->deviceID);
@@ -1025,7 +1022,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
else
screen->scratch = (__volatile__ uint32_t *)
- ((GLubyte *)screen->status.map + RADEON_SCRATCH_REG_OFFSET);
+ ((GLubyte *)screen->status.map + R600_SCRATCH_REG_OFFSET);
screen->buffers = drmMapBufs( sPriv->fd );
if ( !screen->buffers ) {
@@ -1085,7 +1082,7 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
/* +r6/r7 */
if(screen->chip_family >= CHIP_FAMILY_R600)
{
- if (ret)
+ if (ret)
{
FREE( screen );
fprintf(stderr, "Unable to get fb location need newer drm\n");
@@ -1098,18 +1095,18 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
}
else
{
- if (ret)
+ if (ret)
{
if (screen->chip_family < CHIP_FAMILY_RS600 && !screen->kernel_mm)
screen->fbLocation = ( INREG( RADEON_MC_FB_LOCATION ) & 0xffff) << 16;
- else
+ else
{
FREE( screen );
fprintf(stderr, "Unable to get fb location need newer drm\n");
return NULL;
}
- }
- else
+ }
+ else
{
screen->fbLocation = (temp & 0xffff) << 16;
}
@@ -1153,6 +1150,15 @@ radeonCreateScreen( __DRIscreenPrivate *sPriv )
default:
break;
}
+
+ if ( sPriv->drm_version.minor >= 31 ) {
+ ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_Z_PIPES, &temp);
+ if (ret)
+ screen->num_z_pipes = 2;
+ else
+ screen->num_z_pipes = temp;
+ } else
+ screen->num_z_pipes = 2;
}
if ( sPriv->drm_version.minor >= 10 ) {
@@ -1216,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
@@ -1270,9 +1276,7 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
return NULL;
}
-#if DO_DEBUG && RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
- RADEON_DEBUG = driParseDebugString(getenv("RADEON_DEBUG"), debug_control);
-#endif
+ radeon_init_debug();
/* parse information in __driConfigOptions */
driParseOptionInfo (&screen->optionCache,
@@ -1289,6 +1293,7 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
screen->drmSupportsPointSprites = 1;
screen->drmSupportsCubeMapsR100 = 1;
screen->drmSupportsVertexProgram = 1;
+ screen->drmSupportsOcclusionQueries = 1;
screen->irq = 1;
ret = radeonGetParam(sPriv, RADEON_PARAM_DEVICE_ID, &device_id);
@@ -1353,6 +1358,12 @@ radeonCreateScreen2(__DRIscreenPrivate *sPriv)
break;
}
+ ret = radeonGetParam(sPriv, RADEON_PARAM_NUM_Z_PIPES, &temp);
+ if (ret)
+ screen->num_z_pipes = 2;
+ else
+ screen->num_z_pipes = temp;
+
}
i = 0;
@@ -1365,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
@@ -1567,38 +1578,6 @@ radeonDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
_mesa_reference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate)), NULL);
}
-/**
- * Choose the appropriate CreateContext function based on the chipset.
- * Eventually, all drivers will go through this process.
- */
-static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
- __DRIcontextPrivate * driContextPriv,
- void *sharedContextPriv)
-{
- __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv;
- radeonScreenPtr screen = (radeonScreenPtr) (sPriv->private);
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R600)
- if (IS_R600_CLASS(screen))
- return r600CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
-
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300)
- if (IS_R300_CLASS(screen))
- return r300CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
-
-#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R200)
- if (IS_R200_CLASS(screen))
- return r200CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
-
-#if !RADEON_COMMON
- (void)screen;
- return r100CreateContext(glVisual, driContextPriv, sharedContextPriv);
-#endif
- return GL_FALSE;
-}
-
/**
* This is the driver specific part of the createNewScreen entry point.
@@ -1610,22 +1589,22 @@ static GLboolean radeonCreateContext(const __GLcontextModes * glVisual,
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 };
@@ -1651,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
@@ -1705,12 +1684,14 @@ __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_R300) || defined(RADEON_R600))
+ driInitSingleExtension( NULL, gl_20_extension );
#endif
if (!radeonInitDriver(psp)) {
@@ -1791,8 +1772,19 @@ getSwapInfo( __DRIdrawablePrivate *dPriv, __DRIswapInfo * sInfo )
const struct __DriverAPIRec driDriverAPI = {
.InitScreen = radeonInitScreen,
.DestroyScreen = radeonDestroyScreen,
- .CreateContext = radeonCreateContext,
+#if defined(RADEON_R200)
+ .CreateContext = r200CreateContext,
+ .DestroyContext = r200DestroyContext,
+#elif defined(RADEON_R600)
+ .CreateContext = r600CreateContext,
.DestroyContext = radeonDestroyContext,
+#elif defined(RADEON_R300)
+ .CreateContext = r300CreateContext,
+ .DestroyContext = radeonDestroyContext,
+#else
+ .CreateContext = r100CreateContext,
+ .DestroyContext = radeonDestroyContext,
+#endif
.CreateBuffer = radeonCreateBuffer,
.DestroyBuffer = radeonDestroyBuffer,
.SwapBuffers = radeonSwapBuffers,
diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.h b/src/mesa/drivers/dri/radeon/radeon_screen.h
index 2a2f6b1b0b..15744e8828 100644
--- a/src/mesa/drivers/dri/radeon/radeon_screen.h
+++ b/src/mesa/drivers/dri/radeon/radeon_screen.h
@@ -99,6 +99,7 @@ typedef struct radeon_screen {
GLboolean drmSupportsPointSprites; /* need radeon kernel module >= 1.13 */
GLboolean drmSupportsCubeMapsR100; /* need radeon kernel module >= 1.15 */
GLboolean drmSupportsVertexProgram; /* need radeon kernel module >= 1.25 */
+ GLboolean drmSupportsOcclusionQueries; /* need radeon kernel module >= 1.30 */
GLboolean depthHasSurface;
/* Configuration cache with default values for all contexts */
@@ -107,6 +108,7 @@ typedef struct radeon_screen {
const __DRIextension *extensions[16];
int num_gb_pipes;
+ int num_z_pipes;
int kernel_mm;
drm_radeon_sarea_t *sarea; /* Private SAREA data */
struct radeon_bo_manager *bom;
diff --git a/src/mesa/drivers/dri/radeon/radeon_span.c b/src/mesa/drivers/dri/radeon/radeon_span.c
index b2a468b4fd..0c49c3713a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_span.c
+++ b/src/mesa/drivers/dri/radeon/radeon_span.c
@@ -51,6 +51,196 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
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_R200)
+static GLubyte *r200_depth_2byte(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset;
+ if (rrb->has_surface) {
+ offset = x * rrb->cpp + y * rrb->pitch;
+ } else {
+ GLuint b;
+ offset = 0;
+ b = (((y >> 4) * (rrb->pitch >> 8) + (x >> 6)));
+ offset += (b >> 1) << 12;
+ offset += (((rrb->pitch >> 8) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+ offset += ((y >> 2) & 0x3) << 9;
+ offset += ((x >> 3) & 0x1) << 8;
+ offset += ((x >> 4) & 0x3) << 6;
+ offset += ((x >> 2) & 0x1) << 5;
+ offset += ((y >> 1) & 0x1) << 4;
+ offset += ((x >> 1) & 0x1) << 3;
+ offset += (y & 0x1) << 2;
+ offset += (x & 0x1) << 1;
+ }
+ return &ptr[offset];
+}
+
+static GLubyte *r200_depth_4byte(const struct radeon_renderbuffer * rrb,
+ GLint x, GLint y)
+{
+ GLubyte *ptr = rrb->bo->ptr;
+ GLint offset;
+ if (rrb->has_surface) {
+ offset = x * rrb->cpp + y * rrb->pitch;
+ } else {
+ GLuint b;
+ offset = 0;
+ b = (((y & 0x7ff) >> 4) * (rrb->pitch >> 7) + (x >> 5));
+ offset += (b >> 1) << 12;
+ offset += (((rrb->pitch >> 7) & 0x1) ? (b & 0x1) : ((b & 0x1) ^ ((y >> 4) & 0x1))) << 11;
+ offset += ((y >> 2) & 0x3) << 9;
+ offset += ((x >> 2) & 0x1) << 8;
+ offset += ((x >> 3) & 0x3) << 6;
+ offset += ((y >> 1) & 0x1) << 5;
+ offset += ((x >> 1) & 0x1) << 4;
+ offset += (y & 0x1) << 3;
+ offset += (x & 0x1) << 2;
+ }
+ return &ptr[offset];
+}
+#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
@@ -61,7 +251,6 @@ static void radeonSetSpanFunctions(struct radeon_renderbuffer *rrb);
4 byte surface
8/16 byte (unused)
*/
-
static GLubyte *radeon_ptr_4byte(const struct radeon_renderbuffer * rrb,
GLint x, GLint y)
{
@@ -143,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)
{
@@ -156,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
@@ -216,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
@@ -226,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
@@ -236,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
@@ -246,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
@@ -260,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"
/* ================================================================
@@ -285,11 +506,27 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLushort
+#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_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)
+#endif
#define TAG(x) radeon##x##_z16
#include "depthtmp.h"
@@ -301,7 +538,7 @@ s8z24_to_z24s8(uint32_t val)
*/
#define VALUE_TYPE GLuint
-#ifdef 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 ); \
@@ -310,6 +547,24 @@ do { \
tmp |= ((d << 8) & 0xffffff00); \
*_ptr = tmp; \
} while (0)
+#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 ); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0xff000000; \
+ tmp |= ((d) & 0x00ffffff); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
@@ -321,19 +576,26 @@ do { \
} while (0)
#endif
-#ifdef 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_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; \
+ }while(0)
#else
#define READ_DEPTH( d, _x, _y ) \
d = *(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off)) & 0x00ffffff;
#endif
-/*
- fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\
- d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff;
-*/
+
#define TAG(x) radeon##x##_z24
#include "depthtmp.h"
@@ -345,12 +607,33 @@ do { \
*/
#define VALUE_TYPE GLuint
-#ifdef 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_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 ); \
+ GLuint tmp = z24s8_to_s8z24(d); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_DEPTH( _x, _y, d ) \
do { \
@@ -360,20 +643,28 @@ do { \
} while (0)
#endif
-#ifdef 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_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))); \
+ }while(0)
#else
#define READ_DEPTH( d, _x, _y ) do { \
d = s8z24_to_z24s8(*(GLuint*)(radeon_ptr_4byte(rrb, _x + x_off, _y + y_off ))); \
} while (0)
#endif
-/*
- fprintf(stderr, "dval(%d, %d, %d, %d)=0x%08X\n", _x, xo, _y, yo, d);\
- d = *(GLuint*)(radeon_ptr(rrb, _x, _y )) & 0x00ffffff;
-*/
+
#define TAG(x) radeon##x##_z24_s8
#include "depthtmp.h"
@@ -383,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); \
@@ -392,6 +683,24 @@ do { \
tmp |= (d) & 0xff; \
*_ptr = tmp; \
} while (0)
+#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); \
+ GLuint tmp = *_ptr; \
+ tmp &= 0x00ffffff; \
+ tmp |= (((d) & 0xff) << 24); \
+ *_ptr = tmp; \
+} while (0)
#else
#define WRITE_STENCIL( _x, _y, d ) \
do { \
@@ -403,13 +712,27 @@ 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_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 ); \
+ GLuint tmp = *_ptr; \
+ d = (tmp & 0xff000000) >> 24; \
+} while (0)
#else
#define READ_STENCIL( d, _x, _y ) \
do { \
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.c b/src/mesa/drivers/dri/radeon/radeon_state.c
index 0d1728b747..4d0d35ee0c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state.c
@@ -40,6 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/state.h"
#include "main/context.h"
#include "main/framebuffer.h"
+#include "main/simple_list.h"
#include "vbo/vbo.h"
#include "tnl/tnl.h"
@@ -549,31 +550,6 @@ static void radeonPolygonOffset( GLcontext *ctx,
rmesa->hw.zbs.cmd[ZBS_SE_ZBIAS_CONSTANT] = constant.ui32;
}
-static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask )
-{
- r100ContextPtr rmesa = R100_CONTEXT(ctx);
- GLuint i;
- drm_radeon_stipple_t stipple;
-
- /* Must flip pattern upside down.
- */
- for ( i = 0 ; i < 32 ; i++ ) {
- rmesa->state.stipple.mask[31 - i] = ((GLuint *) mask)[i];
- }
-
- /* TODO: push this into cmd mechanism
- */
- radeon_firevertices(&rmesa->radeon);
- LOCK_HARDWARE( &rmesa->radeon );
-
- /* FIXME: Use window x,y offsets into stipple RAM.
- */
- stipple.mask = rmesa->state.stipple.mask;
- drmCommandWrite( rmesa->radeon.dri.fd, DRM_RADEON_STIPPLE,
- &stipple, sizeof(drm_radeon_stipple_t) );
- UNLOCK_HARDWARE( &rmesa->radeon );
-}
-
static void radeonPolygonMode( GLcontext *ctx, GLenum face, GLenum mode )
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
@@ -838,7 +814,7 @@ void radeonUpdateMaterial( GLcontext *ctx )
if (ctx->Light.ColorMaterialEnabled)
mask &= ~ctx->Light.ColorMaterialBitmask;
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s\n", __FUNCTION__);
@@ -1572,7 +1548,7 @@ static void radeonEnable( GLcontext *ctx, GLenum cap, GLboolean state )
r100ContextPtr rmesa = R100_CONTEXT(ctx);
GLuint p, flag;
- if ( RADEON_DEBUG & DEBUG_STATE )
+ if ( RADEON_DEBUG & RADEON_STATE )
fprintf( stderr, "%s( %s = %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr( cap ),
state ? "GL_TRUE" : "GL_FALSE" );
@@ -1866,7 +1842,7 @@ static void radeonLightingSpaceChange( GLcontext *ctx )
GLboolean tmp;
RADEON_STATECHANGE( rmesa, tcl );
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s %d BEFORE %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
@@ -1881,7 +1857,7 @@ static void radeonLightingSpaceChange( GLcontext *ctx )
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL] &= ~RADEON_RESCALE_NORMALS;
}
- if (RADEON_DEBUG & DEBUG_STATE)
+ if (RADEON_DEBUG & RADEON_STATE)
fprintf(stderr, "%s %d AFTER %x\n", __FUNCTION__, ctx->_NeedEyeCoords,
rmesa->hw.tcl.cmd[TCL_LIGHT_MODEL_CTL]);
}
@@ -2099,7 +2075,7 @@ static GLboolean r100ValidateBuffers(GLcontext *ctx)
RADEON_GEM_DOMAIN_GTT | RADEON_GEM_DOMAIN_VRAM, 0);
}
- ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, rmesa->radeon.dma.current, RADEON_GEM_DOMAIN_GTT, 0);
+ ret = radeon_cs_space_check_with_bo(rmesa->radeon.cmdbuf.cs, first_elem(&rmesa->radeon.dma.reserved)->bo, RADEON_GEM_DOMAIN_GTT, 0);
if (ret)
return GL_FALSE;
return GL_TRUE;
@@ -2221,12 +2197,28 @@ static void radeonWrapRunPipeline( GLcontext *ctx )
}
}
+static void radeonPolygonStipple( GLcontext *ctx, const GLubyte *mask )
+{
+ r100ContextPtr r100 = R100_CONTEXT(ctx);
+ GLint i;
+
+ radeon_firevertices(&r100->radeon);
+
+ RADEON_STATECHANGE(r100, stp);
+
+ /* Must flip pattern upside down.
+ */
+ for ( i = 31 ; i >= 0; i--) {
+ r100->hw.stp.cmd[3 + i] = ((GLuint *) mask)[i];
+ }
+}
+
/* Initialize the driver's state functions.
* Many of the ctx->Driver functions might have been initialized to
* software defaults in the earlier _mesa_init_driver_functions() call.
*/
-void radeonInitStateFuncs( GLcontext *ctx )
+void radeonInitStateFuncs( GLcontext *ctx , GLboolean dri2 )
{
ctx->Driver.UpdateState = radeonInvalidateState;
ctx->Driver.LightingSpaceChange = radeonLightingSpaceChange;
@@ -2259,7 +2251,10 @@ void radeonInitStateFuncs( GLcontext *ctx )
ctx->Driver.LogicOpcode = radeonLogicOpCode;
ctx->Driver.PolygonMode = radeonPolygonMode;
ctx->Driver.PolygonOffset = radeonPolygonOffset;
- ctx->Driver.PolygonStipple = radeonPolygonStipple;
+ if (dri2)
+ ctx->Driver.PolygonStipple = radeonPolygonStipple;
+ else
+ ctx->Driver.PolygonStipple = radeonPolygonStipplePreKMS;
ctx->Driver.RenderMode = radeonRenderMode;
ctx->Driver.Scissor = radeonScissor;
ctx->Driver.ShadeModel = radeonShadeModel;
diff --git a/src/mesa/drivers/dri/radeon/radeon_state.h b/src/mesa/drivers/dri/radeon/radeon_state.h
index a7c8eef32a..c780cff0cf 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state.h
+++ b/src/mesa/drivers/dri/radeon/radeon_state.h
@@ -40,7 +40,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_context.h"
extern void radeonInitState( r100ContextPtr rmesa );
-extern void radeonInitStateFuncs( GLcontext *ctx );
+extern void radeonInitStateFuncs( GLcontext *ctx , GLboolean dri2);
extern void radeonUpdateMaterial( GLcontext *ctx );
diff --git a/src/mesa/drivers/dri/radeon/radeon_state_init.c b/src/mesa/drivers/dri/radeon/radeon_state_init.c
index 57aa7f1ca4..f3ad0dd17a 100644
--- a/src/mesa/drivers/dri/radeon/radeon_state_init.c
+++ b/src/mesa/drivers/dri/radeon/radeon_state_init.c
@@ -44,6 +44,7 @@
#include "radeon_tcl.h"
#include "radeon_tex.h"
#include "radeon_swtcl.h"
+#include "radeon_queryobj.h"
#include "../r200/r200_reg.h"
@@ -197,55 +198,85 @@ static int cmdscl( int offset, int stride, int count )
return h.i;
}
-#define CHECK( NM, FLAG ) \
+#define CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \
{ \
- return FLAG ? atom->cmd_size : 0; \
+ return FLAG ? atom->cmd_size + (ADD) : 0; \
}
-#define TCL_CHECK( NM, FLAG ) \
+#define TCL_CHECK( NM, FLAG, ADD ) \
static int check_##NM( GLcontext *ctx, struct radeon_state_atom *atom ) \
{ \
r100ContextPtr rmesa = R100_CONTEXT(ctx); \
- return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size : 0; \
+ return (!rmesa->radeon.TclFallback && (FLAG)) ? atom->cmd_size + (ADD) : 0; \
}
-CHECK( always, GL_TRUE )
-CHECK( never, GL_FALSE )
-CHECK( tex0, ctx->Texture.Unit[0]._ReallyEnabled )
-CHECK( tex1, ctx->Texture.Unit[1]._ReallyEnabled )
+CHECK( always, GL_TRUE, 0 )
+CHECK( always_add2, GL_TRUE, 2 )
+CHECK( always_add4, GL_TRUE, 4 )
+CHECK( never, GL_FALSE, 0 )
+CHECK( tex0_mm, ctx->Texture.Unit[0]._ReallyEnabled, 3 )
+CHECK( tex1_mm, ctx->Texture.Unit[1]._ReallyEnabled, 3 )
/* need this for the cubic_map on disabled unit 2 bug, maybe r100 only? */
-CHECK( tex2, ctx->Texture._EnabledUnits )
-CHECK( cube0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_CUBE_BIT))
-CHECK( cube1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_CUBE_BIT))
-CHECK( cube2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_CUBE_BIT))
-CHECK( fog, ctx->Fog.Enabled )
-TCL_CHECK( tcl, GL_TRUE )
-TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled )
-TCL_CHECK( tcl_tex1, ctx->Texture.Unit[1]._ReallyEnabled )
-TCL_CHECK( tcl_tex2, ctx->Texture.Unit[2]._ReallyEnabled )
-TCL_CHECK( tcl_lighting, ctx->Light.Enabled )
-TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled )
-TCL_CHECK( tcl_lit0, ctx->Light.Enabled && ctx->Light.Light[0].Enabled )
-TCL_CHECK( tcl_lit1, ctx->Light.Enabled && ctx->Light.Light[1].Enabled )
-TCL_CHECK( tcl_lit2, ctx->Light.Enabled && ctx->Light.Light[2].Enabled )
-TCL_CHECK( tcl_lit3, ctx->Light.Enabled && ctx->Light.Light[3].Enabled )
-TCL_CHECK( tcl_lit4, ctx->Light.Enabled && ctx->Light.Light[4].Enabled )
-TCL_CHECK( tcl_lit5, ctx->Light.Enabled && ctx->Light.Light[5].Enabled )
-TCL_CHECK( tcl_lit6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled )
-TCL_CHECK( tcl_lit7, ctx->Light.Enabled && ctx->Light.Light[7].Enabled )
-TCL_CHECK( tcl_ucp0, (ctx->Transform.ClipPlanesEnabled & 0x1) )
-TCL_CHECK( tcl_ucp1, (ctx->Transform.ClipPlanesEnabled & 0x2) )
-TCL_CHECK( tcl_ucp2, (ctx->Transform.ClipPlanesEnabled & 0x4) )
-TCL_CHECK( tcl_ucp3, (ctx->Transform.ClipPlanesEnabled & 0x8) )
-TCL_CHECK( tcl_ucp4, (ctx->Transform.ClipPlanesEnabled & 0x10) )
-TCL_CHECK( tcl_ucp5, (ctx->Transform.ClipPlanesEnabled & 0x20) )
-TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled )
-
-CHECK( txr0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT))
-CHECK( txr1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT))
-CHECK( txr2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_RECT_BIT))
+CHECK( tex2_mm, ctx->Texture._EnabledUnits, 3 )
+CHECK( tex0, ctx->Texture.Unit[0]._ReallyEnabled, 2 )
+CHECK( tex1, ctx->Texture.Unit[1]._ReallyEnabled, 2 )
+CHECK( tex2, ctx->Texture._EnabledUnits, 2 )
+CHECK( cube0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_CUBE_BIT), 3 + 3*5 - CUBE_STATE_SIZE )
+CHECK( cube1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_CUBE_BIT), 3 + 3*5 - CUBE_STATE_SIZE )
+CHECK( cube2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_CUBE_BIT), 3 + 3*5 - CUBE_STATE_SIZE )
+CHECK( cube0_mm, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_CUBE_BIT), 2 + 4*5 - CUBE_STATE_SIZE )
+CHECK( cube1_mm, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_CUBE_BIT), 2 + 4*5 - CUBE_STATE_SIZE )
+CHECK( cube2_mm, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_CUBE_BIT), 2 + 4*5 - CUBE_STATE_SIZE )
+CHECK( fog, ctx->Fog.Enabled, 0 )
+CHECK( fog_add4, ctx->Fog.Enabled, 4 )
+TCL_CHECK( tcl, GL_TRUE, 0 )
+TCL_CHECK( tcl_add4, GL_TRUE, 4 )
+TCL_CHECK( tcl_tex0, ctx->Texture.Unit[0]._ReallyEnabled, 0 )
+TCL_CHECK( tcl_tex1, ctx->Texture.Unit[1]._ReallyEnabled, 0 )
+TCL_CHECK( tcl_tex2, ctx->Texture.Unit[2]._ReallyEnabled, 0 )
+TCL_CHECK( tcl_tex0_add4, ctx->Texture.Unit[0]._ReallyEnabled, 4 )
+TCL_CHECK( tcl_tex1_add4, ctx->Texture.Unit[1]._ReallyEnabled, 4 )
+TCL_CHECK( tcl_tex2_add4, ctx->Texture.Unit[2]._ReallyEnabled, 4 )
+TCL_CHECK( tcl_lighting, ctx->Light.Enabled, 0 )
+TCL_CHECK( tcl_lighting_add4, ctx->Light.Enabled, 4 )
+TCL_CHECK( tcl_eyespace_or_lighting, ctx->_NeedEyeCoords || ctx->Light.Enabled, 0 )
+TCL_CHECK( tcl_eyespace_or_lighting_add4, ctx->_NeedEyeCoords || ctx->Light.Enabled, 4 )
+TCL_CHECK( tcl_lit0, ctx->Light.Enabled && ctx->Light.Light[0].Enabled, 0 )
+TCL_CHECK( tcl_lit1, ctx->Light.Enabled && ctx->Light.Light[1].Enabled, 0 )
+TCL_CHECK( tcl_lit2, ctx->Light.Enabled && ctx->Light.Light[2].Enabled, 0 )
+TCL_CHECK( tcl_lit3, ctx->Light.Enabled && ctx->Light.Light[3].Enabled, 0 )
+TCL_CHECK( tcl_lit4, ctx->Light.Enabled && ctx->Light.Light[4].Enabled, 0 )
+TCL_CHECK( tcl_lit5, ctx->Light.Enabled && ctx->Light.Light[5].Enabled, 0 )
+TCL_CHECK( tcl_lit6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled, 0 )
+TCL_CHECK( tcl_lit7, ctx->Light.Enabled && ctx->Light.Light[7].Enabled, 0 )
+TCL_CHECK( tcl_lit0_add6, ctx->Light.Enabled && ctx->Light.Light[0].Enabled, 6 )
+TCL_CHECK( tcl_lit1_add6, ctx->Light.Enabled && ctx->Light.Light[1].Enabled, 6 )
+TCL_CHECK( tcl_lit2_add6, ctx->Light.Enabled && ctx->Light.Light[2].Enabled, 6 )
+TCL_CHECK( tcl_lit3_add6, ctx->Light.Enabled && ctx->Light.Light[3].Enabled, 6 )
+TCL_CHECK( tcl_lit4_add6, ctx->Light.Enabled && ctx->Light.Light[4].Enabled, 6 )
+TCL_CHECK( tcl_lit5_add6, ctx->Light.Enabled && ctx->Light.Light[5].Enabled, 6 )
+TCL_CHECK( tcl_lit6_add6, ctx->Light.Enabled && ctx->Light.Light[6].Enabled, 6 )
+TCL_CHECK( tcl_lit7_add6, ctx->Light.Enabled && ctx->Light.Light[7].Enabled, 6 )
+TCL_CHECK( tcl_ucp0, (ctx->Transform.ClipPlanesEnabled & 0x1), 0 )
+TCL_CHECK( tcl_ucp1, (ctx->Transform.ClipPlanesEnabled & 0x2), 0 )
+TCL_CHECK( tcl_ucp2, (ctx->Transform.ClipPlanesEnabled & 0x4), 0 )
+TCL_CHECK( tcl_ucp3, (ctx->Transform.ClipPlanesEnabled & 0x8), 0 )
+TCL_CHECK( tcl_ucp4, (ctx->Transform.ClipPlanesEnabled & 0x10), 0 )
+TCL_CHECK( tcl_ucp5, (ctx->Transform.ClipPlanesEnabled & 0x20), 0 )
+TCL_CHECK( tcl_ucp0_add4, (ctx->Transform.ClipPlanesEnabled & 0x1), 4 )
+TCL_CHECK( tcl_ucp1_add4, (ctx->Transform.ClipPlanesEnabled & 0x2), 4 )
+TCL_CHECK( tcl_ucp2_add4, (ctx->Transform.ClipPlanesEnabled & 0x4), 4 )
+TCL_CHECK( tcl_ucp3_add4, (ctx->Transform.ClipPlanesEnabled & 0x8), 4 )
+TCL_CHECK( tcl_ucp4_add4, (ctx->Transform.ClipPlanesEnabled & 0x10), 4 )
+TCL_CHECK( tcl_ucp5_add4, (ctx->Transform.ClipPlanesEnabled & 0x20), 4 )
+TCL_CHECK( tcl_eyespace_or_fog, ctx->_NeedEyeCoords || ctx->Fog.Enabled, 0 )
+TCL_CHECK( tcl_eyespace_or_fog_add4, ctx->_NeedEyeCoords || ctx->Fog.Enabled, 4 )
+
+CHECK( txr0, (ctx->Texture.Unit[0]._ReallyEnabled & TEXTURE_RECT_BIT), 0 )
+CHECK( txr1, (ctx->Texture.Unit[1]._ReallyEnabled & TEXTURE_RECT_BIT), 0 )
+CHECK( txr2, (ctx->Texture.Unit[2]._ReallyEnabled & TEXTURE_RECT_BIT), 0 )
#define OUT_VEC(hdr, data) do { \
drm_radeon_cmd_header_t h; \
@@ -271,9 +302,8 @@ static void scl_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 2;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_SCL(atom->cmd[0], atom->cmd+1);
END_BATCH();
@@ -284,9 +314,8 @@ static void vec_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 4;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[0], atom->cmd+1);
END_BATCH();
@@ -297,9 +326,8 @@ static void lit_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
- dwords += 6;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_VEC(atom->cmd[LIT_CMD_0], atom->cmd+1);
OUT_SCL(atom->cmd[LIT_CMD_1], atom->cmd+LIT_CMD_1+1);
@@ -313,10 +341,10 @@ static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom)
struct radeon_renderbuffer *rrb;
uint32_t cbpitch;
uint32_t zbpitch, depth_fmt;
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
/* output the first 7 bytes of context */
- BEGIN_BATCH_NO_AUTOSTATE(dwords + 4);
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH_TABLE(atom->cmd, 5);
rrb = radeon_get_depthbuffer(&r100->radeon);
@@ -371,6 +399,28 @@ static void ctx_emit(GLcontext *ctx, struct radeon_state_atom *atom)
END_BATCH();
}
+static int check_always_ctx( GLcontext *ctx, struct radeon_state_atom *atom)
+{
+ r100ContextPtr r100 = R100_CONTEXT(ctx);
+ struct radeon_renderbuffer *rrb, *drb;
+ uint32_t dwords;
+
+ rrb = radeon_get_colorbuffer(&r100->radeon);
+ if (!rrb || !rrb->bo) {
+ return 0;
+ }
+
+ drb = radeon_get_depthbuffer(&r100->radeon);
+
+ dwords = 10;
+ if (drb)
+ dwords += 6;
+ if (rrb)
+ dwords += 8;
+
+ return dwords;
+}
+
static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
@@ -378,7 +428,7 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
struct radeon_renderbuffer *rrb, *drb;
uint32_t cbpitch = 0;
uint32_t zbpitch = 0;
- uint32_t dwords = atom->cmd_size;
+ uint32_t dwords = atom->check(ctx, atom);
uint32_t depth_fmt;
rrb = radeon_get_colorbuffer(&r100->radeon);
@@ -418,12 +468,6 @@ static void ctx_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
}
- /* output the first 7 bytes of context */
- dwords = 10;
- if (drb)
- dwords += 6;
- if (rrb)
- dwords += 8;
BEGIN_BATCH_NO_AUTOSTATE(dwords);
/* In the CS case we need to split this up */
@@ -474,7 +518,7 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
- uint32_t dwords = 3;
+ uint32_t dwords = atom->check(ctx, atom);
int i = atom->idx, j;
radeonTexObj *t = r100->state.texture.unit[i].texobj;
radeon_mipmap_level *lvl;
@@ -488,7 +532,7 @@ static void cube_emit(GLcontext *ctx, struct radeon_state_atom *atom)
if (!t->mt)
return;
- BEGIN_BATCH_NO_AUTOSTATE(dwords + (5 * 3));
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH_TABLE(atom->cmd, 3);
lvl = &t->mt->levels[0];
for (j = 0; j < 5; j++) {
@@ -502,7 +546,7 @@ static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
{
r100ContextPtr r100 = R100_CONTEXT(ctx);
BATCH_LOCALS(&r100->radeon);
- uint32_t dwords = 2;
+ uint32_t dwords = atom->check(ctx, atom);
int i = atom->idx, j;
radeonTexObj *t = r100->state.texture.unit[i].texobj;
radeon_mipmap_level *lvl;
@@ -523,13 +567,13 @@ static void cube_emit_cs(GLcontext *ctx, struct radeon_state_atom *atom)
default:
case 0: base_reg = RADEON_PP_CUBIC_OFFSET_T0_0; break;
};
- BEGIN_BATCH_NO_AUTOSTATE(dwords + (5 * 4));
+ BEGIN_BATCH_NO_AUTOSTATE(dwords);
OUT_BATCH_TABLE(atom->cmd, 2);
lvl = &t->mt->levels[0];
for (j = 0; j < 5; j++) {
OUT_BATCH(CP_PACKET0(base_reg + (4 * j), 0));
OUT_BATCH_RELOC(lvl->faces[j].offset, t->mt->bo, lvl->faces[j].offset,
- RADEON_GEM_DOMAIN_VRAM, 0, 0);
+ RADEON_GEM_DOMAIN_GTT|RADEON_GEM_DOMAIN_VRAM, 0, 0);
}
END_BATCH();
}
@@ -665,10 +709,11 @@ void radeonInitState( r100ContextPtr rmesa )
/* Allocate state buffers:
*/
- ALLOC_STATE( ctx, always, CTX_STATE_SIZE, "CTX/context", 0 );
- if (rmesa->radeon.radeonScreen->kernel_mm)
+ ALLOC_STATE( ctx, always_add4, CTX_STATE_SIZE, "CTX/context", 0 );
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
rmesa->hw.ctx.emit = ctx_emit_cs;
- else
+ rmesa->hw.ctx.check = check_always_ctx;
+ } else
rmesa->hw.ctx.emit = ctx_emit;
ALLOC_STATE( lin, always, LIN_STATE_SIZE, "LIN/line", 0 );
ALLOC_STATE( msk, always, MSK_STATE_SIZE, "MSK/mask", 0 );
@@ -678,14 +723,68 @@ void radeonInitState( r100ContextPtr rmesa )
ALLOC_STATE( zbs, always, ZBS_STATE_SIZE, "ZBS/zbias", 0 );
ALLOC_STATE( tcl, always, TCL_STATE_SIZE, "TCL/tcl", 1 );
ALLOC_STATE( mtl, tcl_lighting, MTL_STATE_SIZE, "MTL/material", 1 );
- ALLOC_STATE( grd, always, GRD_STATE_SIZE, "GRD/guard-band", 1 );
- ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 );
- ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 );
- ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 );
- ALLOC_STATE_IDX( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0, 0);
- ALLOC_STATE_IDX( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0, 1);
- ALLOC_STATE_IDX( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0, 2);
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE( grd, always_add2, GRD_STATE_SIZE, "GRD/guard-band", 1 );
+ ALLOC_STATE( fog, fog_add4, FOG_STATE_SIZE, "FOG/fog", 1 );
+ ALLOC_STATE( glt, tcl_lighting_add4, GLT_STATE_SIZE, "GLT/light-global", 1 );
+ ALLOC_STATE( eye, tcl_lighting_add4, EYE_STATE_SIZE, "EYE/eye-vector", 1 );
+ ALLOC_STATE_IDX( tex[0], tex0_mm, TEX_STATE_SIZE, "TEX/tex-0", 0, 0);
+ ALLOC_STATE_IDX( tex[1], tex1_mm, TEX_STATE_SIZE, "TEX/tex-1", 0, 1);
+ ALLOC_STATE_IDX( tex[2], tex2_mm, TEX_STATE_SIZE, "TEX/tex-2", 0, 2);
+ ALLOC_STATE( mat[0], tcl_add4, MAT_STATE_SIZE, "MAT/modelproject", 1 );
+ ALLOC_STATE( mat[1], tcl_eyespace_or_fog_add4, MAT_STATE_SIZE, "MAT/modelview", 1 );
+ ALLOC_STATE( mat[2], tcl_eyespace_or_lighting_add4, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
+ ALLOC_STATE( mat[3], tcl_tex0_add4, MAT_STATE_SIZE, "MAT/texmat0", 1 );
+ ALLOC_STATE( mat[4], tcl_tex1_add4, MAT_STATE_SIZE, "MAT/texmat1", 1 );
+ ALLOC_STATE( mat[5], tcl_tex2_add4, MAT_STATE_SIZE, "MAT/texmat2", 1 );
+ ALLOC_STATE( lit[0], tcl_lit0_add6, LIT_STATE_SIZE, "LIT/light-0", 1 );
+ ALLOC_STATE( lit[1], tcl_lit1_add6, LIT_STATE_SIZE, "LIT/light-1", 1 );
+ ALLOC_STATE( lit[2], tcl_lit2_add6, LIT_STATE_SIZE, "LIT/light-2", 1 );
+ ALLOC_STATE( lit[3], tcl_lit3_add6, LIT_STATE_SIZE, "LIT/light-3", 1 );
+ ALLOC_STATE( lit[4], tcl_lit4_add6, LIT_STATE_SIZE, "LIT/light-4", 1 );
+ ALLOC_STATE( lit[5], tcl_lit5_add6, LIT_STATE_SIZE, "LIT/light-5", 1 );
+ ALLOC_STATE( lit[6], tcl_lit6_add6, LIT_STATE_SIZE, "LIT/light-6", 1 );
+ ALLOC_STATE( lit[7], tcl_lit7_add6, LIT_STATE_SIZE, "LIT/light-7", 1 );
+ ALLOC_STATE( ucp[0], tcl_ucp0_add4, UCP_STATE_SIZE, "UCP/userclip-0", 1 );
+ ALLOC_STATE( ucp[1], tcl_ucp1_add4, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
+ ALLOC_STATE( ucp[2], tcl_ucp2_add4, UCP_STATE_SIZE, "UCP/userclip-2", 1 );
+ ALLOC_STATE( ucp[3], tcl_ucp3_add4, UCP_STATE_SIZE, "UCP/userclip-3", 1 );
+ ALLOC_STATE( ucp[4], tcl_ucp4_add4, UCP_STATE_SIZE, "UCP/userclip-4", 1 );
+ ALLOC_STATE( ucp[5], tcl_ucp5_add4, UCP_STATE_SIZE, "UCP/userclip-5", 1 );
+ } else {
+ ALLOC_STATE( grd, always, GRD_STATE_SIZE, "GRD/guard-band", 1 );
+ ALLOC_STATE( fog, fog, FOG_STATE_SIZE, "FOG/fog", 1 );
+ ALLOC_STATE( glt, tcl_lighting, GLT_STATE_SIZE, "GLT/light-global", 1 );
+ ALLOC_STATE( eye, tcl_lighting, EYE_STATE_SIZE, "EYE/eye-vector", 1 );
+ ALLOC_STATE_IDX( tex[0], tex0, TEX_STATE_SIZE, "TEX/tex-0", 0, 0);
+ ALLOC_STATE_IDX( tex[1], tex1, TEX_STATE_SIZE, "TEX/tex-1", 0, 1);
+ ALLOC_STATE_IDX( tex[2], tex2, TEX_STATE_SIZE, "TEX/tex-2", 0, 2);
+ ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 );
+ ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 );
+ ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
+ ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 );
+ ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 );
+ ALLOC_STATE( mat[5], tcl_tex2, MAT_STATE_SIZE, "MAT/texmat2", 1 );
+ ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 );
+ ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 );
+ ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 );
+ ALLOC_STATE( lit[3], tcl_lit3, LIT_STATE_SIZE, "LIT/light-3", 1 );
+ ALLOC_STATE( lit[4], tcl_lit4, LIT_STATE_SIZE, "LIT/light-4", 1 );
+ ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 );
+ ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 );
+ ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 );
+ ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 );
+ ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
+ ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 );
+ ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 );
+ ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 );
+ ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 );
+ }
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE( stp, always, STP_STATE_SIZE, "STP/stp", 0 );
+ }
+
for (i = 0; i < 3; i++) {
if (rmesa->radeon.radeonScreen->kernel_mm)
rmesa->hw.tex[i].emit = tex_emit_cs;
@@ -694,14 +793,19 @@ void radeonInitState( r100ContextPtr rmesa )
}
if (rmesa->radeon.radeonScreen->drmSupportsCubeMapsR100)
{
- ALLOC_STATE_IDX( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 );
- ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 );
- ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 );
- for (i = 0; i < 3; i++)
- if (rmesa->radeon.radeonScreen->kernel_mm)
- rmesa->hw.cube[i].emit = cube_emit_cs;
- else
- rmesa->hw.cube[i].emit = cube_emit;
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ ALLOC_STATE_IDX( cube[0], cube0_mm, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 );
+ ALLOC_STATE_IDX( cube[1], cube1_mm, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 );
+ ALLOC_STATE_IDX( cube[2], cube2_mm, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 );
+ for (i = 0; i < 3; i++)
+ rmesa->hw.cube[i].emit = cube_emit_cs;
+ } else {
+ ALLOC_STATE_IDX( cube[0], cube0, CUBE_STATE_SIZE, "CUBE/cube-0", 0, 0 );
+ ALLOC_STATE_IDX( cube[1], cube1, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 );
+ ALLOC_STATE_IDX( cube[2], cube2, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 );
+ for (i = 0; i < 3; i++)
+ rmesa->hw.cube[i].emit = cube_emit;
+ }
}
else
{
@@ -709,26 +813,6 @@ void radeonInitState( r100ContextPtr rmesa )
ALLOC_STATE_IDX( cube[1], never, CUBE_STATE_SIZE, "CUBE/cube-1", 0, 1 );
ALLOC_STATE_IDX( cube[2], never, CUBE_STATE_SIZE, "CUBE/cube-2", 0, 2 );
}
- ALLOC_STATE( mat[0], tcl, MAT_STATE_SIZE, "MAT/modelproject", 1 );
- ALLOC_STATE( mat[1], tcl_eyespace_or_fog, MAT_STATE_SIZE, "MAT/modelview", 1 );
- ALLOC_STATE( mat[2], tcl_eyespace_or_lighting, MAT_STATE_SIZE, "MAT/it-modelview", 1 );
- ALLOC_STATE( mat[3], tcl_tex0, MAT_STATE_SIZE, "MAT/texmat0", 1 );
- ALLOC_STATE( mat[4], tcl_tex1, MAT_STATE_SIZE, "MAT/texmat1", 1 );
- ALLOC_STATE( mat[5], tcl_tex2, MAT_STATE_SIZE, "MAT/texmat2", 1 );
- ALLOC_STATE( ucp[0], tcl_ucp0, UCP_STATE_SIZE, "UCP/userclip-0", 1 );
- ALLOC_STATE( ucp[1], tcl_ucp1, UCP_STATE_SIZE, "UCP/userclip-1", 1 );
- ALLOC_STATE( ucp[2], tcl_ucp2, UCP_STATE_SIZE, "UCP/userclip-2", 1 );
- ALLOC_STATE( ucp[3], tcl_ucp3, UCP_STATE_SIZE, "UCP/userclip-3", 1 );
- ALLOC_STATE( ucp[4], tcl_ucp4, UCP_STATE_SIZE, "UCP/userclip-4", 1 );
- ALLOC_STATE( ucp[5], tcl_ucp5, UCP_STATE_SIZE, "UCP/userclip-5", 1 );
- ALLOC_STATE( lit[0], tcl_lit0, LIT_STATE_SIZE, "LIT/light-0", 1 );
- ALLOC_STATE( lit[1], tcl_lit1, LIT_STATE_SIZE, "LIT/light-1", 1 );
- ALLOC_STATE( lit[2], tcl_lit2, LIT_STATE_SIZE, "LIT/light-2", 1 );
- ALLOC_STATE( lit[3], tcl_lit3, LIT_STATE_SIZE, "LIT/light-3", 1 );
- ALLOC_STATE( lit[4], tcl_lit4, LIT_STATE_SIZE, "LIT/light-4", 1 );
- ALLOC_STATE( lit[5], tcl_lit5, LIT_STATE_SIZE, "LIT/light-5", 1 );
- ALLOC_STATE( lit[6], tcl_lit6, LIT_STATE_SIZE, "LIT/light-6", 1 );
- ALLOC_STATE( lit[7], tcl_lit7, LIT_STATE_SIZE, "LIT/light-7", 1 );
ALLOC_STATE_IDX( txr[0], txr0, TXR_STATE_SIZE, "TXR/txr-0", 0, 0 );
ALLOC_STATE_IDX( txr[1], txr1, TXR_STATE_SIZE, "TXR/txr-1", 0, 1 );
ALLOC_STATE_IDX( txr[2], txr2, TXR_STATE_SIZE, "TXR/txr-2", 0, 2 );
@@ -793,12 +877,16 @@ void radeonInitState( r100ContextPtr rmesa )
}
if (rmesa->radeon.radeonScreen->kernel_mm) {
+ rmesa->hw.stp.cmd[STP_CMD_0] = CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0);
+ rmesa->hw.stp.cmd[STP_DATA_0] = 0;
+ rmesa->hw.stp.cmd[STP_CMD_1] = CP_PACKET0_ONE(RADEON_RE_STIPPLE_DATA, 31);
+
rmesa->hw.grd.emit = scl_emit;
rmesa->hw.fog.emit = vec_emit;
rmesa->hw.glt.emit = vec_emit;
rmesa->hw.eye.emit = vec_emit;
- for (i = 0; i <= 6; i++)
+ for (i = 0; i < 6; i++)
rmesa->hw.mat[i].emit = vec_emit;
for (i = 0; i < 8; i++)
@@ -1063,7 +1151,13 @@ void radeonInitState( r100ContextPtr rmesa )
rmesa->hw.eye.cmd[EYE_Y] = 0;
rmesa->hw.eye.cmd[EYE_Z] = IEEE_ONE;
rmesa->hw.eye.cmd[EYE_RESCALE_FACTOR] = IEEE_ONE;
-
+
+ if (rmesa->radeon.radeonScreen->kernel_mm) {
+ radeon_init_query_stateobj(&rmesa->radeon, R100_QUERYOBJ_CMDSIZE);
+ rmesa->radeon.query.queryobj.cmd[R100_QUERYOBJ_CMD_0] = CP_PACKET0(RADEON_RB3D_ZPASS_DATA, 0);
+ rmesa->radeon.query.queryobj.cmd[R100_QUERYOBJ_DATA_0] = 0;
+ }
+
rmesa->radeon.hw.all_dirty = GL_TRUE;
rcommonInitCmdBuf(&rmesa->radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_swtcl.c b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
index e31f045991..e61f59eaea 100644
--- a/src/mesa/drivers/dri/radeon/radeon_swtcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_swtcl.c
@@ -38,6 +38,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/enums.h"
#include "main/imports.h"
#include "main/macros.h"
+#include "main/simple_list.h"
#include "swrast_setup/swrast_setup.h"
#include "math/m_translate.h"
@@ -50,6 +51,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_state.h"
#include "radeon_swtcl.h"
#include "radeon_tcl.h"
+#include "radeon_debug.h"
/* R100: xyzw, c0, c1/fog, stq[0..2] = 4+1+1+3*3 = 15 right? */
@@ -213,22 +215,41 @@ static void radeonSetVertexFormat( GLcontext *ctx )
NULL, 0 );
rmesa->radeon.swtcl.vertex_size /= 4;
RENDERINPUTS_COPY( rmesa->radeon.tnl_index_bitset, index_bitset );
- if (RADEON_DEBUG & DEBUG_VERTS)
- fprintf( stderr, "%s: vertex_size= %d floats\n",
- __FUNCTION__, rmesa->radeon.swtcl.vertex_size);
+ radeon_print(RADEON_SWRENDER, RADEON_VERBOSE,
+ "%s: vertex_size= %d floats\n", __FUNCTION__, rmesa->radeon.swtcl.vertex_size);
}
}
+static void radeon_predict_emit_size( r100ContextPtr rmesa )
+{
+
+ if (!rmesa->radeon.swtcl.emit_prediction) {
+ const int state_size = radeonCountStateEmitSize( &rmesa->radeon );
+ const int scissor_size = 8;
+ const int prims_size = 8;
+ const int vertex_size = 7;
+
+ if (rcommonEnsureCmdBufSpace(&rmesa->radeon,
+ state_size +
+ (scissor_size + prims_size + vertex_size),
+ __FUNCTION__))
+ rmesa->radeon.swtcl.emit_prediction = radeonCountStateEmitSize( &rmesa->radeon );
+ else
+ rmesa->radeon.swtcl.emit_prediction = state_size;
+ rmesa->radeon.swtcl.emit_prediction += scissor_size + prims_size + vertex_size
+ + rmesa->radeon.cmdbuf.cs->cdw;
+ }
+}
static void radeonRenderStart( GLcontext *ctx )
{
- r100ContextPtr rmesa = R100_CONTEXT( ctx );
+ r100ContextPtr rmesa = R100_CONTEXT( ctx );
- radeonSetVertexFormat( ctx );
-
- if (rmesa->radeon.dma.flush != 0 &&
- rmesa->radeon.dma.flush != rcommon_flush_last_swtcl_prim)
- rmesa->radeon.dma.flush( ctx );
+ radeonSetVertexFormat( ctx );
+
+ if (rmesa->radeon.dma.flush != 0 &&
+ rmesa->radeon.dma.flush != rcommon_flush_last_swtcl_prim)
+ rmesa->radeon.dma.flush( ctx );
}
@@ -283,15 +304,12 @@ void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
{
r100ContextPtr rmesa = R100_CONTEXT(ctx);
- rcommonEnsureCmdBufSpace(&rmesa->radeon,
- rmesa->radeon.hw.max_state_size + (12*sizeof(int)),
- __FUNCTION__);
radeonEmitState(&rmesa->radeon);
radeonEmitVertexAOS( rmesa,
rmesa->radeon.swtcl.vertex_size,
- rmesa->radeon.dma.current,
+ first_elem(&rmesa->radeon.dma.reserved)->bo,
current_offset);
@@ -299,6 +317,13 @@ void r100_swtcl_flush(GLcontext *ctx, uint32_t current_offset)
rmesa->swtcl.vertex_format,
rmesa->radeon.swtcl.hw_primitive,
rmesa->radeon.swtcl.numverts);
+ if ( rmesa->radeon.swtcl.emit_prediction < rmesa->radeon.cmdbuf.cs->cdw )
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n",
+ rmesa->radeon.cmdbuf.cs->cdw - rmesa->radeon.swtcl.emit_prediction );
+
+
+ rmesa->radeon.swtcl.emit_prediction = 0;
}
@@ -341,6 +366,16 @@ radeonDmaPrimitive( r100ContextPtr rmesa, GLenum prim )
// assert(rmesa->radeon.dma.current.ptr == rmesa->radeon.dma.current.start);
}
+static void* radeon_alloc_verts( r100ContextPtr rmesa , GLuint nr, GLuint size )
+{
+ void *rv;
+ do {
+ radeon_predict_emit_size( rmesa );
+ rv = rcommonAllocDmaLowVerts( &rmesa->radeon, nr, size );
+ } while (!rv);
+ return rv;
+}
+
#define LOCAL_VARS r100ContextPtr rmesa = R100_CONTEXT(ctx)
#define INIT( prim ) radeonDmaPrimitive( rmesa, prim )
#define FLUSH() RADEON_NEWPRIM( rmesa )
@@ -348,8 +383,7 @@ radeonDmaPrimitive( r100ContextPtr rmesa, GLenum prim )
// (((int)rmesa->radeon.dma.current.end - (int)rmesa->radeon.dma.current.ptr) / (rmesa->radeon.swtcl.vertex_size*4))
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
((RADEON_BUFFER_SIZE) / (rmesa->radeon.swtcl.vertex_size*4))
-#define ALLOC_VERTS( nr ) \
- rcommonAllocDmaLowVerts( &rmesa->radeon, nr, rmesa->radeon.swtcl.vertex_size * 4 )
+#define ALLOC_VERTS( nr ) radeon_alloc_verts( rmesa, nr, rmesa->radeon.swtcl.vertex_size * 4 )
#define EMIT_VERTS( ctx, j, nr, buf ) \
_tnl_emit_vertices_to_buffer(ctx, j, (j)+(nr), buf)
@@ -386,8 +420,8 @@ static GLboolean radeon_run_render( GLcontext *ctx,
if (!length)
continue;
- if (RADEON_DEBUG & DEBUG_PRIMS)
- fprintf(stderr, "radeon_render.c: prim %s %d..%d\n",
+ radeon_print(RADEON_SWRENDER, RADEON_NORMAL,
+ "radeon_render.c: prim %s %d..%d\n",
_mesa_lookup_enum_by_nr(prim & PRIM_MODE_MASK),
start, start+length);
@@ -442,7 +476,7 @@ static void radeonResetLineStipple( GLcontext *ctx );
#undef ALLOC_VERTS
#define CTX_ARG r100ContextPtr rmesa
#define GET_VERTEX_DWORDS() rmesa->radeon.swtcl.vertex_size
-#define ALLOC_VERTS( n, size ) rcommonAllocDmaLowVerts( &rmesa->radeon, n, (size) * 4 )
+#define ALLOC_VERTS( n, size ) radeon_alloc_verts( rmesa, n, (size) * 4 )
#undef LOCAL_VARS
#define LOCAL_VARS \
r100ContextPtr rmesa = R100_CONTEXT(ctx); \
@@ -551,7 +585,7 @@ do { \
#define LOCAL_VARS(n) \
r100ContextPtr rmesa = R100_CONTEXT(ctx); \
- GLuint color[n], spec[n]; \
+ GLuint color[n] = {0}, spec[n] = {0}; \
GLuint coloroffset = rmesa->swtcl.coloroffset; \
GLuint specoffset = rmesa->swtcl.specoffset; \
(void) color; (void) spec; (void) coloroffset; (void) specoffset;
@@ -750,7 +784,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
TCL_FALLBACK( ctx, RADEON_TCL_FALLBACK_RASTER, GL_TRUE );
_swsetup_Wakeup( ctx );
rmesa->radeon.swtcl.RenderIndex = ~0;
- if (RADEON_DEBUG & DEBUG_FALLBACKS) {
+ if (RADEON_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "Radeon begin rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
@@ -781,7 +815,7 @@ void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
radeonChooseVertexState( ctx );
radeonChooseRenderState( ctx );
}
- if (RADEON_DEBUG & DEBUG_FALLBACKS) {
+ if (RADEON_DEBUG & RADEON_FALLBACKS) {
fprintf(stderr, "Radeon end rasterization fallback: 0x%x %s\n",
bit, getFallbackString(bit));
}
@@ -804,6 +838,7 @@ void radeonInitSwtcl( GLcontext *ctx )
init_rast_tab();
firsttime = 0;
}
+ rmesa->radeon.swtcl.emit_prediction = 0;
tnl->Driver.Render.Start = radeonRenderStart;
tnl->Driver.Render.Finish = radeonRenderFinish;
diff --git a/src/mesa/drivers/dri/radeon/radeon_tcl.c b/src/mesa/drivers/dri/radeon/radeon_tcl.c
index df6708f05e..b334ea05e5 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tcl.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tcl.c
@@ -50,6 +50,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "radeon_tcl.h"
#include "radeon_swtcl.h"
#include "radeon_maos.h"
+#include "radeon_common_context.h"
@@ -149,9 +150,6 @@ static GLushort *radeonAllocElts( r100ContextPtr rmesa, GLuint nr )
if (rmesa->radeon.dma.flush)
rmesa->radeon.dma.flush( rmesa->radeon.glCtx );
- rcommonEnsureCmdBufSpace(&rmesa->radeon, rmesa->radeon.hw.max_state_size + ELTS_BUFSZ(nr) +
- AOS_BUFSZ(rmesa->radeon.tcl.aos_count), __FUNCTION__);
-
radeonEmitAOS( rmesa,
rmesa->radeon.tcl.aos_count, 0 );
@@ -176,10 +174,6 @@ static void radeonEmitPrim( GLcontext *ctx,
r100ContextPtr rmesa = R100_CONTEXT( ctx );
radeonTclPrimitive( ctx, prim, hwprim );
- rcommonEnsureCmdBufSpace( &rmesa->radeon,
- AOS_BUFSZ(rmesa->radeon.tcl.aos_count) +
- rmesa->radeon.hw.max_state_size + VBUF_BUFSZ, __FUNCTION__ );
-
radeonEmitAOS( rmesa,
rmesa->radeon.tcl.aos_count,
start );
@@ -196,6 +190,8 @@ static void radeonEmitPrim( GLcontext *ctx,
radeonEmitPrim( ctx, prim, hwprim, start, count ); \
(void) rmesa; } while (0)
+#define MAX_CONVERSION_SIZE 40
+
/* Try & join small primitives
*/
#if 0
@@ -360,6 +356,73 @@ radeonComputeFogBlendFactor( GLcontext *ctx, GLfloat fogcoord )
}
}
+/**
+ * Predict total emit size for next rendering operation so there is no flush in middle of rendering
+ * Prediction has to aim towards the best possible value that is worse than worst case scenario
+ */
+static GLuint radeonEnsureEmitSize( GLcontext * ctx , GLuint inputs )
+{
+ r100ContextPtr rmesa = R100_CONTEXT(ctx);
+ TNLcontext *tnl = TNL_CONTEXT(ctx);
+ struct vertex_buffer *VB = &tnl->vb;
+ GLuint space_required;
+ GLuint state_size;
+ GLuint nr_aos = 1; /* radeonEmitArrays does always emit one */
+ int i;
+ /* list of flags that are allocating aos object */
+ const GLuint flags_to_check[] = {
+ VERT_BIT_NORMAL,
+ VERT_BIT_COLOR0,
+ VERT_BIT_COLOR1,
+ VERT_BIT_FOG
+ };
+ /* predict number of aos to emit */
+ for (i=0; i < sizeof(flags_to_check)/sizeof(flags_to_check[0]); ++i)
+ {
+ if (inputs & flags_to_check[i])
+ ++nr_aos;
+ }
+ for (i = 0; i < ctx->Const.MaxTextureUnits; ++i)
+ {
+ if (inputs & VERT_BIT_TEX(i))
+ ++nr_aos;
+ }
+
+ {
+ /* count the prediction for state size */
+ space_required = 0;
+ state_size = radeonCountStateEmitSize( &rmesa->radeon );
+ /* tcl may be changed in radeonEmitArrays so account for it if not dirty */
+ if (!rmesa->hw.tcl.dirty)
+ state_size += rmesa->hw.tcl.check( rmesa->radeon.glCtx, &rmesa->hw.tcl );
+ /* predict size for elements */
+ for (i = 0; i < VB->PrimitiveCount; ++i)
+ {
+ if (!VB->Primitive[i].count)
+ continue;
+ /* If primitive.count is less than MAX_CONVERSION_SIZE
+ rendering code may decide convert to elts.
+ In that case we have to make pessimistic prediction.
+ and use larger of 2 paths. */
+ const GLuint elts = ELTS_BUFSZ(nr_aos);
+ const GLuint index = INDEX_BUFSZ;
+ const GLuint vbuf = VBUF_BUFSZ;
+ if ( (!VB->Elts && VB->Primitive[i].count >= MAX_CONVERSION_SIZE)
+ || vbuf > index + elts)
+ space_required += vbuf;
+ else
+ space_required += index + elts;
+ space_required += AOS_BUFSZ(nr_aos);
+ }
+ space_required += SCISSOR_BUFSZ;
+ }
+ /* flush the buffer in case we need more than is left. */
+ if (rcommonEnsureCmdBufSpace(&rmesa->radeon, space_required, __FUNCTION__))
+ return space_required + radeonCountStateEmitSize( &rmesa->radeon );
+ else
+ return space_required + state_size;
+}
+
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
@@ -410,6 +473,8 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
}
radeonReleaseArrays( ctx, ~0 );
+ GLuint emit_end = radeonEnsureEmitSize( ctx, inputs )
+ + rmesa->radeon.cmdbuf.cs->cdw;
radeonEmitArrays( ctx, inputs );
rmesa->tcl.Elts = VB->Elts;
@@ -429,6 +494,10 @@ static GLboolean radeon_run_tcl_render( GLcontext *ctx,
radeonEmitPrimitive( ctx, start, start+length, prim );
}
+ if (emit_end < rmesa->radeon.cmdbuf.cs->cdw)
+ WARN_ONCE("Rendering was %d commands larger than predicted size."
+ " We might overflow command buffer.\n", rmesa->radeon.cmdbuf.cs->cdw - emit_end);
+
return GL_FALSE; /* finished the pipe */
}
@@ -518,7 +587,7 @@ static void transition_to_hwtnl( GLcontext *ctx )
// radeonReleaseDmaRegion( rmesa, &rmesa->swtcl.indexed_verts,
// __FUNCTION__ );
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "Radeon end tcl fallback\n");
}
@@ -555,7 +624,7 @@ void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
if (mode) {
rmesa->radeon.TclFallback |= bit;
if (oldfallback == 0) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "Radeon begin tcl fallback %s\n",
getFallbackString( bit ));
transition_to_swtnl( ctx );
@@ -564,7 +633,7 @@ void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode )
else {
rmesa->radeon.TclFallback &= ~bit;
if (oldfallback == bit) {
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "Radeon end tcl fallback %s\n",
getFallbackString( bit ));
transition_to_hwtnl( ctx );
diff --git a/src/mesa/drivers/dri/radeon/radeon_tex.c b/src/mesa/drivers/dri/radeon/radeon_tex.c
index 2549d5cb5c..99865fff27 100644
--- a/src/mesa/drivers/dri/radeon/radeon_tex.c
+++ b/src/mesa/drivers/dri/radeon/radeon_tex.c
@@ -263,7 +263,7 @@ static void radeonTexEnv( GLcontext *ctx, GLenum target,
GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
- if ( RADEON_DEBUG & DEBUG_STATE ) {
+ if ( RADEON_DEBUG & RADEON_STATE ) {
fprintf( stderr, "%s( %s )\n",
__FUNCTION__, _mesa_lookup_enum_by_nr( pname ) );
}
@@ -325,10 +325,8 @@ static void radeonTexParameter( GLcontext *ctx, GLenum target,
{
radeonTexObj* t = radeon_tex_obj(texObj);
- if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
- fprintf( stderr, "%s( %s )\n", __FUNCTION__,
+ radeon_print(RADEON_TEXTURE, RADEON_VERBOSE, "%s( %s )\n", __FUNCTION__,
_mesa_lookup_enum_by_nr( pname ) );
- }
switch ( pname ) {
case GL_TEXTURE_MIN_FILTER:
@@ -376,10 +374,9 @@ static void radeonDeleteTexture( GLcontext *ctx,
radeonTexObj* t = radeon_tex_obj(texObj);
int i;
- if ( RADEON_DEBUG & (DEBUG_STATE|DEBUG_TEXTURE) ) {
- fprintf( stderr, "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj,
+ radeon_print(RADEON_TEXTURE, RADEON_NORMAL,
+ "%s( %p (target = %s) )\n", __FUNCTION__, (void *)texObj,
_mesa_lookup_enum_by_nr( texObj->Target ) );
- }
if ( rmesa ) {
radeon_firevertices(&rmesa->radeon);
diff --git a/src/mesa/drivers/dri/radeon/radeon_texstate.c b/src/mesa/drivers/dri/radeon/radeon_texstate.c
index c29105d7b8..ae41b90efe 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texstate.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texstate.c
@@ -277,7 +277,7 @@ static GLboolean radeonUpdateTextureEnv( GLcontext *ctx, int unit )
assert( (texUnit->_ReallyEnabled == 0)
|| (texUnit->_Current != NULL) );
- if ( RADEON_DEBUG & DEBUG_TEXTURE ) {
+ if ( RADEON_DEBUG & RADEON_TEXTURE ) {
fprintf( stderr, "%s( %p, %d )\n", __FUNCTION__, (void *)ctx, unit );
}
@@ -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 {
@@ -933,7 +936,7 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
(texUnit->GenS.Mode != texUnit->GenQ.Mode)) ) {
/* Mixed modes, fallback:
*/
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback mixed texgen\n");
return GL_FALSE;
}
@@ -941,7 +944,7 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
}
else {
/* some texgen mode not including both S and T bits */
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback mixed texgen/nontexgen\n");
return GL_FALSE;
}
@@ -991,7 +994,7 @@ static GLboolean radeon_validate_texgen( GLcontext *ctx, GLuint unit )
default:
/* Unsupported mode, fallback:
*/
- if (RADEON_DEBUG & DEBUG_FALLBACKS)
+ if (RADEON_DEBUG & RADEON_FALLBACKS)
fprintf(stderr, "fallback GL_SPHERE_MAP\n");
return GL_FALSE;
}
@@ -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 ad501c454c..049284ef8c 100644
--- a/src/mesa/drivers/dri/radeon/radeon_texture.c
+++ b/src/mesa/drivers/dri/radeon/radeon_texture.c
@@ -579,7 +579,7 @@ static void radeon_teximage(
}
if (!t->mt)
- radeon_try_alloc_miptree(rmesa, t, texImage, face, level);
+ radeon_try_alloc_miptree(rmesa, t, image, face, level);
if (t->mt && radeon_miptree_matches_image(t->mt, texImage, face, level)) {
radeon_mipmap_level *lvl;
image->mt = t->mt;
@@ -610,9 +610,17 @@ static void radeon_teximage(
if (pixels) {
radeon_teximage_map(image, GL_TRUE);
-
if (compressed) {
- memcpy(texImage->Data, pixels, imageSize);
+ if (image->mt) {
+ uint32_t srcRowStride, bytesPerRow, rows;
+ srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
+ bytesPerRow = srcRowStride;
+ rows = (height + 3) / 4;
+ copy_rows(texImage->Data, image->mt->levels[level].rowstride,
+ pixels, srcRowStride, rows, bytesPerRow);
+ } else {
+ memcpy(texImage->Data, pixels, imageSize);
+ }
} else {
GLuint dstRowStride;
GLuint *dstImageOffsets;
@@ -651,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);
@@ -756,14 +759,23 @@ static void radeon_texsubimage(GLcontext* ctx, int dims, GLenum target, int leve
}
if (compressed) {
- uint32_t srcRowStride, bytesPerRow, rows;
- dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+ uint32_t srcRowStride, bytesPerRow, rows;
+ GLubyte *img_start;
+ if (!image->mt) {
+ dstRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, texImage->Width);
+ img_start = _mesa_compressed_image_address(xoffset, yoffset, 0,
+ texImage->TexFormat->MesaFormat,
+ texImage->Width, texImage->Data);
+ }
+ else {
+ uint32_t blocks_x = dstRowStride / (image->mt->bpp * 4);
+ img_start = texImage->Data + image->mt->bpp * 4 * (blocks_x * (yoffset / 4) + xoffset / 4);
+ }
srcRowStride = _mesa_compressed_row_stride(texImage->TexFormat->MesaFormat, width);
bytesPerRow = srcRowStride;
- rows = height / 4;
+ rows = (height + 3) / 4;
- copy_rows(texImage->Data, dstRowStride, image->base.Data, srcRowStride, rows,
- bytesPerRow);
+ copy_rows(img_start, dstRowStride, pixels, srcRowStride, rows, bytesPerRow);
} else {
if (!texImage->TexFormat->StoreImage(ctx, dims, texImage->_BaseFormat,
@@ -775,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);
@@ -884,8 +891,8 @@ static void migrate_image_to_miptree(radeon_mipmap_tree *mt, radeon_texture_imag
uint32_t height;
/* need to confirm this value is correct */
if (mt->compressed) {
- height = image->base.Height / 4;
- srcrowstride = image->base.RowStride * mt->bpp;
+ height = (image->base.Height + 3) / 4;
+ srcrowstride = _mesa_compressed_row_stride(image->base.TexFormat->MesaFormat, image->base.Width);
} else {
height = image->base.Height * image->base.Depth;
srcrowstride = image->base.Width * image->base.TexFormat->TexelBytes;
@@ -919,7 +926,7 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
if (t->validated || t->image_override)
return GL_TRUE;
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, "%s: Validating texture %p now\n", __FUNCTION__, texObj);
if (baseimage->base.Border > 0)
@@ -947,11 +954,11 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
}
if (!t->mt) {
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, " Allocate new miptree\n");
- radeon_try_alloc_miptree(rmesa, t, &baseimage->base, 0, texObj->BaseLevel);
+ radeon_try_alloc_miptree(rmesa, t, baseimage, 0, texObj->BaseLevel);
if (!t->mt) {
- _mesa_problem(ctx, "r300_validate_texture failed to alloc miptree");
+ _mesa_problem(ctx, "radeon_validate_texture failed to alloc miptree");
return GL_FALSE;
}
}
@@ -960,16 +967,16 @@ int radeon_validate_texture_miptree(GLcontext * ctx, struct gl_texture_object *t
for(face = 0; face < t->mt->faces; ++face) {
for(level = t->mt->firstLevel; level <= t->mt->lastLevel; ++level) {
radeon_texture_image *image = get_radeon_texture_image(texObj->Image[face][level]);
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, " face %i, level %i... %p vs %p ", face, level, t->mt, image->mt);
if (t->mt == image->mt) {
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, "OK\n");
continue;
}
- if (RADEON_DEBUG & DEBUG_TEXTURE)
+ if (RADEON_DEBUG & RADEON_TEXTURE)
fprintf(stderr, "migrating\n");
migrate_image_to_miptree(t->mt, image, face, level);
}
@@ -1000,6 +1007,8 @@ radeon_get_tex_image(GLcontext * ctx, GLenum target, GLint level,
}
if (compressed) {
+ /* FIXME: this can't work for small textures (mips) which
+ use different hw stride */
_mesa_get_compressed_teximage(ctx, target, level, pixels,
texObj, texImage);
} else {
diff --git a/src/mesa/drivers/dri/radeon/server/radeon_reg.h b/src/mesa/drivers/dri/radeon/server/radeon_reg.h
index 866807462a..e81d7fdcd0 100644
--- a/src/mesa/drivers/dri/radeon/server/radeon_reg.h
+++ b/src/mesa/drivers/dri/radeon/server/radeon_reg.h
@@ -1601,6 +1601,8 @@
# define RADEON_STENCIL_VALUE_MASK (0xff << 16)
# define RADEON_STENCIL_WRITEMASK_SHIFT 24
# define RADEON_STENCIL_WRITE_MASK (0xff << 24)
+#define RADEON_RB3D_ZPASS_DATA 0x3290
+#define RADEON_RB3D_ZPASS_ADDR 0x3294
#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
# define RADEON_DEPTH_FORMAT_MASK (0xf << 0)
# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
@@ -1661,6 +1663,9 @@
# define RADEON_FORCE_Z_DIRTY (1 << 29)
# define RADEON_Z_WRITE_ENABLE (1 << 30)
# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31)
+
+#define RADEON_RE_STIPPLE_ADDR 0x1cc8
+#define RADEON_RE_STIPPLE_DATA 0x1ccc
#define RADEON_RE_LINE_PATTERN 0x1cd0
# define RADEON_LINE_PATTERN_MASK 0x0000ffff
# define RADEON_LINE_REPEAT_COUNT_SHIFT 16
diff --git a/src/mesa/drivers/dri/s3v/s3v_state.c b/src/mesa/drivers/dri/s3v/s3v_state.c
index c71c89a3e1..561f42c705 100644
--- a/src/mesa/drivers/dri/s3v/s3v_state.c
+++ b/src/mesa/drivers/dri/s3v/s3v_state.c
@@ -2,7 +2,6 @@
* Author: Max Lingua <sunmax@libero.it>
*/
-#include <X11/Xlibint.h>
#include "s3v_context.h"
#include "s3v_macros.h"
#include "s3v_dri.h"
@@ -24,7 +23,7 @@
static void s3vUpdateAlphaMode( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
- CARD32 cmd = vmesa->CMD;
+ uint32_t cmd = vmesa->CMD;
cmd &= ~ALPHA_BLEND_MASK;
if ( ctx->Color.BlendEnabled ) {
@@ -173,7 +172,7 @@ static void s3vDDClear( GLcontext *ctx, GLbitfield mask )
static void s3vUpdateZMode( GLcontext *ctx )
{
s3vContextPtr vmesa = S3V_CONTEXT(ctx);
- CARD32 cmd = vmesa->CMD;
+ uint32_t cmd = vmesa->CMD;
DEBUG(("Depth.Test = %i\n", ctx->Depth.Test));
DEBUG(("CMD was = 0x%x ", cmd));
diff --git a/src/mesa/drivers/dri/s3v/s3v_tex.c b/src/mesa/drivers/dri/s3v/s3v_tex.c
index 9b92519862..ec1182f34f 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/savage/savage_xmesa.c b/src/mesa/drivers/dri/savage/savage_xmesa.c
index a94f1c076c..931ceff0a8 100644
--- a/src/mesa/drivers/dri/savage/savage_xmesa.c
+++ b/src/mesa/drivers/dri/savage/savage_xmesa.c
@@ -23,7 +23,6 @@
*/
-#include <X11/Xlibint.h>
#include <stdio.h>
#include "main/context.h"
@@ -180,7 +179,7 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
}
/* Allocate the private area */
- savageScreen = (savageScreenPrivate *)Xmalloc(sizeof(savageScreenPrivate));
+ savageScreen = (savageScreenPrivate *)_mesa_malloc(sizeof(savageScreenPrivate));
if (!savageScreen)
return GL_FALSE;
@@ -227,7 +226,7 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
savageScreen->agpTextures.handle,
savageScreen->agpTextures.size,
(drmAddress *)&(savageScreen->agpTextures.map)) != 0) {
- Xfree(savageScreen);
+ _mesa_free(savageScreen);
sPriv->private = NULL;
return GL_FALSE;
}
@@ -247,7 +246,7 @@ savageInitDriver(__DRIscreenPrivate *sPriv)
savageScreen->aperture.size,
(drmAddress *)&savageScreen->aperture.map) != 0)
{
- Xfree(savageScreen);
+ _mesa_free(savageScreen);
sPriv->private = NULL;
return GL_FALSE;
}
@@ -283,7 +282,7 @@ savageDestroyScreen(__DRIscreenPrivate *sPriv)
/* free all option information */
driDestroyOptionInfo (&savageScreen->optionCache);
- Xfree(savageScreen);
+ _mesa_free(savageScreen);
sPriv->private = NULL;
}
@@ -301,7 +300,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,
savageScreen->sarea_priv_offset);
int textureSize[SAVAGE_NR_TEX_HEAPS];
int i;
- imesa = (savageContextPtr)Xcalloc(sizeof(savageContext), 1);
+ imesa = (savageContextPtr)_mesa_calloc(sizeof(savageContext));
if (!imesa) {
return GL_FALSE;
}
@@ -318,7 +317,7 @@ savageCreateContext( const __GLcontextModes *mesaVis,
shareCtx = NULL;
ctx = _mesa_create_context(mesaVis, shareCtx, &functions, imesa);
if (!ctx) {
- Xfree(imesa);
+ _mesa_free(imesa);
return GL_FALSE;
}
driContextPriv->driverPrivate = imesa;
diff --git a/src/mesa/drivers/dri/savage/savagecontext.h b/src/mesa/drivers/dri/savage/savagecontext.h
index fd6399d6a6..53a37db1cb 100644
--- a/src/mesa/drivers/dri/savage/savagecontext.h
+++ b/src/mesa/drivers/dri/savage/savagecontext.h
@@ -31,7 +31,6 @@ typedef struct savage_context_t savageContext;
typedef struct savage_context_t *savageContextPtr;
typedef struct savage_texture_object_t *savageTextureObjectPtr;
-#include <X11/Xlibint.h>
#include "dri_util.h"
#include "main/mtypes.h"
#include "xf86drm.h"
diff --git a/src/mesa/drivers/dri/swrast/swrast.c b/src/mesa/drivers/dri/swrast/swrast.c
index fbfa49c99d..cd499cd5d2 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"
@@ -62,8 +63,11 @@
#define need_GL_SGI_color_table
/* sw extensions not associated with some GL version */
+#define need_GL_ARB_draw_elements_base_vertex
#define need_GL_ARB_shader_objects
+#define need_GL_ARB_vertex_array_object
#define need_GL_ARB_vertex_program
+#define need_GL_ARB_sync
#define need_GL_APPLE_vertex_array_object
#define need_GL_ATI_fragment_shader
#define need_GL_ATI_separate_stencil
@@ -93,8 +97,12 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_histogram", GL_EXT_histogram_functions },
{ "GL_SGI_color_table", GL_SGI_color_table_functions },
+ { "GL_ARB_depth_clamp", NULL },
+ { "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions },
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
+ { "GL_ARB_vertex_array_object", GL_ARB_vertex_array_object_functions },
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
+ { "GL_ARB_sync", GL_ARB_sync_functions },
{ "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
{ "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
{ "GL_ATI_separate_stencil", GL_ATI_separate_stencil_functions },
@@ -105,6 +113,7 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
{ "GL_EXT_stencil_two_side", GL_EXT_stencil_two_side_functions },
{ "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
+ { "GL_NV_depth_clamp", NULL },
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
{ "GL_NV_fragment_program", GL_NV_fragment_program_functions },
{ NULL, NULL }
@@ -641,6 +650,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;
}
@@ -652,6 +663,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 1f7257eaea..f6a48b3ae1 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 d2010f0907..54073e7691 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 904659e345..692657a5df 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 ede43ef4c0..5abcd1d927 100644
--- a/src/mesa/drivers/windows/gdi/mesa.def
+++ b/src/mesa/drivers/windows/gdi/mesa.def
@@ -902,7 +902,6 @@ EXPORTS
_mesa_generate_mipmap
_mesa_get_compressed_teximage
_mesa_get_current_context
- _mesa_get_program_register
_mesa_get_teximage
_mesa_init_driver_functions
_mesa_init_glsl_driver_functions
@@ -944,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
@@ -954,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 e1971db693..8929b22af1 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 342a742867..7ac425a109 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 465b380a0c..25ac08a2f0 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 6ae5b6fd58..79b058634c 100644
--- a/src/mesa/drivers/x11/xm_api.c
+++ b/src/mesa/drivers/x11/xm_api.c
@@ -79,6 +79,7 @@
#include "tnl/t_context.h"
#include "tnl/t_pipeline.h"
#include "drivers/common/driverfuncs.h"
+#include "drivers/common/meta.h"
/**
* Global X driver lock
@@ -1316,7 +1317,9 @@ xmesa_convert_from_x_visual_type( int visualType )
#define need_GL_SGI_color_table
/* sw extensions not associated with some GL version */
+#define need_GL_ARB_draw_elements_base_vertex
#define need_GL_ARB_shader_objects
+#define need_GL_ARB_sync
#define need_GL_ARB_vertex_program
#define need_GL_APPLE_vertex_array_object
#define need_GL_ATI_fragment_shader
@@ -1345,7 +1348,10 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_histogram", GL_EXT_histogram_functions },
{ "GL_SGI_color_table", GL_SGI_color_table_functions },
+ { "GL_ARB_depth_clamp", NULL },
+ { "GL_ARB_draw_elements_base_vertex", GL_ARB_draw_elements_base_vertex_functions },
{ "GL_ARB_shader_objects", GL_ARB_shader_objects_functions },
+ { "GL_ARB_sync", GL_ARB_sync_functions },
{ "GL_ARB_vertex_program", GL_ARB_vertex_program_functions },
{ "GL_APPLE_vertex_array_object", GL_APPLE_vertex_array_object_functions },
{ "GL_ATI_fragment_shader", GL_ATI_fragment_shader_functions },
@@ -1355,6 +1361,7 @@ const struct dri_extension card_extensions[] =
{ "GL_EXT_gpu_program_parameters", GL_EXT_gpu_program_parameters_functions },
{ "GL_EXT_paletted_texture", GL_EXT_paletted_texture_functions },
{ "GL_MESA_resize_buffers", GL_MESA_resize_buffers_functions },
+ { "GL_NV_depth_clamp", NULL },
{ "GL_NV_vertex_program", GL_NV_vertex_program_functions },
{ "GL_NV_fragment_program", GL_NV_fragment_program_functions },
{ NULL, NULL }
@@ -1641,6 +1648,8 @@ XMesaContext XMesaCreateContext( XMesaVisual v, XMesaContext share_list )
xmesa_register_swrast_functions( mesaCtx );
_swsetup_Wakeup(mesaCtx);
+ _mesa_meta_init(mesaCtx);
+
return c;
}
@@ -1655,6 +1664,8 @@ void XMesaDestroyContext( XMesaContext c )
FXdestroyContext( XMESA_BUFFER(mesaCtx->DrawBuffer) );
#endif
+ _mesa_meta_free( mesaCtx );
+
_swsetup_DestroyContext( mesaCtx );
_swrast_DestroyContext( mesaCtx );
_tnl_DestroyContext( mesaCtx );
diff --git a/src/mesa/drivers/x11/xm_dd.c b/src/mesa/drivers/x11/xm_dd.c
index 9a01465bdf..e2d4aa9b2d 100644
--- a/src/mesa/drivers/x11/xm_dd.c
+++ b/src/mesa/drivers/x11/xm_dd.c
@@ -51,6 +51,7 @@
#include "swrast_setup/swrast_setup.h"
#include "tnl/tnl.h"
#include "tnl/t_context.h"
+#include "drivers/common/meta.h"
#include "xmesaP.h"
@@ -1147,19 +1148,28 @@ xmesa_init_driver_functions( XMesaVisual xmvisual,
driver->IndexMask = index_mask;
driver->ColorMask = color_mask;
driver->Enable = enable;
- driver->Clear = clear_buffers;
driver->Viewport = xmesa_viewport;
-#ifndef XFree86Server
- driver->CopyPixels = xmesa_CopyPixels;
- if (xmvisual->undithered_pf == PF_8R8G8B &&
- xmvisual->dithered_pf == PF_8R8G8B &&
- xmvisual->BitsPerPixel == 32) {
- driver->DrawPixels = xmesa_DrawPixels_8R8G8B;
- }
- else if (xmvisual->undithered_pf == PF_5R6G5B) {
- driver->DrawPixels = xmesa_DrawPixels_5R6G5B;
+ if (TEST_META_FUNCS) {
+ 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;
+#ifndef XFree86Server
+ driver->CopyPixels = xmesa_CopyPixels;
+ if (xmvisual->undithered_pf == PF_8R8G8B &&
+ xmvisual->dithered_pf == PF_8R8G8B &&
+ xmvisual->BitsPerPixel == 32) {
+ driver->DrawPixels = xmesa_DrawPixels_8R8G8B;
+ }
+ else if (xmvisual->undithered_pf == PF_5R6G5B) {
+ driver->DrawPixels = xmesa_DrawPixels_5R6G5B;
+ }
#endif
+ }
driver->TestProxyTexImage = test_proxy_teximage;
#if ENABLE_EXT_texure_compression_s3tc
driver->ChooseTextureFormat = choose_tex_format;
diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h
index 65e747d7b9..25db55862e 100644
--- a/src/mesa/drivers/x11/xmesaP.h
+++ b/src/mesa/drivers/x11/xmesaP.h
@@ -581,4 +581,8 @@ extern void xmesa_register_swrast_functions( GLcontext *ctx );
#define ENABLE_EXT_timer_query 0 /* may not have 64-bit GLuint64EXT */
#endif
+
+#define TEST_META_FUNCS 0
+
+
#endif
diff --git a/src/mesa/glapi/ARB_depth_clamp.xml b/src/mesa/glapi/ARB_depth_clamp.xml
new file mode 100644
index 0000000000..157c9a86b1
--- /dev/null
+++ b/src/mesa/glapi/ARB_depth_clamp.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_depth_clamp" number="61">
+ <enum name="DEPTH_CLAMP" count="1" value="0x864F">
+ <size name="Get" mode="get"/>
+ </enum>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/ARB_draw_elements_base_vertex.xml b/src/mesa/glapi/ARB_draw_elements_base_vertex.xml
new file mode 100644
index 0000000000..f4067f4c8d
--- /dev/null
+++ b/src/mesa/glapi/ARB_draw_elements_base_vertex.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<!-- Note: no GLX protocol info yet. -->
+
+
+<OpenGLAPI>
+
+<category name="GL_ARB_draw_elements_base_vertex" number="62">
+
+ <function name="DrawElementsBaseVertex" offset="assign">
+ <param name="mode" type="GLenum"/>
+ <param name="count" type="GLsizei"/>
+ <param name="type" type="GLenum"/>
+ <param name="indices" type="const GLvoid *"/>
+ <param name="basevertex" type="GLint"/>
+ </function>
+
+ <function name="DrawRangeElementsBaseVertex" offset="assign">
+ <param name="mode" type="GLenum"/>
+ <param name="start" type="GLuint"/>
+ <param name="end" type="GLuint"/>
+ <param name="count" type="GLsizei"/>
+ <param name="type" type="GLenum"/>
+ <param name="indices" type="const GLvoid *"/>
+ <param name="basevertex" type="GLint"/>
+ </function>
+
+ <function name="MultiDrawElementsBaseVertex" offset="assign">
+ <param name="mode" type="GLenum"/>
+ <param name="count" type="const GLsizei *"/>
+ <param name="type" type="GLenum"/>
+ <param name="indices" type="const GLvoid **"/>
+ <param name="primcount" type="GLsizei"/>
+ <param name="basevertex" type="const GLint *"/>
+ </function>
+
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/ARB_seamless_cube_map.xml b/src/mesa/glapi/ARB_seamless_cube_map.xml
new file mode 100644
index 0000000000..3cdc84d2b9
--- /dev/null
+++ b/src/mesa/glapi/ARB_seamless_cube_map.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_ARB_seamless_cubemap" number="65">
+ <enum name="TEXTURE_CUBE_MAP_SEAMLESS" count="1" value="0x88F4">
+ <size name="Get" mode="get"/>
+ </enum>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/ARB_sync.xml b/src/mesa/glapi/ARB_sync.xml
new file mode 100644
index 0000000000..37f474980c
--- /dev/null
+++ b/src/mesa/glapi/ARB_sync.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+<category name="GL_ARB_sync" number="61">
+ <type name="int64" size="8" glx_name="CARD64"/>
+ <type name="uint64" size="8" unsigned="true" glx_name="CARD64"/>
+ <type name="sync" size="8" unsigned="true" glx_name="CARD64"/>
+
+ <enum name="MAX_SERVER_WAIT_TIMEOUT" count="1" value="0x9111">
+ <size name="Get" mode="get"/>
+ </enum>
+ <enum name="OBJECT_TYPE" count="1" value="0x9112">
+ <size name="GetSynciv" mode="get"/>
+ </enum>
+ <enum name="SYNC_CONDITION" count="1" value="0x9113">
+ <size name="GetSynciv" mode="get"/>
+ </enum>
+ <enum name="SYNC_STATUS" count="1" value="0x9114">
+ <size name="GetSynciv" mode="get"/>
+ </enum>
+ <enum name="SYNC_FLAGS" count="1" value="0x9115">
+ <size name="GetSynciv" mode="get"/>
+ </enum>
+
+ <enum name="SYNC_FENCE" value="0x9116"/>
+ <enum name="SYNC_GPU_COMMANDS_COMPLETE" value="0x9117"/>
+ <enum name="UNSIGNALED" value="0x9118"/>
+ <enum name="SIGNALED" value="0x9119"/>
+ <enum name="ALREADY_SIGNALED" value="0x911A"/>
+ <enum name="TIMEOUT_EXPIRED" value="0x911B"/>
+ <enum name="CONDITION_SATISFIED" value="0x911C"/>
+ <enum name="WAIT_FAILED" value="0x911D"/>
+
+ <enum name="SYNC_FLUSH_COMMANDS_BIT" value="0x00000001"/>
+ <enum name="TIMEOUT_IGNORED" value="0xFFFFFFFFFFFFFFFF"/>
+
+
+
+ <function name="FenceSync" offset="assign">
+ <param name="condition" type="GLenum"/>
+ <param name="flags" type="GLbitfield"/>
+ <return type="GLsync"/>
+ </function>
+
+ <function name="IsSync" offset="assign">
+ <param name="sync" type="GLsync"/>
+ <return type="GLboolean"/>
+ </function>
+
+ <function name="DeleteSync" offset="assign">
+ <param name="sync" type="GLsync"/>
+ </function>
+
+ <function name="ClientWaitSync" offset="assign">
+ <param name="sync" type="GLsync"/>
+ <param name="flags" type="GLbitfield"/>
+ <param name="timeout" type="GLuint64"/>
+ <return type="GLenum"/>
+ </function>
+
+ <function name="WaitSync" offset="assign">
+ <param name="sync" type="GLsync"/>
+ <param name="flags" type="GLbitfield"/>
+ <param name="timeout" type="GLuint64"/>
+ </function>
+
+ <function name="GetInteger64v" offset="assign">
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLint64 *" output="true" variable_param="pname"/>
+ </function>
+
+ <function name="GetSynciv" offset="assign">
+ <param name="sync" type="GLsync"/>
+ <param name="pname" type="GLenum"/>
+ <param name="bufSize" type="GLsizei"/>
+ <param name="length" type="GLsizei *" output="true"/>
+ <param name="values" type="GLint *" output="true" variable_param="pname"/>
+ </function>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_framebuffer_object.xml b/src/mesa/glapi/EXT_framebuffer_object.xml
index 1b0de2ad23..5559b48b11 100644
--- a/src/mesa/glapi/EXT_framebuffer_object.xml
+++ b/src/mesa/glapi/EXT_framebuffer_object.xml
@@ -192,42 +192,4 @@
</function>
</category>
-
-
-<category name="GL_EXT_texture_array" number="329">
- <enum name="TEXTURE_1D_ARRAY_EXT" value="0x8C18"/>
- <enum name="PROXY_TEXTURE_1D_ARRAY_EXT" value="0x8C19"/>
- <enum name="TEXTURE_2D_ARRAY_EXT" value="0x8C1A"/>
- <enum name="PROXY_TEXTURE_2D_ARRAY_EXT" value="0x8C1B"/>
-
- <enum name="TEXTURE_BINDING_1D_ARRAY_EXT" count="1" value="0x8C1C">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="TEXTURE_BINDING_2D_ARRAY_EXT" count="1" value="0x8C1D">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="MAX_ARRAY_TEXTURE_LAYERS_EXT" count="1" value="0x88FF">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="COMPARE_REF_DEPTH_TO_TEXTURE_EXT" count="1" value="0x884E">
- <size name="Get" mode="get"/>
- </enum>
-
- <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" count="1" value="0x8CD4">
- <size name="GetFramebufferAttachmentParameterivEXT" mode="get"/>
- </enum>
-
- <function name="FramebufferTextureLayerEXT" offset="assign">
- <param name="target" type="GLenum"/>
- <param name="attachment" type="GLenum"/>
- <param name="texture" type="GLuint"/>
- <param name="level" type="GLint"/>
- <param name="layer" type="GLint"/>
- </function>
-</category>
-
-
</OpenGLAPI>
diff --git a/src/mesa/glapi/EXT_provoking_vertex.xml b/src/mesa/glapi/EXT_provoking_vertex.xml
index f528a2c7d3..71d2c72909 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/EXT_texture_array.xml b/src/mesa/glapi/EXT_texture_array.xml
new file mode 100644
index 0000000000..e5bd9f3c69
--- /dev/null
+++ b/src/mesa/glapi/EXT_texture_array.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<!DOCTYPE OpenGLAPI SYSTEM "gl_API.dtd">
+
+<OpenGLAPI>
+
+<category name="GL_EXT_texture_array" number="329">
+ <enum name="TEXTURE_1D_ARRAY_EXT" value="0x8C18"/>
+ <enum name="PROXY_TEXTURE_1D_ARRAY_EXT" value="0x8C19"/>
+ <enum name="TEXTURE_2D_ARRAY_EXT" value="0x8C1A"/>
+ <enum name="PROXY_TEXTURE_2D_ARRAY_EXT" value="0x8C1B"/>
+
+ <enum name="TEXTURE_BINDING_1D_ARRAY_EXT" count="1" value="0x8C1C">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="TEXTURE_BINDING_2D_ARRAY_EXT" count="1" value="0x8C1D">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="MAX_ARRAY_TEXTURE_LAYERS_EXT" count="1" value="0x88FF">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="COMPARE_REF_DEPTH_TO_TEXTURE_EXT" count="1" value="0x884E">
+ <size name="Get" mode="get"/>
+ </enum>
+
+ <enum name="FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" count="1" value="0x8CD4">
+ <size name="GetFramebufferAttachmentParameterivEXT" mode="get"/>
+ </enum>
+
+ <function name="FramebufferTextureLayerEXT" offset="assign">
+ <param name="target" type="GLenum"/>
+ <param name="attachment" type="GLenum"/>
+ <param name="texture" type="GLuint"/>
+ <param name="level" type="GLint"/>
+ <param name="layer" type="GLint"/>
+ </function>
+</category>
+
+</OpenGLAPI>
diff --git a/src/mesa/glapi/Makefile b/src/mesa/glapi/Makefile
index 2178eacef5..22f65b74c2 100644
--- a/src/mesa/glapi/Makefile
+++ b/src/mesa/glapi/Makefile
@@ -48,8 +48,11 @@ SERVER_OUTPUTS = \
API_XML = gl_API.xml \
EXT_framebuffer_object.xml \
ARB_copy_buffer.xml \
+ ARB_depth_clamp.xml \
ARB_framebuffer_object.xml \
ARB_map_buffer_range.xml \
+ ARB_seamless_cube_map.xml \
+ ARB_sync.xml \
ARB_vertex_array_object.xml \
APPLE_vertex_array_object.xml \
EXT_provoking_vertex.xml
diff --git a/src/mesa/glapi/dispatch.h b/src/mesa/glapi/dispatch.h
index b3f1aed1a4..efbd56fa71 100644
--- a/src/mesa/glapi/dispatch.h
+++ b/src/mesa/glapi/dispatch.h
@@ -1761,6 +1761,36 @@
#define CALL_CopyBufferSubData(disp, parameters) (*((disp)->CopyBufferSubData)) parameters
#define GET_CopyBufferSubData(disp) ((disp)->CopyBufferSubData)
#define SET_CopyBufferSubData(disp, fn) ((disp)->CopyBufferSubData = fn)
+#define CALL_ClientWaitSync(disp, parameters) (*((disp)->ClientWaitSync)) parameters
+#define GET_ClientWaitSync(disp) ((disp)->ClientWaitSync)
+#define SET_ClientWaitSync(disp, fn) ((disp)->ClientWaitSync = fn)
+#define CALL_DeleteSync(disp, parameters) (*((disp)->DeleteSync)) parameters
+#define GET_DeleteSync(disp) ((disp)->DeleteSync)
+#define SET_DeleteSync(disp, fn) ((disp)->DeleteSync = fn)
+#define CALL_FenceSync(disp, parameters) (*((disp)->FenceSync)) parameters
+#define GET_FenceSync(disp) ((disp)->FenceSync)
+#define SET_FenceSync(disp, fn) ((disp)->FenceSync = fn)
+#define CALL_GetInteger64v(disp, parameters) (*((disp)->GetInteger64v)) parameters
+#define GET_GetInteger64v(disp) ((disp)->GetInteger64v)
+#define SET_GetInteger64v(disp, fn) ((disp)->GetInteger64v = fn)
+#define CALL_GetSynciv(disp, parameters) (*((disp)->GetSynciv)) parameters
+#define GET_GetSynciv(disp) ((disp)->GetSynciv)
+#define SET_GetSynciv(disp, fn) ((disp)->GetSynciv = fn)
+#define CALL_IsSync(disp, parameters) (*((disp)->IsSync)) parameters
+#define GET_IsSync(disp) ((disp)->IsSync)
+#define SET_IsSync(disp, fn) ((disp)->IsSync = fn)
+#define CALL_WaitSync(disp, parameters) (*((disp)->WaitSync)) parameters
+#define GET_WaitSync(disp) ((disp)->WaitSync)
+#define SET_WaitSync(disp, fn) ((disp)->WaitSync = fn)
+#define CALL_DrawElementsBaseVertex(disp, parameters) (*((disp)->DrawElementsBaseVertex)) parameters
+#define GET_DrawElementsBaseVertex(disp) ((disp)->DrawElementsBaseVertex)
+#define SET_DrawElementsBaseVertex(disp, fn) ((disp)->DrawElementsBaseVertex = fn)
+#define CALL_DrawRangeElementsBaseVertex(disp, parameters) (*((disp)->DrawRangeElementsBaseVertex)) parameters
+#define GET_DrawRangeElementsBaseVertex(disp) ((disp)->DrawRangeElementsBaseVertex)
+#define SET_DrawRangeElementsBaseVertex(disp, fn) ((disp)->DrawRangeElementsBaseVertex = fn)
+#define CALL_MultiDrawElementsBaseVertex(disp, parameters) (*((disp)->MultiDrawElementsBaseVertex)) parameters
+#define GET_MultiDrawElementsBaseVertex(disp) ((disp)->MultiDrawElementsBaseVertex)
+#define SET_MultiDrawElementsBaseVertex(disp, fn) ((disp)->MultiDrawElementsBaseVertex = fn)
#define CALL_PolygonOffsetEXT(disp, parameters) (*((disp)->PolygonOffsetEXT)) parameters
#define GET_PolygonOffsetEXT(disp) ((disp)->PolygonOffsetEXT)
#define SET_PolygonOffsetEXT(disp, fn) ((disp)->PolygonOffsetEXT = fn)
@@ -2382,12 +2412,24 @@
#define CALL_BlitFramebufferEXT(disp, parameters) (*((disp)->BlitFramebufferEXT)) parameters
#define GET_BlitFramebufferEXT(disp) ((disp)->BlitFramebufferEXT)
#define SET_BlitFramebufferEXT(disp, fn) ((disp)->BlitFramebufferEXT = fn)
+#define CALL_BufferParameteriAPPLE(disp, parameters) (*((disp)->BufferParameteriAPPLE)) parameters
+#define GET_BufferParameteriAPPLE(disp) ((disp)->BufferParameteriAPPLE)
+#define SET_BufferParameteriAPPLE(disp, fn) ((disp)->BufferParameteriAPPLE = fn)
+#define CALL_FlushMappedBufferRangeAPPLE(disp, parameters) (*((disp)->FlushMappedBufferRangeAPPLE)) parameters
+#define GET_FlushMappedBufferRangeAPPLE(disp) ((disp)->FlushMappedBufferRangeAPPLE)
+#define SET_FlushMappedBufferRangeAPPLE(disp, fn) ((disp)->FlushMappedBufferRangeAPPLE = fn)
#define CALL_FramebufferTextureLayerEXT(disp, parameters) (*((disp)->FramebufferTextureLayerEXT)) parameters
#define GET_FramebufferTextureLayerEXT(disp) ((disp)->FramebufferTextureLayerEXT)
#define SET_FramebufferTextureLayerEXT(disp, fn) ((disp)->FramebufferTextureLayerEXT = fn)
#define CALL_ProvokingVertexEXT(disp, parameters) (*((disp)->ProvokingVertexEXT)) parameters
#define GET_ProvokingVertexEXT(disp) ((disp)->ProvokingVertexEXT)
#define SET_ProvokingVertexEXT(disp, fn) ((disp)->ProvokingVertexEXT = fn)
+#define CALL_GetTexParameterPointervAPPLE(disp, parameters) (*((disp)->GetTexParameterPointervAPPLE)) parameters
+#define GET_GetTexParameterPointervAPPLE(disp) ((disp)->GetTexParameterPointervAPPLE)
+#define SET_GetTexParameterPointervAPPLE(disp, fn) ((disp)->GetTexParameterPointervAPPLE = fn)
+#define CALL_TextureRangeAPPLE(disp, parameters) (*((disp)->TextureRangeAPPLE)) parameters
+#define GET_TextureRangeAPPLE(disp) ((disp)->TextureRangeAPPLE)
+#define SET_TextureRangeAPPLE(disp, fn) ((disp)->TextureRangeAPPLE = fn)
#define CALL_StencilFuncSeparateATI(disp, parameters) (*((disp)->StencilFuncSeparateATI)) parameters
#define GET_StencilFuncSeparateATI(disp) ((disp)->StencilFuncSeparateATI)
#define SET_StencilFuncSeparateATI(disp, fn) ((disp)->StencilFuncSeparateATI = fn)
@@ -2406,7 +2448,7 @@
#else
-#define driDispatchRemapTable_size 373
+#define driDispatchRemapTable_size 387
extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
#define AttachShader_remap_index 0
@@ -2568,220 +2610,234 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
#define BindVertexArray_remap_index 156
#define GenVertexArrays_remap_index 157
#define CopyBufferSubData_remap_index 158
-#define PolygonOffsetEXT_remap_index 159
-#define GetPixelTexGenParameterfvSGIS_remap_index 160
-#define GetPixelTexGenParameterivSGIS_remap_index 161
-#define PixelTexGenParameterfSGIS_remap_index 162
-#define PixelTexGenParameterfvSGIS_remap_index 163
-#define PixelTexGenParameteriSGIS_remap_index 164
-#define PixelTexGenParameterivSGIS_remap_index 165
-#define SampleMaskSGIS_remap_index 166
-#define SamplePatternSGIS_remap_index 167
-#define ColorPointerEXT_remap_index 168
-#define EdgeFlagPointerEXT_remap_index 169
-#define IndexPointerEXT_remap_index 170
-#define NormalPointerEXT_remap_index 171
-#define TexCoordPointerEXT_remap_index 172
-#define VertexPointerEXT_remap_index 173
-#define PointParameterfEXT_remap_index 174
-#define PointParameterfvEXT_remap_index 175
-#define LockArraysEXT_remap_index 176
-#define UnlockArraysEXT_remap_index 177
-#define CullParameterdvEXT_remap_index 178
-#define CullParameterfvEXT_remap_index 179
-#define SecondaryColor3bEXT_remap_index 180
-#define SecondaryColor3bvEXT_remap_index 181
-#define SecondaryColor3dEXT_remap_index 182
-#define SecondaryColor3dvEXT_remap_index 183
-#define SecondaryColor3fEXT_remap_index 184
-#define SecondaryColor3fvEXT_remap_index 185
-#define SecondaryColor3iEXT_remap_index 186
-#define SecondaryColor3ivEXT_remap_index 187
-#define SecondaryColor3sEXT_remap_index 188
-#define SecondaryColor3svEXT_remap_index 189
-#define SecondaryColor3ubEXT_remap_index 190
-#define SecondaryColor3ubvEXT_remap_index 191
-#define SecondaryColor3uiEXT_remap_index 192
-#define SecondaryColor3uivEXT_remap_index 193
-#define SecondaryColor3usEXT_remap_index 194
-#define SecondaryColor3usvEXT_remap_index 195
-#define SecondaryColorPointerEXT_remap_index 196
-#define MultiDrawArraysEXT_remap_index 197
-#define MultiDrawElementsEXT_remap_index 198
-#define FogCoordPointerEXT_remap_index 199
-#define FogCoorddEXT_remap_index 200
-#define FogCoorddvEXT_remap_index 201
-#define FogCoordfEXT_remap_index 202
-#define FogCoordfvEXT_remap_index 203
-#define PixelTexGenSGIX_remap_index 204
-#define BlendFuncSeparateEXT_remap_index 205
-#define FlushVertexArrayRangeNV_remap_index 206
-#define VertexArrayRangeNV_remap_index 207
-#define CombinerInputNV_remap_index 208
-#define CombinerOutputNV_remap_index 209
-#define CombinerParameterfNV_remap_index 210
-#define CombinerParameterfvNV_remap_index 211
-#define CombinerParameteriNV_remap_index 212
-#define CombinerParameterivNV_remap_index 213
-#define FinalCombinerInputNV_remap_index 214
-#define GetCombinerInputParameterfvNV_remap_index 215
-#define GetCombinerInputParameterivNV_remap_index 216
-#define GetCombinerOutputParameterfvNV_remap_index 217
-#define GetCombinerOutputParameterivNV_remap_index 218
-#define GetFinalCombinerInputParameterfvNV_remap_index 219
-#define GetFinalCombinerInputParameterivNV_remap_index 220
-#define ResizeBuffersMESA_remap_index 221
-#define WindowPos2dMESA_remap_index 222
-#define WindowPos2dvMESA_remap_index 223
-#define WindowPos2fMESA_remap_index 224
-#define WindowPos2fvMESA_remap_index 225
-#define WindowPos2iMESA_remap_index 226
-#define WindowPos2ivMESA_remap_index 227
-#define WindowPos2sMESA_remap_index 228
-#define WindowPos2svMESA_remap_index 229
-#define WindowPos3dMESA_remap_index 230
-#define WindowPos3dvMESA_remap_index 231
-#define WindowPos3fMESA_remap_index 232
-#define WindowPos3fvMESA_remap_index 233
-#define WindowPos3iMESA_remap_index 234
-#define WindowPos3ivMESA_remap_index 235
-#define WindowPos3sMESA_remap_index 236
-#define WindowPos3svMESA_remap_index 237
-#define WindowPos4dMESA_remap_index 238
-#define WindowPos4dvMESA_remap_index 239
-#define WindowPos4fMESA_remap_index 240
-#define WindowPos4fvMESA_remap_index 241
-#define WindowPos4iMESA_remap_index 242
-#define WindowPos4ivMESA_remap_index 243
-#define WindowPos4sMESA_remap_index 244
-#define WindowPos4svMESA_remap_index 245
-#define MultiModeDrawArraysIBM_remap_index 246
-#define MultiModeDrawElementsIBM_remap_index 247
-#define DeleteFencesNV_remap_index 248
-#define FinishFenceNV_remap_index 249
-#define GenFencesNV_remap_index 250
-#define GetFenceivNV_remap_index 251
-#define IsFenceNV_remap_index 252
-#define SetFenceNV_remap_index 253
-#define TestFenceNV_remap_index 254
-#define AreProgramsResidentNV_remap_index 255
-#define BindProgramNV_remap_index 256
-#define DeleteProgramsNV_remap_index 257
-#define ExecuteProgramNV_remap_index 258
-#define GenProgramsNV_remap_index 259
-#define GetProgramParameterdvNV_remap_index 260
-#define GetProgramParameterfvNV_remap_index 261
-#define GetProgramStringNV_remap_index 262
-#define GetProgramivNV_remap_index 263
-#define GetTrackMatrixivNV_remap_index 264
-#define GetVertexAttribPointervNV_remap_index 265
-#define GetVertexAttribdvNV_remap_index 266
-#define GetVertexAttribfvNV_remap_index 267
-#define GetVertexAttribivNV_remap_index 268
-#define IsProgramNV_remap_index 269
-#define LoadProgramNV_remap_index 270
-#define ProgramParameters4dvNV_remap_index 271
-#define ProgramParameters4fvNV_remap_index 272
-#define RequestResidentProgramsNV_remap_index 273
-#define TrackMatrixNV_remap_index 274
-#define VertexAttrib1dNV_remap_index 275
-#define VertexAttrib1dvNV_remap_index 276
-#define VertexAttrib1fNV_remap_index 277
-#define VertexAttrib1fvNV_remap_index 278
-#define VertexAttrib1sNV_remap_index 279
-#define VertexAttrib1svNV_remap_index 280
-#define VertexAttrib2dNV_remap_index 281
-#define VertexAttrib2dvNV_remap_index 282
-#define VertexAttrib2fNV_remap_index 283
-#define VertexAttrib2fvNV_remap_index 284
-#define VertexAttrib2sNV_remap_index 285
-#define VertexAttrib2svNV_remap_index 286
-#define VertexAttrib3dNV_remap_index 287
-#define VertexAttrib3dvNV_remap_index 288
-#define VertexAttrib3fNV_remap_index 289
-#define VertexAttrib3fvNV_remap_index 290
-#define VertexAttrib3sNV_remap_index 291
-#define VertexAttrib3svNV_remap_index 292
-#define VertexAttrib4dNV_remap_index 293
-#define VertexAttrib4dvNV_remap_index 294
-#define VertexAttrib4fNV_remap_index 295
-#define VertexAttrib4fvNV_remap_index 296
-#define VertexAttrib4sNV_remap_index 297
-#define VertexAttrib4svNV_remap_index 298
-#define VertexAttrib4ubNV_remap_index 299
-#define VertexAttrib4ubvNV_remap_index 300
-#define VertexAttribPointerNV_remap_index 301
-#define VertexAttribs1dvNV_remap_index 302
-#define VertexAttribs1fvNV_remap_index 303
-#define VertexAttribs1svNV_remap_index 304
-#define VertexAttribs2dvNV_remap_index 305
-#define VertexAttribs2fvNV_remap_index 306
-#define VertexAttribs2svNV_remap_index 307
-#define VertexAttribs3dvNV_remap_index 308
-#define VertexAttribs3fvNV_remap_index 309
-#define VertexAttribs3svNV_remap_index 310
-#define VertexAttribs4dvNV_remap_index 311
-#define VertexAttribs4fvNV_remap_index 312
-#define VertexAttribs4svNV_remap_index 313
-#define VertexAttribs4ubvNV_remap_index 314
-#define GetTexBumpParameterfvATI_remap_index 315
-#define GetTexBumpParameterivATI_remap_index 316
-#define TexBumpParameterfvATI_remap_index 317
-#define TexBumpParameterivATI_remap_index 318
-#define AlphaFragmentOp1ATI_remap_index 319
-#define AlphaFragmentOp2ATI_remap_index 320
-#define AlphaFragmentOp3ATI_remap_index 321
-#define BeginFragmentShaderATI_remap_index 322
-#define BindFragmentShaderATI_remap_index 323
-#define ColorFragmentOp1ATI_remap_index 324
-#define ColorFragmentOp2ATI_remap_index 325
-#define ColorFragmentOp3ATI_remap_index 326
-#define DeleteFragmentShaderATI_remap_index 327
-#define EndFragmentShaderATI_remap_index 328
-#define GenFragmentShadersATI_remap_index 329
-#define PassTexCoordATI_remap_index 330
-#define SampleMapATI_remap_index 331
-#define SetFragmentShaderConstantATI_remap_index 332
-#define PointParameteriNV_remap_index 333
-#define PointParameterivNV_remap_index 334
-#define ActiveStencilFaceEXT_remap_index 335
-#define BindVertexArrayAPPLE_remap_index 336
-#define DeleteVertexArraysAPPLE_remap_index 337
-#define GenVertexArraysAPPLE_remap_index 338
-#define IsVertexArrayAPPLE_remap_index 339
-#define GetProgramNamedParameterdvNV_remap_index 340
-#define GetProgramNamedParameterfvNV_remap_index 341
-#define ProgramNamedParameter4dNV_remap_index 342
-#define ProgramNamedParameter4dvNV_remap_index 343
-#define ProgramNamedParameter4fNV_remap_index 344
-#define ProgramNamedParameter4fvNV_remap_index 345
-#define DepthBoundsEXT_remap_index 346
-#define BlendEquationSeparateEXT_remap_index 347
-#define BindFramebufferEXT_remap_index 348
-#define BindRenderbufferEXT_remap_index 349
-#define CheckFramebufferStatusEXT_remap_index 350
-#define DeleteFramebuffersEXT_remap_index 351
-#define DeleteRenderbuffersEXT_remap_index 352
-#define FramebufferRenderbufferEXT_remap_index 353
-#define FramebufferTexture1DEXT_remap_index 354
-#define FramebufferTexture2DEXT_remap_index 355
-#define FramebufferTexture3DEXT_remap_index 356
-#define GenFramebuffersEXT_remap_index 357
-#define GenRenderbuffersEXT_remap_index 358
-#define GenerateMipmapEXT_remap_index 359
-#define GetFramebufferAttachmentParameterivEXT_remap_index 360
-#define GetRenderbufferParameterivEXT_remap_index 361
-#define IsFramebufferEXT_remap_index 362
-#define IsRenderbufferEXT_remap_index 363
-#define RenderbufferStorageEXT_remap_index 364
-#define BlitFramebufferEXT_remap_index 365
-#define FramebufferTextureLayerEXT_remap_index 366
-#define ProvokingVertexEXT_remap_index 367
-#define StencilFuncSeparateATI_remap_index 368
-#define ProgramEnvParameters4fvEXT_remap_index 369
-#define ProgramLocalParameters4fvEXT_remap_index 370
-#define GetQueryObjecti64vEXT_remap_index 371
-#define GetQueryObjectui64vEXT_remap_index 372
+#define ClientWaitSync_remap_index 159
+#define DeleteSync_remap_index 160
+#define FenceSync_remap_index 161
+#define GetInteger64v_remap_index 162
+#define GetSynciv_remap_index 163
+#define IsSync_remap_index 164
+#define WaitSync_remap_index 165
+#define DrawElementsBaseVertex_remap_index 166
+#define DrawRangeElementsBaseVertex_remap_index 167
+#define MultiDrawElementsBaseVertex_remap_index 168
+#define PolygonOffsetEXT_remap_index 169
+#define GetPixelTexGenParameterfvSGIS_remap_index 170
+#define GetPixelTexGenParameterivSGIS_remap_index 171
+#define PixelTexGenParameterfSGIS_remap_index 172
+#define PixelTexGenParameterfvSGIS_remap_index 173
+#define PixelTexGenParameteriSGIS_remap_index 174
+#define PixelTexGenParameterivSGIS_remap_index 175
+#define SampleMaskSGIS_remap_index 176
+#define SamplePatternSGIS_remap_index 177
+#define ColorPointerEXT_remap_index 178
+#define EdgeFlagPointerEXT_remap_index 179
+#define IndexPointerEXT_remap_index 180
+#define NormalPointerEXT_remap_index 181
+#define TexCoordPointerEXT_remap_index 182
+#define VertexPointerEXT_remap_index 183
+#define PointParameterfEXT_remap_index 184
+#define PointParameterfvEXT_remap_index 185
+#define LockArraysEXT_remap_index 186
+#define UnlockArraysEXT_remap_index 187
+#define CullParameterdvEXT_remap_index 188
+#define CullParameterfvEXT_remap_index 189
+#define SecondaryColor3bEXT_remap_index 190
+#define SecondaryColor3bvEXT_remap_index 191
+#define SecondaryColor3dEXT_remap_index 192
+#define SecondaryColor3dvEXT_remap_index 193
+#define SecondaryColor3fEXT_remap_index 194
+#define SecondaryColor3fvEXT_remap_index 195
+#define SecondaryColor3iEXT_remap_index 196
+#define SecondaryColor3ivEXT_remap_index 197
+#define SecondaryColor3sEXT_remap_index 198
+#define SecondaryColor3svEXT_remap_index 199
+#define SecondaryColor3ubEXT_remap_index 200
+#define SecondaryColor3ubvEXT_remap_index 201
+#define SecondaryColor3uiEXT_remap_index 202
+#define SecondaryColor3uivEXT_remap_index 203
+#define SecondaryColor3usEXT_remap_index 204
+#define SecondaryColor3usvEXT_remap_index 205
+#define SecondaryColorPointerEXT_remap_index 206
+#define MultiDrawArraysEXT_remap_index 207
+#define MultiDrawElementsEXT_remap_index 208
+#define FogCoordPointerEXT_remap_index 209
+#define FogCoorddEXT_remap_index 210
+#define FogCoorddvEXT_remap_index 211
+#define FogCoordfEXT_remap_index 212
+#define FogCoordfvEXT_remap_index 213
+#define PixelTexGenSGIX_remap_index 214
+#define BlendFuncSeparateEXT_remap_index 215
+#define FlushVertexArrayRangeNV_remap_index 216
+#define VertexArrayRangeNV_remap_index 217
+#define CombinerInputNV_remap_index 218
+#define CombinerOutputNV_remap_index 219
+#define CombinerParameterfNV_remap_index 220
+#define CombinerParameterfvNV_remap_index 221
+#define CombinerParameteriNV_remap_index 222
+#define CombinerParameterivNV_remap_index 223
+#define FinalCombinerInputNV_remap_index 224
+#define GetCombinerInputParameterfvNV_remap_index 225
+#define GetCombinerInputParameterivNV_remap_index 226
+#define GetCombinerOutputParameterfvNV_remap_index 227
+#define GetCombinerOutputParameterivNV_remap_index 228
+#define GetFinalCombinerInputParameterfvNV_remap_index 229
+#define GetFinalCombinerInputParameterivNV_remap_index 230
+#define ResizeBuffersMESA_remap_index 231
+#define WindowPos2dMESA_remap_index 232
+#define WindowPos2dvMESA_remap_index 233
+#define WindowPos2fMESA_remap_index 234
+#define WindowPos2fvMESA_remap_index 235
+#define WindowPos2iMESA_remap_index 236
+#define WindowPos2ivMESA_remap_index 237
+#define WindowPos2sMESA_remap_index 238
+#define WindowPos2svMESA_remap_index 239
+#define WindowPos3dMESA_remap_index 240
+#define WindowPos3dvMESA_remap_index 241
+#define WindowPos3fMESA_remap_index 242
+#define WindowPos3fvMESA_remap_index 243
+#define WindowPos3iMESA_remap_index 244
+#define WindowPos3ivMESA_remap_index 245
+#define WindowPos3sMESA_remap_index 246
+#define WindowPos3svMESA_remap_index 247
+#define WindowPos4dMESA_remap_index 248
+#define WindowPos4dvMESA_remap_index 249
+#define WindowPos4fMESA_remap_index 250
+#define WindowPos4fvMESA_remap_index 251
+#define WindowPos4iMESA_remap_index 252
+#define WindowPos4ivMESA_remap_index 253
+#define WindowPos4sMESA_remap_index 254
+#define WindowPos4svMESA_remap_index 255
+#define MultiModeDrawArraysIBM_remap_index 256
+#define MultiModeDrawElementsIBM_remap_index 257
+#define DeleteFencesNV_remap_index 258
+#define FinishFenceNV_remap_index 259
+#define GenFencesNV_remap_index 260
+#define GetFenceivNV_remap_index 261
+#define IsFenceNV_remap_index 262
+#define SetFenceNV_remap_index 263
+#define TestFenceNV_remap_index 264
+#define AreProgramsResidentNV_remap_index 265
+#define BindProgramNV_remap_index 266
+#define DeleteProgramsNV_remap_index 267
+#define ExecuteProgramNV_remap_index 268
+#define GenProgramsNV_remap_index 269
+#define GetProgramParameterdvNV_remap_index 270
+#define GetProgramParameterfvNV_remap_index 271
+#define GetProgramStringNV_remap_index 272
+#define GetProgramivNV_remap_index 273
+#define GetTrackMatrixivNV_remap_index 274
+#define GetVertexAttribPointervNV_remap_index 275
+#define GetVertexAttribdvNV_remap_index 276
+#define GetVertexAttribfvNV_remap_index 277
+#define GetVertexAttribivNV_remap_index 278
+#define IsProgramNV_remap_index 279
+#define LoadProgramNV_remap_index 280
+#define ProgramParameters4dvNV_remap_index 281
+#define ProgramParameters4fvNV_remap_index 282
+#define RequestResidentProgramsNV_remap_index 283
+#define TrackMatrixNV_remap_index 284
+#define VertexAttrib1dNV_remap_index 285
+#define VertexAttrib1dvNV_remap_index 286
+#define VertexAttrib1fNV_remap_index 287
+#define VertexAttrib1fvNV_remap_index 288
+#define VertexAttrib1sNV_remap_index 289
+#define VertexAttrib1svNV_remap_index 290
+#define VertexAttrib2dNV_remap_index 291
+#define VertexAttrib2dvNV_remap_index 292
+#define VertexAttrib2fNV_remap_index 293
+#define VertexAttrib2fvNV_remap_index 294
+#define VertexAttrib2sNV_remap_index 295
+#define VertexAttrib2svNV_remap_index 296
+#define VertexAttrib3dNV_remap_index 297
+#define VertexAttrib3dvNV_remap_index 298
+#define VertexAttrib3fNV_remap_index 299
+#define VertexAttrib3fvNV_remap_index 300
+#define VertexAttrib3sNV_remap_index 301
+#define VertexAttrib3svNV_remap_index 302
+#define VertexAttrib4dNV_remap_index 303
+#define VertexAttrib4dvNV_remap_index 304
+#define VertexAttrib4fNV_remap_index 305
+#define VertexAttrib4fvNV_remap_index 306
+#define VertexAttrib4sNV_remap_index 307
+#define VertexAttrib4svNV_remap_index 308
+#define VertexAttrib4ubNV_remap_index 309
+#define VertexAttrib4ubvNV_remap_index 310
+#define VertexAttribPointerNV_remap_index 311
+#define VertexAttribs1dvNV_remap_index 312
+#define VertexAttribs1fvNV_remap_index 313
+#define VertexAttribs1svNV_remap_index 314
+#define VertexAttribs2dvNV_remap_index 315
+#define VertexAttribs2fvNV_remap_index 316
+#define VertexAttribs2svNV_remap_index 317
+#define VertexAttribs3dvNV_remap_index 318
+#define VertexAttribs3fvNV_remap_index 319
+#define VertexAttribs3svNV_remap_index 320
+#define VertexAttribs4dvNV_remap_index 321
+#define VertexAttribs4fvNV_remap_index 322
+#define VertexAttribs4svNV_remap_index 323
+#define VertexAttribs4ubvNV_remap_index 324
+#define GetTexBumpParameterfvATI_remap_index 325
+#define GetTexBumpParameterivATI_remap_index 326
+#define TexBumpParameterfvATI_remap_index 327
+#define TexBumpParameterivATI_remap_index 328
+#define AlphaFragmentOp1ATI_remap_index 329
+#define AlphaFragmentOp2ATI_remap_index 330
+#define AlphaFragmentOp3ATI_remap_index 331
+#define BeginFragmentShaderATI_remap_index 332
+#define BindFragmentShaderATI_remap_index 333
+#define ColorFragmentOp1ATI_remap_index 334
+#define ColorFragmentOp2ATI_remap_index 335
+#define ColorFragmentOp3ATI_remap_index 336
+#define DeleteFragmentShaderATI_remap_index 337
+#define EndFragmentShaderATI_remap_index 338
+#define GenFragmentShadersATI_remap_index 339
+#define PassTexCoordATI_remap_index 340
+#define SampleMapATI_remap_index 341
+#define SetFragmentShaderConstantATI_remap_index 342
+#define PointParameteriNV_remap_index 343
+#define PointParameterivNV_remap_index 344
+#define ActiveStencilFaceEXT_remap_index 345
+#define BindVertexArrayAPPLE_remap_index 346
+#define DeleteVertexArraysAPPLE_remap_index 347
+#define GenVertexArraysAPPLE_remap_index 348
+#define IsVertexArrayAPPLE_remap_index 349
+#define GetProgramNamedParameterdvNV_remap_index 350
+#define GetProgramNamedParameterfvNV_remap_index 351
+#define ProgramNamedParameter4dNV_remap_index 352
+#define ProgramNamedParameter4dvNV_remap_index 353
+#define ProgramNamedParameter4fNV_remap_index 354
+#define ProgramNamedParameter4fvNV_remap_index 355
+#define DepthBoundsEXT_remap_index 356
+#define BlendEquationSeparateEXT_remap_index 357
+#define BindFramebufferEXT_remap_index 358
+#define BindRenderbufferEXT_remap_index 359
+#define CheckFramebufferStatusEXT_remap_index 360
+#define DeleteFramebuffersEXT_remap_index 361
+#define DeleteRenderbuffersEXT_remap_index 362
+#define FramebufferRenderbufferEXT_remap_index 363
+#define FramebufferTexture1DEXT_remap_index 364
+#define FramebufferTexture2DEXT_remap_index 365
+#define FramebufferTexture3DEXT_remap_index 366
+#define GenFramebuffersEXT_remap_index 367
+#define GenRenderbuffersEXT_remap_index 368
+#define GenerateMipmapEXT_remap_index 369
+#define GetFramebufferAttachmentParameterivEXT_remap_index 370
+#define GetRenderbufferParameterivEXT_remap_index 371
+#define IsFramebufferEXT_remap_index 372
+#define IsRenderbufferEXT_remap_index 373
+#define RenderbufferStorageEXT_remap_index 374
+#define BlitFramebufferEXT_remap_index 375
+#define BufferParameteriAPPLE_remap_index 376
+#define FlushMappedBufferRangeAPPLE_remap_index 377
+#define FramebufferTextureLayerEXT_remap_index 378
+#define ProvokingVertexEXT_remap_index 379
+#define GetTexParameterPointervAPPLE_remap_index 380
+#define TextureRangeAPPLE_remap_index 381
+#define StencilFuncSeparateATI_remap_index 382
+#define ProgramEnvParameters4fvEXT_remap_index 383
+#define ProgramLocalParameters4fvEXT_remap_index 384
+#define GetQueryObjecti64vEXT_remap_index 385
+#define GetQueryObjectui64vEXT_remap_index 386
#define CALL_AttachShader(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLuint, GLuint)), driDispatchRemapTable[AttachShader_remap_index], parameters)
#define GET_AttachShader(disp) GET_by_offset(disp, driDispatchRemapTable[AttachShader_remap_index])
@@ -3260,6 +3316,36 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
#define CALL_CopyBufferSubData(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLintptr, GLintptr, GLsizeiptr)), driDispatchRemapTable[CopyBufferSubData_remap_index], parameters)
#define GET_CopyBufferSubData(disp) GET_by_offset(disp, driDispatchRemapTable[CopyBufferSubData_remap_index])
#define SET_CopyBufferSubData(disp, fn) SET_by_offset(disp, driDispatchRemapTable[CopyBufferSubData_remap_index], fn)
+#define CALL_ClientWaitSync(disp, parameters) CALL_by_offset(disp, (GLenum (GLAPIENTRYP)(GLsync, GLbitfield, GLuint64)), driDispatchRemapTable[ClientWaitSync_remap_index], parameters)
+#define GET_ClientWaitSync(disp) GET_by_offset(disp, driDispatchRemapTable[ClientWaitSync_remap_index])
+#define SET_ClientWaitSync(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ClientWaitSync_remap_index], fn)
+#define CALL_DeleteSync(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLsync)), driDispatchRemapTable[DeleteSync_remap_index], parameters)
+#define GET_DeleteSync(disp) GET_by_offset(disp, driDispatchRemapTable[DeleteSync_remap_index])
+#define SET_DeleteSync(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DeleteSync_remap_index], fn)
+#define CALL_FenceSync(disp, parameters) CALL_by_offset(disp, (GLsync (GLAPIENTRYP)(GLenum, GLbitfield)), driDispatchRemapTable[FenceSync_remap_index], parameters)
+#define GET_FenceSync(disp) GET_by_offset(disp, driDispatchRemapTable[FenceSync_remap_index])
+#define SET_FenceSync(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FenceSync_remap_index], fn)
+#define CALL_GetInteger64v(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLint64 *)), driDispatchRemapTable[GetInteger64v_remap_index], parameters)
+#define GET_GetInteger64v(disp) GET_by_offset(disp, driDispatchRemapTable[GetInteger64v_remap_index])
+#define SET_GetInteger64v(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GetInteger64v_remap_index], fn)
+#define CALL_GetSynciv(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLsync, GLenum, GLsizei, GLsizei *, GLint *)), driDispatchRemapTable[GetSynciv_remap_index], parameters)
+#define GET_GetSynciv(disp) GET_by_offset(disp, driDispatchRemapTable[GetSynciv_remap_index])
+#define SET_GetSynciv(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GetSynciv_remap_index], fn)
+#define CALL_IsSync(disp, parameters) CALL_by_offset(disp, (GLboolean (GLAPIENTRYP)(GLsync)), driDispatchRemapTable[IsSync_remap_index], parameters)
+#define GET_IsSync(disp) GET_by_offset(disp, driDispatchRemapTable[IsSync_remap_index])
+#define SET_IsSync(disp, fn) SET_by_offset(disp, driDispatchRemapTable[IsSync_remap_index], fn)
+#define CALL_WaitSync(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLsync, GLbitfield, GLuint64)), driDispatchRemapTable[WaitSync_remap_index], parameters)
+#define GET_WaitSync(disp) GET_by_offset(disp, driDispatchRemapTable[WaitSync_remap_index])
+#define SET_WaitSync(disp, fn) SET_by_offset(disp, driDispatchRemapTable[WaitSync_remap_index], fn)
+#define CALL_DrawElementsBaseVertex(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLsizei, GLenum, const GLvoid *, GLint)), driDispatchRemapTable[DrawElementsBaseVertex_remap_index], parameters)
+#define GET_DrawElementsBaseVertex(disp) GET_by_offset(disp, driDispatchRemapTable[DrawElementsBaseVertex_remap_index])
+#define SET_DrawElementsBaseVertex(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DrawElementsBaseVertex_remap_index], fn)
+#define CALL_DrawRangeElementsBaseVertex(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLuint, GLuint, GLsizei, GLenum, const GLvoid *, GLint)), driDispatchRemapTable[DrawRangeElementsBaseVertex_remap_index], parameters)
+#define GET_DrawRangeElementsBaseVertex(disp) GET_by_offset(disp, driDispatchRemapTable[DrawRangeElementsBaseVertex_remap_index])
+#define SET_DrawRangeElementsBaseVertex(disp, fn) SET_by_offset(disp, driDispatchRemapTable[DrawRangeElementsBaseVertex_remap_index], fn)
+#define CALL_MultiDrawElementsBaseVertex(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, const GLsizei *, GLenum, const GLvoid **, GLsizei, const GLint *)), driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index], parameters)
+#define GET_MultiDrawElementsBaseVertex(disp) GET_by_offset(disp, driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index])
+#define SET_MultiDrawElementsBaseVertex(disp, fn) SET_by_offset(disp, driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index], fn)
#define CALL_PolygonOffsetEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLfloat, GLfloat)), driDispatchRemapTable[PolygonOffsetEXT_remap_index], parameters)
#define GET_PolygonOffsetEXT(disp) GET_by_offset(disp, driDispatchRemapTable[PolygonOffsetEXT_remap_index])
#define SET_PolygonOffsetEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[PolygonOffsetEXT_remap_index], fn)
@@ -3881,12 +3967,24 @@ extern int driDispatchRemapTable[ driDispatchRemapTable_size ];
#define CALL_BlitFramebufferEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum)), driDispatchRemapTable[BlitFramebufferEXT_remap_index], parameters)
#define GET_BlitFramebufferEXT(disp) GET_by_offset(disp, driDispatchRemapTable[BlitFramebufferEXT_remap_index])
#define SET_BlitFramebufferEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[BlitFramebufferEXT_remap_index], fn)
+#define CALL_BufferParameteriAPPLE(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLint)), driDispatchRemapTable[BufferParameteriAPPLE_remap_index], parameters)
+#define GET_BufferParameteriAPPLE(disp) GET_by_offset(disp, driDispatchRemapTable[BufferParameteriAPPLE_remap_index])
+#define SET_BufferParameteriAPPLE(disp, fn) SET_by_offset(disp, driDispatchRemapTable[BufferParameteriAPPLE_remap_index], fn)
+#define CALL_FlushMappedBufferRangeAPPLE(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLintptr, GLsizeiptr)), driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index], parameters)
+#define GET_FlushMappedBufferRangeAPPLE(disp) GET_by_offset(disp, driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index])
+#define SET_FlushMappedBufferRangeAPPLE(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index], fn)
#define CALL_FramebufferTextureLayerEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLuint, GLint, GLint)), driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index], parameters)
#define GET_FramebufferTextureLayerEXT(disp) GET_by_offset(disp, driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index])
#define SET_FramebufferTextureLayerEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index], fn)
#define CALL_ProvokingVertexEXT(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum)), driDispatchRemapTable[ProvokingVertexEXT_remap_index], parameters)
#define GET_ProvokingVertexEXT(disp) GET_by_offset(disp, driDispatchRemapTable[ProvokingVertexEXT_remap_index])
#define SET_ProvokingVertexEXT(disp, fn) SET_by_offset(disp, driDispatchRemapTable[ProvokingVertexEXT_remap_index], fn)
+#define CALL_GetTexParameterPointervAPPLE(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLvoid **)), driDispatchRemapTable[GetTexParameterPointervAPPLE_remap_index], parameters)
+#define GET_GetTexParameterPointervAPPLE(disp) GET_by_offset(disp, driDispatchRemapTable[GetTexParameterPointervAPPLE_remap_index])
+#define SET_GetTexParameterPointervAPPLE(disp, fn) SET_by_offset(disp, driDispatchRemapTable[GetTexParameterPointervAPPLE_remap_index], fn)
+#define CALL_TextureRangeAPPLE(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLsizei, GLvoid *)), driDispatchRemapTable[TextureRangeAPPLE_remap_index], parameters)
+#define GET_TextureRangeAPPLE(disp) GET_by_offset(disp, driDispatchRemapTable[TextureRangeAPPLE_remap_index])
+#define SET_TextureRangeAPPLE(disp, fn) SET_by_offset(disp, driDispatchRemapTable[TextureRangeAPPLE_remap_index], fn)
#define CALL_StencilFuncSeparateATI(disp, parameters) CALL_by_offset(disp, (void (GLAPIENTRYP)(GLenum, GLenum, GLint, GLuint)), driDispatchRemapTable[StencilFuncSeparateATI_remap_index], parameters)
#define GET_StencilFuncSeparateATI(disp) GET_by_offset(disp, driDispatchRemapTable[StencilFuncSeparateATI_remap_index])
#define SET_StencilFuncSeparateATI(disp, fn) SET_by_offset(disp, driDispatchRemapTable[StencilFuncSeparateATI_remap_index], fn)
diff --git a/src/mesa/glapi/extension_helper.py b/src/mesa/glapi/extension_helper.py
index 64f64a2fd8..83471d89f5 100644
--- a/src/mesa/glapi/extension_helper.py
+++ b/src/mesa/glapi/extension_helper.py
@@ -170,7 +170,7 @@ class PrintGlExtensionGlue(gl_XML.gl_print_base):
condition = condition_for_function(f, abi, 0)
if len(condition):
print '#if %s' % (string.join(condition, " || "))
- print 'static const char %s_names[] = ' % (f.name)
+ print 'static const char %s_names[] =' % (f.name)
parameter_signature = ''
for p in f.parameterIterator():
diff --git a/src/mesa/glapi/gl_API.xml b/src/mesa/glapi/gl_API.xml
index 06560d175a..da4be14707 100644
--- a/src/mesa/glapi/gl_API.xml
+++ b/src/mesa/glapi/gl_API.xml
@@ -7950,10 +7950,18 @@
<xi:include href="ARB_copy_buffer.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="ARB_depth_clamp.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<xi:include href="ARB_map_buffer_range.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="ARB_vertex_array_object.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+<xi:include href="ARB_sync.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<xi:include href="ARB_seamless_cube_map.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<xi:include href="ARB_draw_elements_base_vertex.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
<!-- Non-ARB extensions sorted by extension number. -->
@@ -12255,6 +12263,65 @@
</function>
</category>
+<category name="GL_APPLE_flush_buffer_range" number="321">
+ <enum name="BUFFER_SERIALIZED_MODIFY_APPLE" count="1" value="0x8A12">
+ <size name="GetBufferParameteriv" mode="get"/>
+ </enum>
+ <enum name="BUFFER_FLUSHING_UNMAP_APPLE" count="1" value="0x8A13">
+ <size name="GetBufferParameteriv" mode="get"/>
+ </enum>
+ <function name="BufferParameteriAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="param" type="GLint"/>
+ </function>
+ <function name="FlushMappedBufferRangeAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="offset" type="GLintptr"/>
+ <param name="size" type="GLsizeiptr"/>
+ </function>
+</category>
+
+<xi:include href="EXT_texture_array.xml" xmlns:xi="http://www.w3.org/2001/XInclude"/>
+
+<category name="GL_APPLE_texture_range" number="367">
+ <enum name="TEXTURE_STORAGE_HINT_APPLE" count="1" value="0x85BC">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ <size name="GetTexParameteriv" mode="get"/>
+ <size name="GetTexParameterfv" mode="get"/>
+ </enum>
+ <enum name="STORAGE_PRIVATE_APPLE" count="1" value="0x85BD">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="STORAGE_CACHED_APPLE" count="1" value="0x85BE">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="STORAGE_SHARED_APPLE" count="1" value="0x85BF">
+ <size name="TexParameteriv"/>
+ <size name="TexParameterfv"/>
+ </enum>
+ <enum name="TEXTURE_RANGE_LENGTH_APPLE" count="1" value="0x85B7">
+ <size name="GetTexParameteriv" mode="get"/>
+ <size name="GetTexParameterfv" mode="get"/>
+ </enum>
+ <enum name="TEXTURE_RANGE_POINTER_APPLE" count="1" value="0x85B8">
+ <size name="GetTexParameterPointervAPPLE" mode="get"/>
+ </enum>
+ <function name="TextureRangeAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="length" type="GLsizei"/>
+ <param name="pointer" type="GLvoid *"/>
+ </function>
+ <function name="GetTexParameterPointervAPPLE" offset="assign" static_dispatch="false">
+ <param name="target" type="GLenum"/>
+ <param name="pname" type="GLenum"/>
+ <param name="params" type="GLvoid **"/>
+ </function>
+</category>
+
<!-- Unnumbered extensions sorted by name. -->
<category name="GL_ATI_blend_equation_separate">
diff --git a/src/mesa/glapi/gl_x86-64_asm.py b/src/mesa/glapi/gl_x86-64_asm.py
index fa45406f47..f36ad3a5d8 100644
--- a/src/mesa/glapi/gl_x86-64_asm.py
+++ b/src/mesa/glapi/gl_x86-64_asm.py
@@ -138,7 +138,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '# define GL_PREFIX(n) GLNAME(CONCAT(gl,n))'
print '# endif'
print ''
- print '#if defined(PTHREADS) || defined(USE_XTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+ print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
print '# define THREADS'
print '#endif'
print ''
diff --git a/src/mesa/glapi/gl_x86_asm.py b/src/mesa/glapi/gl_x86_asm.py
index 0dbf3ebe0a..36f0e31fe2 100644
--- a/src/mesa/glapi/gl_x86_asm.py
+++ b/src/mesa/glapi/gl_x86_asm.py
@@ -79,7 +79,7 @@ class PrintGenericStubs(gl_XML.gl_print_base):
print '#define GLOBL_FN(x) GLOBL x'
print '#endif'
print ''
- print '#if defined(PTHREADS) || defined(USE_XTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
+ print '#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)'
print '# define THREADS'
print '#endif'
print ''
diff --git a/src/mesa/glapi/glapi.c b/src/mesa/glapi/glapi.c
index 2b105d0f17..e36fccb354 100644
--- a/src/mesa/glapi/glapi.c
+++ b/src/mesa/glapi/glapi.c
@@ -198,6 +198,16 @@ PUBLIC const void *_glapi_Context = NULL;
#if defined(THREADS)
+#ifdef WIN32_THREADS
+/* _glthread_DECLARE_STATIC_MUTEX is broken on windows. There will be race! */
+#define CHECK_MULTITHREAD_LOCK()
+#define CHECK_MULTITHREAD_UNLOCK()
+#else
+_glthread_DECLARE_STATIC_MUTEX(ThreadCheckMutex);
+#define CHECK_MULTITHREAD_LOCK() _glthread_LOCK_MUTEX(ThreadCheckMutex)
+#define CHECK_MULTITHREAD_UNLOCK() _glthread_UNLOCK_MUTEX(ThreadCheckMutex)
+#endif
+
static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */
_glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */
static _glthread_TSD ContextTSD; /**< Per-thread context pointer */
@@ -231,23 +241,27 @@ void
_glapi_check_multithread(void)
{
#if defined(THREADS) && !defined(GLX_USE_TLS)
- if (!ThreadSafe) {
- static unsigned long knownID;
- static GLboolean firstCall = GL_TRUE;
- if (firstCall) {
- knownID = _glthread_GetID();
- firstCall = GL_FALSE;
- }
- else if (knownID != _glthread_GetID()) {
- ThreadSafe = GL_TRUE;
- _glapi_set_dispatch(NULL);
- _glapi_set_context(NULL);
- }
+ static unsigned long knownID;
+ static GLboolean firstCall = GL_TRUE;
+
+ if (ThreadSafe)
+ return;
+
+ CHECK_MULTITHREAD_LOCK();
+ if (firstCall) {
+ /* initialize TSDs */
+ (void) _glthread_GetTSD(&ContextTSD);
+ (void) _glthread_GetTSD(&_gl_DispatchTSD);
+
+ knownID = _glthread_GetID();
+ firstCall = GL_FALSE;
}
- else if (!_glapi_get_dispatch()) {
- /* make sure that this thread's dispatch pointer isn't null */
+ else if (knownID != _glthread_GetID()) {
+ ThreadSafe = GL_TRUE;
_glapi_set_dispatch(NULL);
+ _glapi_set_context(NULL);
}
+ CHECK_MULTITHREAD_UNLOCK();
#endif
}
diff --git a/src/mesa/glapi/glapi.h b/src/mesa/glapi/glapi.h
index 8f2cf66218..5fb5401229 100644
--- a/src/mesa/glapi/glapi.h
+++ b/src/mesa/glapi/glapi.h
@@ -80,8 +80,8 @@ typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...);
**/
#if defined (GLX_USE_TLS)
-const extern void *_glapi_Context;
-const extern struct _glapi_table *_glapi_Dispatch;
+extern const void *_glapi_Context;
+extern const struct _glapi_table *_glapi_Dispatch;
extern __thread void * _glapi_tls_Context
__attribute__((tls_model("initial-exec")));
diff --git a/src/mesa/glapi/glapioffsets.h b/src/mesa/glapi/glapioffsets.h
index 9ed67a645f..a3807744ff 100644
--- a/src/mesa/glapi/glapioffsets.h
+++ b/src/mesa/glapi/glapioffsets.h
@@ -599,221 +599,235 @@
#define _gloffset_BindVertexArray 564
#define _gloffset_GenVertexArrays 565
#define _gloffset_CopyBufferSubData 566
-#define _gloffset_PolygonOffsetEXT 567
-#define _gloffset_GetPixelTexGenParameterfvSGIS 568
-#define _gloffset_GetPixelTexGenParameterivSGIS 569
-#define _gloffset_PixelTexGenParameterfSGIS 570
-#define _gloffset_PixelTexGenParameterfvSGIS 571
-#define _gloffset_PixelTexGenParameteriSGIS 572
-#define _gloffset_PixelTexGenParameterivSGIS 573
-#define _gloffset_SampleMaskSGIS 574
-#define _gloffset_SamplePatternSGIS 575
-#define _gloffset_ColorPointerEXT 576
-#define _gloffset_EdgeFlagPointerEXT 577
-#define _gloffset_IndexPointerEXT 578
-#define _gloffset_NormalPointerEXT 579
-#define _gloffset_TexCoordPointerEXT 580
-#define _gloffset_VertexPointerEXT 581
-#define _gloffset_PointParameterfEXT 582
-#define _gloffset_PointParameterfvEXT 583
-#define _gloffset_LockArraysEXT 584
-#define _gloffset_UnlockArraysEXT 585
-#define _gloffset_CullParameterdvEXT 586
-#define _gloffset_CullParameterfvEXT 587
-#define _gloffset_SecondaryColor3bEXT 588
-#define _gloffset_SecondaryColor3bvEXT 589
-#define _gloffset_SecondaryColor3dEXT 590
-#define _gloffset_SecondaryColor3dvEXT 591
-#define _gloffset_SecondaryColor3fEXT 592
-#define _gloffset_SecondaryColor3fvEXT 593
-#define _gloffset_SecondaryColor3iEXT 594
-#define _gloffset_SecondaryColor3ivEXT 595
-#define _gloffset_SecondaryColor3sEXT 596
-#define _gloffset_SecondaryColor3svEXT 597
-#define _gloffset_SecondaryColor3ubEXT 598
-#define _gloffset_SecondaryColor3ubvEXT 599
-#define _gloffset_SecondaryColor3uiEXT 600
-#define _gloffset_SecondaryColor3uivEXT 601
-#define _gloffset_SecondaryColor3usEXT 602
-#define _gloffset_SecondaryColor3usvEXT 603
-#define _gloffset_SecondaryColorPointerEXT 604
-#define _gloffset_MultiDrawArraysEXT 605
-#define _gloffset_MultiDrawElementsEXT 606
-#define _gloffset_FogCoordPointerEXT 607
-#define _gloffset_FogCoorddEXT 608
-#define _gloffset_FogCoorddvEXT 609
-#define _gloffset_FogCoordfEXT 610
-#define _gloffset_FogCoordfvEXT 611
-#define _gloffset_PixelTexGenSGIX 612
-#define _gloffset_BlendFuncSeparateEXT 613
-#define _gloffset_FlushVertexArrayRangeNV 614
-#define _gloffset_VertexArrayRangeNV 615
-#define _gloffset_CombinerInputNV 616
-#define _gloffset_CombinerOutputNV 617
-#define _gloffset_CombinerParameterfNV 618
-#define _gloffset_CombinerParameterfvNV 619
-#define _gloffset_CombinerParameteriNV 620
-#define _gloffset_CombinerParameterivNV 621
-#define _gloffset_FinalCombinerInputNV 622
-#define _gloffset_GetCombinerInputParameterfvNV 623
-#define _gloffset_GetCombinerInputParameterivNV 624
-#define _gloffset_GetCombinerOutputParameterfvNV 625
-#define _gloffset_GetCombinerOutputParameterivNV 626
-#define _gloffset_GetFinalCombinerInputParameterfvNV 627
-#define _gloffset_GetFinalCombinerInputParameterivNV 628
-#define _gloffset_ResizeBuffersMESA 629
-#define _gloffset_WindowPos2dMESA 630
-#define _gloffset_WindowPos2dvMESA 631
-#define _gloffset_WindowPos2fMESA 632
-#define _gloffset_WindowPos2fvMESA 633
-#define _gloffset_WindowPos2iMESA 634
-#define _gloffset_WindowPos2ivMESA 635
-#define _gloffset_WindowPos2sMESA 636
-#define _gloffset_WindowPos2svMESA 637
-#define _gloffset_WindowPos3dMESA 638
-#define _gloffset_WindowPos3dvMESA 639
-#define _gloffset_WindowPos3fMESA 640
-#define _gloffset_WindowPos3fvMESA 641
-#define _gloffset_WindowPos3iMESA 642
-#define _gloffset_WindowPos3ivMESA 643
-#define _gloffset_WindowPos3sMESA 644
-#define _gloffset_WindowPos3svMESA 645
-#define _gloffset_WindowPos4dMESA 646
-#define _gloffset_WindowPos4dvMESA 647
-#define _gloffset_WindowPos4fMESA 648
-#define _gloffset_WindowPos4fvMESA 649
-#define _gloffset_WindowPos4iMESA 650
-#define _gloffset_WindowPos4ivMESA 651
-#define _gloffset_WindowPos4sMESA 652
-#define _gloffset_WindowPos4svMESA 653
-#define _gloffset_MultiModeDrawArraysIBM 654
-#define _gloffset_MultiModeDrawElementsIBM 655
-#define _gloffset_DeleteFencesNV 656
-#define _gloffset_FinishFenceNV 657
-#define _gloffset_GenFencesNV 658
-#define _gloffset_GetFenceivNV 659
-#define _gloffset_IsFenceNV 660
-#define _gloffset_SetFenceNV 661
-#define _gloffset_TestFenceNV 662
-#define _gloffset_AreProgramsResidentNV 663
-#define _gloffset_BindProgramNV 664
-#define _gloffset_DeleteProgramsNV 665
-#define _gloffset_ExecuteProgramNV 666
-#define _gloffset_GenProgramsNV 667
-#define _gloffset_GetProgramParameterdvNV 668
-#define _gloffset_GetProgramParameterfvNV 669
-#define _gloffset_GetProgramStringNV 670
-#define _gloffset_GetProgramivNV 671
-#define _gloffset_GetTrackMatrixivNV 672
-#define _gloffset_GetVertexAttribPointervNV 673
-#define _gloffset_GetVertexAttribdvNV 674
-#define _gloffset_GetVertexAttribfvNV 675
-#define _gloffset_GetVertexAttribivNV 676
-#define _gloffset_IsProgramNV 677
-#define _gloffset_LoadProgramNV 678
-#define _gloffset_ProgramParameters4dvNV 679
-#define _gloffset_ProgramParameters4fvNV 680
-#define _gloffset_RequestResidentProgramsNV 681
-#define _gloffset_TrackMatrixNV 682
-#define _gloffset_VertexAttrib1dNV 683
-#define _gloffset_VertexAttrib1dvNV 684
-#define _gloffset_VertexAttrib1fNV 685
-#define _gloffset_VertexAttrib1fvNV 686
-#define _gloffset_VertexAttrib1sNV 687
-#define _gloffset_VertexAttrib1svNV 688
-#define _gloffset_VertexAttrib2dNV 689
-#define _gloffset_VertexAttrib2dvNV 690
-#define _gloffset_VertexAttrib2fNV 691
-#define _gloffset_VertexAttrib2fvNV 692
-#define _gloffset_VertexAttrib2sNV 693
-#define _gloffset_VertexAttrib2svNV 694
-#define _gloffset_VertexAttrib3dNV 695
-#define _gloffset_VertexAttrib3dvNV 696
-#define _gloffset_VertexAttrib3fNV 697
-#define _gloffset_VertexAttrib3fvNV 698
-#define _gloffset_VertexAttrib3sNV 699
-#define _gloffset_VertexAttrib3svNV 700
-#define _gloffset_VertexAttrib4dNV 701
-#define _gloffset_VertexAttrib4dvNV 702
-#define _gloffset_VertexAttrib4fNV 703
-#define _gloffset_VertexAttrib4fvNV 704
-#define _gloffset_VertexAttrib4sNV 705
-#define _gloffset_VertexAttrib4svNV 706
-#define _gloffset_VertexAttrib4ubNV 707
-#define _gloffset_VertexAttrib4ubvNV 708
-#define _gloffset_VertexAttribPointerNV 709
-#define _gloffset_VertexAttribs1dvNV 710
-#define _gloffset_VertexAttribs1fvNV 711
-#define _gloffset_VertexAttribs1svNV 712
-#define _gloffset_VertexAttribs2dvNV 713
-#define _gloffset_VertexAttribs2fvNV 714
-#define _gloffset_VertexAttribs2svNV 715
-#define _gloffset_VertexAttribs3dvNV 716
-#define _gloffset_VertexAttribs3fvNV 717
-#define _gloffset_VertexAttribs3svNV 718
-#define _gloffset_VertexAttribs4dvNV 719
-#define _gloffset_VertexAttribs4fvNV 720
-#define _gloffset_VertexAttribs4svNV 721
-#define _gloffset_VertexAttribs4ubvNV 722
-#define _gloffset_GetTexBumpParameterfvATI 723
-#define _gloffset_GetTexBumpParameterivATI 724
-#define _gloffset_TexBumpParameterfvATI 725
-#define _gloffset_TexBumpParameterivATI 726
-#define _gloffset_AlphaFragmentOp1ATI 727
-#define _gloffset_AlphaFragmentOp2ATI 728
-#define _gloffset_AlphaFragmentOp3ATI 729
-#define _gloffset_BeginFragmentShaderATI 730
-#define _gloffset_BindFragmentShaderATI 731
-#define _gloffset_ColorFragmentOp1ATI 732
-#define _gloffset_ColorFragmentOp2ATI 733
-#define _gloffset_ColorFragmentOp3ATI 734
-#define _gloffset_DeleteFragmentShaderATI 735
-#define _gloffset_EndFragmentShaderATI 736
-#define _gloffset_GenFragmentShadersATI 737
-#define _gloffset_PassTexCoordATI 738
-#define _gloffset_SampleMapATI 739
-#define _gloffset_SetFragmentShaderConstantATI 740
-#define _gloffset_PointParameteriNV 741
-#define _gloffset_PointParameterivNV 742
-#define _gloffset_ActiveStencilFaceEXT 743
-#define _gloffset_BindVertexArrayAPPLE 744
-#define _gloffset_DeleteVertexArraysAPPLE 745
-#define _gloffset_GenVertexArraysAPPLE 746
-#define _gloffset_IsVertexArrayAPPLE 747
-#define _gloffset_GetProgramNamedParameterdvNV 748
-#define _gloffset_GetProgramNamedParameterfvNV 749
-#define _gloffset_ProgramNamedParameter4dNV 750
-#define _gloffset_ProgramNamedParameter4dvNV 751
-#define _gloffset_ProgramNamedParameter4fNV 752
-#define _gloffset_ProgramNamedParameter4fvNV 753
-#define _gloffset_DepthBoundsEXT 754
-#define _gloffset_BlendEquationSeparateEXT 755
-#define _gloffset_BindFramebufferEXT 756
-#define _gloffset_BindRenderbufferEXT 757
-#define _gloffset_CheckFramebufferStatusEXT 758
-#define _gloffset_DeleteFramebuffersEXT 759
-#define _gloffset_DeleteRenderbuffersEXT 760
-#define _gloffset_FramebufferRenderbufferEXT 761
-#define _gloffset_FramebufferTexture1DEXT 762
-#define _gloffset_FramebufferTexture2DEXT 763
-#define _gloffset_FramebufferTexture3DEXT 764
-#define _gloffset_GenFramebuffersEXT 765
-#define _gloffset_GenRenderbuffersEXT 766
-#define _gloffset_GenerateMipmapEXT 767
-#define _gloffset_GetFramebufferAttachmentParameterivEXT 768
-#define _gloffset_GetRenderbufferParameterivEXT 769
-#define _gloffset_IsFramebufferEXT 770
-#define _gloffset_IsRenderbufferEXT 771
-#define _gloffset_RenderbufferStorageEXT 772
-#define _gloffset_BlitFramebufferEXT 773
-#define _gloffset_FramebufferTextureLayerEXT 774
-#define _gloffset_ProvokingVertexEXT 775
-#define _gloffset_StencilFuncSeparateATI 776
-#define _gloffset_ProgramEnvParameters4fvEXT 777
-#define _gloffset_ProgramLocalParameters4fvEXT 778
-#define _gloffset_GetQueryObjecti64vEXT 779
-#define _gloffset_GetQueryObjectui64vEXT 780
-#define _gloffset_FIRST_DYNAMIC 781
+#define _gloffset_ClientWaitSync 567
+#define _gloffset_DeleteSync 568
+#define _gloffset_FenceSync 569
+#define _gloffset_GetInteger64v 570
+#define _gloffset_GetSynciv 571
+#define _gloffset_IsSync 572
+#define _gloffset_WaitSync 573
+#define _gloffset_DrawElementsBaseVertex 574
+#define _gloffset_DrawRangeElementsBaseVertex 575
+#define _gloffset_MultiDrawElementsBaseVertex 576
+#define _gloffset_PolygonOffsetEXT 577
+#define _gloffset_GetPixelTexGenParameterfvSGIS 578
+#define _gloffset_GetPixelTexGenParameterivSGIS 579
+#define _gloffset_PixelTexGenParameterfSGIS 580
+#define _gloffset_PixelTexGenParameterfvSGIS 581
+#define _gloffset_PixelTexGenParameteriSGIS 582
+#define _gloffset_PixelTexGenParameterivSGIS 583
+#define _gloffset_SampleMaskSGIS 584
+#define _gloffset_SamplePatternSGIS 585
+#define _gloffset_ColorPointerEXT 586
+#define _gloffset_EdgeFlagPointerEXT 587
+#define _gloffset_IndexPointerEXT 588
+#define _gloffset_NormalPointerEXT 589
+#define _gloffset_TexCoordPointerEXT 590
+#define _gloffset_VertexPointerEXT 591
+#define _gloffset_PointParameterfEXT 592
+#define _gloffset_PointParameterfvEXT 593
+#define _gloffset_LockArraysEXT 594
+#define _gloffset_UnlockArraysEXT 595
+#define _gloffset_CullParameterdvEXT 596
+#define _gloffset_CullParameterfvEXT 597
+#define _gloffset_SecondaryColor3bEXT 598
+#define _gloffset_SecondaryColor3bvEXT 599
+#define _gloffset_SecondaryColor3dEXT 600
+#define _gloffset_SecondaryColor3dvEXT 601
+#define _gloffset_SecondaryColor3fEXT 602
+#define _gloffset_SecondaryColor3fvEXT 603
+#define _gloffset_SecondaryColor3iEXT 604
+#define _gloffset_SecondaryColor3ivEXT 605
+#define _gloffset_SecondaryColor3sEXT 606
+#define _gloffset_SecondaryColor3svEXT 607
+#define _gloffset_SecondaryColor3ubEXT 608
+#define _gloffset_SecondaryColor3ubvEXT 609
+#define _gloffset_SecondaryColor3uiEXT 610
+#define _gloffset_SecondaryColor3uivEXT 611
+#define _gloffset_SecondaryColor3usEXT 612
+#define _gloffset_SecondaryColor3usvEXT 613
+#define _gloffset_SecondaryColorPointerEXT 614
+#define _gloffset_MultiDrawArraysEXT 615
+#define _gloffset_MultiDrawElementsEXT 616
+#define _gloffset_FogCoordPointerEXT 617
+#define _gloffset_FogCoorddEXT 618
+#define _gloffset_FogCoorddvEXT 619
+#define _gloffset_FogCoordfEXT 620
+#define _gloffset_FogCoordfvEXT 621
+#define _gloffset_PixelTexGenSGIX 622
+#define _gloffset_BlendFuncSeparateEXT 623
+#define _gloffset_FlushVertexArrayRangeNV 624
+#define _gloffset_VertexArrayRangeNV 625
+#define _gloffset_CombinerInputNV 626
+#define _gloffset_CombinerOutputNV 627
+#define _gloffset_CombinerParameterfNV 628
+#define _gloffset_CombinerParameterfvNV 629
+#define _gloffset_CombinerParameteriNV 630
+#define _gloffset_CombinerParameterivNV 631
+#define _gloffset_FinalCombinerInputNV 632
+#define _gloffset_GetCombinerInputParameterfvNV 633
+#define _gloffset_GetCombinerInputParameterivNV 634
+#define _gloffset_GetCombinerOutputParameterfvNV 635
+#define _gloffset_GetCombinerOutputParameterivNV 636
+#define _gloffset_GetFinalCombinerInputParameterfvNV 637
+#define _gloffset_GetFinalCombinerInputParameterivNV 638
+#define _gloffset_ResizeBuffersMESA 639
+#define _gloffset_WindowPos2dMESA 640
+#define _gloffset_WindowPos2dvMESA 641
+#define _gloffset_WindowPos2fMESA 642
+#define _gloffset_WindowPos2fvMESA 643
+#define _gloffset_WindowPos2iMESA 644
+#define _gloffset_WindowPos2ivMESA 645
+#define _gloffset_WindowPos2sMESA 646
+#define _gloffset_WindowPos2svMESA 647
+#define _gloffset_WindowPos3dMESA 648
+#define _gloffset_WindowPos3dvMESA 649
+#define _gloffset_WindowPos3fMESA 650
+#define _gloffset_WindowPos3fvMESA 651
+#define _gloffset_WindowPos3iMESA 652
+#define _gloffset_WindowPos3ivMESA 653
+#define _gloffset_WindowPos3sMESA 654
+#define _gloffset_WindowPos3svMESA 655
+#define _gloffset_WindowPos4dMESA 656
+#define _gloffset_WindowPos4dvMESA 657
+#define _gloffset_WindowPos4fMESA 658
+#define _gloffset_WindowPos4fvMESA 659
+#define _gloffset_WindowPos4iMESA 660
+#define _gloffset_WindowPos4ivMESA 661
+#define _gloffset_WindowPos4sMESA 662
+#define _gloffset_WindowPos4svMESA 663
+#define _gloffset_MultiModeDrawArraysIBM 664
+#define _gloffset_MultiModeDrawElementsIBM 665
+#define _gloffset_DeleteFencesNV 666
+#define _gloffset_FinishFenceNV 667
+#define _gloffset_GenFencesNV 668
+#define _gloffset_GetFenceivNV 669
+#define _gloffset_IsFenceNV 670
+#define _gloffset_SetFenceNV 671
+#define _gloffset_TestFenceNV 672
+#define _gloffset_AreProgramsResidentNV 673
+#define _gloffset_BindProgramNV 674
+#define _gloffset_DeleteProgramsNV 675
+#define _gloffset_ExecuteProgramNV 676
+#define _gloffset_GenProgramsNV 677
+#define _gloffset_GetProgramParameterdvNV 678
+#define _gloffset_GetProgramParameterfvNV 679
+#define _gloffset_GetProgramStringNV 680
+#define _gloffset_GetProgramivNV 681
+#define _gloffset_GetTrackMatrixivNV 682
+#define _gloffset_GetVertexAttribPointervNV 683
+#define _gloffset_GetVertexAttribdvNV 684
+#define _gloffset_GetVertexAttribfvNV 685
+#define _gloffset_GetVertexAttribivNV 686
+#define _gloffset_IsProgramNV 687
+#define _gloffset_LoadProgramNV 688
+#define _gloffset_ProgramParameters4dvNV 689
+#define _gloffset_ProgramParameters4fvNV 690
+#define _gloffset_RequestResidentProgramsNV 691
+#define _gloffset_TrackMatrixNV 692
+#define _gloffset_VertexAttrib1dNV 693
+#define _gloffset_VertexAttrib1dvNV 694
+#define _gloffset_VertexAttrib1fNV 695
+#define _gloffset_VertexAttrib1fvNV 696
+#define _gloffset_VertexAttrib1sNV 697
+#define _gloffset_VertexAttrib1svNV 698
+#define _gloffset_VertexAttrib2dNV 699
+#define _gloffset_VertexAttrib2dvNV 700
+#define _gloffset_VertexAttrib2fNV 701
+#define _gloffset_VertexAttrib2fvNV 702
+#define _gloffset_VertexAttrib2sNV 703
+#define _gloffset_VertexAttrib2svNV 704
+#define _gloffset_VertexAttrib3dNV 705
+#define _gloffset_VertexAttrib3dvNV 706
+#define _gloffset_VertexAttrib3fNV 707
+#define _gloffset_VertexAttrib3fvNV 708
+#define _gloffset_VertexAttrib3sNV 709
+#define _gloffset_VertexAttrib3svNV 710
+#define _gloffset_VertexAttrib4dNV 711
+#define _gloffset_VertexAttrib4dvNV 712
+#define _gloffset_VertexAttrib4fNV 713
+#define _gloffset_VertexAttrib4fvNV 714
+#define _gloffset_VertexAttrib4sNV 715
+#define _gloffset_VertexAttrib4svNV 716
+#define _gloffset_VertexAttrib4ubNV 717
+#define _gloffset_VertexAttrib4ubvNV 718
+#define _gloffset_VertexAttribPointerNV 719
+#define _gloffset_VertexAttribs1dvNV 720
+#define _gloffset_VertexAttribs1fvNV 721
+#define _gloffset_VertexAttribs1svNV 722
+#define _gloffset_VertexAttribs2dvNV 723
+#define _gloffset_VertexAttribs2fvNV 724
+#define _gloffset_VertexAttribs2svNV 725
+#define _gloffset_VertexAttribs3dvNV 726
+#define _gloffset_VertexAttribs3fvNV 727
+#define _gloffset_VertexAttribs3svNV 728
+#define _gloffset_VertexAttribs4dvNV 729
+#define _gloffset_VertexAttribs4fvNV 730
+#define _gloffset_VertexAttribs4svNV 731
+#define _gloffset_VertexAttribs4ubvNV 732
+#define _gloffset_GetTexBumpParameterfvATI 733
+#define _gloffset_GetTexBumpParameterivATI 734
+#define _gloffset_TexBumpParameterfvATI 735
+#define _gloffset_TexBumpParameterivATI 736
+#define _gloffset_AlphaFragmentOp1ATI 737
+#define _gloffset_AlphaFragmentOp2ATI 738
+#define _gloffset_AlphaFragmentOp3ATI 739
+#define _gloffset_BeginFragmentShaderATI 740
+#define _gloffset_BindFragmentShaderATI 741
+#define _gloffset_ColorFragmentOp1ATI 742
+#define _gloffset_ColorFragmentOp2ATI 743
+#define _gloffset_ColorFragmentOp3ATI 744
+#define _gloffset_DeleteFragmentShaderATI 745
+#define _gloffset_EndFragmentShaderATI 746
+#define _gloffset_GenFragmentShadersATI 747
+#define _gloffset_PassTexCoordATI 748
+#define _gloffset_SampleMapATI 749
+#define _gloffset_SetFragmentShaderConstantATI 750
+#define _gloffset_PointParameteriNV 751
+#define _gloffset_PointParameterivNV 752
+#define _gloffset_ActiveStencilFaceEXT 753
+#define _gloffset_BindVertexArrayAPPLE 754
+#define _gloffset_DeleteVertexArraysAPPLE 755
+#define _gloffset_GenVertexArraysAPPLE 756
+#define _gloffset_IsVertexArrayAPPLE 757
+#define _gloffset_GetProgramNamedParameterdvNV 758
+#define _gloffset_GetProgramNamedParameterfvNV 759
+#define _gloffset_ProgramNamedParameter4dNV 760
+#define _gloffset_ProgramNamedParameter4dvNV 761
+#define _gloffset_ProgramNamedParameter4fNV 762
+#define _gloffset_ProgramNamedParameter4fvNV 763
+#define _gloffset_DepthBoundsEXT 764
+#define _gloffset_BlendEquationSeparateEXT 765
+#define _gloffset_BindFramebufferEXT 766
+#define _gloffset_BindRenderbufferEXT 767
+#define _gloffset_CheckFramebufferStatusEXT 768
+#define _gloffset_DeleteFramebuffersEXT 769
+#define _gloffset_DeleteRenderbuffersEXT 770
+#define _gloffset_FramebufferRenderbufferEXT 771
+#define _gloffset_FramebufferTexture1DEXT 772
+#define _gloffset_FramebufferTexture2DEXT 773
+#define _gloffset_FramebufferTexture3DEXT 774
+#define _gloffset_GenFramebuffersEXT 775
+#define _gloffset_GenRenderbuffersEXT 776
+#define _gloffset_GenerateMipmapEXT 777
+#define _gloffset_GetFramebufferAttachmentParameterivEXT 778
+#define _gloffset_GetRenderbufferParameterivEXT 779
+#define _gloffset_IsFramebufferEXT 780
+#define _gloffset_IsRenderbufferEXT 781
+#define _gloffset_RenderbufferStorageEXT 782
+#define _gloffset_BlitFramebufferEXT 783
+#define _gloffset_BufferParameteriAPPLE 784
+#define _gloffset_FlushMappedBufferRangeAPPLE 785
+#define _gloffset_FramebufferTextureLayerEXT 786
+#define _gloffset_ProvokingVertexEXT 787
+#define _gloffset_GetTexParameterPointervAPPLE 788
+#define _gloffset_TextureRangeAPPLE 789
+#define _gloffset_StencilFuncSeparateATI 790
+#define _gloffset_ProgramEnvParameters4fvEXT 791
+#define _gloffset_ProgramLocalParameters4fvEXT 792
+#define _gloffset_GetQueryObjecti64vEXT 793
+#define _gloffset_GetQueryObjectui64vEXT 794
+#define _gloffset_FIRST_DYNAMIC 795
#else
@@ -976,6 +990,16 @@
#define _gloffset_BindVertexArray driDispatchRemapTable[BindVertexArray_remap_index]
#define _gloffset_GenVertexArrays driDispatchRemapTable[GenVertexArrays_remap_index]
#define _gloffset_CopyBufferSubData driDispatchRemapTable[CopyBufferSubData_remap_index]
+#define _gloffset_ClientWaitSync driDispatchRemapTable[ClientWaitSync_remap_index]
+#define _gloffset_DeleteSync driDispatchRemapTable[DeleteSync_remap_index]
+#define _gloffset_FenceSync driDispatchRemapTable[FenceSync_remap_index]
+#define _gloffset_GetInteger64v driDispatchRemapTable[GetInteger64v_remap_index]
+#define _gloffset_GetSynciv driDispatchRemapTable[GetSynciv_remap_index]
+#define _gloffset_IsSync driDispatchRemapTable[IsSync_remap_index]
+#define _gloffset_WaitSync driDispatchRemapTable[WaitSync_remap_index]
+#define _gloffset_DrawElementsBaseVertex driDispatchRemapTable[DrawElementsBaseVertex_remap_index]
+#define _gloffset_DrawRangeElementsBaseVertex driDispatchRemapTable[DrawRangeElementsBaseVertex_remap_index]
+#define _gloffset_MultiDrawElementsBaseVertex driDispatchRemapTable[MultiDrawElementsBaseVertex_remap_index]
#define _gloffset_PolygonOffsetEXT driDispatchRemapTable[PolygonOffsetEXT_remap_index]
#define _gloffset_GetPixelTexGenParameterfvSGIS driDispatchRemapTable[GetPixelTexGenParameterfvSGIS_remap_index]
#define _gloffset_GetPixelTexGenParameterivSGIS driDispatchRemapTable[GetPixelTexGenParameterivSGIS_remap_index]
@@ -1183,8 +1207,12 @@
#define _gloffset_IsRenderbufferEXT driDispatchRemapTable[IsRenderbufferEXT_remap_index]
#define _gloffset_RenderbufferStorageEXT driDispatchRemapTable[RenderbufferStorageEXT_remap_index]
#define _gloffset_BlitFramebufferEXT driDispatchRemapTable[BlitFramebufferEXT_remap_index]
+#define _gloffset_BufferParameteriAPPLE driDispatchRemapTable[BufferParameteriAPPLE_remap_index]
+#define _gloffset_FlushMappedBufferRangeAPPLE driDispatchRemapTable[FlushMappedBufferRangeAPPLE_remap_index]
#define _gloffset_FramebufferTextureLayerEXT driDispatchRemapTable[FramebufferTextureLayerEXT_remap_index]
#define _gloffset_ProvokingVertexEXT driDispatchRemapTable[ProvokingVertexEXT_remap_index]
+#define _gloffset_GetTexParameterPointervAPPLE driDispatchRemapTable[GetTexParameterPointervAPPLE_remap_index]
+#define _gloffset_TextureRangeAPPLE driDispatchRemapTable[TextureRangeAPPLE_remap_index]
#define _gloffset_StencilFuncSeparateATI driDispatchRemapTable[StencilFuncSeparateATI_remap_index]
#define _gloffset_ProgramEnvParameters4fvEXT driDispatchRemapTable[ProgramEnvParameters4fvEXT_remap_index]
#define _gloffset_ProgramLocalParameters4fvEXT driDispatchRemapTable[ProgramLocalParameters4fvEXT_remap_index]
diff --git a/src/mesa/glapi/glapitable.h b/src/mesa/glapi/glapitable.h
index 308de4facc..4f9e53b62d 100644
--- a/src/mesa/glapi/glapitable.h
+++ b/src/mesa/glapi/glapitable.h
@@ -607,220 +607,234 @@ struct _glapi_table
void (GLAPIENTRYP BindVertexArray)(GLuint array); /* 564 */
void (GLAPIENTRYP GenVertexArrays)(GLsizei n, GLuint * arrays); /* 565 */
void (GLAPIENTRYP CopyBufferSubData)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); /* 566 */
- void (GLAPIENTRYP PolygonOffsetEXT)(GLfloat factor, GLfloat bias); /* 567 */
- void (GLAPIENTRYP GetPixelTexGenParameterfvSGIS)(GLenum pname, GLfloat * params); /* 568 */
- void (GLAPIENTRYP GetPixelTexGenParameterivSGIS)(GLenum pname, GLint * params); /* 569 */
- void (GLAPIENTRYP PixelTexGenParameterfSGIS)(GLenum pname, GLfloat param); /* 570 */
- void (GLAPIENTRYP PixelTexGenParameterfvSGIS)(GLenum pname, const GLfloat * params); /* 571 */
- void (GLAPIENTRYP PixelTexGenParameteriSGIS)(GLenum pname, GLint param); /* 572 */
- void (GLAPIENTRYP PixelTexGenParameterivSGIS)(GLenum pname, const GLint * params); /* 573 */
- void (GLAPIENTRYP SampleMaskSGIS)(GLclampf value, GLboolean invert); /* 574 */
- void (GLAPIENTRYP SamplePatternSGIS)(GLenum pattern); /* 575 */
- void (GLAPIENTRYP ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 576 */
- void (GLAPIENTRYP EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean * pointer); /* 577 */
- void (GLAPIENTRYP IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 578 */
- void (GLAPIENTRYP NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 579 */
- void (GLAPIENTRYP TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 580 */
- void (GLAPIENTRYP VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 581 */
- void (GLAPIENTRYP PointParameterfEXT)(GLenum pname, GLfloat param); /* 582 */
- void (GLAPIENTRYP PointParameterfvEXT)(GLenum pname, const GLfloat * params); /* 583 */
- void (GLAPIENTRYP LockArraysEXT)(GLint first, GLsizei count); /* 584 */
- void (GLAPIENTRYP UnlockArraysEXT)(void); /* 585 */
- void (GLAPIENTRYP CullParameterdvEXT)(GLenum pname, GLdouble * params); /* 586 */
- void (GLAPIENTRYP CullParameterfvEXT)(GLenum pname, GLfloat * params); /* 587 */
- void (GLAPIENTRYP SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue); /* 588 */
- void (GLAPIENTRYP SecondaryColor3bvEXT)(const GLbyte * v); /* 589 */
- void (GLAPIENTRYP SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue); /* 590 */
- void (GLAPIENTRYP SecondaryColor3dvEXT)(const GLdouble * v); /* 591 */
- void (GLAPIENTRYP SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue); /* 592 */
- void (GLAPIENTRYP SecondaryColor3fvEXT)(const GLfloat * v); /* 593 */
- void (GLAPIENTRYP SecondaryColor3iEXT)(GLint red, GLint green, GLint blue); /* 594 */
- void (GLAPIENTRYP SecondaryColor3ivEXT)(const GLint * v); /* 595 */
- void (GLAPIENTRYP SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue); /* 596 */
- void (GLAPIENTRYP SecondaryColor3svEXT)(const GLshort * v); /* 597 */
- void (GLAPIENTRYP SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue); /* 598 */
- void (GLAPIENTRYP SecondaryColor3ubvEXT)(const GLubyte * v); /* 599 */
- void (GLAPIENTRYP SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue); /* 600 */
- void (GLAPIENTRYP SecondaryColor3uivEXT)(const GLuint * v); /* 601 */
- void (GLAPIENTRYP SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue); /* 602 */
- void (GLAPIENTRYP SecondaryColor3usvEXT)(const GLushort * v); /* 603 */
- void (GLAPIENTRYP SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 604 */
- void (GLAPIENTRYP MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); /* 605 */
- void (GLAPIENTRYP MultiDrawElementsEXT)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount); /* 606 */
- void (GLAPIENTRYP FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 607 */
- void (GLAPIENTRYP FogCoorddEXT)(GLdouble coord); /* 608 */
- void (GLAPIENTRYP FogCoorddvEXT)(const GLdouble * coord); /* 609 */
- void (GLAPIENTRYP FogCoordfEXT)(GLfloat coord); /* 610 */
- void (GLAPIENTRYP FogCoordfvEXT)(const GLfloat * coord); /* 611 */
- void (GLAPIENTRYP PixelTexGenSGIX)(GLenum mode); /* 612 */
- void (GLAPIENTRYP BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); /* 613 */
- void (GLAPIENTRYP FlushVertexArrayRangeNV)(void); /* 614 */
- void (GLAPIENTRYP VertexArrayRangeNV)(GLsizei length, const GLvoid * pointer); /* 615 */
- void (GLAPIENTRYP CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 616 */
- void (GLAPIENTRYP CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); /* 617 */
- void (GLAPIENTRYP CombinerParameterfNV)(GLenum pname, GLfloat param); /* 618 */
- void (GLAPIENTRYP CombinerParameterfvNV)(GLenum pname, const GLfloat * params); /* 619 */
- void (GLAPIENTRYP CombinerParameteriNV)(GLenum pname, GLint param); /* 620 */
- void (GLAPIENTRYP CombinerParameterivNV)(GLenum pname, const GLint * params); /* 621 */
- void (GLAPIENTRYP FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 622 */
- void (GLAPIENTRYP GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); /* 623 */
- void (GLAPIENTRYP GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); /* 624 */
- void (GLAPIENTRYP GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); /* 625 */
- void (GLAPIENTRYP GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params); /* 626 */
- void (GLAPIENTRYP GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params); /* 627 */
- void (GLAPIENTRYP GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params); /* 628 */
- void (GLAPIENTRYP ResizeBuffersMESA)(void); /* 629 */
- void (GLAPIENTRYP WindowPos2dMESA)(GLdouble x, GLdouble y); /* 630 */
- void (GLAPIENTRYP WindowPos2dvMESA)(const GLdouble * v); /* 631 */
- void (GLAPIENTRYP WindowPos2fMESA)(GLfloat x, GLfloat y); /* 632 */
- void (GLAPIENTRYP WindowPos2fvMESA)(const GLfloat * v); /* 633 */
- void (GLAPIENTRYP WindowPos2iMESA)(GLint x, GLint y); /* 634 */
- void (GLAPIENTRYP WindowPos2ivMESA)(const GLint * v); /* 635 */
- void (GLAPIENTRYP WindowPos2sMESA)(GLshort x, GLshort y); /* 636 */
- void (GLAPIENTRYP WindowPos2svMESA)(const GLshort * v); /* 637 */
- void (GLAPIENTRYP WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z); /* 638 */
- void (GLAPIENTRYP WindowPos3dvMESA)(const GLdouble * v); /* 639 */
- void (GLAPIENTRYP WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z); /* 640 */
- void (GLAPIENTRYP WindowPos3fvMESA)(const GLfloat * v); /* 641 */
- void (GLAPIENTRYP WindowPos3iMESA)(GLint x, GLint y, GLint z); /* 642 */
- void (GLAPIENTRYP WindowPos3ivMESA)(const GLint * v); /* 643 */
- void (GLAPIENTRYP WindowPos3sMESA)(GLshort x, GLshort y, GLshort z); /* 644 */
- void (GLAPIENTRYP WindowPos3svMESA)(const GLshort * v); /* 645 */
- void (GLAPIENTRYP WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 646 */
- void (GLAPIENTRYP WindowPos4dvMESA)(const GLdouble * v); /* 647 */
- void (GLAPIENTRYP WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 648 */
- void (GLAPIENTRYP WindowPos4fvMESA)(const GLfloat * v); /* 649 */
- void (GLAPIENTRYP WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w); /* 650 */
- void (GLAPIENTRYP WindowPos4ivMESA)(const GLint * v); /* 651 */
- void (GLAPIENTRYP WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w); /* 652 */
- void (GLAPIENTRYP WindowPos4svMESA)(const GLshort * v); /* 653 */
- void (GLAPIENTRYP MultiModeDrawArraysIBM)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); /* 654 */
- void (GLAPIENTRYP MultiModeDrawElementsIBM)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride); /* 655 */
- void (GLAPIENTRYP DeleteFencesNV)(GLsizei n, const GLuint * fences); /* 656 */
- void (GLAPIENTRYP FinishFenceNV)(GLuint fence); /* 657 */
- void (GLAPIENTRYP GenFencesNV)(GLsizei n, GLuint * fences); /* 658 */
- void (GLAPIENTRYP GetFenceivNV)(GLuint fence, GLenum pname, GLint * params); /* 659 */
- GLboolean (GLAPIENTRYP IsFenceNV)(GLuint fence); /* 660 */
- void (GLAPIENTRYP SetFenceNV)(GLuint fence, GLenum condition); /* 661 */
- GLboolean (GLAPIENTRYP TestFenceNV)(GLuint fence); /* 662 */
- GLboolean (GLAPIENTRYP AreProgramsResidentNV)(GLsizei n, const GLuint * ids, GLboolean * residences); /* 663 */
- void (GLAPIENTRYP BindProgramNV)(GLenum target, GLuint program); /* 664 */
- void (GLAPIENTRYP DeleteProgramsNV)(GLsizei n, const GLuint * programs); /* 665 */
- void (GLAPIENTRYP ExecuteProgramNV)(GLenum target, GLuint id, const GLfloat * params); /* 666 */
- void (GLAPIENTRYP GenProgramsNV)(GLsizei n, GLuint * programs); /* 667 */
- void (GLAPIENTRYP GetProgramParameterdvNV)(GLenum target, GLuint index, GLenum pname, GLdouble * params); /* 668 */
- void (GLAPIENTRYP GetProgramParameterfvNV)(GLenum target, GLuint index, GLenum pname, GLfloat * params); /* 669 */
- void (GLAPIENTRYP GetProgramStringNV)(GLuint id, GLenum pname, GLubyte * program); /* 670 */
- void (GLAPIENTRYP GetProgramivNV)(GLuint id, GLenum pname, GLint * params); /* 671 */
- void (GLAPIENTRYP GetTrackMatrixivNV)(GLenum target, GLuint address, GLenum pname, GLint * params); /* 672 */
- void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** pointer); /* 673 */
- void (GLAPIENTRYP GetVertexAttribdvNV)(GLuint index, GLenum pname, GLdouble * params); /* 674 */
- void (GLAPIENTRYP GetVertexAttribfvNV)(GLuint index, GLenum pname, GLfloat * params); /* 675 */
- void (GLAPIENTRYP GetVertexAttribivNV)(GLuint index, GLenum pname, GLint * params); /* 676 */
- GLboolean (GLAPIENTRYP IsProgramNV)(GLuint program); /* 677 */
- void (GLAPIENTRYP LoadProgramNV)(GLenum target, GLuint id, GLsizei len, const GLubyte * program); /* 678 */
- void (GLAPIENTRYP ProgramParameters4dvNV)(GLenum target, GLuint index, GLuint num, const GLdouble * params); /* 679 */
- void (GLAPIENTRYP ProgramParameters4fvNV)(GLenum target, GLuint index, GLuint num, const GLfloat * params); /* 680 */
- void (GLAPIENTRYP RequestResidentProgramsNV)(GLsizei n, const GLuint * ids); /* 681 */
- void (GLAPIENTRYP TrackMatrixNV)(GLenum target, GLuint address, GLenum matrix, GLenum transform); /* 682 */
- void (GLAPIENTRYP VertexAttrib1dNV)(GLuint index, GLdouble x); /* 683 */
- void (GLAPIENTRYP VertexAttrib1dvNV)(GLuint index, const GLdouble * v); /* 684 */
- void (GLAPIENTRYP VertexAttrib1fNV)(GLuint index, GLfloat x); /* 685 */
- void (GLAPIENTRYP VertexAttrib1fvNV)(GLuint index, const GLfloat * v); /* 686 */
- void (GLAPIENTRYP VertexAttrib1sNV)(GLuint index, GLshort x); /* 687 */
- void (GLAPIENTRYP VertexAttrib1svNV)(GLuint index, const GLshort * v); /* 688 */
- void (GLAPIENTRYP VertexAttrib2dNV)(GLuint index, GLdouble x, GLdouble y); /* 689 */
- void (GLAPIENTRYP VertexAttrib2dvNV)(GLuint index, const GLdouble * v); /* 690 */
- void (GLAPIENTRYP VertexAttrib2fNV)(GLuint index, GLfloat x, GLfloat y); /* 691 */
- void (GLAPIENTRYP VertexAttrib2fvNV)(GLuint index, const GLfloat * v); /* 692 */
- void (GLAPIENTRYP VertexAttrib2sNV)(GLuint index, GLshort x, GLshort y); /* 693 */
- void (GLAPIENTRYP VertexAttrib2svNV)(GLuint index, const GLshort * v); /* 694 */
- void (GLAPIENTRYP VertexAttrib3dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z); /* 695 */
- void (GLAPIENTRYP VertexAttrib3dvNV)(GLuint index, const GLdouble * v); /* 696 */
- void (GLAPIENTRYP VertexAttrib3fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z); /* 697 */
- void (GLAPIENTRYP VertexAttrib3fvNV)(GLuint index, const GLfloat * v); /* 698 */
- void (GLAPIENTRYP VertexAttrib3sNV)(GLuint index, GLshort x, GLshort y, GLshort z); /* 699 */
- void (GLAPIENTRYP VertexAttrib3svNV)(GLuint index, const GLshort * v); /* 700 */
- void (GLAPIENTRYP VertexAttrib4dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 701 */
- void (GLAPIENTRYP VertexAttrib4dvNV)(GLuint index, const GLdouble * v); /* 702 */
- void (GLAPIENTRYP VertexAttrib4fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 703 */
- void (GLAPIENTRYP VertexAttrib4fvNV)(GLuint index, const GLfloat * v); /* 704 */
- void (GLAPIENTRYP VertexAttrib4sNV)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); /* 705 */
- void (GLAPIENTRYP VertexAttrib4svNV)(GLuint index, const GLshort * v); /* 706 */
- void (GLAPIENTRYP VertexAttrib4ubNV)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); /* 707 */
- void (GLAPIENTRYP VertexAttrib4ubvNV)(GLuint index, const GLubyte * v); /* 708 */
- void (GLAPIENTRYP VertexAttribPointerNV)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 709 */
- void (GLAPIENTRYP VertexAttribs1dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 710 */
- void (GLAPIENTRYP VertexAttribs1fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 711 */
- void (GLAPIENTRYP VertexAttribs1svNV)(GLuint index, GLsizei n, const GLshort * v); /* 712 */
- void (GLAPIENTRYP VertexAttribs2dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 713 */
- void (GLAPIENTRYP VertexAttribs2fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 714 */
- void (GLAPIENTRYP VertexAttribs2svNV)(GLuint index, GLsizei n, const GLshort * v); /* 715 */
- void (GLAPIENTRYP VertexAttribs3dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 716 */
- void (GLAPIENTRYP VertexAttribs3fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 717 */
- void (GLAPIENTRYP VertexAttribs3svNV)(GLuint index, GLsizei n, const GLshort * v); /* 718 */
- void (GLAPIENTRYP VertexAttribs4dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 719 */
- void (GLAPIENTRYP VertexAttribs4fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 720 */
- void (GLAPIENTRYP VertexAttribs4svNV)(GLuint index, GLsizei n, const GLshort * v); /* 721 */
- void (GLAPIENTRYP VertexAttribs4ubvNV)(GLuint index, GLsizei n, const GLubyte * v); /* 722 */
- void (GLAPIENTRYP GetTexBumpParameterfvATI)(GLenum pname, GLfloat * param); /* 723 */
- void (GLAPIENTRYP GetTexBumpParameterivATI)(GLenum pname, GLint * param); /* 724 */
- void (GLAPIENTRYP TexBumpParameterfvATI)(GLenum pname, const GLfloat * param); /* 725 */
- void (GLAPIENTRYP TexBumpParameterivATI)(GLenum pname, const GLint * param); /* 726 */
- void (GLAPIENTRYP AlphaFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 727 */
- void (GLAPIENTRYP AlphaFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 728 */
- void (GLAPIENTRYP AlphaFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 729 */
- void (GLAPIENTRYP BeginFragmentShaderATI)(void); /* 730 */
- void (GLAPIENTRYP BindFragmentShaderATI)(GLuint id); /* 731 */
- void (GLAPIENTRYP ColorFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 732 */
- void (GLAPIENTRYP ColorFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 733 */
- void (GLAPIENTRYP ColorFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 734 */
- void (GLAPIENTRYP DeleteFragmentShaderATI)(GLuint id); /* 735 */
- void (GLAPIENTRYP EndFragmentShaderATI)(void); /* 736 */
- GLuint (GLAPIENTRYP GenFragmentShadersATI)(GLuint range); /* 737 */
- void (GLAPIENTRYP PassTexCoordATI)(GLuint dst, GLuint coord, GLenum swizzle); /* 738 */
- void (GLAPIENTRYP SampleMapATI)(GLuint dst, GLuint interp, GLenum swizzle); /* 739 */
- void (GLAPIENTRYP SetFragmentShaderConstantATI)(GLuint dst, const GLfloat * value); /* 740 */
- void (GLAPIENTRYP PointParameteriNV)(GLenum pname, GLint param); /* 741 */
- void (GLAPIENTRYP PointParameterivNV)(GLenum pname, const GLint * params); /* 742 */
- void (GLAPIENTRYP ActiveStencilFaceEXT)(GLenum face); /* 743 */
- void (GLAPIENTRYP BindVertexArrayAPPLE)(GLuint array); /* 744 */
- void (GLAPIENTRYP DeleteVertexArraysAPPLE)(GLsizei n, const GLuint * arrays); /* 745 */
- void (GLAPIENTRYP GenVertexArraysAPPLE)(GLsizei n, GLuint * arrays); /* 746 */
- GLboolean (GLAPIENTRYP IsVertexArrayAPPLE)(GLuint array); /* 747 */
- void (GLAPIENTRYP GetProgramNamedParameterdvNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); /* 748 */
- void (GLAPIENTRYP GetProgramNamedParameterfvNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); /* 749 */
- void (GLAPIENTRYP ProgramNamedParameter4dNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 750 */
- void (GLAPIENTRYP ProgramNamedParameter4dvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); /* 751 */
- void (GLAPIENTRYP ProgramNamedParameter4fNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 752 */
- void (GLAPIENTRYP ProgramNamedParameter4fvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); /* 753 */
- void (GLAPIENTRYP DepthBoundsEXT)(GLclampd zmin, GLclampd zmax); /* 754 */
- void (GLAPIENTRYP BlendEquationSeparateEXT)(GLenum modeRGB, GLenum modeA); /* 755 */
- void (GLAPIENTRYP BindFramebufferEXT)(GLenum target, GLuint framebuffer); /* 756 */
- void (GLAPIENTRYP BindRenderbufferEXT)(GLenum target, GLuint renderbuffer); /* 757 */
- GLenum (GLAPIENTRYP CheckFramebufferStatusEXT)(GLenum target); /* 758 */
- void (GLAPIENTRYP DeleteFramebuffersEXT)(GLsizei n, const GLuint * framebuffers); /* 759 */
- void (GLAPIENTRYP DeleteRenderbuffersEXT)(GLsizei n, const GLuint * renderbuffers); /* 760 */
- void (GLAPIENTRYP FramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); /* 761 */
- void (GLAPIENTRYP FramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 762 */
- void (GLAPIENTRYP FramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 763 */
- void (GLAPIENTRYP FramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); /* 764 */
- void (GLAPIENTRYP GenFramebuffersEXT)(GLsizei n, GLuint * framebuffers); /* 765 */
- void (GLAPIENTRYP GenRenderbuffersEXT)(GLsizei n, GLuint * renderbuffers); /* 766 */
- void (GLAPIENTRYP GenerateMipmapEXT)(GLenum target); /* 767 */
- void (GLAPIENTRYP GetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint * params); /* 768 */
- void (GLAPIENTRYP GetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 769 */
- GLboolean (GLAPIENTRYP IsFramebufferEXT)(GLuint framebuffer); /* 770 */
- GLboolean (GLAPIENTRYP IsRenderbufferEXT)(GLuint renderbuffer); /* 771 */
- void (GLAPIENTRYP RenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); /* 772 */
- void (GLAPIENTRYP BlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); /* 773 */
- void (GLAPIENTRYP FramebufferTextureLayerEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); /* 774 */
- void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 775 */
- void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 776 */
- void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 777 */
- void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 778 */
- void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 779 */
- void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 780 */
+ GLenum (GLAPIENTRYP ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 567 */
+ void (GLAPIENTRYP DeleteSync)(GLsync sync); /* 568 */
+ GLsync (GLAPIENTRYP FenceSync)(GLenum condition, GLbitfield flags); /* 569 */
+ void (GLAPIENTRYP GetInteger64v)(GLenum pname, GLint64 * params); /* 570 */
+ void (GLAPIENTRYP GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values); /* 571 */
+ GLboolean (GLAPIENTRYP IsSync)(GLsync sync); /* 572 */
+ void (GLAPIENTRYP WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout); /* 573 */
+ void (GLAPIENTRYP DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 574 */
+ void (GLAPIENTRYP DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex); /* 575 */
+ void (GLAPIENTRYP MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount, const GLint * basevertex); /* 576 */
+ void (GLAPIENTRYP PolygonOffsetEXT)(GLfloat factor, GLfloat bias); /* 577 */
+ void (GLAPIENTRYP GetPixelTexGenParameterfvSGIS)(GLenum pname, GLfloat * params); /* 578 */
+ void (GLAPIENTRYP GetPixelTexGenParameterivSGIS)(GLenum pname, GLint * params); /* 579 */
+ void (GLAPIENTRYP PixelTexGenParameterfSGIS)(GLenum pname, GLfloat param); /* 580 */
+ void (GLAPIENTRYP PixelTexGenParameterfvSGIS)(GLenum pname, const GLfloat * params); /* 581 */
+ void (GLAPIENTRYP PixelTexGenParameteriSGIS)(GLenum pname, GLint param); /* 582 */
+ void (GLAPIENTRYP PixelTexGenParameterivSGIS)(GLenum pname, const GLint * params); /* 583 */
+ void (GLAPIENTRYP SampleMaskSGIS)(GLclampf value, GLboolean invert); /* 584 */
+ void (GLAPIENTRYP SamplePatternSGIS)(GLenum pattern); /* 585 */
+ void (GLAPIENTRYP ColorPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 586 */
+ void (GLAPIENTRYP EdgeFlagPointerEXT)(GLsizei stride, GLsizei count, const GLboolean * pointer); /* 587 */
+ void (GLAPIENTRYP IndexPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 588 */
+ void (GLAPIENTRYP NormalPointerEXT)(GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 589 */
+ void (GLAPIENTRYP TexCoordPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 590 */
+ void (GLAPIENTRYP VertexPointerEXT)(GLint size, GLenum type, GLsizei stride, GLsizei count, const GLvoid * pointer); /* 591 */
+ void (GLAPIENTRYP PointParameterfEXT)(GLenum pname, GLfloat param); /* 592 */
+ void (GLAPIENTRYP PointParameterfvEXT)(GLenum pname, const GLfloat * params); /* 593 */
+ void (GLAPIENTRYP LockArraysEXT)(GLint first, GLsizei count); /* 594 */
+ void (GLAPIENTRYP UnlockArraysEXT)(void); /* 595 */
+ void (GLAPIENTRYP CullParameterdvEXT)(GLenum pname, GLdouble * params); /* 596 */
+ void (GLAPIENTRYP CullParameterfvEXT)(GLenum pname, GLfloat * params); /* 597 */
+ void (GLAPIENTRYP SecondaryColor3bEXT)(GLbyte red, GLbyte green, GLbyte blue); /* 598 */
+ void (GLAPIENTRYP SecondaryColor3bvEXT)(const GLbyte * v); /* 599 */
+ void (GLAPIENTRYP SecondaryColor3dEXT)(GLdouble red, GLdouble green, GLdouble blue); /* 600 */
+ void (GLAPIENTRYP SecondaryColor3dvEXT)(const GLdouble * v); /* 601 */
+ void (GLAPIENTRYP SecondaryColor3fEXT)(GLfloat red, GLfloat green, GLfloat blue); /* 602 */
+ void (GLAPIENTRYP SecondaryColor3fvEXT)(const GLfloat * v); /* 603 */
+ void (GLAPIENTRYP SecondaryColor3iEXT)(GLint red, GLint green, GLint blue); /* 604 */
+ void (GLAPIENTRYP SecondaryColor3ivEXT)(const GLint * v); /* 605 */
+ void (GLAPIENTRYP SecondaryColor3sEXT)(GLshort red, GLshort green, GLshort blue); /* 606 */
+ void (GLAPIENTRYP SecondaryColor3svEXT)(const GLshort * v); /* 607 */
+ void (GLAPIENTRYP SecondaryColor3ubEXT)(GLubyte red, GLubyte green, GLubyte blue); /* 608 */
+ void (GLAPIENTRYP SecondaryColor3ubvEXT)(const GLubyte * v); /* 609 */
+ void (GLAPIENTRYP SecondaryColor3uiEXT)(GLuint red, GLuint green, GLuint blue); /* 610 */
+ void (GLAPIENTRYP SecondaryColor3uivEXT)(const GLuint * v); /* 611 */
+ void (GLAPIENTRYP SecondaryColor3usEXT)(GLushort red, GLushort green, GLushort blue); /* 612 */
+ void (GLAPIENTRYP SecondaryColor3usvEXT)(const GLushort * v); /* 613 */
+ void (GLAPIENTRYP SecondaryColorPointerEXT)(GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 614 */
+ void (GLAPIENTRYP MultiDrawArraysEXT)(GLenum mode, GLint * first, GLsizei * count, GLsizei primcount); /* 615 */
+ void (GLAPIENTRYP MultiDrawElementsEXT)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount); /* 616 */
+ void (GLAPIENTRYP FogCoordPointerEXT)(GLenum type, GLsizei stride, const GLvoid * pointer); /* 617 */
+ void (GLAPIENTRYP FogCoorddEXT)(GLdouble coord); /* 618 */
+ void (GLAPIENTRYP FogCoorddvEXT)(const GLdouble * coord); /* 619 */
+ void (GLAPIENTRYP FogCoordfEXT)(GLfloat coord); /* 620 */
+ void (GLAPIENTRYP FogCoordfvEXT)(const GLfloat * coord); /* 621 */
+ void (GLAPIENTRYP PixelTexGenSGIX)(GLenum mode); /* 622 */
+ void (GLAPIENTRYP BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); /* 623 */
+ void (GLAPIENTRYP FlushVertexArrayRangeNV)(void); /* 624 */
+ void (GLAPIENTRYP VertexArrayRangeNV)(GLsizei length, const GLvoid * pointer); /* 625 */
+ void (GLAPIENTRYP CombinerInputNV)(GLenum stage, GLenum portion, GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 626 */
+ void (GLAPIENTRYP CombinerOutputNV)(GLenum stage, GLenum portion, GLenum abOutput, GLenum cdOutput, GLenum sumOutput, GLenum scale, GLenum bias, GLboolean abDotProduct, GLboolean cdDotProduct, GLboolean muxSum); /* 627 */
+ void (GLAPIENTRYP CombinerParameterfNV)(GLenum pname, GLfloat param); /* 628 */
+ void (GLAPIENTRYP CombinerParameterfvNV)(GLenum pname, const GLfloat * params); /* 629 */
+ void (GLAPIENTRYP CombinerParameteriNV)(GLenum pname, GLint param); /* 630 */
+ void (GLAPIENTRYP CombinerParameterivNV)(GLenum pname, const GLint * params); /* 631 */
+ void (GLAPIENTRYP FinalCombinerInputNV)(GLenum variable, GLenum input, GLenum mapping, GLenum componentUsage); /* 632 */
+ void (GLAPIENTRYP GetCombinerInputParameterfvNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLfloat * params); /* 633 */
+ void (GLAPIENTRYP GetCombinerInputParameterivNV)(GLenum stage, GLenum portion, GLenum variable, GLenum pname, GLint * params); /* 634 */
+ void (GLAPIENTRYP GetCombinerOutputParameterfvNV)(GLenum stage, GLenum portion, GLenum pname, GLfloat * params); /* 635 */
+ void (GLAPIENTRYP GetCombinerOutputParameterivNV)(GLenum stage, GLenum portion, GLenum pname, GLint * params); /* 636 */
+ void (GLAPIENTRYP GetFinalCombinerInputParameterfvNV)(GLenum variable, GLenum pname, GLfloat * params); /* 637 */
+ void (GLAPIENTRYP GetFinalCombinerInputParameterivNV)(GLenum variable, GLenum pname, GLint * params); /* 638 */
+ void (GLAPIENTRYP ResizeBuffersMESA)(void); /* 639 */
+ void (GLAPIENTRYP WindowPos2dMESA)(GLdouble x, GLdouble y); /* 640 */
+ void (GLAPIENTRYP WindowPos2dvMESA)(const GLdouble * v); /* 641 */
+ void (GLAPIENTRYP WindowPos2fMESA)(GLfloat x, GLfloat y); /* 642 */
+ void (GLAPIENTRYP WindowPos2fvMESA)(const GLfloat * v); /* 643 */
+ void (GLAPIENTRYP WindowPos2iMESA)(GLint x, GLint y); /* 644 */
+ void (GLAPIENTRYP WindowPos2ivMESA)(const GLint * v); /* 645 */
+ void (GLAPIENTRYP WindowPos2sMESA)(GLshort x, GLshort y); /* 646 */
+ void (GLAPIENTRYP WindowPos2svMESA)(const GLshort * v); /* 647 */
+ void (GLAPIENTRYP WindowPos3dMESA)(GLdouble x, GLdouble y, GLdouble z); /* 648 */
+ void (GLAPIENTRYP WindowPos3dvMESA)(const GLdouble * v); /* 649 */
+ void (GLAPIENTRYP WindowPos3fMESA)(GLfloat x, GLfloat y, GLfloat z); /* 650 */
+ void (GLAPIENTRYP WindowPos3fvMESA)(const GLfloat * v); /* 651 */
+ void (GLAPIENTRYP WindowPos3iMESA)(GLint x, GLint y, GLint z); /* 652 */
+ void (GLAPIENTRYP WindowPos3ivMESA)(const GLint * v); /* 653 */
+ void (GLAPIENTRYP WindowPos3sMESA)(GLshort x, GLshort y, GLshort z); /* 654 */
+ void (GLAPIENTRYP WindowPos3svMESA)(const GLshort * v); /* 655 */
+ void (GLAPIENTRYP WindowPos4dMESA)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 656 */
+ void (GLAPIENTRYP WindowPos4dvMESA)(const GLdouble * v); /* 657 */
+ void (GLAPIENTRYP WindowPos4fMESA)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 658 */
+ void (GLAPIENTRYP WindowPos4fvMESA)(const GLfloat * v); /* 659 */
+ void (GLAPIENTRYP WindowPos4iMESA)(GLint x, GLint y, GLint z, GLint w); /* 660 */
+ void (GLAPIENTRYP WindowPos4ivMESA)(const GLint * v); /* 661 */
+ void (GLAPIENTRYP WindowPos4sMESA)(GLshort x, GLshort y, GLshort z, GLshort w); /* 662 */
+ void (GLAPIENTRYP WindowPos4svMESA)(const GLshort * v); /* 663 */
+ void (GLAPIENTRYP MultiModeDrawArraysIBM)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride); /* 664 */
+ void (GLAPIENTRYP MultiModeDrawElementsIBM)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride); /* 665 */
+ void (GLAPIENTRYP DeleteFencesNV)(GLsizei n, const GLuint * fences); /* 666 */
+ void (GLAPIENTRYP FinishFenceNV)(GLuint fence); /* 667 */
+ void (GLAPIENTRYP GenFencesNV)(GLsizei n, GLuint * fences); /* 668 */
+ void (GLAPIENTRYP GetFenceivNV)(GLuint fence, GLenum pname, GLint * params); /* 669 */
+ GLboolean (GLAPIENTRYP IsFenceNV)(GLuint fence); /* 670 */
+ void (GLAPIENTRYP SetFenceNV)(GLuint fence, GLenum condition); /* 671 */
+ GLboolean (GLAPIENTRYP TestFenceNV)(GLuint fence); /* 672 */
+ GLboolean (GLAPIENTRYP AreProgramsResidentNV)(GLsizei n, const GLuint * ids, GLboolean * residences); /* 673 */
+ void (GLAPIENTRYP BindProgramNV)(GLenum target, GLuint program); /* 674 */
+ void (GLAPIENTRYP DeleteProgramsNV)(GLsizei n, const GLuint * programs); /* 675 */
+ void (GLAPIENTRYP ExecuteProgramNV)(GLenum target, GLuint id, const GLfloat * params); /* 676 */
+ void (GLAPIENTRYP GenProgramsNV)(GLsizei n, GLuint * programs); /* 677 */
+ void (GLAPIENTRYP GetProgramParameterdvNV)(GLenum target, GLuint index, GLenum pname, GLdouble * params); /* 678 */
+ void (GLAPIENTRYP GetProgramParameterfvNV)(GLenum target, GLuint index, GLenum pname, GLfloat * params); /* 679 */
+ void (GLAPIENTRYP GetProgramStringNV)(GLuint id, GLenum pname, GLubyte * program); /* 680 */
+ void (GLAPIENTRYP GetProgramivNV)(GLuint id, GLenum pname, GLint * params); /* 681 */
+ void (GLAPIENTRYP GetTrackMatrixivNV)(GLenum target, GLuint address, GLenum pname, GLint * params); /* 682 */
+ void (GLAPIENTRYP GetVertexAttribPointervNV)(GLuint index, GLenum pname, GLvoid ** pointer); /* 683 */
+ void (GLAPIENTRYP GetVertexAttribdvNV)(GLuint index, GLenum pname, GLdouble * params); /* 684 */
+ void (GLAPIENTRYP GetVertexAttribfvNV)(GLuint index, GLenum pname, GLfloat * params); /* 685 */
+ void (GLAPIENTRYP GetVertexAttribivNV)(GLuint index, GLenum pname, GLint * params); /* 686 */
+ GLboolean (GLAPIENTRYP IsProgramNV)(GLuint program); /* 687 */
+ void (GLAPIENTRYP LoadProgramNV)(GLenum target, GLuint id, GLsizei len, const GLubyte * program); /* 688 */
+ void (GLAPIENTRYP ProgramParameters4dvNV)(GLenum target, GLuint index, GLuint num, const GLdouble * params); /* 689 */
+ void (GLAPIENTRYP ProgramParameters4fvNV)(GLenum target, GLuint index, GLuint num, const GLfloat * params); /* 690 */
+ void (GLAPIENTRYP RequestResidentProgramsNV)(GLsizei n, const GLuint * ids); /* 691 */
+ void (GLAPIENTRYP TrackMatrixNV)(GLenum target, GLuint address, GLenum matrix, GLenum transform); /* 692 */
+ void (GLAPIENTRYP VertexAttrib1dNV)(GLuint index, GLdouble x); /* 693 */
+ void (GLAPIENTRYP VertexAttrib1dvNV)(GLuint index, const GLdouble * v); /* 694 */
+ void (GLAPIENTRYP VertexAttrib1fNV)(GLuint index, GLfloat x); /* 695 */
+ void (GLAPIENTRYP VertexAttrib1fvNV)(GLuint index, const GLfloat * v); /* 696 */
+ void (GLAPIENTRYP VertexAttrib1sNV)(GLuint index, GLshort x); /* 697 */
+ void (GLAPIENTRYP VertexAttrib1svNV)(GLuint index, const GLshort * v); /* 698 */
+ void (GLAPIENTRYP VertexAttrib2dNV)(GLuint index, GLdouble x, GLdouble y); /* 699 */
+ void (GLAPIENTRYP VertexAttrib2dvNV)(GLuint index, const GLdouble * v); /* 700 */
+ void (GLAPIENTRYP VertexAttrib2fNV)(GLuint index, GLfloat x, GLfloat y); /* 701 */
+ void (GLAPIENTRYP VertexAttrib2fvNV)(GLuint index, const GLfloat * v); /* 702 */
+ void (GLAPIENTRYP VertexAttrib2sNV)(GLuint index, GLshort x, GLshort y); /* 703 */
+ void (GLAPIENTRYP VertexAttrib2svNV)(GLuint index, const GLshort * v); /* 704 */
+ void (GLAPIENTRYP VertexAttrib3dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z); /* 705 */
+ void (GLAPIENTRYP VertexAttrib3dvNV)(GLuint index, const GLdouble * v); /* 706 */
+ void (GLAPIENTRYP VertexAttrib3fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z); /* 707 */
+ void (GLAPIENTRYP VertexAttrib3fvNV)(GLuint index, const GLfloat * v); /* 708 */
+ void (GLAPIENTRYP VertexAttrib3sNV)(GLuint index, GLshort x, GLshort y, GLshort z); /* 709 */
+ void (GLAPIENTRYP VertexAttrib3svNV)(GLuint index, const GLshort * v); /* 710 */
+ void (GLAPIENTRYP VertexAttrib4dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 711 */
+ void (GLAPIENTRYP VertexAttrib4dvNV)(GLuint index, const GLdouble * v); /* 712 */
+ void (GLAPIENTRYP VertexAttrib4fNV)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 713 */
+ void (GLAPIENTRYP VertexAttrib4fvNV)(GLuint index, const GLfloat * v); /* 714 */
+ void (GLAPIENTRYP VertexAttrib4sNV)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); /* 715 */
+ void (GLAPIENTRYP VertexAttrib4svNV)(GLuint index, const GLshort * v); /* 716 */
+ void (GLAPIENTRYP VertexAttrib4ubNV)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); /* 717 */
+ void (GLAPIENTRYP VertexAttrib4ubvNV)(GLuint index, const GLubyte * v); /* 718 */
+ void (GLAPIENTRYP VertexAttribPointerNV)(GLuint index, GLint size, GLenum type, GLsizei stride, const GLvoid * pointer); /* 719 */
+ void (GLAPIENTRYP VertexAttribs1dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 720 */
+ void (GLAPIENTRYP VertexAttribs1fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 721 */
+ void (GLAPIENTRYP VertexAttribs1svNV)(GLuint index, GLsizei n, const GLshort * v); /* 722 */
+ void (GLAPIENTRYP VertexAttribs2dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 723 */
+ void (GLAPIENTRYP VertexAttribs2fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 724 */
+ void (GLAPIENTRYP VertexAttribs2svNV)(GLuint index, GLsizei n, const GLshort * v); /* 725 */
+ void (GLAPIENTRYP VertexAttribs3dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 726 */
+ void (GLAPIENTRYP VertexAttribs3fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 727 */
+ void (GLAPIENTRYP VertexAttribs3svNV)(GLuint index, GLsizei n, const GLshort * v); /* 728 */
+ void (GLAPIENTRYP VertexAttribs4dvNV)(GLuint index, GLsizei n, const GLdouble * v); /* 729 */
+ void (GLAPIENTRYP VertexAttribs4fvNV)(GLuint index, GLsizei n, const GLfloat * v); /* 730 */
+ void (GLAPIENTRYP VertexAttribs4svNV)(GLuint index, GLsizei n, const GLshort * v); /* 731 */
+ void (GLAPIENTRYP VertexAttribs4ubvNV)(GLuint index, GLsizei n, const GLubyte * v); /* 732 */
+ void (GLAPIENTRYP GetTexBumpParameterfvATI)(GLenum pname, GLfloat * param); /* 733 */
+ void (GLAPIENTRYP GetTexBumpParameterivATI)(GLenum pname, GLint * param); /* 734 */
+ void (GLAPIENTRYP TexBumpParameterfvATI)(GLenum pname, const GLfloat * param); /* 735 */
+ void (GLAPIENTRYP TexBumpParameterivATI)(GLenum pname, const GLint * param); /* 736 */
+ void (GLAPIENTRYP AlphaFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 737 */
+ void (GLAPIENTRYP AlphaFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 738 */
+ void (GLAPIENTRYP AlphaFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 739 */
+ void (GLAPIENTRYP BeginFragmentShaderATI)(void); /* 740 */
+ void (GLAPIENTRYP BindFragmentShaderATI)(GLuint id); /* 741 */
+ void (GLAPIENTRYP ColorFragmentOp1ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod); /* 742 */
+ void (GLAPIENTRYP ColorFragmentOp2ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod); /* 743 */
+ void (GLAPIENTRYP ColorFragmentOp3ATI)(GLenum op, GLuint dst, GLuint dstMask, GLuint dstMod, GLuint arg1, GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, GLuint arg3Mod); /* 744 */
+ void (GLAPIENTRYP DeleteFragmentShaderATI)(GLuint id); /* 745 */
+ void (GLAPIENTRYP EndFragmentShaderATI)(void); /* 746 */
+ GLuint (GLAPIENTRYP GenFragmentShadersATI)(GLuint range); /* 747 */
+ void (GLAPIENTRYP PassTexCoordATI)(GLuint dst, GLuint coord, GLenum swizzle); /* 748 */
+ void (GLAPIENTRYP SampleMapATI)(GLuint dst, GLuint interp, GLenum swizzle); /* 749 */
+ void (GLAPIENTRYP SetFragmentShaderConstantATI)(GLuint dst, const GLfloat * value); /* 750 */
+ void (GLAPIENTRYP PointParameteriNV)(GLenum pname, GLint param); /* 751 */
+ void (GLAPIENTRYP PointParameterivNV)(GLenum pname, const GLint * params); /* 752 */
+ void (GLAPIENTRYP ActiveStencilFaceEXT)(GLenum face); /* 753 */
+ void (GLAPIENTRYP BindVertexArrayAPPLE)(GLuint array); /* 754 */
+ void (GLAPIENTRYP DeleteVertexArraysAPPLE)(GLsizei n, const GLuint * arrays); /* 755 */
+ void (GLAPIENTRYP GenVertexArraysAPPLE)(GLsizei n, GLuint * arrays); /* 756 */
+ GLboolean (GLAPIENTRYP IsVertexArrayAPPLE)(GLuint array); /* 757 */
+ void (GLAPIENTRYP GetProgramNamedParameterdvNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble * params); /* 758 */
+ void (GLAPIENTRYP GetProgramNamedParameterfvNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat * params); /* 759 */
+ void (GLAPIENTRYP ProgramNamedParameter4dNV)(GLuint id, GLsizei len, const GLubyte * name, GLdouble x, GLdouble y, GLdouble z, GLdouble w); /* 760 */
+ void (GLAPIENTRYP ProgramNamedParameter4dvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLdouble * v); /* 761 */
+ void (GLAPIENTRYP ProgramNamedParameter4fNV)(GLuint id, GLsizei len, const GLubyte * name, GLfloat x, GLfloat y, GLfloat z, GLfloat w); /* 762 */
+ void (GLAPIENTRYP ProgramNamedParameter4fvNV)(GLuint id, GLsizei len, const GLubyte * name, const GLfloat * v); /* 763 */
+ void (GLAPIENTRYP DepthBoundsEXT)(GLclampd zmin, GLclampd zmax); /* 764 */
+ void (GLAPIENTRYP BlendEquationSeparateEXT)(GLenum modeRGB, GLenum modeA); /* 765 */
+ void (GLAPIENTRYP BindFramebufferEXT)(GLenum target, GLuint framebuffer); /* 766 */
+ void (GLAPIENTRYP BindRenderbufferEXT)(GLenum target, GLuint renderbuffer); /* 767 */
+ GLenum (GLAPIENTRYP CheckFramebufferStatusEXT)(GLenum target); /* 768 */
+ void (GLAPIENTRYP DeleteFramebuffersEXT)(GLsizei n, const GLuint * framebuffers); /* 769 */
+ void (GLAPIENTRYP DeleteRenderbuffersEXT)(GLsizei n, const GLuint * renderbuffers); /* 770 */
+ void (GLAPIENTRYP FramebufferRenderbufferEXT)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); /* 771 */
+ void (GLAPIENTRYP FramebufferTexture1DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 772 */
+ void (GLAPIENTRYP FramebufferTexture2DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); /* 773 */
+ void (GLAPIENTRYP FramebufferTexture3DEXT)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); /* 774 */
+ void (GLAPIENTRYP GenFramebuffersEXT)(GLsizei n, GLuint * framebuffers); /* 775 */
+ void (GLAPIENTRYP GenRenderbuffersEXT)(GLsizei n, GLuint * renderbuffers); /* 776 */
+ void (GLAPIENTRYP GenerateMipmapEXT)(GLenum target); /* 777 */
+ void (GLAPIENTRYP GetFramebufferAttachmentParameterivEXT)(GLenum target, GLenum attachment, GLenum pname, GLint * params); /* 778 */
+ void (GLAPIENTRYP GetRenderbufferParameterivEXT)(GLenum target, GLenum pname, GLint * params); /* 779 */
+ GLboolean (GLAPIENTRYP IsFramebufferEXT)(GLuint framebuffer); /* 780 */
+ GLboolean (GLAPIENTRYP IsRenderbufferEXT)(GLuint renderbuffer); /* 781 */
+ void (GLAPIENTRYP RenderbufferStorageEXT)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); /* 782 */
+ void (GLAPIENTRYP BlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); /* 783 */
+ void (GLAPIENTRYP BufferParameteriAPPLE)(GLenum target, GLenum pname, GLint param); /* 784 */
+ void (GLAPIENTRYP FlushMappedBufferRangeAPPLE)(GLenum target, GLintptr offset, GLsizeiptr size); /* 785 */
+ void (GLAPIENTRYP FramebufferTextureLayerEXT)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); /* 786 */
+ void (GLAPIENTRYP ProvokingVertexEXT)(GLenum mode); /* 787 */
+ void (GLAPIENTRYP GetTexParameterPointervAPPLE)(GLenum target, GLenum pname, GLvoid ** params); /* 788 */
+ void (GLAPIENTRYP TextureRangeAPPLE)(GLenum target, GLsizei length, GLvoid * pointer); /* 789 */
+ void (GLAPIENTRYP StencilFuncSeparateATI)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); /* 790 */
+ void (GLAPIENTRYP ProgramEnvParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 791 */
+ void (GLAPIENTRYP ProgramLocalParameters4fvEXT)(GLenum target, GLuint index, GLsizei count, const GLfloat * params); /* 792 */
+ void (GLAPIENTRYP GetQueryObjecti64vEXT)(GLuint id, GLenum pname, GLint64EXT * params); /* 793 */
+ void (GLAPIENTRYP GetQueryObjectui64vEXT)(GLuint id, GLenum pname, GLuint64EXT * params); /* 794 */
};
#endif /* !defined( _GLAPI_TABLE_H_ ) */
diff --git a/src/mesa/glapi/glapitemp.h b/src/mesa/glapi/glapitemp.h
index 86fda613f0..d9a3690f2a 100644
--- a/src/mesa/glapi/glapitemp.h
+++ b/src/mesa/glapi/glapitemp.h
@@ -4036,63 +4036,113 @@ KEYWORD1 void KEYWORD2 NAME(CopyBufferSubData)(GLenum readTarget, GLenum writeTa
DISPATCH(CopyBufferSubData, (readTarget, writeTarget, readOffset, writeOffset, size), (F, "glCopyBufferSubData(0x%x, 0x%x, %d, %d, %d);\n", readTarget, writeTarget, readOffset, writeOffset, size));
}
+KEYWORD1 GLenum KEYWORD2 NAME(ClientWaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ RETURN_DISPATCH(ClientWaitSync, (sync, flags, timeout), (F, "glClientWaitSync(%d, %d, %d);\n", sync, flags, timeout));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DeleteSync)(GLsync sync)
+{
+ DISPATCH(DeleteSync, (sync), (F, "glDeleteSync(%d);\n", sync));
+}
+
+KEYWORD1 GLsync KEYWORD2 NAME(FenceSync)(GLenum condition, GLbitfield flags)
+{
+ RETURN_DISPATCH(FenceSync, (condition, flags), (F, "glFenceSync(0x%x, %d);\n", condition, flags));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetInteger64v)(GLenum pname, GLint64 * params)
+{
+ DISPATCH(GetInteger64v, (pname, params), (F, "glGetInteger64v(0x%x, %p);\n", pname, (const void *) params));
+}
+
+KEYWORD1 void KEYWORD2 NAME(GetSynciv)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values)
+{
+ DISPATCH(GetSynciv, (sync, pname, bufSize, length, values), (F, "glGetSynciv(%d, 0x%x, %d, %p, %p);\n", sync, pname, bufSize, (const void *) length, (const void *) values));
+}
+
+KEYWORD1 GLboolean KEYWORD2 NAME(IsSync)(GLsync sync)
+{
+ RETURN_DISPATCH(IsSync, (sync), (F, "glIsSync(%d);\n", sync));
+}
+
+KEYWORD1 void KEYWORD2 NAME(WaitSync)(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ DISPATCH(WaitSync, (sync, flags, timeout), (F, "glWaitSync(%d, %d, %d);\n", sync, flags, timeout));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DrawElementsBaseVertex)(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex)
+{
+ DISPATCH(DrawElementsBaseVertex, (mode, count, type, indices, basevertex), (F, "glDrawElementsBaseVertex(0x%x, %d, 0x%x, %p, %d);\n", mode, count, type, (const void *) indices, basevertex));
+}
+
+KEYWORD1 void KEYWORD2 NAME(DrawRangeElementsBaseVertex)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid * indices, GLint basevertex)
+{
+ DISPATCH(DrawRangeElementsBaseVertex, (mode, start, end, count, type, indices, basevertex), (F, "glDrawRangeElementsBaseVertex(0x%x, %d, %d, %d, 0x%x, %p, %d);\n", mode, start, end, count, type, (const void *) indices, basevertex));
+}
+
+KEYWORD1 void KEYWORD2 NAME(MultiDrawElementsBaseVertex)(GLenum mode, const GLsizei * count, GLenum type, const GLvoid ** indices, GLsizei primcount, const GLint * basevertex)
+{
+ DISPATCH(MultiDrawElementsBaseVertex, (mode, count, type, indices, primcount, basevertex), (F, "glMultiDrawElementsBaseVertex(0x%x, %p, 0x%x, %p, %d, %p);\n", mode, (const void *) count, type, (const void *) indices, primcount, (const void *) basevertex));
+}
+
KEYWORD1 void KEYWORD2 NAME(PolygonOffsetEXT)(GLfloat factor, GLfloat bias)
{
DISPATCH(PolygonOffsetEXT, (factor, bias), (F, "glPolygonOffsetEXT(%f, %f);\n", factor, bias));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_568)(GLenum pname, GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_578)(GLenum pname, GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_568)(GLenum pname, GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_578)(GLenum pname, GLfloat * params)
{
DISPATCH(GetPixelTexGenParameterfvSGIS, (pname, params), (F, "glGetPixelTexGenParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_569)(GLenum pname, GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_579)(GLenum pname, GLint * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_569)(GLenum pname, GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_579)(GLenum pname, GLint * params)
{
DISPATCH(GetPixelTexGenParameterivSGIS, (pname, params), (F, "glGetPixelTexGenParameterivSGIS(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_570)(GLenum pname, GLfloat param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_580)(GLenum pname, GLfloat param);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_570)(GLenum pname, GLfloat param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_580)(GLenum pname, GLfloat param)
{
DISPATCH(PixelTexGenParameterfSGIS, (pname, param), (F, "glPixelTexGenParameterfSGIS(0x%x, %f);\n", pname, param));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_571)(GLenum pname, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_581)(GLenum pname, const GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_571)(GLenum pname, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_581)(GLenum pname, const GLfloat * params)
{
DISPATCH(PixelTexGenParameterfvSGIS, (pname, params), (F, "glPixelTexGenParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_572)(GLenum pname, GLint param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLint param);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_572)(GLenum pname, GLint param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLint param)
{
DISPATCH(PixelTexGenParameteriSGIS, (pname, param), (F, "glPixelTexGenParameteriSGIS(0x%x, %d);\n", pname, param));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_573)(GLenum pname, const GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLint * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_573)(GLenum pname, const GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLint * params)
{
DISPATCH(PixelTexGenParameterivSGIS, (pname, params), (F, "glPixelTexGenParameterivSGIS(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_574)(GLclampf value, GLboolean invert);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_584)(GLclampf value, GLboolean invert);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_574)(GLclampf value, GLboolean invert)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_584)(GLclampf value, GLboolean invert)
{
DISPATCH(SampleMaskSGIS, (value, invert), (F, "glSampleMaskSGIS(%f, %d);\n", value, invert));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_575)(GLenum pattern);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_585)(GLenum pattern);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_575)(GLenum pattern)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_585)(GLenum pattern)
{
DISPATCH(SamplePatternSGIS, (pattern), (F, "glSamplePatternSGIS(0x%x);\n", pattern));
}
@@ -4142,9 +4192,9 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterfEXT)(GLenum pname, GLfloat param)
DISPATCH(PointParameterfEXT, (pname, param), (F, "glPointParameterfEXT(0x%x, %f);\n", pname, param));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLfloat param);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_592)(GLenum pname, GLfloat param);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_582)(GLenum pname, GLfloat param)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_592)(GLenum pname, GLfloat param)
{
DISPATCH(PointParameterfEXT, (pname, param), (F, "glPointParameterfSGIS(0x%x, %f);\n", pname, param));
}
@@ -4164,9 +4214,9 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterfvEXT)(GLenum pname, const GLfloat * p
DISPATCH(PointParameterfvEXT, (pname, params), (F, "glPointParameterfvEXT(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_593)(GLenum pname, const GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_583)(GLenum pname, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_593)(GLenum pname, const GLfloat * params)
{
DISPATCH(PointParameterfvEXT, (pname, params), (F, "glPointParameterfvSGIS(0x%x, %p);\n", pname, (const void *) params));
}
@@ -4181,16 +4231,16 @@ KEYWORD1 void KEYWORD2 NAME(UnlockArraysEXT)(void)
DISPATCH(UnlockArraysEXT, (), (F, "glUnlockArraysEXT();\n"));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_586)(GLenum pname, GLdouble * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_596)(GLenum pname, GLdouble * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_586)(GLenum pname, GLdouble * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_596)(GLenum pname, GLdouble * params)
{
DISPATCH(CullParameterdvEXT, (pname, params), (F, "glCullParameterdvEXT(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_587)(GLenum pname, GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_597)(GLenum pname, GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_587)(GLenum pname, GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_597)(GLenum pname, GLfloat * params)
{
DISPATCH(CullParameterfvEXT, (pname, params), (F, "glCullParameterfvEXT(0x%x, %p);\n", pname, (const void *) params));
}
@@ -4435,9 +4485,9 @@ KEYWORD1 void KEYWORD2 NAME(FogCoordfvEXT)(const GLfloat * coord)
DISPATCH(FogCoordfvEXT, (coord), (F, "glFogCoordfvEXT(%p);\n", (const void *) coord));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_612)(GLenum mode);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_622)(GLenum mode);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_612)(GLenum mode)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_622)(GLenum mode)
{
DISPATCH(PixelTexGenSGIX, (mode), (F, "glPixelTexGenSGIX(0x%x);\n", mode));
}
@@ -4452,9 +4502,9 @@ KEYWORD1 void KEYWORD2 NAME(BlendFuncSeparateEXT)(GLenum sfactorRGB, GLenum dfac
DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, "glBlendFuncSeparateEXT(0x%x, 0x%x, 0x%x, 0x%x);\n", sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_613)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_623)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_613)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_623)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha)
{
DISPATCH(BlendFuncSeparateEXT, (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), (F, "glBlendFuncSeparateINGR(0x%x, 0x%x, 0x%x, 0x%x);\n", sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha));
}
@@ -4819,65 +4869,65 @@ KEYWORD1 void KEYWORD2 NAME(WindowPos4svMESA)(const GLshort * v)
DISPATCH(WindowPos4svMESA, (v), (F, "glWindowPos4svMESA(%p);\n", (const void *) v));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_654)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_664)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_654)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_664)(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride)
{
DISPATCH(MultiModeDrawArraysIBM, (mode, first, count, primcount, modestride), (F, "glMultiModeDrawArraysIBM(%p, %p, %p, %d, %d);\n", (const void *) mode, (const void *) first, (const void *) count, primcount, modestride));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_655)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_665)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_655)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_665)(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride)
{
DISPATCH(MultiModeDrawElementsIBM, (mode, count, type, indices, primcount, modestride), (F, "glMultiModeDrawElementsIBM(%p, %p, 0x%x, %p, %d, %d);\n", (const void *) mode, (const void *) count, type, (const void *) indices, primcount, modestride));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_656)(GLsizei n, const GLuint * fences);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_666)(GLsizei n, const GLuint * fences);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_656)(GLsizei n, const GLuint * fences)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_666)(GLsizei n, const GLuint * fences)
{
DISPATCH(DeleteFencesNV, (n, fences), (F, "glDeleteFencesNV(%d, %p);\n", n, (const void *) fences));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_657)(GLuint fence);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_667)(GLuint fence);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_657)(GLuint fence)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_667)(GLuint fence)
{
DISPATCH(FinishFenceNV, (fence), (F, "glFinishFenceNV(%d);\n", fence));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_658)(GLsizei n, GLuint * fences);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_668)(GLsizei n, GLuint * fences);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_658)(GLsizei n, GLuint * fences)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_668)(GLsizei n, GLuint * fences)
{
DISPATCH(GenFencesNV, (n, fences), (F, "glGenFencesNV(%d, %p);\n", n, (const void *) fences));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_659)(GLuint fence, GLenum pname, GLint * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_669)(GLuint fence, GLenum pname, GLint * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_659)(GLuint fence, GLenum pname, GLint * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_669)(GLuint fence, GLenum pname, GLint * params)
{
DISPATCH(GetFenceivNV, (fence, pname, params), (F, "glGetFenceivNV(%d, 0x%x, %p);\n", fence, pname, (const void *) params));
}
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_660)(GLuint fence);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_670)(GLuint fence);
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_660)(GLuint fence)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_670)(GLuint fence)
{
RETURN_DISPATCH(IsFenceNV, (fence), (F, "glIsFenceNV(%d);\n", fence));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_661)(GLuint fence, GLenum condition);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_671)(GLuint fence, GLenum condition);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_661)(GLuint fence, GLenum condition)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_671)(GLuint fence, GLenum condition)
{
DISPATCH(SetFenceNV, (fence, condition), (F, "glSetFenceNV(%d, 0x%x);\n", fence, condition));
}
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_662)(GLuint fence);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_672)(GLuint fence);
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_662)(GLuint fence)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_672)(GLuint fence)
{
RETURN_DISPATCH(TestFenceNV, (fence), (F, "glTestFenceNV(%d);\n", fence));
}
@@ -5322,16 +5372,16 @@ KEYWORD1 void KEYWORD2 NAME(PointParameterivNV)(GLenum pname, const GLint * para
DISPATCH(PointParameterivNV, (pname, params), (F, "glPointParameterivNV(0x%x, %p);\n", pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_743)(GLenum face);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_753)(GLenum face);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_743)(GLenum face)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_753)(GLenum face)
{
DISPATCH(ActiveStencilFaceEXT, (face), (F, "glActiveStencilFaceEXT(0x%x);\n", face));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_744)(GLuint array);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_754)(GLuint array);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_744)(GLuint array)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_754)(GLuint array)
{
DISPATCH(BindVertexArrayAPPLE, (array), (F, "glBindVertexArrayAPPLE(%d);\n", array));
}
@@ -5341,16 +5391,16 @@ KEYWORD1 void KEYWORD2 NAME(DeleteVertexArrays)(GLsizei n, const GLuint * arrays
DISPATCH(DeleteVertexArraysAPPLE, (n, arrays), (F, "glDeleteVertexArrays(%d, %p);\n", n, (const void *) arrays));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_745)(GLsizei n, const GLuint * arrays);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLsizei n, const GLuint * arrays);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_745)(GLsizei n, const GLuint * arrays)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLsizei n, const GLuint * arrays)
{
DISPATCH(DeleteVertexArraysAPPLE, (n, arrays), (F, "glDeleteVertexArraysAPPLE(%d, %p);\n", n, (const void *) arrays));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_746)(GLsizei n, GLuint * arrays);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_756)(GLsizei n, GLuint * arrays);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_746)(GLsizei n, GLuint * arrays)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_756)(GLsizei n, GLuint * arrays)
{
DISPATCH(GenVertexArraysAPPLE, (n, arrays), (F, "glGenVertexArraysAPPLE(%d, %p);\n", n, (const void *) arrays));
}
@@ -5360,9 +5410,9 @@ KEYWORD1 GLboolean KEYWORD2 NAME(IsVertexArray)(GLuint array)
RETURN_DISPATCH(IsVertexArrayAPPLE, (array), (F, "glIsVertexArray(%d);\n", array));
}
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_747)(GLuint array);
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_757)(GLuint array);
-KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_747)(GLuint array)
+KEYWORD1_ALT GLboolean KEYWORD2 NAME(_dispatch_stub_757)(GLuint array)
{
RETURN_DISPATCH(IsVertexArrayAPPLE, (array), (F, "glIsVertexArrayAPPLE(%d);\n", array));
}
@@ -5397,9 +5447,9 @@ KEYWORD1 void KEYWORD2 NAME(ProgramNamedParameter4fvNV)(GLuint id, GLsizei len,
DISPATCH(ProgramNamedParameter4fvNV, (id, len, name, v), (F, "glProgramNamedParameter4fvNV(%d, %d, %p, %p);\n", id, len, (const void *) name, (const void *) v));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_754)(GLclampd zmin, GLclampd zmax);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_764)(GLclampd zmin, GLclampd zmax);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_754)(GLclampd zmin, GLclampd zmax)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_764)(GLclampd zmin, GLclampd zmax)
{
DISPATCH(DepthBoundsEXT, (zmin, zmax), (F, "glDepthBoundsEXT(%f, %f);\n", zmin, zmax));
}
@@ -5409,9 +5459,9 @@ KEYWORD1 void KEYWORD2 NAME(BlendEquationSeparate)(GLenum modeRGB, GLenum modeA)
DISPATCH(BlendEquationSeparateEXT, (modeRGB, modeA), (F, "glBlendEquationSeparate(0x%x, 0x%x);\n", modeRGB, modeA));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLenum modeRGB, GLenum modeA);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_765)(GLenum modeRGB, GLenum modeA);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_755)(GLenum modeRGB, GLenum modeA)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_765)(GLenum modeRGB, GLenum modeA)
{
DISPATCH(BlendEquationSeparateEXT, (modeRGB, modeA), (F, "glBlendEquationSeparateEXT(0x%x, 0x%x);\n", modeRGB, modeA));
}
@@ -5591,13 +5641,27 @@ KEYWORD1 void KEYWORD2 NAME(BlitFramebuffer)(GLint srcX0, GLint srcY0, GLint src
DISPATCH(BlitFramebufferEXT, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter), (F, "glBlitFramebuffer(%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x);\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_773)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_783)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_773)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_783)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
DISPATCH(BlitFramebufferEXT, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter), (F, "glBlitFramebufferEXT(%d, %d, %d, %d, %d, %d, %d, %d, %d, 0x%x);\n", srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter));
}
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_784)(GLenum target, GLenum pname, GLint param);
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_784)(GLenum target, GLenum pname, GLint param)
+{
+ DISPATCH(BufferParameteriAPPLE, (target, pname, param), (F, "glBufferParameteriAPPLE(0x%x, 0x%x, %d);\n", target, pname, param));
+}
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_785)(GLenum target, GLintptr offset, GLsizeiptr size);
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_785)(GLenum target, GLintptr offset, GLsizeiptr size)
+{
+ DISPATCH(FlushMappedBufferRangeAPPLE, (target, offset, size), (F, "glFlushMappedBufferRangeAPPLE(0x%x, %d, %d);\n", target, offset, size));
+}
+
KEYWORD1 void KEYWORD2 NAME(FramebufferTextureLayer)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
{
DISPATCH(FramebufferTextureLayerEXT, (target, attachment, texture, level, layer), (F, "glFramebufferTextureLayer(0x%x, 0x%x, %d, %d, %d);\n", target, attachment, texture, level, layer));
@@ -5613,37 +5677,56 @@ KEYWORD1 void KEYWORD2 NAME(ProvokingVertexEXT)(GLenum mode)
DISPATCH(ProvokingVertexEXT, (mode), (F, "glProvokingVertexEXT(0x%x);\n", mode));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_776)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+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_776)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_788)(GLenum target, GLenum pname, GLvoid ** params)
+{
+ DISPATCH(GetTexParameterPointervAPPLE, (target, pname, params), (F, "glGetTexParameterPointervAPPLE(0x%x, 0x%x, %p);\n", target, pname, (const void *) params));
+}
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_789)(GLenum target, GLsizei length, GLvoid * pointer);
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_789)(GLenum target, GLsizei length, GLvoid * pointer)
+{
+ DISPATCH(TextureRangeAPPLE, (target, length, pointer), (F, "glTextureRangeAPPLE(0x%x, %d, %p);\n", target, length, (const void *) pointer));
+}
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_790)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_790)(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask)
{
DISPATCH(StencilFuncSeparateATI, (frontfunc, backfunc, ref, mask), (F, "glStencilFuncSeparateATI(0x%x, 0x%x, %d, %d);\n", frontfunc, backfunc, ref, mask));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_777)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_791)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_777)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_791)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
{
DISPATCH(ProgramEnvParameters4fvEXT, (target, index, count, params), (F, "glProgramEnvParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_778)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_792)(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_778)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_792)(GLenum target, GLuint index, GLsizei count, const GLfloat * params)
{
DISPATCH(ProgramLocalParameters4fvEXT, (target, index, count, params), (F, "glProgramLocalParameters4fvEXT(0x%x, %d, %d, %p);\n", target, index, count, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_779)(GLuint id, GLenum pname, GLint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_793)(GLuint id, GLenum pname, GLint64EXT * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_779)(GLuint id, GLenum pname, GLint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_793)(GLuint id, GLenum pname, GLint64EXT * params)
{
DISPATCH(GetQueryObjecti64vEXT, (id, pname, params), (F, "glGetQueryObjecti64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
}
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_780)(GLuint id, GLenum pname, GLuint64EXT * params);
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_794)(GLuint id, GLenum pname, GLuint64EXT * params);
-KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_780)(GLuint id, GLenum pname, GLuint64EXT * params)
+KEYWORD1_ALT void KEYWORD2 NAME(_dispatch_stub_794)(GLuint id, GLenum pname, GLuint64EXT * params)
{
DISPATCH(GetQueryObjectui64vEXT, (id, pname, params), (F, "glGetQueryObjectui64vEXT(%d, 0x%x, %p);\n", id, pname, (const void *) params));
}
@@ -6229,15 +6312,25 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(BindVertexArray),
TABLE_ENTRY(GenVertexArrays),
TABLE_ENTRY(CopyBufferSubData),
+ TABLE_ENTRY(ClientWaitSync),
+ TABLE_ENTRY(DeleteSync),
+ TABLE_ENTRY(FenceSync),
+ TABLE_ENTRY(GetInteger64v),
+ TABLE_ENTRY(GetSynciv),
+ TABLE_ENTRY(IsSync),
+ TABLE_ENTRY(WaitSync),
+ TABLE_ENTRY(DrawElementsBaseVertex),
+ TABLE_ENTRY(DrawRangeElementsBaseVertex),
+ TABLE_ENTRY(MultiDrawElementsBaseVertex),
TABLE_ENTRY(PolygonOffsetEXT),
- TABLE_ENTRY(_dispatch_stub_568),
- TABLE_ENTRY(_dispatch_stub_569),
- TABLE_ENTRY(_dispatch_stub_570),
- TABLE_ENTRY(_dispatch_stub_571),
- TABLE_ENTRY(_dispatch_stub_572),
- TABLE_ENTRY(_dispatch_stub_573),
- TABLE_ENTRY(_dispatch_stub_574),
- TABLE_ENTRY(_dispatch_stub_575),
+ TABLE_ENTRY(_dispatch_stub_578),
+ TABLE_ENTRY(_dispatch_stub_579),
+ TABLE_ENTRY(_dispatch_stub_580),
+ TABLE_ENTRY(_dispatch_stub_581),
+ TABLE_ENTRY(_dispatch_stub_582),
+ TABLE_ENTRY(_dispatch_stub_583),
+ TABLE_ENTRY(_dispatch_stub_584),
+ TABLE_ENTRY(_dispatch_stub_585),
TABLE_ENTRY(ColorPointerEXT),
TABLE_ENTRY(EdgeFlagPointerEXT),
TABLE_ENTRY(IndexPointerEXT),
@@ -6248,8 +6341,8 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(PointParameterfvEXT),
TABLE_ENTRY(LockArraysEXT),
TABLE_ENTRY(UnlockArraysEXT),
- TABLE_ENTRY(_dispatch_stub_586),
- TABLE_ENTRY(_dispatch_stub_587),
+ TABLE_ENTRY(_dispatch_stub_596),
+ TABLE_ENTRY(_dispatch_stub_597),
TABLE_ENTRY(SecondaryColor3bEXT),
TABLE_ENTRY(SecondaryColor3bvEXT),
TABLE_ENTRY(SecondaryColor3dEXT),
@@ -6274,7 +6367,7 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(FogCoorddvEXT),
TABLE_ENTRY(FogCoordfEXT),
TABLE_ENTRY(FogCoordfvEXT),
- TABLE_ENTRY(_dispatch_stub_612),
+ TABLE_ENTRY(_dispatch_stub_622),
TABLE_ENTRY(BlendFuncSeparateEXT),
TABLE_ENTRY(FlushVertexArrayRangeNV),
TABLE_ENTRY(VertexArrayRangeNV),
@@ -6316,15 +6409,15 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(WindowPos4ivMESA),
TABLE_ENTRY(WindowPos4sMESA),
TABLE_ENTRY(WindowPos4svMESA),
- TABLE_ENTRY(_dispatch_stub_654),
- TABLE_ENTRY(_dispatch_stub_655),
- TABLE_ENTRY(_dispatch_stub_656),
- TABLE_ENTRY(_dispatch_stub_657),
- TABLE_ENTRY(_dispatch_stub_658),
- TABLE_ENTRY(_dispatch_stub_659),
- TABLE_ENTRY(_dispatch_stub_660),
- TABLE_ENTRY(_dispatch_stub_661),
- TABLE_ENTRY(_dispatch_stub_662),
+ TABLE_ENTRY(_dispatch_stub_664),
+ TABLE_ENTRY(_dispatch_stub_665),
+ TABLE_ENTRY(_dispatch_stub_666),
+ TABLE_ENTRY(_dispatch_stub_667),
+ TABLE_ENTRY(_dispatch_stub_668),
+ TABLE_ENTRY(_dispatch_stub_669),
+ TABLE_ENTRY(_dispatch_stub_670),
+ TABLE_ENTRY(_dispatch_stub_671),
+ TABLE_ENTRY(_dispatch_stub_672),
TABLE_ENTRY(AreProgramsResidentNV),
TABLE_ENTRY(BindProgramNV),
TABLE_ENTRY(DeleteProgramsNV),
@@ -6405,19 +6498,19 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(SetFragmentShaderConstantATI),
TABLE_ENTRY(PointParameteriNV),
TABLE_ENTRY(PointParameterivNV),
- TABLE_ENTRY(_dispatch_stub_743),
- TABLE_ENTRY(_dispatch_stub_744),
- TABLE_ENTRY(_dispatch_stub_745),
- TABLE_ENTRY(_dispatch_stub_746),
- TABLE_ENTRY(_dispatch_stub_747),
+ TABLE_ENTRY(_dispatch_stub_753),
+ TABLE_ENTRY(_dispatch_stub_754),
+ TABLE_ENTRY(_dispatch_stub_755),
+ TABLE_ENTRY(_dispatch_stub_756),
+ TABLE_ENTRY(_dispatch_stub_757),
TABLE_ENTRY(GetProgramNamedParameterdvNV),
TABLE_ENTRY(GetProgramNamedParameterfvNV),
TABLE_ENTRY(ProgramNamedParameter4dNV),
TABLE_ENTRY(ProgramNamedParameter4dvNV),
TABLE_ENTRY(ProgramNamedParameter4fNV),
TABLE_ENTRY(ProgramNamedParameter4fvNV),
- TABLE_ENTRY(_dispatch_stub_754),
- TABLE_ENTRY(_dispatch_stub_755),
+ TABLE_ENTRY(_dispatch_stub_764),
+ TABLE_ENTRY(_dispatch_stub_765),
TABLE_ENTRY(BindFramebufferEXT),
TABLE_ENTRY(BindRenderbufferEXT),
TABLE_ENTRY(CheckFramebufferStatusEXT),
@@ -6435,14 +6528,18 @@ static _glapi_proc DISPATCH_TABLE_NAME[] = {
TABLE_ENTRY(IsFramebufferEXT),
TABLE_ENTRY(IsRenderbufferEXT),
TABLE_ENTRY(RenderbufferStorageEXT),
- TABLE_ENTRY(_dispatch_stub_773),
+ TABLE_ENTRY(_dispatch_stub_783),
+ TABLE_ENTRY(_dispatch_stub_784),
+ TABLE_ENTRY(_dispatch_stub_785),
TABLE_ENTRY(FramebufferTextureLayerEXT),
TABLE_ENTRY(ProvokingVertexEXT),
- TABLE_ENTRY(_dispatch_stub_776),
- TABLE_ENTRY(_dispatch_stub_777),
- TABLE_ENTRY(_dispatch_stub_778),
- TABLE_ENTRY(_dispatch_stub_779),
- TABLE_ENTRY(_dispatch_stub_780),
+ TABLE_ENTRY(_dispatch_stub_788),
+ TABLE_ENTRY(_dispatch_stub_789),
+ TABLE_ENTRY(_dispatch_stub_790),
+ TABLE_ENTRY(_dispatch_stub_791),
+ TABLE_ENTRY(_dispatch_stub_792),
+ TABLE_ENTRY(_dispatch_stub_793),
+ TABLE_ENTRY(_dispatch_stub_794),
/* A whole bunch of no-op functions. These might be called
* when someone tries to call a dynamically-registered
* extension function without a current rendering context.
@@ -6831,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 bd3ebc8872..c29f8b57be 100644
--- a/src/mesa/glapi/glprocs.h
+++ b/src/mesa/glapi/glprocs.h
@@ -619,6 +619,16 @@ static const char gl_string_table[] =
"glBindVertexArray\0"
"glGenVertexArrays\0"
"glCopyBufferSubData\0"
+ "glClientWaitSync\0"
+ "glDeleteSync\0"
+ "glFenceSync\0"
+ "glGetInteger64v\0"
+ "glGetSynciv\0"
+ "glIsSync\0"
+ "glWaitSync\0"
+ "glDrawElementsBaseVertex\0"
+ "glDrawRangeElementsBaseVertex\0"
+ "glMultiDrawElementsBaseVertex\0"
"glPolygonOffsetEXT\0"
"glGetPixelTexGenParameterfvSGIS\0"
"glGetPixelTexGenParameterivSGIS\0"
@@ -826,8 +836,12 @@ static const char gl_string_table[] =
"glIsRenderbufferEXT\0"
"glRenderbufferStorageEXT\0"
"glBlitFramebufferEXT\0"
+ "glBufferParameteriAPPLE\0"
+ "glFlushMappedBufferRangeAPPLE\0"
"glFramebufferTextureLayerEXT\0"
"glProvokingVertexEXT\0"
+ "glGetTexParameterPointervAPPLE\0"
+ "glTextureRangeAPPLE\0"
"glStencilFuncSeparateATI\0"
"glProgramEnvParameters4fvEXT\0"
"glProgramLocalParameters4fvEXT\0"
@@ -1133,6 +1147,7 @@ static const char gl_string_table[] =
"glRenderbufferStorage\0"
"glBlitFramebuffer\0"
"glFramebufferTextureLayer\0"
+ "glProvokingVertex\0"
;
@@ -1150,39 +1165,43 @@ static const char gl_string_table[] =
#define gl_dispatch_stub_364 mgl_dispatch_stub_364
#define gl_dispatch_stub_365 mgl_dispatch_stub_365
#define gl_dispatch_stub_366 mgl_dispatch_stub_366
-#define gl_dispatch_stub_568 mgl_dispatch_stub_568
-#define gl_dispatch_stub_569 mgl_dispatch_stub_569
-#define gl_dispatch_stub_570 mgl_dispatch_stub_570
-#define gl_dispatch_stub_571 mgl_dispatch_stub_571
-#define gl_dispatch_stub_572 mgl_dispatch_stub_572
-#define gl_dispatch_stub_573 mgl_dispatch_stub_573
-#define gl_dispatch_stub_574 mgl_dispatch_stub_574
-#define gl_dispatch_stub_575 mgl_dispatch_stub_575
-#define gl_dispatch_stub_586 mgl_dispatch_stub_586
-#define gl_dispatch_stub_587 mgl_dispatch_stub_587
-#define gl_dispatch_stub_612 mgl_dispatch_stub_612
-#define gl_dispatch_stub_654 mgl_dispatch_stub_654
-#define gl_dispatch_stub_655 mgl_dispatch_stub_655
-#define gl_dispatch_stub_656 mgl_dispatch_stub_656
-#define gl_dispatch_stub_657 mgl_dispatch_stub_657
-#define gl_dispatch_stub_658 mgl_dispatch_stub_658
-#define gl_dispatch_stub_659 mgl_dispatch_stub_659
-#define gl_dispatch_stub_660 mgl_dispatch_stub_660
-#define gl_dispatch_stub_661 mgl_dispatch_stub_661
-#define gl_dispatch_stub_662 mgl_dispatch_stub_662
-#define gl_dispatch_stub_743 mgl_dispatch_stub_743
-#define gl_dispatch_stub_744 mgl_dispatch_stub_744
-#define gl_dispatch_stub_745 mgl_dispatch_stub_745
-#define gl_dispatch_stub_746 mgl_dispatch_stub_746
-#define gl_dispatch_stub_747 mgl_dispatch_stub_747
+#define gl_dispatch_stub_578 mgl_dispatch_stub_578
+#define gl_dispatch_stub_579 mgl_dispatch_stub_579
+#define gl_dispatch_stub_580 mgl_dispatch_stub_580
+#define gl_dispatch_stub_581 mgl_dispatch_stub_581
+#define gl_dispatch_stub_582 mgl_dispatch_stub_582
+#define gl_dispatch_stub_583 mgl_dispatch_stub_583
+#define gl_dispatch_stub_584 mgl_dispatch_stub_584
+#define gl_dispatch_stub_585 mgl_dispatch_stub_585
+#define gl_dispatch_stub_596 mgl_dispatch_stub_596
+#define gl_dispatch_stub_597 mgl_dispatch_stub_597
+#define gl_dispatch_stub_622 mgl_dispatch_stub_622
+#define gl_dispatch_stub_664 mgl_dispatch_stub_664
+#define gl_dispatch_stub_665 mgl_dispatch_stub_665
+#define gl_dispatch_stub_666 mgl_dispatch_stub_666
+#define gl_dispatch_stub_667 mgl_dispatch_stub_667
+#define gl_dispatch_stub_668 mgl_dispatch_stub_668
+#define gl_dispatch_stub_669 mgl_dispatch_stub_669
+#define gl_dispatch_stub_670 mgl_dispatch_stub_670
+#define gl_dispatch_stub_671 mgl_dispatch_stub_671
+#define gl_dispatch_stub_672 mgl_dispatch_stub_672
+#define gl_dispatch_stub_753 mgl_dispatch_stub_753
#define gl_dispatch_stub_754 mgl_dispatch_stub_754
#define gl_dispatch_stub_755 mgl_dispatch_stub_755
-#define gl_dispatch_stub_773 mgl_dispatch_stub_773
-#define gl_dispatch_stub_776 mgl_dispatch_stub_776
-#define gl_dispatch_stub_777 mgl_dispatch_stub_777
-#define gl_dispatch_stub_778 mgl_dispatch_stub_778
-#define gl_dispatch_stub_779 mgl_dispatch_stub_779
-#define gl_dispatch_stub_780 mgl_dispatch_stub_780
+#define gl_dispatch_stub_756 mgl_dispatch_stub_756
+#define gl_dispatch_stub_757 mgl_dispatch_stub_757
+#define gl_dispatch_stub_764 mgl_dispatch_stub_764
+#define gl_dispatch_stub_765 mgl_dispatch_stub_765
+#define gl_dispatch_stub_783 mgl_dispatch_stub_783
+#define gl_dispatch_stub_784 mgl_dispatch_stub_784
+#define gl_dispatch_stub_785 mgl_dispatch_stub_785
+#define gl_dispatch_stub_788 mgl_dispatch_stub_788
+#define gl_dispatch_stub_789 mgl_dispatch_stub_789
+#define gl_dispatch_stub_790 mgl_dispatch_stub_790
+#define gl_dispatch_stub_791 mgl_dispatch_stub_791
+#define gl_dispatch_stub_792 mgl_dispatch_stub_792
+#define gl_dispatch_stub_793 mgl_dispatch_stub_793
+#define gl_dispatch_stub_794 mgl_dispatch_stub_794
#endif /* USE_MGL_NAMESPACE */
@@ -1200,39 +1219,43 @@ void GLAPIENTRY gl_dispatch_stub_363(GLenum target, GLenum pname, GLint * params
void GLAPIENTRY gl_dispatch_stub_364(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvoid * values);
void GLAPIENTRY gl_dispatch_stub_365(GLenum target, GLenum pname, GLfloat * params);
void GLAPIENTRY gl_dispatch_stub_366(GLenum target, GLenum pname, GLint * params);
-void GLAPIENTRY gl_dispatch_stub_568(GLenum pname, GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_569(GLenum pname, GLint * params);
-void GLAPIENTRY gl_dispatch_stub_570(GLenum pname, GLfloat param);
-void GLAPIENTRY gl_dispatch_stub_571(GLenum pname, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_572(GLenum pname, GLint param);
-void GLAPIENTRY gl_dispatch_stub_573(GLenum pname, const GLint * params);
-void GLAPIENTRY gl_dispatch_stub_574(GLclampf value, GLboolean invert);
-void GLAPIENTRY gl_dispatch_stub_575(GLenum pattern);
-void GLAPIENTRY gl_dispatch_stub_586(GLenum pname, GLdouble * params);
-void GLAPIENTRY gl_dispatch_stub_587(GLenum pname, GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_612(GLenum mode);
-void GLAPIENTRY gl_dispatch_stub_654(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
-void GLAPIENTRY gl_dispatch_stub_655(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
-void GLAPIENTRY gl_dispatch_stub_656(GLsizei n, const GLuint * fences);
-void GLAPIENTRY gl_dispatch_stub_657(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_658(GLsizei n, GLuint * fences);
-void GLAPIENTRY gl_dispatch_stub_659(GLuint fence, GLenum pname, GLint * params);
-GLboolean GLAPIENTRY gl_dispatch_stub_660(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_661(GLuint fence, GLenum condition);
-GLboolean GLAPIENTRY gl_dispatch_stub_662(GLuint fence);
-void GLAPIENTRY gl_dispatch_stub_743(GLenum face);
-void GLAPIENTRY gl_dispatch_stub_744(GLuint array);
-void GLAPIENTRY gl_dispatch_stub_745(GLsizei n, const GLuint * arrays);
-void GLAPIENTRY gl_dispatch_stub_746(GLsizei n, GLuint * arrays);
-GLboolean GLAPIENTRY gl_dispatch_stub_747(GLuint array);
-void GLAPIENTRY gl_dispatch_stub_754(GLclampd zmin, GLclampd zmax);
-void GLAPIENTRY gl_dispatch_stub_755(GLenum modeRGB, GLenum modeA);
-void GLAPIENTRY gl_dispatch_stub_773(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
-void GLAPIENTRY gl_dispatch_stub_776(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
-void GLAPIENTRY gl_dispatch_stub_777(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_778(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
-void GLAPIENTRY gl_dispatch_stub_779(GLuint id, GLenum pname, GLint64EXT * params);
-void GLAPIENTRY gl_dispatch_stub_780(GLuint id, GLenum pname, GLuint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_578(GLenum pname, GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_579(GLenum pname, GLint * params);
+void GLAPIENTRY gl_dispatch_stub_580(GLenum pname, GLfloat param);
+void GLAPIENTRY gl_dispatch_stub_581(GLenum pname, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_582(GLenum pname, GLint param);
+void GLAPIENTRY gl_dispatch_stub_583(GLenum pname, const GLint * params);
+void GLAPIENTRY gl_dispatch_stub_584(GLclampf value, GLboolean invert);
+void GLAPIENTRY gl_dispatch_stub_585(GLenum pattern);
+void GLAPIENTRY gl_dispatch_stub_596(GLenum pname, GLdouble * params);
+void GLAPIENTRY gl_dispatch_stub_597(GLenum pname, GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_622(GLenum mode);
+void GLAPIENTRY gl_dispatch_stub_664(const GLenum * mode, const GLint * first, const GLsizei * count, GLsizei primcount, GLint modestride);
+void GLAPIENTRY gl_dispatch_stub_665(const GLenum * mode, const GLsizei * count, GLenum type, const GLvoid * const * indices, GLsizei primcount, GLint modestride);
+void GLAPIENTRY gl_dispatch_stub_666(GLsizei n, const GLuint * fences);
+void GLAPIENTRY gl_dispatch_stub_667(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_668(GLsizei n, GLuint * fences);
+void GLAPIENTRY gl_dispatch_stub_669(GLuint fence, GLenum pname, GLint * params);
+GLboolean GLAPIENTRY gl_dispatch_stub_670(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_671(GLuint fence, GLenum condition);
+GLboolean GLAPIENTRY gl_dispatch_stub_672(GLuint fence);
+void GLAPIENTRY gl_dispatch_stub_753(GLenum face);
+void GLAPIENTRY gl_dispatch_stub_754(GLuint array);
+void GLAPIENTRY gl_dispatch_stub_755(GLsizei n, const GLuint * arrays);
+void GLAPIENTRY gl_dispatch_stub_756(GLsizei n, GLuint * arrays);
+GLboolean GLAPIENTRY gl_dispatch_stub_757(GLuint array);
+void GLAPIENTRY gl_dispatch_stub_764(GLclampd zmin, GLclampd zmax);
+void GLAPIENTRY gl_dispatch_stub_765(GLenum modeRGB, GLenum modeA);
+void GLAPIENTRY gl_dispatch_stub_783(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+void GLAPIENTRY gl_dispatch_stub_784(GLenum target, GLenum pname, GLint param);
+void GLAPIENTRY gl_dispatch_stub_785(GLenum target, GLintptr offset, GLsizeiptr size);
+void GLAPIENTRY gl_dispatch_stub_788(GLenum target, GLenum pname, GLvoid ** params);
+void GLAPIENTRY gl_dispatch_stub_789(GLenum target, GLsizei length, GLvoid * pointer);
+void GLAPIENTRY gl_dispatch_stub_790(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask);
+void GLAPIENTRY gl_dispatch_stub_791(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_792(GLenum target, GLuint index, GLsizei count, const GLfloat * params);
+void GLAPIENTRY gl_dispatch_stub_793(GLuint id, GLenum pname, GLint64EXT * params);
+void GLAPIENTRY gl_dispatch_stub_794(GLuint id, GLenum pname, GLuint64EXT * params);
#endif /* defined(NEED_FUNCTION_POINTER) || defined(GLX_INDIRECT_RENDERING) */
static const glprocs_table_t static_functions[] = {
@@ -1803,520 +1826,535 @@ static const glprocs_table_t static_functions[] = {
NAME_FUNC_OFFSET( 9026, glBindVertexArray, glBindVertexArray, NULL, _gloffset_BindVertexArray),
NAME_FUNC_OFFSET( 9044, glGenVertexArrays, glGenVertexArrays, NULL, _gloffset_GenVertexArrays),
NAME_FUNC_OFFSET( 9062, glCopyBufferSubData, glCopyBufferSubData, NULL, _gloffset_CopyBufferSubData),
- NAME_FUNC_OFFSET( 9082, glPolygonOffsetEXT, glPolygonOffsetEXT, NULL, _gloffset_PolygonOffsetEXT),
- NAME_FUNC_OFFSET( 9101, gl_dispatch_stub_568, gl_dispatch_stub_568, NULL, _gloffset_GetPixelTexGenParameterfvSGIS),
- NAME_FUNC_OFFSET( 9133, gl_dispatch_stub_569, gl_dispatch_stub_569, NULL, _gloffset_GetPixelTexGenParameterivSGIS),
- NAME_FUNC_OFFSET( 9165, gl_dispatch_stub_570, gl_dispatch_stub_570, NULL, _gloffset_PixelTexGenParameterfSGIS),
- NAME_FUNC_OFFSET( 9193, gl_dispatch_stub_571, gl_dispatch_stub_571, NULL, _gloffset_PixelTexGenParameterfvSGIS),
- NAME_FUNC_OFFSET( 9222, gl_dispatch_stub_572, gl_dispatch_stub_572, NULL, _gloffset_PixelTexGenParameteriSGIS),
- NAME_FUNC_OFFSET( 9250, gl_dispatch_stub_573, gl_dispatch_stub_573, NULL, _gloffset_PixelTexGenParameterivSGIS),
- NAME_FUNC_OFFSET( 9279, gl_dispatch_stub_574, gl_dispatch_stub_574, NULL, _gloffset_SampleMaskSGIS),
- NAME_FUNC_OFFSET( 9296, gl_dispatch_stub_575, gl_dispatch_stub_575, NULL, _gloffset_SamplePatternSGIS),
- NAME_FUNC_OFFSET( 9316, glColorPointerEXT, glColorPointerEXT, NULL, _gloffset_ColorPointerEXT),
- NAME_FUNC_OFFSET( 9334, glEdgeFlagPointerEXT, glEdgeFlagPointerEXT, NULL, _gloffset_EdgeFlagPointerEXT),
- NAME_FUNC_OFFSET( 9355, glIndexPointerEXT, glIndexPointerEXT, NULL, _gloffset_IndexPointerEXT),
- NAME_FUNC_OFFSET( 9373, glNormalPointerEXT, glNormalPointerEXT, NULL, _gloffset_NormalPointerEXT),
- NAME_FUNC_OFFSET( 9392, glTexCoordPointerEXT, glTexCoordPointerEXT, NULL, _gloffset_TexCoordPointerEXT),
- NAME_FUNC_OFFSET( 9413, glVertexPointerEXT, glVertexPointerEXT, NULL, _gloffset_VertexPointerEXT),
- NAME_FUNC_OFFSET( 9432, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
- NAME_FUNC_OFFSET( 9453, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
- NAME_FUNC_OFFSET( 9475, glLockArraysEXT, glLockArraysEXT, NULL, _gloffset_LockArraysEXT),
- NAME_FUNC_OFFSET( 9491, glUnlockArraysEXT, glUnlockArraysEXT, NULL, _gloffset_UnlockArraysEXT),
- NAME_FUNC_OFFSET( 9509, gl_dispatch_stub_586, gl_dispatch_stub_586, NULL, _gloffset_CullParameterdvEXT),
- NAME_FUNC_OFFSET( 9530, gl_dispatch_stub_587, gl_dispatch_stub_587, NULL, _gloffset_CullParameterfvEXT),
- NAME_FUNC_OFFSET( 9551, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
- NAME_FUNC_OFFSET( 9573, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
- NAME_FUNC_OFFSET( 9596, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
- NAME_FUNC_OFFSET( 9618, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
- NAME_FUNC_OFFSET( 9641, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
- NAME_FUNC_OFFSET( 9663, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
- NAME_FUNC_OFFSET( 9686, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
- NAME_FUNC_OFFSET( 9708, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
- NAME_FUNC_OFFSET( 9731, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
- NAME_FUNC_OFFSET( 9753, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
- NAME_FUNC_OFFSET( 9776, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
- NAME_FUNC_OFFSET( 9799, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
- NAME_FUNC_OFFSET( 9823, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
- NAME_FUNC_OFFSET( 9846, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
- NAME_FUNC_OFFSET( 9870, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
- NAME_FUNC_OFFSET( 9893, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
- NAME_FUNC_OFFSET( 9917, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
- NAME_FUNC_OFFSET( 9944, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
- NAME_FUNC_OFFSET( 9965, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
- NAME_FUNC_OFFSET( 9988, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
- NAME_FUNC_OFFSET(10009, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
- NAME_FUNC_OFFSET(10024, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
- NAME_FUNC_OFFSET(10040, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
- NAME_FUNC_OFFSET(10055, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
- NAME_FUNC_OFFSET(10071, gl_dispatch_stub_612, gl_dispatch_stub_612, NULL, _gloffset_PixelTexGenSGIX),
- NAME_FUNC_OFFSET(10089, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
- NAME_FUNC_OFFSET(10112, glFlushVertexArrayRangeNV, glFlushVertexArrayRangeNV, NULL, _gloffset_FlushVertexArrayRangeNV),
- NAME_FUNC_OFFSET(10138, glVertexArrayRangeNV, glVertexArrayRangeNV, NULL, _gloffset_VertexArrayRangeNV),
- NAME_FUNC_OFFSET(10159, glCombinerInputNV, glCombinerInputNV, NULL, _gloffset_CombinerInputNV),
- NAME_FUNC_OFFSET(10177, glCombinerOutputNV, glCombinerOutputNV, NULL, _gloffset_CombinerOutputNV),
- NAME_FUNC_OFFSET(10196, glCombinerParameterfNV, glCombinerParameterfNV, NULL, _gloffset_CombinerParameterfNV),
- NAME_FUNC_OFFSET(10219, glCombinerParameterfvNV, glCombinerParameterfvNV, NULL, _gloffset_CombinerParameterfvNV),
- NAME_FUNC_OFFSET(10243, glCombinerParameteriNV, glCombinerParameteriNV, NULL, _gloffset_CombinerParameteriNV),
- NAME_FUNC_OFFSET(10266, glCombinerParameterivNV, glCombinerParameterivNV, NULL, _gloffset_CombinerParameterivNV),
- NAME_FUNC_OFFSET(10290, glFinalCombinerInputNV, glFinalCombinerInputNV, NULL, _gloffset_FinalCombinerInputNV),
- NAME_FUNC_OFFSET(10313, glGetCombinerInputParameterfvNV, glGetCombinerInputParameterfvNV, NULL, _gloffset_GetCombinerInputParameterfvNV),
- NAME_FUNC_OFFSET(10345, glGetCombinerInputParameterivNV, glGetCombinerInputParameterivNV, NULL, _gloffset_GetCombinerInputParameterivNV),
- NAME_FUNC_OFFSET(10377, glGetCombinerOutputParameterfvNV, glGetCombinerOutputParameterfvNV, NULL, _gloffset_GetCombinerOutputParameterfvNV),
- NAME_FUNC_OFFSET(10410, glGetCombinerOutputParameterivNV, glGetCombinerOutputParameterivNV, NULL, _gloffset_GetCombinerOutputParameterivNV),
- NAME_FUNC_OFFSET(10443, glGetFinalCombinerInputParameterfvNV, glGetFinalCombinerInputParameterfvNV, NULL, _gloffset_GetFinalCombinerInputParameterfvNV),
- NAME_FUNC_OFFSET(10480, glGetFinalCombinerInputParameterivNV, glGetFinalCombinerInputParameterivNV, NULL, _gloffset_GetFinalCombinerInputParameterivNV),
- NAME_FUNC_OFFSET(10517, glResizeBuffersMESA, glResizeBuffersMESA, NULL, _gloffset_ResizeBuffersMESA),
- NAME_FUNC_OFFSET(10537, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
- NAME_FUNC_OFFSET(10555, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
- NAME_FUNC_OFFSET(10574, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
- NAME_FUNC_OFFSET(10592, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
- NAME_FUNC_OFFSET(10611, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
- NAME_FUNC_OFFSET(10629, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
- NAME_FUNC_OFFSET(10648, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
- NAME_FUNC_OFFSET(10666, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
- NAME_FUNC_OFFSET(10685, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
- NAME_FUNC_OFFSET(10703, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
- NAME_FUNC_OFFSET(10722, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
- NAME_FUNC_OFFSET(10740, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
- NAME_FUNC_OFFSET(10759, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
- NAME_FUNC_OFFSET(10777, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
- NAME_FUNC_OFFSET(10796, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
- NAME_FUNC_OFFSET(10814, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
- NAME_FUNC_OFFSET(10833, glWindowPos4dMESA, glWindowPos4dMESA, NULL, _gloffset_WindowPos4dMESA),
- NAME_FUNC_OFFSET(10851, glWindowPos4dvMESA, glWindowPos4dvMESA, NULL, _gloffset_WindowPos4dvMESA),
- NAME_FUNC_OFFSET(10870, glWindowPos4fMESA, glWindowPos4fMESA, NULL, _gloffset_WindowPos4fMESA),
- NAME_FUNC_OFFSET(10888, glWindowPos4fvMESA, glWindowPos4fvMESA, NULL, _gloffset_WindowPos4fvMESA),
- NAME_FUNC_OFFSET(10907, glWindowPos4iMESA, glWindowPos4iMESA, NULL, _gloffset_WindowPos4iMESA),
- NAME_FUNC_OFFSET(10925, glWindowPos4ivMESA, glWindowPos4ivMESA, NULL, _gloffset_WindowPos4ivMESA),
- NAME_FUNC_OFFSET(10944, glWindowPos4sMESA, glWindowPos4sMESA, NULL, _gloffset_WindowPos4sMESA),
- NAME_FUNC_OFFSET(10962, glWindowPos4svMESA, glWindowPos4svMESA, NULL, _gloffset_WindowPos4svMESA),
- NAME_FUNC_OFFSET(10981, gl_dispatch_stub_654, gl_dispatch_stub_654, NULL, _gloffset_MultiModeDrawArraysIBM),
- NAME_FUNC_OFFSET(11006, gl_dispatch_stub_655, gl_dispatch_stub_655, NULL, _gloffset_MultiModeDrawElementsIBM),
- NAME_FUNC_OFFSET(11033, gl_dispatch_stub_656, gl_dispatch_stub_656, NULL, _gloffset_DeleteFencesNV),
- NAME_FUNC_OFFSET(11050, gl_dispatch_stub_657, gl_dispatch_stub_657, NULL, _gloffset_FinishFenceNV),
- NAME_FUNC_OFFSET(11066, gl_dispatch_stub_658, gl_dispatch_stub_658, NULL, _gloffset_GenFencesNV),
- NAME_FUNC_OFFSET(11080, gl_dispatch_stub_659, gl_dispatch_stub_659, NULL, _gloffset_GetFenceivNV),
- NAME_FUNC_OFFSET(11095, gl_dispatch_stub_660, gl_dispatch_stub_660, NULL, _gloffset_IsFenceNV),
- NAME_FUNC_OFFSET(11107, gl_dispatch_stub_661, gl_dispatch_stub_661, NULL, _gloffset_SetFenceNV),
- NAME_FUNC_OFFSET(11120, gl_dispatch_stub_662, gl_dispatch_stub_662, NULL, _gloffset_TestFenceNV),
- NAME_FUNC_OFFSET(11134, glAreProgramsResidentNV, glAreProgramsResidentNV, NULL, _gloffset_AreProgramsResidentNV),
- NAME_FUNC_OFFSET(11158, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
- NAME_FUNC_OFFSET(11174, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
- NAME_FUNC_OFFSET(11193, glExecuteProgramNV, glExecuteProgramNV, NULL, _gloffset_ExecuteProgramNV),
- NAME_FUNC_OFFSET(11212, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
- NAME_FUNC_OFFSET(11228, glGetProgramParameterdvNV, glGetProgramParameterdvNV, NULL, _gloffset_GetProgramParameterdvNV),
- NAME_FUNC_OFFSET(11254, glGetProgramParameterfvNV, glGetProgramParameterfvNV, NULL, _gloffset_GetProgramParameterfvNV),
- NAME_FUNC_OFFSET(11280, glGetProgramStringNV, glGetProgramStringNV, NULL, _gloffset_GetProgramStringNV),
- NAME_FUNC_OFFSET(11301, glGetProgramivNV, glGetProgramivNV, NULL, _gloffset_GetProgramivNV),
- NAME_FUNC_OFFSET(11318, glGetTrackMatrixivNV, glGetTrackMatrixivNV, NULL, _gloffset_GetTrackMatrixivNV),
- NAME_FUNC_OFFSET(11339, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
- NAME_FUNC_OFFSET(11367, glGetVertexAttribdvNV, glGetVertexAttribdvNV, NULL, _gloffset_GetVertexAttribdvNV),
- NAME_FUNC_OFFSET(11389, glGetVertexAttribfvNV, glGetVertexAttribfvNV, NULL, _gloffset_GetVertexAttribfvNV),
- NAME_FUNC_OFFSET(11411, glGetVertexAttribivNV, glGetVertexAttribivNV, NULL, _gloffset_GetVertexAttribivNV),
- NAME_FUNC_OFFSET(11433, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
- NAME_FUNC_OFFSET(11447, glLoadProgramNV, glLoadProgramNV, NULL, _gloffset_LoadProgramNV),
- NAME_FUNC_OFFSET(11463, glProgramParameters4dvNV, glProgramParameters4dvNV, NULL, _gloffset_ProgramParameters4dvNV),
- NAME_FUNC_OFFSET(11488, glProgramParameters4fvNV, glProgramParameters4fvNV, NULL, _gloffset_ProgramParameters4fvNV),
- NAME_FUNC_OFFSET(11513, glRequestResidentProgramsNV, glRequestResidentProgramsNV, NULL, _gloffset_RequestResidentProgramsNV),
- NAME_FUNC_OFFSET(11541, glTrackMatrixNV, glTrackMatrixNV, NULL, _gloffset_TrackMatrixNV),
- NAME_FUNC_OFFSET(11557, glVertexAttrib1dNV, glVertexAttrib1dNV, NULL, _gloffset_VertexAttrib1dNV),
- NAME_FUNC_OFFSET(11576, glVertexAttrib1dvNV, glVertexAttrib1dvNV, NULL, _gloffset_VertexAttrib1dvNV),
- NAME_FUNC_OFFSET(11596, glVertexAttrib1fNV, glVertexAttrib1fNV, NULL, _gloffset_VertexAttrib1fNV),
- NAME_FUNC_OFFSET(11615, glVertexAttrib1fvNV, glVertexAttrib1fvNV, NULL, _gloffset_VertexAttrib1fvNV),
- NAME_FUNC_OFFSET(11635, glVertexAttrib1sNV, glVertexAttrib1sNV, NULL, _gloffset_VertexAttrib1sNV),
- NAME_FUNC_OFFSET(11654, glVertexAttrib1svNV, glVertexAttrib1svNV, NULL, _gloffset_VertexAttrib1svNV),
- NAME_FUNC_OFFSET(11674, glVertexAttrib2dNV, glVertexAttrib2dNV, NULL, _gloffset_VertexAttrib2dNV),
- NAME_FUNC_OFFSET(11693, glVertexAttrib2dvNV, glVertexAttrib2dvNV, NULL, _gloffset_VertexAttrib2dvNV),
- NAME_FUNC_OFFSET(11713, glVertexAttrib2fNV, glVertexAttrib2fNV, NULL, _gloffset_VertexAttrib2fNV),
- NAME_FUNC_OFFSET(11732, glVertexAttrib2fvNV, glVertexAttrib2fvNV, NULL, _gloffset_VertexAttrib2fvNV),
- NAME_FUNC_OFFSET(11752, glVertexAttrib2sNV, glVertexAttrib2sNV, NULL, _gloffset_VertexAttrib2sNV),
- NAME_FUNC_OFFSET(11771, glVertexAttrib2svNV, glVertexAttrib2svNV, NULL, _gloffset_VertexAttrib2svNV),
- NAME_FUNC_OFFSET(11791, glVertexAttrib3dNV, glVertexAttrib3dNV, NULL, _gloffset_VertexAttrib3dNV),
- NAME_FUNC_OFFSET(11810, glVertexAttrib3dvNV, glVertexAttrib3dvNV, NULL, _gloffset_VertexAttrib3dvNV),
- NAME_FUNC_OFFSET(11830, glVertexAttrib3fNV, glVertexAttrib3fNV, NULL, _gloffset_VertexAttrib3fNV),
- NAME_FUNC_OFFSET(11849, glVertexAttrib3fvNV, glVertexAttrib3fvNV, NULL, _gloffset_VertexAttrib3fvNV),
- NAME_FUNC_OFFSET(11869, glVertexAttrib3sNV, glVertexAttrib3sNV, NULL, _gloffset_VertexAttrib3sNV),
- NAME_FUNC_OFFSET(11888, glVertexAttrib3svNV, glVertexAttrib3svNV, NULL, _gloffset_VertexAttrib3svNV),
- NAME_FUNC_OFFSET(11908, glVertexAttrib4dNV, glVertexAttrib4dNV, NULL, _gloffset_VertexAttrib4dNV),
- NAME_FUNC_OFFSET(11927, glVertexAttrib4dvNV, glVertexAttrib4dvNV, NULL, _gloffset_VertexAttrib4dvNV),
- NAME_FUNC_OFFSET(11947, glVertexAttrib4fNV, glVertexAttrib4fNV, NULL, _gloffset_VertexAttrib4fNV),
- NAME_FUNC_OFFSET(11966, glVertexAttrib4fvNV, glVertexAttrib4fvNV, NULL, _gloffset_VertexAttrib4fvNV),
- NAME_FUNC_OFFSET(11986, glVertexAttrib4sNV, glVertexAttrib4sNV, NULL, _gloffset_VertexAttrib4sNV),
- NAME_FUNC_OFFSET(12005, glVertexAttrib4svNV, glVertexAttrib4svNV, NULL, _gloffset_VertexAttrib4svNV),
- NAME_FUNC_OFFSET(12025, glVertexAttrib4ubNV, glVertexAttrib4ubNV, NULL, _gloffset_VertexAttrib4ubNV),
- NAME_FUNC_OFFSET(12045, glVertexAttrib4ubvNV, glVertexAttrib4ubvNV, NULL, _gloffset_VertexAttrib4ubvNV),
- NAME_FUNC_OFFSET(12066, glVertexAttribPointerNV, glVertexAttribPointerNV, NULL, _gloffset_VertexAttribPointerNV),
- NAME_FUNC_OFFSET(12090, glVertexAttribs1dvNV, glVertexAttribs1dvNV, NULL, _gloffset_VertexAttribs1dvNV),
- NAME_FUNC_OFFSET(12111, glVertexAttribs1fvNV, glVertexAttribs1fvNV, NULL, _gloffset_VertexAttribs1fvNV),
- NAME_FUNC_OFFSET(12132, glVertexAttribs1svNV, glVertexAttribs1svNV, NULL, _gloffset_VertexAttribs1svNV),
- NAME_FUNC_OFFSET(12153, glVertexAttribs2dvNV, glVertexAttribs2dvNV, NULL, _gloffset_VertexAttribs2dvNV),
- NAME_FUNC_OFFSET(12174, glVertexAttribs2fvNV, glVertexAttribs2fvNV, NULL, _gloffset_VertexAttribs2fvNV),
- NAME_FUNC_OFFSET(12195, glVertexAttribs2svNV, glVertexAttribs2svNV, NULL, _gloffset_VertexAttribs2svNV),
- NAME_FUNC_OFFSET(12216, glVertexAttribs3dvNV, glVertexAttribs3dvNV, NULL, _gloffset_VertexAttribs3dvNV),
- NAME_FUNC_OFFSET(12237, glVertexAttribs3fvNV, glVertexAttribs3fvNV, NULL, _gloffset_VertexAttribs3fvNV),
- NAME_FUNC_OFFSET(12258, glVertexAttribs3svNV, glVertexAttribs3svNV, NULL, _gloffset_VertexAttribs3svNV),
- NAME_FUNC_OFFSET(12279, glVertexAttribs4dvNV, glVertexAttribs4dvNV, NULL, _gloffset_VertexAttribs4dvNV),
- NAME_FUNC_OFFSET(12300, glVertexAttribs4fvNV, glVertexAttribs4fvNV, NULL, _gloffset_VertexAttribs4fvNV),
- NAME_FUNC_OFFSET(12321, glVertexAttribs4svNV, glVertexAttribs4svNV, NULL, _gloffset_VertexAttribs4svNV),
- NAME_FUNC_OFFSET(12342, glVertexAttribs4ubvNV, glVertexAttribs4ubvNV, NULL, _gloffset_VertexAttribs4ubvNV),
- NAME_FUNC_OFFSET(12364, glGetTexBumpParameterfvATI, glGetTexBumpParameterfvATI, NULL, _gloffset_GetTexBumpParameterfvATI),
- NAME_FUNC_OFFSET(12391, glGetTexBumpParameterivATI, glGetTexBumpParameterivATI, NULL, _gloffset_GetTexBumpParameterivATI),
- NAME_FUNC_OFFSET(12418, glTexBumpParameterfvATI, glTexBumpParameterfvATI, NULL, _gloffset_TexBumpParameterfvATI),
- NAME_FUNC_OFFSET(12442, glTexBumpParameterivATI, glTexBumpParameterivATI, NULL, _gloffset_TexBumpParameterivATI),
- NAME_FUNC_OFFSET(12466, glAlphaFragmentOp1ATI, glAlphaFragmentOp1ATI, NULL, _gloffset_AlphaFragmentOp1ATI),
- NAME_FUNC_OFFSET(12488, glAlphaFragmentOp2ATI, glAlphaFragmentOp2ATI, NULL, _gloffset_AlphaFragmentOp2ATI),
- NAME_FUNC_OFFSET(12510, glAlphaFragmentOp3ATI, glAlphaFragmentOp3ATI, NULL, _gloffset_AlphaFragmentOp3ATI),
- NAME_FUNC_OFFSET(12532, glBeginFragmentShaderATI, glBeginFragmentShaderATI, NULL, _gloffset_BeginFragmentShaderATI),
- NAME_FUNC_OFFSET(12557, glBindFragmentShaderATI, glBindFragmentShaderATI, NULL, _gloffset_BindFragmentShaderATI),
- NAME_FUNC_OFFSET(12581, glColorFragmentOp1ATI, glColorFragmentOp1ATI, NULL, _gloffset_ColorFragmentOp1ATI),
- NAME_FUNC_OFFSET(12603, glColorFragmentOp2ATI, glColorFragmentOp2ATI, NULL, _gloffset_ColorFragmentOp2ATI),
- NAME_FUNC_OFFSET(12625, glColorFragmentOp3ATI, glColorFragmentOp3ATI, NULL, _gloffset_ColorFragmentOp3ATI),
- NAME_FUNC_OFFSET(12647, glDeleteFragmentShaderATI, glDeleteFragmentShaderATI, NULL, _gloffset_DeleteFragmentShaderATI),
- NAME_FUNC_OFFSET(12673, glEndFragmentShaderATI, glEndFragmentShaderATI, NULL, _gloffset_EndFragmentShaderATI),
- NAME_FUNC_OFFSET(12696, glGenFragmentShadersATI, glGenFragmentShadersATI, NULL, _gloffset_GenFragmentShadersATI),
- NAME_FUNC_OFFSET(12720, glPassTexCoordATI, glPassTexCoordATI, NULL, _gloffset_PassTexCoordATI),
- NAME_FUNC_OFFSET(12738, glSampleMapATI, glSampleMapATI, NULL, _gloffset_SampleMapATI),
- NAME_FUNC_OFFSET(12753, glSetFragmentShaderConstantATI, glSetFragmentShaderConstantATI, NULL, _gloffset_SetFragmentShaderConstantATI),
- NAME_FUNC_OFFSET(12784, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
- NAME_FUNC_OFFSET(12804, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
- NAME_FUNC_OFFSET(12825, gl_dispatch_stub_743, gl_dispatch_stub_743, NULL, _gloffset_ActiveStencilFaceEXT),
- NAME_FUNC_OFFSET(12848, gl_dispatch_stub_744, gl_dispatch_stub_744, NULL, _gloffset_BindVertexArrayAPPLE),
- NAME_FUNC_OFFSET(12871, gl_dispatch_stub_745, gl_dispatch_stub_745, NULL, _gloffset_DeleteVertexArraysAPPLE),
- NAME_FUNC_OFFSET(12897, gl_dispatch_stub_746, gl_dispatch_stub_746, NULL, _gloffset_GenVertexArraysAPPLE),
- NAME_FUNC_OFFSET(12920, gl_dispatch_stub_747, gl_dispatch_stub_747, NULL, _gloffset_IsVertexArrayAPPLE),
- NAME_FUNC_OFFSET(12941, glGetProgramNamedParameterdvNV, glGetProgramNamedParameterdvNV, NULL, _gloffset_GetProgramNamedParameterdvNV),
- NAME_FUNC_OFFSET(12972, glGetProgramNamedParameterfvNV, glGetProgramNamedParameterfvNV, NULL, _gloffset_GetProgramNamedParameterfvNV),
- NAME_FUNC_OFFSET(13003, glProgramNamedParameter4dNV, glProgramNamedParameter4dNV, NULL, _gloffset_ProgramNamedParameter4dNV),
- NAME_FUNC_OFFSET(13031, glProgramNamedParameter4dvNV, glProgramNamedParameter4dvNV, NULL, _gloffset_ProgramNamedParameter4dvNV),
- NAME_FUNC_OFFSET(13060, glProgramNamedParameter4fNV, glProgramNamedParameter4fNV, NULL, _gloffset_ProgramNamedParameter4fNV),
- NAME_FUNC_OFFSET(13088, glProgramNamedParameter4fvNV, glProgramNamedParameter4fvNV, NULL, _gloffset_ProgramNamedParameter4fvNV),
- NAME_FUNC_OFFSET(13117, gl_dispatch_stub_754, gl_dispatch_stub_754, NULL, _gloffset_DepthBoundsEXT),
- NAME_FUNC_OFFSET(13134, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_BlendEquationSeparateEXT),
- NAME_FUNC_OFFSET(13161, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
- NAME_FUNC_OFFSET(13182, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
- NAME_FUNC_OFFSET(13204, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
- NAME_FUNC_OFFSET(13232, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
- NAME_FUNC_OFFSET(13256, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
- NAME_FUNC_OFFSET(13281, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
- NAME_FUNC_OFFSET(13310, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
- NAME_FUNC_OFFSET(13336, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
- NAME_FUNC_OFFSET(13362, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
- NAME_FUNC_OFFSET(13388, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
- NAME_FUNC_OFFSET(13409, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
- NAME_FUNC_OFFSET(13431, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
- NAME_FUNC_OFFSET(13451, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
- NAME_FUNC_OFFSET(13492, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
- NAME_FUNC_OFFSET(13524, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
- NAME_FUNC_OFFSET(13543, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
- NAME_FUNC_OFFSET(13563, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
- NAME_FUNC_OFFSET(13588, gl_dispatch_stub_773, gl_dispatch_stub_773, NULL, _gloffset_BlitFramebufferEXT),
- NAME_FUNC_OFFSET(13609, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
- NAME_FUNC_OFFSET(13638, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
- NAME_FUNC_OFFSET(13659, gl_dispatch_stub_776, gl_dispatch_stub_776, NULL, _gloffset_StencilFuncSeparateATI),
- NAME_FUNC_OFFSET(13684, gl_dispatch_stub_777, gl_dispatch_stub_777, NULL, _gloffset_ProgramEnvParameters4fvEXT),
- NAME_FUNC_OFFSET(13713, gl_dispatch_stub_778, gl_dispatch_stub_778, NULL, _gloffset_ProgramLocalParameters4fvEXT),
- NAME_FUNC_OFFSET(13744, gl_dispatch_stub_779, gl_dispatch_stub_779, NULL, _gloffset_GetQueryObjecti64vEXT),
- NAME_FUNC_OFFSET(13768, gl_dispatch_stub_780, gl_dispatch_stub_780, NULL, _gloffset_GetQueryObjectui64vEXT),
- NAME_FUNC_OFFSET(13793, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
- NAME_FUNC_OFFSET(13811, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
- NAME_FUNC_OFFSET(13828, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
- NAME_FUNC_OFFSET(13844, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
- NAME_FUNC_OFFSET(13869, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
- NAME_FUNC_OFFSET(13889, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
- NAME_FUNC_OFFSET(13909, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
- NAME_FUNC_OFFSET(13932, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
- NAME_FUNC_OFFSET(13955, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
- NAME_FUNC_OFFSET(13975, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
- NAME_FUNC_OFFSET(13992, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
- NAME_FUNC_OFFSET(14009, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
- NAME_FUNC_OFFSET(14024, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
- NAME_FUNC_OFFSET(14048, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
- NAME_FUNC_OFFSET(14067, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
- NAME_FUNC_OFFSET(14086, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
- NAME_FUNC_OFFSET(14102, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
- NAME_FUNC_OFFSET(14121, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
- NAME_FUNC_OFFSET(14144, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
- NAME_FUNC_OFFSET(14160, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
- NAME_FUNC_OFFSET(14176, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
- NAME_FUNC_OFFSET(14203, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
- NAME_FUNC_OFFSET(14230, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
- NAME_FUNC_OFFSET(14250, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
- NAME_FUNC_OFFSET(14269, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
- NAME_FUNC_OFFSET(14288, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
- NAME_FUNC_OFFSET(14318, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
- NAME_FUNC_OFFSET(14348, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
- NAME_FUNC_OFFSET(14378, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
- NAME_FUNC_OFFSET(14408, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
- NAME_FUNC_OFFSET(14427, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
- NAME_FUNC_OFFSET(14450, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
- NAME_FUNC_OFFSET(14475, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
- NAME_FUNC_OFFSET(14500, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
- NAME_FUNC_OFFSET(14527, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
- NAME_FUNC_OFFSET(14555, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
- NAME_FUNC_OFFSET(14582, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
- NAME_FUNC_OFFSET(14610, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
- NAME_FUNC_OFFSET(14639, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
- NAME_FUNC_OFFSET(14668, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
- NAME_FUNC_OFFSET(14694, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
- NAME_FUNC_OFFSET(14725, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
- NAME_FUNC_OFFSET(14756, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
- NAME_FUNC_OFFSET(14780, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
- NAME_FUNC_OFFSET(14803, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
- NAME_FUNC_OFFSET(14821, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
- NAME_FUNC_OFFSET(14850, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
- NAME_FUNC_OFFSET(14879, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
- NAME_FUNC_OFFSET(14894, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
- NAME_FUNC_OFFSET(14920, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
- NAME_FUNC_OFFSET(14946, glHistogram, glHistogram, NULL, _gloffset_Histogram),
- NAME_FUNC_OFFSET(14961, glMinmax, glMinmax, NULL, _gloffset_Minmax),
- NAME_FUNC_OFFSET(14973, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
- NAME_FUNC_OFFSET(14993, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
- NAME_FUNC_OFFSET(15010, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
- NAME_FUNC_OFFSET(15026, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
- NAME_FUNC_OFFSET(15045, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
- NAME_FUNC_OFFSET(15068, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
- NAME_FUNC_OFFSET(15084, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
- NAME_FUNC_OFFSET(15106, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
- NAME_FUNC_OFFSET(15124, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
- NAME_FUNC_OFFSET(15143, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
- NAME_FUNC_OFFSET(15161, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
- NAME_FUNC_OFFSET(15180, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
- NAME_FUNC_OFFSET(15198, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
- NAME_FUNC_OFFSET(15217, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
- NAME_FUNC_OFFSET(15235, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
- NAME_FUNC_OFFSET(15254, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
- NAME_FUNC_OFFSET(15272, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
- NAME_FUNC_OFFSET(15291, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
- NAME_FUNC_OFFSET(15309, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
- NAME_FUNC_OFFSET(15328, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
- NAME_FUNC_OFFSET(15346, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
- NAME_FUNC_OFFSET(15365, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
- NAME_FUNC_OFFSET(15383, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
- NAME_FUNC_OFFSET(15402, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
- NAME_FUNC_OFFSET(15420, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
- NAME_FUNC_OFFSET(15439, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
- NAME_FUNC_OFFSET(15457, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
- NAME_FUNC_OFFSET(15476, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
- NAME_FUNC_OFFSET(15494, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
- NAME_FUNC_OFFSET(15513, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
- NAME_FUNC_OFFSET(15531, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
- NAME_FUNC_OFFSET(15550, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
- NAME_FUNC_OFFSET(15568, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
- NAME_FUNC_OFFSET(15587, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
- NAME_FUNC_OFFSET(15605, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
- NAME_FUNC_OFFSET(15624, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
- NAME_FUNC_OFFSET(15642, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
- NAME_FUNC_OFFSET(15661, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
- NAME_FUNC_OFFSET(15679, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
- NAME_FUNC_OFFSET(15698, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
- NAME_FUNC_OFFSET(15721, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
- NAME_FUNC_OFFSET(15744, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
- NAME_FUNC_OFFSET(15767, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
- NAME_FUNC_OFFSET(15790, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
- NAME_FUNC_OFFSET(15813, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
- NAME_FUNC_OFFSET(15830, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
- NAME_FUNC_OFFSET(15853, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
- NAME_FUNC_OFFSET(15876, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
- NAME_FUNC_OFFSET(15899, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
- NAME_FUNC_OFFSET(15925, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
- NAME_FUNC_OFFSET(15951, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
- NAME_FUNC_OFFSET(15977, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
- NAME_FUNC_OFFSET(16001, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
- NAME_FUNC_OFFSET(16028, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
- NAME_FUNC_OFFSET(16054, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
- NAME_FUNC_OFFSET(16074, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
- NAME_FUNC_OFFSET(16094, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
- NAME_FUNC_OFFSET(16114, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
- NAME_FUNC_OFFSET(16137, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
- NAME_FUNC_OFFSET(16161, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
- NAME_FUNC_OFFSET(16184, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
- NAME_FUNC_OFFSET(16208, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
- NAME_FUNC_OFFSET(16225, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
- NAME_FUNC_OFFSET(16243, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
- NAME_FUNC_OFFSET(16260, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
- NAME_FUNC_OFFSET(16278, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
- NAME_FUNC_OFFSET(16295, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
- NAME_FUNC_OFFSET(16313, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
- NAME_FUNC_OFFSET(16330, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
- NAME_FUNC_OFFSET(16348, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
- NAME_FUNC_OFFSET(16365, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
- NAME_FUNC_OFFSET(16383, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
- NAME_FUNC_OFFSET(16400, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
- NAME_FUNC_OFFSET(16418, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
- NAME_FUNC_OFFSET(16435, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
- NAME_FUNC_OFFSET(16453, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
- NAME_FUNC_OFFSET(16470, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
- NAME_FUNC_OFFSET(16488, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
- NAME_FUNC_OFFSET(16505, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
- NAME_FUNC_OFFSET(16523, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
- NAME_FUNC_OFFSET(16542, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
- NAME_FUNC_OFFSET(16561, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
- NAME_FUNC_OFFSET(16580, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
- NAME_FUNC_OFFSET(16599, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
- NAME_FUNC_OFFSET(16619, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
- NAME_FUNC_OFFSET(16639, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
- NAME_FUNC_OFFSET(16659, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
- NAME_FUNC_OFFSET(16677, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
- NAME_FUNC_OFFSET(16694, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
- NAME_FUNC_OFFSET(16712, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
- NAME_FUNC_OFFSET(16729, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
- NAME_FUNC_OFFSET(16747, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
- NAME_FUNC_OFFSET(16765, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
- NAME_FUNC_OFFSET(16782, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
- NAME_FUNC_OFFSET(16800, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
- NAME_FUNC_OFFSET(16819, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
- NAME_FUNC_OFFSET(16838, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
- NAME_FUNC_OFFSET(16857, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
- NAME_FUNC_OFFSET(16879, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
- NAME_FUNC_OFFSET(16892, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
- NAME_FUNC_OFFSET(16905, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
- NAME_FUNC_OFFSET(16921, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
- NAME_FUNC_OFFSET(16937, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
- NAME_FUNC_OFFSET(16950, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
- NAME_FUNC_OFFSET(16973, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
- NAME_FUNC_OFFSET(16993, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
- NAME_FUNC_OFFSET(17012, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
- NAME_FUNC_OFFSET(17023, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
- NAME_FUNC_OFFSET(17035, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
- NAME_FUNC_OFFSET(17049, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
- NAME_FUNC_OFFSET(17062, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
- NAME_FUNC_OFFSET(17078, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
- NAME_FUNC_OFFSET(17089, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
- NAME_FUNC_OFFSET(17102, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
- NAME_FUNC_OFFSET(17121, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
- NAME_FUNC_OFFSET(17141, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
- NAME_FUNC_OFFSET(17154, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
- NAME_FUNC_OFFSET(17164, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
- NAME_FUNC_OFFSET(17180, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
- NAME_FUNC_OFFSET(17199, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
- NAME_FUNC_OFFSET(17217, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
- NAME_FUNC_OFFSET(17238, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
- NAME_FUNC_OFFSET(17253, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
- NAME_FUNC_OFFSET(17268, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
- NAME_FUNC_OFFSET(17282, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
- NAME_FUNC_OFFSET(17297, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
- NAME_FUNC_OFFSET(17309, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
- NAME_FUNC_OFFSET(17322, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
- NAME_FUNC_OFFSET(17334, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
- NAME_FUNC_OFFSET(17347, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
- NAME_FUNC_OFFSET(17359, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
- NAME_FUNC_OFFSET(17372, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
- NAME_FUNC_OFFSET(17384, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
- NAME_FUNC_OFFSET(17397, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
- NAME_FUNC_OFFSET(17409, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
- NAME_FUNC_OFFSET(17422, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
- NAME_FUNC_OFFSET(17434, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
- NAME_FUNC_OFFSET(17447, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
- NAME_FUNC_OFFSET(17459, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
- NAME_FUNC_OFFSET(17472, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
- NAME_FUNC_OFFSET(17484, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
- NAME_FUNC_OFFSET(17497, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
- NAME_FUNC_OFFSET(17516, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
- NAME_FUNC_OFFSET(17535, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
- NAME_FUNC_OFFSET(17554, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
- NAME_FUNC_OFFSET(17567, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
- NAME_FUNC_OFFSET(17585, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
- NAME_FUNC_OFFSET(17606, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
- NAME_FUNC_OFFSET(17624, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
- NAME_FUNC_OFFSET(17644, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
- NAME_FUNC_OFFSET(17658, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
- NAME_FUNC_OFFSET(17675, gl_dispatch_stub_574, gl_dispatch_stub_574, NULL, _gloffset_SampleMaskSGIS),
- NAME_FUNC_OFFSET(17691, gl_dispatch_stub_575, gl_dispatch_stub_575, NULL, _gloffset_SamplePatternSGIS),
- NAME_FUNC_OFFSET(17710, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
- NAME_FUNC_OFFSET(17728, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
- NAME_FUNC_OFFSET(17749, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
- NAME_FUNC_OFFSET(17771, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
- NAME_FUNC_OFFSET(17790, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
- NAME_FUNC_OFFSET(17812, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
- NAME_FUNC_OFFSET(17835, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
- NAME_FUNC_OFFSET(17854, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
- NAME_FUNC_OFFSET(17874, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
- NAME_FUNC_OFFSET(17893, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
- NAME_FUNC_OFFSET(17913, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
- NAME_FUNC_OFFSET(17932, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
- NAME_FUNC_OFFSET(17952, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
- NAME_FUNC_OFFSET(17971, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
- NAME_FUNC_OFFSET(17991, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
- NAME_FUNC_OFFSET(18010, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
- NAME_FUNC_OFFSET(18030, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
- NAME_FUNC_OFFSET(18050, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
- NAME_FUNC_OFFSET(18071, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
- NAME_FUNC_OFFSET(18091, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
- NAME_FUNC_OFFSET(18112, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
- NAME_FUNC_OFFSET(18132, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
- NAME_FUNC_OFFSET(18153, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
- NAME_FUNC_OFFSET(18177, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
- NAME_FUNC_OFFSET(18195, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
- NAME_FUNC_OFFSET(18215, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
- NAME_FUNC_OFFSET(18233, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
- NAME_FUNC_OFFSET(18245, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
- NAME_FUNC_OFFSET(18258, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
- NAME_FUNC_OFFSET(18270, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
- NAME_FUNC_OFFSET(18283, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
- NAME_FUNC_OFFSET(18303, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
- NAME_FUNC_OFFSET(18327, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
- NAME_FUNC_OFFSET(18341, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
- NAME_FUNC_OFFSET(18358, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
- NAME_FUNC_OFFSET(18373, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
- NAME_FUNC_OFFSET(18391, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
- NAME_FUNC_OFFSET(18405, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
- NAME_FUNC_OFFSET(18422, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
- NAME_FUNC_OFFSET(18437, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
- NAME_FUNC_OFFSET(18455, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
- NAME_FUNC_OFFSET(18469, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
- NAME_FUNC_OFFSET(18486, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
- NAME_FUNC_OFFSET(18501, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
- NAME_FUNC_OFFSET(18519, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
- NAME_FUNC_OFFSET(18533, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
- NAME_FUNC_OFFSET(18550, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
- NAME_FUNC_OFFSET(18565, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
- NAME_FUNC_OFFSET(18583, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
- NAME_FUNC_OFFSET(18597, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
- NAME_FUNC_OFFSET(18614, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
- NAME_FUNC_OFFSET(18629, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
- NAME_FUNC_OFFSET(18647, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
- NAME_FUNC_OFFSET(18661, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
- NAME_FUNC_OFFSET(18678, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
- NAME_FUNC_OFFSET(18693, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
- NAME_FUNC_OFFSET(18711, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
- NAME_FUNC_OFFSET(18725, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
- NAME_FUNC_OFFSET(18742, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
- NAME_FUNC_OFFSET(18757, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
- NAME_FUNC_OFFSET(18775, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
- NAME_FUNC_OFFSET(18789, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
- NAME_FUNC_OFFSET(18806, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
- NAME_FUNC_OFFSET(18821, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
- NAME_FUNC_OFFSET(18839, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
- NAME_FUNC_OFFSET(18856, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
- NAME_FUNC_OFFSET(18876, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
- NAME_FUNC_OFFSET(18893, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
- NAME_FUNC_OFFSET(18919, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
- NAME_FUNC_OFFSET(18948, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
- NAME_FUNC_OFFSET(18963, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
- NAME_FUNC_OFFSET(18981, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
- NAME_FUNC_OFFSET(19000, gl_dispatch_stub_745, gl_dispatch_stub_745, NULL, _gloffset_DeleteVertexArraysAPPLE),
- NAME_FUNC_OFFSET(19021, gl_dispatch_stub_747, gl_dispatch_stub_747, NULL, _gloffset_IsVertexArrayAPPLE),
- NAME_FUNC_OFFSET(19037, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_BlendEquationSeparateEXT),
- NAME_FUNC_OFFSET(19061, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_BlendEquationSeparateEXT),
- NAME_FUNC_OFFSET(19088, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
- NAME_FUNC_OFFSET(19106, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
- NAME_FUNC_OFFSET(19125, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
- NAME_FUNC_OFFSET(19150, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
- NAME_FUNC_OFFSET(19171, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
- NAME_FUNC_OFFSET(19193, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
- NAME_FUNC_OFFSET(19219, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
- NAME_FUNC_OFFSET(19242, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
- NAME_FUNC_OFFSET(19265, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
- NAME_FUNC_OFFSET(19288, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
- NAME_FUNC_OFFSET(19306, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
- NAME_FUNC_OFFSET(19325, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
- NAME_FUNC_OFFSET(19342, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
- NAME_FUNC_OFFSET(19380, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
- NAME_FUNC_OFFSET(19409, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
- NAME_FUNC_OFFSET(19425, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
- NAME_FUNC_OFFSET(19442, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
- NAME_FUNC_OFFSET(19464, gl_dispatch_stub_773, gl_dispatch_stub_773, NULL, _gloffset_BlitFramebufferEXT),
- NAME_FUNC_OFFSET(19482, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+ NAME_FUNC_OFFSET( 9082, glClientWaitSync, glClientWaitSync, NULL, _gloffset_ClientWaitSync),
+ NAME_FUNC_OFFSET( 9099, glDeleteSync, glDeleteSync, NULL, _gloffset_DeleteSync),
+ NAME_FUNC_OFFSET( 9112, glFenceSync, glFenceSync, NULL, _gloffset_FenceSync),
+ NAME_FUNC_OFFSET( 9124, glGetInteger64v, glGetInteger64v, NULL, _gloffset_GetInteger64v),
+ NAME_FUNC_OFFSET( 9140, glGetSynciv, glGetSynciv, NULL, _gloffset_GetSynciv),
+ NAME_FUNC_OFFSET( 9152, glIsSync, glIsSync, NULL, _gloffset_IsSync),
+ NAME_FUNC_OFFSET( 9161, glWaitSync, glWaitSync, NULL, _gloffset_WaitSync),
+ NAME_FUNC_OFFSET( 9172, glDrawElementsBaseVertex, glDrawElementsBaseVertex, NULL, _gloffset_DrawElementsBaseVertex),
+ NAME_FUNC_OFFSET( 9197, glDrawRangeElementsBaseVertex, glDrawRangeElementsBaseVertex, NULL, _gloffset_DrawRangeElementsBaseVertex),
+ NAME_FUNC_OFFSET( 9227, glMultiDrawElementsBaseVertex, glMultiDrawElementsBaseVertex, NULL, _gloffset_MultiDrawElementsBaseVertex),
+ NAME_FUNC_OFFSET( 9257, glPolygonOffsetEXT, glPolygonOffsetEXT, NULL, _gloffset_PolygonOffsetEXT),
+ NAME_FUNC_OFFSET( 9276, gl_dispatch_stub_578, gl_dispatch_stub_578, NULL, _gloffset_GetPixelTexGenParameterfvSGIS),
+ NAME_FUNC_OFFSET( 9308, gl_dispatch_stub_579, gl_dispatch_stub_579, NULL, _gloffset_GetPixelTexGenParameterivSGIS),
+ NAME_FUNC_OFFSET( 9340, gl_dispatch_stub_580, gl_dispatch_stub_580, NULL, _gloffset_PixelTexGenParameterfSGIS),
+ NAME_FUNC_OFFSET( 9368, gl_dispatch_stub_581, gl_dispatch_stub_581, NULL, _gloffset_PixelTexGenParameterfvSGIS),
+ NAME_FUNC_OFFSET( 9397, gl_dispatch_stub_582, gl_dispatch_stub_582, NULL, _gloffset_PixelTexGenParameteriSGIS),
+ NAME_FUNC_OFFSET( 9425, gl_dispatch_stub_583, gl_dispatch_stub_583, NULL, _gloffset_PixelTexGenParameterivSGIS),
+ NAME_FUNC_OFFSET( 9454, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_SampleMaskSGIS),
+ NAME_FUNC_OFFSET( 9471, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_SamplePatternSGIS),
+ NAME_FUNC_OFFSET( 9491, glColorPointerEXT, glColorPointerEXT, NULL, _gloffset_ColorPointerEXT),
+ NAME_FUNC_OFFSET( 9509, glEdgeFlagPointerEXT, glEdgeFlagPointerEXT, NULL, _gloffset_EdgeFlagPointerEXT),
+ NAME_FUNC_OFFSET( 9530, glIndexPointerEXT, glIndexPointerEXT, NULL, _gloffset_IndexPointerEXT),
+ NAME_FUNC_OFFSET( 9548, glNormalPointerEXT, glNormalPointerEXT, NULL, _gloffset_NormalPointerEXT),
+ NAME_FUNC_OFFSET( 9567, glTexCoordPointerEXT, glTexCoordPointerEXT, NULL, _gloffset_TexCoordPointerEXT),
+ NAME_FUNC_OFFSET( 9588, glVertexPointerEXT, glVertexPointerEXT, NULL, _gloffset_VertexPointerEXT),
+ NAME_FUNC_OFFSET( 9607, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+ NAME_FUNC_OFFSET( 9628, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+ NAME_FUNC_OFFSET( 9650, glLockArraysEXT, glLockArraysEXT, NULL, _gloffset_LockArraysEXT),
+ NAME_FUNC_OFFSET( 9666, glUnlockArraysEXT, glUnlockArraysEXT, NULL, _gloffset_UnlockArraysEXT),
+ NAME_FUNC_OFFSET( 9684, gl_dispatch_stub_596, gl_dispatch_stub_596, NULL, _gloffset_CullParameterdvEXT),
+ NAME_FUNC_OFFSET( 9705, gl_dispatch_stub_597, gl_dispatch_stub_597, NULL, _gloffset_CullParameterfvEXT),
+ NAME_FUNC_OFFSET( 9726, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
+ NAME_FUNC_OFFSET( 9748, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
+ NAME_FUNC_OFFSET( 9771, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
+ NAME_FUNC_OFFSET( 9793, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
+ NAME_FUNC_OFFSET( 9816, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
+ NAME_FUNC_OFFSET( 9838, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
+ NAME_FUNC_OFFSET( 9861, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
+ NAME_FUNC_OFFSET( 9883, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
+ NAME_FUNC_OFFSET( 9906, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
+ NAME_FUNC_OFFSET( 9928, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
+ NAME_FUNC_OFFSET( 9951, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
+ NAME_FUNC_OFFSET( 9974, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
+ NAME_FUNC_OFFSET( 9998, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
+ NAME_FUNC_OFFSET(10021, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
+ NAME_FUNC_OFFSET(10045, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
+ NAME_FUNC_OFFSET(10068, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
+ NAME_FUNC_OFFSET(10092, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
+ NAME_FUNC_OFFSET(10119, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
+ NAME_FUNC_OFFSET(10140, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
+ NAME_FUNC_OFFSET(10163, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
+ NAME_FUNC_OFFSET(10184, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
+ NAME_FUNC_OFFSET(10199, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
+ NAME_FUNC_OFFSET(10215, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
+ NAME_FUNC_OFFSET(10230, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
+ NAME_FUNC_OFFSET(10246, gl_dispatch_stub_622, gl_dispatch_stub_622, NULL, _gloffset_PixelTexGenSGIX),
+ NAME_FUNC_OFFSET(10264, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+ NAME_FUNC_OFFSET(10287, glFlushVertexArrayRangeNV, glFlushVertexArrayRangeNV, NULL, _gloffset_FlushVertexArrayRangeNV),
+ NAME_FUNC_OFFSET(10313, glVertexArrayRangeNV, glVertexArrayRangeNV, NULL, _gloffset_VertexArrayRangeNV),
+ NAME_FUNC_OFFSET(10334, glCombinerInputNV, glCombinerInputNV, NULL, _gloffset_CombinerInputNV),
+ NAME_FUNC_OFFSET(10352, glCombinerOutputNV, glCombinerOutputNV, NULL, _gloffset_CombinerOutputNV),
+ NAME_FUNC_OFFSET(10371, glCombinerParameterfNV, glCombinerParameterfNV, NULL, _gloffset_CombinerParameterfNV),
+ NAME_FUNC_OFFSET(10394, glCombinerParameterfvNV, glCombinerParameterfvNV, NULL, _gloffset_CombinerParameterfvNV),
+ NAME_FUNC_OFFSET(10418, glCombinerParameteriNV, glCombinerParameteriNV, NULL, _gloffset_CombinerParameteriNV),
+ NAME_FUNC_OFFSET(10441, glCombinerParameterivNV, glCombinerParameterivNV, NULL, _gloffset_CombinerParameterivNV),
+ NAME_FUNC_OFFSET(10465, glFinalCombinerInputNV, glFinalCombinerInputNV, NULL, _gloffset_FinalCombinerInputNV),
+ NAME_FUNC_OFFSET(10488, glGetCombinerInputParameterfvNV, glGetCombinerInputParameterfvNV, NULL, _gloffset_GetCombinerInputParameterfvNV),
+ NAME_FUNC_OFFSET(10520, glGetCombinerInputParameterivNV, glGetCombinerInputParameterivNV, NULL, _gloffset_GetCombinerInputParameterivNV),
+ NAME_FUNC_OFFSET(10552, glGetCombinerOutputParameterfvNV, glGetCombinerOutputParameterfvNV, NULL, _gloffset_GetCombinerOutputParameterfvNV),
+ NAME_FUNC_OFFSET(10585, glGetCombinerOutputParameterivNV, glGetCombinerOutputParameterivNV, NULL, _gloffset_GetCombinerOutputParameterivNV),
+ NAME_FUNC_OFFSET(10618, glGetFinalCombinerInputParameterfvNV, glGetFinalCombinerInputParameterfvNV, NULL, _gloffset_GetFinalCombinerInputParameterfvNV),
+ NAME_FUNC_OFFSET(10655, glGetFinalCombinerInputParameterivNV, glGetFinalCombinerInputParameterivNV, NULL, _gloffset_GetFinalCombinerInputParameterivNV),
+ NAME_FUNC_OFFSET(10692, glResizeBuffersMESA, glResizeBuffersMESA, NULL, _gloffset_ResizeBuffersMESA),
+ NAME_FUNC_OFFSET(10712, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+ NAME_FUNC_OFFSET(10730, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+ NAME_FUNC_OFFSET(10749, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+ NAME_FUNC_OFFSET(10767, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+ NAME_FUNC_OFFSET(10786, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+ NAME_FUNC_OFFSET(10804, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+ NAME_FUNC_OFFSET(10823, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+ NAME_FUNC_OFFSET(10841, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+ NAME_FUNC_OFFSET(10860, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+ NAME_FUNC_OFFSET(10878, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+ NAME_FUNC_OFFSET(10897, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+ NAME_FUNC_OFFSET(10915, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+ NAME_FUNC_OFFSET(10934, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+ NAME_FUNC_OFFSET(10952, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+ NAME_FUNC_OFFSET(10971, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+ NAME_FUNC_OFFSET(10989, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+ NAME_FUNC_OFFSET(11008, glWindowPos4dMESA, glWindowPos4dMESA, NULL, _gloffset_WindowPos4dMESA),
+ NAME_FUNC_OFFSET(11026, glWindowPos4dvMESA, glWindowPos4dvMESA, NULL, _gloffset_WindowPos4dvMESA),
+ NAME_FUNC_OFFSET(11045, glWindowPos4fMESA, glWindowPos4fMESA, NULL, _gloffset_WindowPos4fMESA),
+ NAME_FUNC_OFFSET(11063, glWindowPos4fvMESA, glWindowPos4fvMESA, NULL, _gloffset_WindowPos4fvMESA),
+ NAME_FUNC_OFFSET(11082, glWindowPos4iMESA, glWindowPos4iMESA, NULL, _gloffset_WindowPos4iMESA),
+ NAME_FUNC_OFFSET(11100, glWindowPos4ivMESA, glWindowPos4ivMESA, NULL, _gloffset_WindowPos4ivMESA),
+ NAME_FUNC_OFFSET(11119, glWindowPos4sMESA, glWindowPos4sMESA, NULL, _gloffset_WindowPos4sMESA),
+ NAME_FUNC_OFFSET(11137, glWindowPos4svMESA, glWindowPos4svMESA, NULL, _gloffset_WindowPos4svMESA),
+ NAME_FUNC_OFFSET(11156, gl_dispatch_stub_664, gl_dispatch_stub_664, NULL, _gloffset_MultiModeDrawArraysIBM),
+ NAME_FUNC_OFFSET(11181, gl_dispatch_stub_665, gl_dispatch_stub_665, NULL, _gloffset_MultiModeDrawElementsIBM),
+ NAME_FUNC_OFFSET(11208, gl_dispatch_stub_666, gl_dispatch_stub_666, NULL, _gloffset_DeleteFencesNV),
+ NAME_FUNC_OFFSET(11225, gl_dispatch_stub_667, gl_dispatch_stub_667, NULL, _gloffset_FinishFenceNV),
+ NAME_FUNC_OFFSET(11241, gl_dispatch_stub_668, gl_dispatch_stub_668, NULL, _gloffset_GenFencesNV),
+ NAME_FUNC_OFFSET(11255, gl_dispatch_stub_669, gl_dispatch_stub_669, NULL, _gloffset_GetFenceivNV),
+ NAME_FUNC_OFFSET(11270, gl_dispatch_stub_670, gl_dispatch_stub_670, NULL, _gloffset_IsFenceNV),
+ NAME_FUNC_OFFSET(11282, gl_dispatch_stub_671, gl_dispatch_stub_671, NULL, _gloffset_SetFenceNV),
+ NAME_FUNC_OFFSET(11295, gl_dispatch_stub_672, gl_dispatch_stub_672, NULL, _gloffset_TestFenceNV),
+ NAME_FUNC_OFFSET(11309, glAreProgramsResidentNV, glAreProgramsResidentNV, NULL, _gloffset_AreProgramsResidentNV),
+ NAME_FUNC_OFFSET(11333, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
+ NAME_FUNC_OFFSET(11349, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
+ NAME_FUNC_OFFSET(11368, glExecuteProgramNV, glExecuteProgramNV, NULL, _gloffset_ExecuteProgramNV),
+ NAME_FUNC_OFFSET(11387, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
+ NAME_FUNC_OFFSET(11403, glGetProgramParameterdvNV, glGetProgramParameterdvNV, NULL, _gloffset_GetProgramParameterdvNV),
+ NAME_FUNC_OFFSET(11429, glGetProgramParameterfvNV, glGetProgramParameterfvNV, NULL, _gloffset_GetProgramParameterfvNV),
+ NAME_FUNC_OFFSET(11455, glGetProgramStringNV, glGetProgramStringNV, NULL, _gloffset_GetProgramStringNV),
+ NAME_FUNC_OFFSET(11476, glGetProgramivNV, glGetProgramivNV, NULL, _gloffset_GetProgramivNV),
+ NAME_FUNC_OFFSET(11493, glGetTrackMatrixivNV, glGetTrackMatrixivNV, NULL, _gloffset_GetTrackMatrixivNV),
+ NAME_FUNC_OFFSET(11514, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+ NAME_FUNC_OFFSET(11542, glGetVertexAttribdvNV, glGetVertexAttribdvNV, NULL, _gloffset_GetVertexAttribdvNV),
+ NAME_FUNC_OFFSET(11564, glGetVertexAttribfvNV, glGetVertexAttribfvNV, NULL, _gloffset_GetVertexAttribfvNV),
+ NAME_FUNC_OFFSET(11586, glGetVertexAttribivNV, glGetVertexAttribivNV, NULL, _gloffset_GetVertexAttribivNV),
+ NAME_FUNC_OFFSET(11608, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
+ NAME_FUNC_OFFSET(11622, glLoadProgramNV, glLoadProgramNV, NULL, _gloffset_LoadProgramNV),
+ NAME_FUNC_OFFSET(11638, glProgramParameters4dvNV, glProgramParameters4dvNV, NULL, _gloffset_ProgramParameters4dvNV),
+ NAME_FUNC_OFFSET(11663, glProgramParameters4fvNV, glProgramParameters4fvNV, NULL, _gloffset_ProgramParameters4fvNV),
+ NAME_FUNC_OFFSET(11688, glRequestResidentProgramsNV, glRequestResidentProgramsNV, NULL, _gloffset_RequestResidentProgramsNV),
+ NAME_FUNC_OFFSET(11716, glTrackMatrixNV, glTrackMatrixNV, NULL, _gloffset_TrackMatrixNV),
+ NAME_FUNC_OFFSET(11732, glVertexAttrib1dNV, glVertexAttrib1dNV, NULL, _gloffset_VertexAttrib1dNV),
+ NAME_FUNC_OFFSET(11751, glVertexAttrib1dvNV, glVertexAttrib1dvNV, NULL, _gloffset_VertexAttrib1dvNV),
+ NAME_FUNC_OFFSET(11771, glVertexAttrib1fNV, glVertexAttrib1fNV, NULL, _gloffset_VertexAttrib1fNV),
+ NAME_FUNC_OFFSET(11790, glVertexAttrib1fvNV, glVertexAttrib1fvNV, NULL, _gloffset_VertexAttrib1fvNV),
+ NAME_FUNC_OFFSET(11810, glVertexAttrib1sNV, glVertexAttrib1sNV, NULL, _gloffset_VertexAttrib1sNV),
+ NAME_FUNC_OFFSET(11829, glVertexAttrib1svNV, glVertexAttrib1svNV, NULL, _gloffset_VertexAttrib1svNV),
+ NAME_FUNC_OFFSET(11849, glVertexAttrib2dNV, glVertexAttrib2dNV, NULL, _gloffset_VertexAttrib2dNV),
+ NAME_FUNC_OFFSET(11868, glVertexAttrib2dvNV, glVertexAttrib2dvNV, NULL, _gloffset_VertexAttrib2dvNV),
+ NAME_FUNC_OFFSET(11888, glVertexAttrib2fNV, glVertexAttrib2fNV, NULL, _gloffset_VertexAttrib2fNV),
+ NAME_FUNC_OFFSET(11907, glVertexAttrib2fvNV, glVertexAttrib2fvNV, NULL, _gloffset_VertexAttrib2fvNV),
+ NAME_FUNC_OFFSET(11927, glVertexAttrib2sNV, glVertexAttrib2sNV, NULL, _gloffset_VertexAttrib2sNV),
+ NAME_FUNC_OFFSET(11946, glVertexAttrib2svNV, glVertexAttrib2svNV, NULL, _gloffset_VertexAttrib2svNV),
+ NAME_FUNC_OFFSET(11966, glVertexAttrib3dNV, glVertexAttrib3dNV, NULL, _gloffset_VertexAttrib3dNV),
+ NAME_FUNC_OFFSET(11985, glVertexAttrib3dvNV, glVertexAttrib3dvNV, NULL, _gloffset_VertexAttrib3dvNV),
+ NAME_FUNC_OFFSET(12005, glVertexAttrib3fNV, glVertexAttrib3fNV, NULL, _gloffset_VertexAttrib3fNV),
+ NAME_FUNC_OFFSET(12024, glVertexAttrib3fvNV, glVertexAttrib3fvNV, NULL, _gloffset_VertexAttrib3fvNV),
+ NAME_FUNC_OFFSET(12044, glVertexAttrib3sNV, glVertexAttrib3sNV, NULL, _gloffset_VertexAttrib3sNV),
+ NAME_FUNC_OFFSET(12063, glVertexAttrib3svNV, glVertexAttrib3svNV, NULL, _gloffset_VertexAttrib3svNV),
+ NAME_FUNC_OFFSET(12083, glVertexAttrib4dNV, glVertexAttrib4dNV, NULL, _gloffset_VertexAttrib4dNV),
+ NAME_FUNC_OFFSET(12102, glVertexAttrib4dvNV, glVertexAttrib4dvNV, NULL, _gloffset_VertexAttrib4dvNV),
+ NAME_FUNC_OFFSET(12122, glVertexAttrib4fNV, glVertexAttrib4fNV, NULL, _gloffset_VertexAttrib4fNV),
+ NAME_FUNC_OFFSET(12141, glVertexAttrib4fvNV, glVertexAttrib4fvNV, NULL, _gloffset_VertexAttrib4fvNV),
+ NAME_FUNC_OFFSET(12161, glVertexAttrib4sNV, glVertexAttrib4sNV, NULL, _gloffset_VertexAttrib4sNV),
+ NAME_FUNC_OFFSET(12180, glVertexAttrib4svNV, glVertexAttrib4svNV, NULL, _gloffset_VertexAttrib4svNV),
+ NAME_FUNC_OFFSET(12200, glVertexAttrib4ubNV, glVertexAttrib4ubNV, NULL, _gloffset_VertexAttrib4ubNV),
+ NAME_FUNC_OFFSET(12220, glVertexAttrib4ubvNV, glVertexAttrib4ubvNV, NULL, _gloffset_VertexAttrib4ubvNV),
+ NAME_FUNC_OFFSET(12241, glVertexAttribPointerNV, glVertexAttribPointerNV, NULL, _gloffset_VertexAttribPointerNV),
+ NAME_FUNC_OFFSET(12265, glVertexAttribs1dvNV, glVertexAttribs1dvNV, NULL, _gloffset_VertexAttribs1dvNV),
+ NAME_FUNC_OFFSET(12286, glVertexAttribs1fvNV, glVertexAttribs1fvNV, NULL, _gloffset_VertexAttribs1fvNV),
+ NAME_FUNC_OFFSET(12307, glVertexAttribs1svNV, glVertexAttribs1svNV, NULL, _gloffset_VertexAttribs1svNV),
+ NAME_FUNC_OFFSET(12328, glVertexAttribs2dvNV, glVertexAttribs2dvNV, NULL, _gloffset_VertexAttribs2dvNV),
+ NAME_FUNC_OFFSET(12349, glVertexAttribs2fvNV, glVertexAttribs2fvNV, NULL, _gloffset_VertexAttribs2fvNV),
+ NAME_FUNC_OFFSET(12370, glVertexAttribs2svNV, glVertexAttribs2svNV, NULL, _gloffset_VertexAttribs2svNV),
+ NAME_FUNC_OFFSET(12391, glVertexAttribs3dvNV, glVertexAttribs3dvNV, NULL, _gloffset_VertexAttribs3dvNV),
+ NAME_FUNC_OFFSET(12412, glVertexAttribs3fvNV, glVertexAttribs3fvNV, NULL, _gloffset_VertexAttribs3fvNV),
+ NAME_FUNC_OFFSET(12433, glVertexAttribs3svNV, glVertexAttribs3svNV, NULL, _gloffset_VertexAttribs3svNV),
+ NAME_FUNC_OFFSET(12454, glVertexAttribs4dvNV, glVertexAttribs4dvNV, NULL, _gloffset_VertexAttribs4dvNV),
+ NAME_FUNC_OFFSET(12475, glVertexAttribs4fvNV, glVertexAttribs4fvNV, NULL, _gloffset_VertexAttribs4fvNV),
+ NAME_FUNC_OFFSET(12496, glVertexAttribs4svNV, glVertexAttribs4svNV, NULL, _gloffset_VertexAttribs4svNV),
+ NAME_FUNC_OFFSET(12517, glVertexAttribs4ubvNV, glVertexAttribs4ubvNV, NULL, _gloffset_VertexAttribs4ubvNV),
+ NAME_FUNC_OFFSET(12539, glGetTexBumpParameterfvATI, glGetTexBumpParameterfvATI, NULL, _gloffset_GetTexBumpParameterfvATI),
+ NAME_FUNC_OFFSET(12566, glGetTexBumpParameterivATI, glGetTexBumpParameterivATI, NULL, _gloffset_GetTexBumpParameterivATI),
+ NAME_FUNC_OFFSET(12593, glTexBumpParameterfvATI, glTexBumpParameterfvATI, NULL, _gloffset_TexBumpParameterfvATI),
+ NAME_FUNC_OFFSET(12617, glTexBumpParameterivATI, glTexBumpParameterivATI, NULL, _gloffset_TexBumpParameterivATI),
+ NAME_FUNC_OFFSET(12641, glAlphaFragmentOp1ATI, glAlphaFragmentOp1ATI, NULL, _gloffset_AlphaFragmentOp1ATI),
+ NAME_FUNC_OFFSET(12663, glAlphaFragmentOp2ATI, glAlphaFragmentOp2ATI, NULL, _gloffset_AlphaFragmentOp2ATI),
+ NAME_FUNC_OFFSET(12685, glAlphaFragmentOp3ATI, glAlphaFragmentOp3ATI, NULL, _gloffset_AlphaFragmentOp3ATI),
+ NAME_FUNC_OFFSET(12707, glBeginFragmentShaderATI, glBeginFragmentShaderATI, NULL, _gloffset_BeginFragmentShaderATI),
+ NAME_FUNC_OFFSET(12732, glBindFragmentShaderATI, glBindFragmentShaderATI, NULL, _gloffset_BindFragmentShaderATI),
+ NAME_FUNC_OFFSET(12756, glColorFragmentOp1ATI, glColorFragmentOp1ATI, NULL, _gloffset_ColorFragmentOp1ATI),
+ NAME_FUNC_OFFSET(12778, glColorFragmentOp2ATI, glColorFragmentOp2ATI, NULL, _gloffset_ColorFragmentOp2ATI),
+ NAME_FUNC_OFFSET(12800, glColorFragmentOp3ATI, glColorFragmentOp3ATI, NULL, _gloffset_ColorFragmentOp3ATI),
+ NAME_FUNC_OFFSET(12822, glDeleteFragmentShaderATI, glDeleteFragmentShaderATI, NULL, _gloffset_DeleteFragmentShaderATI),
+ NAME_FUNC_OFFSET(12848, glEndFragmentShaderATI, glEndFragmentShaderATI, NULL, _gloffset_EndFragmentShaderATI),
+ NAME_FUNC_OFFSET(12871, glGenFragmentShadersATI, glGenFragmentShadersATI, NULL, _gloffset_GenFragmentShadersATI),
+ NAME_FUNC_OFFSET(12895, glPassTexCoordATI, glPassTexCoordATI, NULL, _gloffset_PassTexCoordATI),
+ NAME_FUNC_OFFSET(12913, glSampleMapATI, glSampleMapATI, NULL, _gloffset_SampleMapATI),
+ NAME_FUNC_OFFSET(12928, glSetFragmentShaderConstantATI, glSetFragmentShaderConstantATI, NULL, _gloffset_SetFragmentShaderConstantATI),
+ NAME_FUNC_OFFSET(12959, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
+ NAME_FUNC_OFFSET(12979, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
+ NAME_FUNC_OFFSET(13000, gl_dispatch_stub_753, gl_dispatch_stub_753, NULL, _gloffset_ActiveStencilFaceEXT),
+ NAME_FUNC_OFFSET(13023, gl_dispatch_stub_754, gl_dispatch_stub_754, NULL, _gloffset_BindVertexArrayAPPLE),
+ NAME_FUNC_OFFSET(13046, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_DeleteVertexArraysAPPLE),
+ NAME_FUNC_OFFSET(13072, gl_dispatch_stub_756, gl_dispatch_stub_756, NULL, _gloffset_GenVertexArraysAPPLE),
+ NAME_FUNC_OFFSET(13095, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_IsVertexArrayAPPLE),
+ NAME_FUNC_OFFSET(13116, glGetProgramNamedParameterdvNV, glGetProgramNamedParameterdvNV, NULL, _gloffset_GetProgramNamedParameterdvNV),
+ NAME_FUNC_OFFSET(13147, glGetProgramNamedParameterfvNV, glGetProgramNamedParameterfvNV, NULL, _gloffset_GetProgramNamedParameterfvNV),
+ NAME_FUNC_OFFSET(13178, glProgramNamedParameter4dNV, glProgramNamedParameter4dNV, NULL, _gloffset_ProgramNamedParameter4dNV),
+ NAME_FUNC_OFFSET(13206, glProgramNamedParameter4dvNV, glProgramNamedParameter4dvNV, NULL, _gloffset_ProgramNamedParameter4dvNV),
+ NAME_FUNC_OFFSET(13235, glProgramNamedParameter4fNV, glProgramNamedParameter4fNV, NULL, _gloffset_ProgramNamedParameter4fNV),
+ NAME_FUNC_OFFSET(13263, glProgramNamedParameter4fvNV, glProgramNamedParameter4fvNV, NULL, _gloffset_ProgramNamedParameter4fvNV),
+ NAME_FUNC_OFFSET(13292, gl_dispatch_stub_764, gl_dispatch_stub_764, NULL, _gloffset_DepthBoundsEXT),
+ NAME_FUNC_OFFSET(13309, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
+ NAME_FUNC_OFFSET(13336, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
+ NAME_FUNC_OFFSET(13357, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
+ NAME_FUNC_OFFSET(13379, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
+ NAME_FUNC_OFFSET(13407, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
+ NAME_FUNC_OFFSET(13431, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
+ NAME_FUNC_OFFSET(13456, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
+ NAME_FUNC_OFFSET(13485, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
+ NAME_FUNC_OFFSET(13511, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
+ NAME_FUNC_OFFSET(13537, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
+ NAME_FUNC_OFFSET(13563, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
+ NAME_FUNC_OFFSET(13584, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
+ NAME_FUNC_OFFSET(13606, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
+ NAME_FUNC_OFFSET(13626, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
+ NAME_FUNC_OFFSET(13667, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
+ NAME_FUNC_OFFSET(13699, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
+ NAME_FUNC_OFFSET(13718, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
+ NAME_FUNC_OFFSET(13738, glRenderbufferStorageEXT, glRenderbufferStorageEXT, NULL, _gloffset_RenderbufferStorageEXT),
+ NAME_FUNC_OFFSET(13763, gl_dispatch_stub_783, gl_dispatch_stub_783, NULL, _gloffset_BlitFramebufferEXT),
+ NAME_FUNC_OFFSET(13784, gl_dispatch_stub_784, gl_dispatch_stub_784, NULL, _gloffset_BufferParameteriAPPLE),
+ NAME_FUNC_OFFSET(13808, gl_dispatch_stub_785, gl_dispatch_stub_785, NULL, _gloffset_FlushMappedBufferRangeAPPLE),
+ NAME_FUNC_OFFSET(13838, glFramebufferTextureLayerEXT, glFramebufferTextureLayerEXT, NULL, _gloffset_FramebufferTextureLayerEXT),
+ NAME_FUNC_OFFSET(13867, glProvokingVertexEXT, glProvokingVertexEXT, NULL, _gloffset_ProvokingVertexEXT),
+ NAME_FUNC_OFFSET(13888, gl_dispatch_stub_788, gl_dispatch_stub_788, NULL, _gloffset_GetTexParameterPointervAPPLE),
+ NAME_FUNC_OFFSET(13919, gl_dispatch_stub_789, gl_dispatch_stub_789, NULL, _gloffset_TextureRangeAPPLE),
+ NAME_FUNC_OFFSET(13939, gl_dispatch_stub_790, gl_dispatch_stub_790, NULL, _gloffset_StencilFuncSeparateATI),
+ NAME_FUNC_OFFSET(13964, gl_dispatch_stub_791, gl_dispatch_stub_791, NULL, _gloffset_ProgramEnvParameters4fvEXT),
+ NAME_FUNC_OFFSET(13993, gl_dispatch_stub_792, gl_dispatch_stub_792, NULL, _gloffset_ProgramLocalParameters4fvEXT),
+ NAME_FUNC_OFFSET(14024, gl_dispatch_stub_793, gl_dispatch_stub_793, NULL, _gloffset_GetQueryObjecti64vEXT),
+ NAME_FUNC_OFFSET(14048, gl_dispatch_stub_794, gl_dispatch_stub_794, NULL, _gloffset_GetQueryObjectui64vEXT),
+ NAME_FUNC_OFFSET(14073, glArrayElement, glArrayElement, NULL, _gloffset_ArrayElement),
+ NAME_FUNC_OFFSET(14091, glBindTexture, glBindTexture, NULL, _gloffset_BindTexture),
+ NAME_FUNC_OFFSET(14108, glDrawArrays, glDrawArrays, NULL, _gloffset_DrawArrays),
+ NAME_FUNC_OFFSET(14124, glAreTexturesResident, glAreTexturesResidentEXT, glAreTexturesResidentEXT, _gloffset_AreTexturesResident),
+ NAME_FUNC_OFFSET(14149, glCopyTexImage1D, glCopyTexImage1D, NULL, _gloffset_CopyTexImage1D),
+ NAME_FUNC_OFFSET(14169, glCopyTexImage2D, glCopyTexImage2D, NULL, _gloffset_CopyTexImage2D),
+ NAME_FUNC_OFFSET(14189, glCopyTexSubImage1D, glCopyTexSubImage1D, NULL, _gloffset_CopyTexSubImage1D),
+ NAME_FUNC_OFFSET(14212, glCopyTexSubImage2D, glCopyTexSubImage2D, NULL, _gloffset_CopyTexSubImage2D),
+ NAME_FUNC_OFFSET(14235, glDeleteTextures, glDeleteTexturesEXT, glDeleteTexturesEXT, _gloffset_DeleteTextures),
+ NAME_FUNC_OFFSET(14255, glGenTextures, glGenTexturesEXT, glGenTexturesEXT, _gloffset_GenTextures),
+ NAME_FUNC_OFFSET(14272, glGetPointerv, glGetPointerv, NULL, _gloffset_GetPointerv),
+ NAME_FUNC_OFFSET(14289, glIsTexture, glIsTextureEXT, glIsTextureEXT, _gloffset_IsTexture),
+ NAME_FUNC_OFFSET(14304, glPrioritizeTextures, glPrioritizeTextures, NULL, _gloffset_PrioritizeTextures),
+ NAME_FUNC_OFFSET(14328, glTexSubImage1D, glTexSubImage1D, NULL, _gloffset_TexSubImage1D),
+ NAME_FUNC_OFFSET(14347, glTexSubImage2D, glTexSubImage2D, NULL, _gloffset_TexSubImage2D),
+ NAME_FUNC_OFFSET(14366, glBlendColor, glBlendColor, NULL, _gloffset_BlendColor),
+ NAME_FUNC_OFFSET(14382, glBlendEquation, glBlendEquation, NULL, _gloffset_BlendEquation),
+ NAME_FUNC_OFFSET(14401, glDrawRangeElements, glDrawRangeElements, NULL, _gloffset_DrawRangeElements),
+ NAME_FUNC_OFFSET(14424, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+ NAME_FUNC_OFFSET(14440, glColorTable, glColorTable, NULL, _gloffset_ColorTable),
+ NAME_FUNC_OFFSET(14456, glColorTableParameterfv, glColorTableParameterfv, NULL, _gloffset_ColorTableParameterfv),
+ NAME_FUNC_OFFSET(14483, glColorTableParameteriv, glColorTableParameteriv, NULL, _gloffset_ColorTableParameteriv),
+ NAME_FUNC_OFFSET(14510, glCopyColorTable, glCopyColorTable, NULL, _gloffset_CopyColorTable),
+ NAME_FUNC_OFFSET(14530, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+ NAME_FUNC_OFFSET(14549, glGetColorTable, glGetColorTableEXT, glGetColorTableEXT, _gloffset_GetColorTable),
+ NAME_FUNC_OFFSET(14568, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+ NAME_FUNC_OFFSET(14598, glGetColorTableParameterfv, glGetColorTableParameterfvEXT, glGetColorTableParameterfvEXT, _gloffset_GetColorTableParameterfv),
+ NAME_FUNC_OFFSET(14628, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+ NAME_FUNC_OFFSET(14658, glGetColorTableParameteriv, glGetColorTableParameterivEXT, glGetColorTableParameterivEXT, _gloffset_GetColorTableParameteriv),
+ NAME_FUNC_OFFSET(14688, glColorSubTable, glColorSubTable, NULL, _gloffset_ColorSubTable),
+ NAME_FUNC_OFFSET(14707, glCopyColorSubTable, glCopyColorSubTable, NULL, _gloffset_CopyColorSubTable),
+ NAME_FUNC_OFFSET(14730, glConvolutionFilter1D, glConvolutionFilter1D, NULL, _gloffset_ConvolutionFilter1D),
+ NAME_FUNC_OFFSET(14755, glConvolutionFilter2D, glConvolutionFilter2D, NULL, _gloffset_ConvolutionFilter2D),
+ NAME_FUNC_OFFSET(14780, glConvolutionParameterf, glConvolutionParameterf, NULL, _gloffset_ConvolutionParameterf),
+ NAME_FUNC_OFFSET(14807, glConvolutionParameterfv, glConvolutionParameterfv, NULL, _gloffset_ConvolutionParameterfv),
+ NAME_FUNC_OFFSET(14835, glConvolutionParameteri, glConvolutionParameteri, NULL, _gloffset_ConvolutionParameteri),
+ NAME_FUNC_OFFSET(14862, glConvolutionParameteriv, glConvolutionParameteriv, NULL, _gloffset_ConvolutionParameteriv),
+ NAME_FUNC_OFFSET(14890, glCopyConvolutionFilter1D, glCopyConvolutionFilter1D, NULL, _gloffset_CopyConvolutionFilter1D),
+ NAME_FUNC_OFFSET(14919, glCopyConvolutionFilter2D, glCopyConvolutionFilter2D, NULL, _gloffset_CopyConvolutionFilter2D),
+ NAME_FUNC_OFFSET(14948, glGetConvolutionFilter, gl_dispatch_stub_356, gl_dispatch_stub_356, _gloffset_GetConvolutionFilter),
+ NAME_FUNC_OFFSET(14974, glGetConvolutionParameterfv, gl_dispatch_stub_357, gl_dispatch_stub_357, _gloffset_GetConvolutionParameterfv),
+ NAME_FUNC_OFFSET(15005, glGetConvolutionParameteriv, gl_dispatch_stub_358, gl_dispatch_stub_358, _gloffset_GetConvolutionParameteriv),
+ NAME_FUNC_OFFSET(15036, glGetSeparableFilter, gl_dispatch_stub_359, gl_dispatch_stub_359, _gloffset_GetSeparableFilter),
+ NAME_FUNC_OFFSET(15060, glSeparableFilter2D, glSeparableFilter2D, NULL, _gloffset_SeparableFilter2D),
+ NAME_FUNC_OFFSET(15083, glGetHistogram, gl_dispatch_stub_361, gl_dispatch_stub_361, _gloffset_GetHistogram),
+ NAME_FUNC_OFFSET(15101, glGetHistogramParameterfv, gl_dispatch_stub_362, gl_dispatch_stub_362, _gloffset_GetHistogramParameterfv),
+ NAME_FUNC_OFFSET(15130, glGetHistogramParameteriv, gl_dispatch_stub_363, gl_dispatch_stub_363, _gloffset_GetHistogramParameteriv),
+ NAME_FUNC_OFFSET(15159, glGetMinmax, gl_dispatch_stub_364, gl_dispatch_stub_364, _gloffset_GetMinmax),
+ NAME_FUNC_OFFSET(15174, glGetMinmaxParameterfv, gl_dispatch_stub_365, gl_dispatch_stub_365, _gloffset_GetMinmaxParameterfv),
+ NAME_FUNC_OFFSET(15200, glGetMinmaxParameteriv, gl_dispatch_stub_366, gl_dispatch_stub_366, _gloffset_GetMinmaxParameteriv),
+ NAME_FUNC_OFFSET(15226, glHistogram, glHistogram, NULL, _gloffset_Histogram),
+ NAME_FUNC_OFFSET(15241, glMinmax, glMinmax, NULL, _gloffset_Minmax),
+ NAME_FUNC_OFFSET(15253, glResetHistogram, glResetHistogram, NULL, _gloffset_ResetHistogram),
+ NAME_FUNC_OFFSET(15273, glResetMinmax, glResetMinmax, NULL, _gloffset_ResetMinmax),
+ NAME_FUNC_OFFSET(15290, glTexImage3D, glTexImage3D, NULL, _gloffset_TexImage3D),
+ NAME_FUNC_OFFSET(15306, glTexSubImage3D, glTexSubImage3D, NULL, _gloffset_TexSubImage3D),
+ NAME_FUNC_OFFSET(15325, glCopyTexSubImage3D, glCopyTexSubImage3D, NULL, _gloffset_CopyTexSubImage3D),
+ NAME_FUNC_OFFSET(15348, glActiveTextureARB, glActiveTextureARB, NULL, _gloffset_ActiveTextureARB),
+ NAME_FUNC_OFFSET(15364, glClientActiveTextureARB, glClientActiveTextureARB, NULL, _gloffset_ClientActiveTextureARB),
+ NAME_FUNC_OFFSET(15386, glMultiTexCoord1dARB, glMultiTexCoord1dARB, NULL, _gloffset_MultiTexCoord1dARB),
+ NAME_FUNC_OFFSET(15404, glMultiTexCoord1dvARB, glMultiTexCoord1dvARB, NULL, _gloffset_MultiTexCoord1dvARB),
+ NAME_FUNC_OFFSET(15423, glMultiTexCoord1fARB, glMultiTexCoord1fARB, NULL, _gloffset_MultiTexCoord1fARB),
+ NAME_FUNC_OFFSET(15441, glMultiTexCoord1fvARB, glMultiTexCoord1fvARB, NULL, _gloffset_MultiTexCoord1fvARB),
+ NAME_FUNC_OFFSET(15460, glMultiTexCoord1iARB, glMultiTexCoord1iARB, NULL, _gloffset_MultiTexCoord1iARB),
+ NAME_FUNC_OFFSET(15478, glMultiTexCoord1ivARB, glMultiTexCoord1ivARB, NULL, _gloffset_MultiTexCoord1ivARB),
+ NAME_FUNC_OFFSET(15497, glMultiTexCoord1sARB, glMultiTexCoord1sARB, NULL, _gloffset_MultiTexCoord1sARB),
+ NAME_FUNC_OFFSET(15515, glMultiTexCoord1svARB, glMultiTexCoord1svARB, NULL, _gloffset_MultiTexCoord1svARB),
+ NAME_FUNC_OFFSET(15534, glMultiTexCoord2dARB, glMultiTexCoord2dARB, NULL, _gloffset_MultiTexCoord2dARB),
+ NAME_FUNC_OFFSET(15552, glMultiTexCoord2dvARB, glMultiTexCoord2dvARB, NULL, _gloffset_MultiTexCoord2dvARB),
+ NAME_FUNC_OFFSET(15571, glMultiTexCoord2fARB, glMultiTexCoord2fARB, NULL, _gloffset_MultiTexCoord2fARB),
+ NAME_FUNC_OFFSET(15589, glMultiTexCoord2fvARB, glMultiTexCoord2fvARB, NULL, _gloffset_MultiTexCoord2fvARB),
+ NAME_FUNC_OFFSET(15608, glMultiTexCoord2iARB, glMultiTexCoord2iARB, NULL, _gloffset_MultiTexCoord2iARB),
+ NAME_FUNC_OFFSET(15626, glMultiTexCoord2ivARB, glMultiTexCoord2ivARB, NULL, _gloffset_MultiTexCoord2ivARB),
+ NAME_FUNC_OFFSET(15645, glMultiTexCoord2sARB, glMultiTexCoord2sARB, NULL, _gloffset_MultiTexCoord2sARB),
+ NAME_FUNC_OFFSET(15663, glMultiTexCoord2svARB, glMultiTexCoord2svARB, NULL, _gloffset_MultiTexCoord2svARB),
+ NAME_FUNC_OFFSET(15682, glMultiTexCoord3dARB, glMultiTexCoord3dARB, NULL, _gloffset_MultiTexCoord3dARB),
+ NAME_FUNC_OFFSET(15700, glMultiTexCoord3dvARB, glMultiTexCoord3dvARB, NULL, _gloffset_MultiTexCoord3dvARB),
+ NAME_FUNC_OFFSET(15719, glMultiTexCoord3fARB, glMultiTexCoord3fARB, NULL, _gloffset_MultiTexCoord3fARB),
+ NAME_FUNC_OFFSET(15737, glMultiTexCoord3fvARB, glMultiTexCoord3fvARB, NULL, _gloffset_MultiTexCoord3fvARB),
+ NAME_FUNC_OFFSET(15756, glMultiTexCoord3iARB, glMultiTexCoord3iARB, NULL, _gloffset_MultiTexCoord3iARB),
+ NAME_FUNC_OFFSET(15774, glMultiTexCoord3ivARB, glMultiTexCoord3ivARB, NULL, _gloffset_MultiTexCoord3ivARB),
+ NAME_FUNC_OFFSET(15793, glMultiTexCoord3sARB, glMultiTexCoord3sARB, NULL, _gloffset_MultiTexCoord3sARB),
+ NAME_FUNC_OFFSET(15811, glMultiTexCoord3svARB, glMultiTexCoord3svARB, NULL, _gloffset_MultiTexCoord3svARB),
+ NAME_FUNC_OFFSET(15830, glMultiTexCoord4dARB, glMultiTexCoord4dARB, NULL, _gloffset_MultiTexCoord4dARB),
+ NAME_FUNC_OFFSET(15848, glMultiTexCoord4dvARB, glMultiTexCoord4dvARB, NULL, _gloffset_MultiTexCoord4dvARB),
+ NAME_FUNC_OFFSET(15867, glMultiTexCoord4fARB, glMultiTexCoord4fARB, NULL, _gloffset_MultiTexCoord4fARB),
+ NAME_FUNC_OFFSET(15885, glMultiTexCoord4fvARB, glMultiTexCoord4fvARB, NULL, _gloffset_MultiTexCoord4fvARB),
+ NAME_FUNC_OFFSET(15904, glMultiTexCoord4iARB, glMultiTexCoord4iARB, NULL, _gloffset_MultiTexCoord4iARB),
+ NAME_FUNC_OFFSET(15922, glMultiTexCoord4ivARB, glMultiTexCoord4ivARB, NULL, _gloffset_MultiTexCoord4ivARB),
+ NAME_FUNC_OFFSET(15941, glMultiTexCoord4sARB, glMultiTexCoord4sARB, NULL, _gloffset_MultiTexCoord4sARB),
+ NAME_FUNC_OFFSET(15959, glMultiTexCoord4svARB, glMultiTexCoord4svARB, NULL, _gloffset_MultiTexCoord4svARB),
+ NAME_FUNC_OFFSET(15978, glStencilOpSeparate, glStencilOpSeparate, NULL, _gloffset_StencilOpSeparate),
+ NAME_FUNC_OFFSET(16001, glLoadTransposeMatrixdARB, glLoadTransposeMatrixdARB, NULL, _gloffset_LoadTransposeMatrixdARB),
+ NAME_FUNC_OFFSET(16024, glLoadTransposeMatrixfARB, glLoadTransposeMatrixfARB, NULL, _gloffset_LoadTransposeMatrixfARB),
+ NAME_FUNC_OFFSET(16047, glMultTransposeMatrixdARB, glMultTransposeMatrixdARB, NULL, _gloffset_MultTransposeMatrixdARB),
+ NAME_FUNC_OFFSET(16070, glMultTransposeMatrixfARB, glMultTransposeMatrixfARB, NULL, _gloffset_MultTransposeMatrixfARB),
+ NAME_FUNC_OFFSET(16093, glSampleCoverageARB, glSampleCoverageARB, NULL, _gloffset_SampleCoverageARB),
+ NAME_FUNC_OFFSET(16110, glCompressedTexImage1DARB, glCompressedTexImage1DARB, NULL, _gloffset_CompressedTexImage1DARB),
+ NAME_FUNC_OFFSET(16133, glCompressedTexImage2DARB, glCompressedTexImage2DARB, NULL, _gloffset_CompressedTexImage2DARB),
+ NAME_FUNC_OFFSET(16156, glCompressedTexImage3DARB, glCompressedTexImage3DARB, NULL, _gloffset_CompressedTexImage3DARB),
+ NAME_FUNC_OFFSET(16179, glCompressedTexSubImage1DARB, glCompressedTexSubImage1DARB, NULL, _gloffset_CompressedTexSubImage1DARB),
+ NAME_FUNC_OFFSET(16205, glCompressedTexSubImage2DARB, glCompressedTexSubImage2DARB, NULL, _gloffset_CompressedTexSubImage2DARB),
+ NAME_FUNC_OFFSET(16231, glCompressedTexSubImage3DARB, glCompressedTexSubImage3DARB, NULL, _gloffset_CompressedTexSubImage3DARB),
+ NAME_FUNC_OFFSET(16257, glGetCompressedTexImageARB, glGetCompressedTexImageARB, NULL, _gloffset_GetCompressedTexImageARB),
+ NAME_FUNC_OFFSET(16281, glDisableVertexAttribArrayARB, glDisableVertexAttribArrayARB, NULL, _gloffset_DisableVertexAttribArrayARB),
+ NAME_FUNC_OFFSET(16308, glEnableVertexAttribArrayARB, glEnableVertexAttribArrayARB, NULL, _gloffset_EnableVertexAttribArrayARB),
+ NAME_FUNC_OFFSET(16334, glGetVertexAttribdvARB, glGetVertexAttribdvARB, NULL, _gloffset_GetVertexAttribdvARB),
+ NAME_FUNC_OFFSET(16354, glGetVertexAttribfvARB, glGetVertexAttribfvARB, NULL, _gloffset_GetVertexAttribfvARB),
+ NAME_FUNC_OFFSET(16374, glGetVertexAttribivARB, glGetVertexAttribivARB, NULL, _gloffset_GetVertexAttribivARB),
+ NAME_FUNC_OFFSET(16394, glProgramEnvParameter4dARB, glProgramEnvParameter4dARB, NULL, _gloffset_ProgramEnvParameter4dARB),
+ NAME_FUNC_OFFSET(16417, glProgramEnvParameter4dvARB, glProgramEnvParameter4dvARB, NULL, _gloffset_ProgramEnvParameter4dvARB),
+ NAME_FUNC_OFFSET(16441, glProgramEnvParameter4fARB, glProgramEnvParameter4fARB, NULL, _gloffset_ProgramEnvParameter4fARB),
+ NAME_FUNC_OFFSET(16464, glProgramEnvParameter4fvARB, glProgramEnvParameter4fvARB, NULL, _gloffset_ProgramEnvParameter4fvARB),
+ NAME_FUNC_OFFSET(16488, glVertexAttrib1dARB, glVertexAttrib1dARB, NULL, _gloffset_VertexAttrib1dARB),
+ NAME_FUNC_OFFSET(16505, glVertexAttrib1dvARB, glVertexAttrib1dvARB, NULL, _gloffset_VertexAttrib1dvARB),
+ NAME_FUNC_OFFSET(16523, glVertexAttrib1fARB, glVertexAttrib1fARB, NULL, _gloffset_VertexAttrib1fARB),
+ NAME_FUNC_OFFSET(16540, glVertexAttrib1fvARB, glVertexAttrib1fvARB, NULL, _gloffset_VertexAttrib1fvARB),
+ NAME_FUNC_OFFSET(16558, glVertexAttrib1sARB, glVertexAttrib1sARB, NULL, _gloffset_VertexAttrib1sARB),
+ NAME_FUNC_OFFSET(16575, glVertexAttrib1svARB, glVertexAttrib1svARB, NULL, _gloffset_VertexAttrib1svARB),
+ NAME_FUNC_OFFSET(16593, glVertexAttrib2dARB, glVertexAttrib2dARB, NULL, _gloffset_VertexAttrib2dARB),
+ NAME_FUNC_OFFSET(16610, glVertexAttrib2dvARB, glVertexAttrib2dvARB, NULL, _gloffset_VertexAttrib2dvARB),
+ NAME_FUNC_OFFSET(16628, glVertexAttrib2fARB, glVertexAttrib2fARB, NULL, _gloffset_VertexAttrib2fARB),
+ NAME_FUNC_OFFSET(16645, glVertexAttrib2fvARB, glVertexAttrib2fvARB, NULL, _gloffset_VertexAttrib2fvARB),
+ NAME_FUNC_OFFSET(16663, glVertexAttrib2sARB, glVertexAttrib2sARB, NULL, _gloffset_VertexAttrib2sARB),
+ NAME_FUNC_OFFSET(16680, glVertexAttrib2svARB, glVertexAttrib2svARB, NULL, _gloffset_VertexAttrib2svARB),
+ NAME_FUNC_OFFSET(16698, glVertexAttrib3dARB, glVertexAttrib3dARB, NULL, _gloffset_VertexAttrib3dARB),
+ NAME_FUNC_OFFSET(16715, glVertexAttrib3dvARB, glVertexAttrib3dvARB, NULL, _gloffset_VertexAttrib3dvARB),
+ NAME_FUNC_OFFSET(16733, glVertexAttrib3fARB, glVertexAttrib3fARB, NULL, _gloffset_VertexAttrib3fARB),
+ NAME_FUNC_OFFSET(16750, glVertexAttrib3fvARB, glVertexAttrib3fvARB, NULL, _gloffset_VertexAttrib3fvARB),
+ NAME_FUNC_OFFSET(16768, glVertexAttrib3sARB, glVertexAttrib3sARB, NULL, _gloffset_VertexAttrib3sARB),
+ NAME_FUNC_OFFSET(16785, glVertexAttrib3svARB, glVertexAttrib3svARB, NULL, _gloffset_VertexAttrib3svARB),
+ NAME_FUNC_OFFSET(16803, glVertexAttrib4NbvARB, glVertexAttrib4NbvARB, NULL, _gloffset_VertexAttrib4NbvARB),
+ NAME_FUNC_OFFSET(16822, glVertexAttrib4NivARB, glVertexAttrib4NivARB, NULL, _gloffset_VertexAttrib4NivARB),
+ NAME_FUNC_OFFSET(16841, glVertexAttrib4NsvARB, glVertexAttrib4NsvARB, NULL, _gloffset_VertexAttrib4NsvARB),
+ NAME_FUNC_OFFSET(16860, glVertexAttrib4NubARB, glVertexAttrib4NubARB, NULL, _gloffset_VertexAttrib4NubARB),
+ NAME_FUNC_OFFSET(16879, glVertexAttrib4NubvARB, glVertexAttrib4NubvARB, NULL, _gloffset_VertexAttrib4NubvARB),
+ NAME_FUNC_OFFSET(16899, glVertexAttrib4NuivARB, glVertexAttrib4NuivARB, NULL, _gloffset_VertexAttrib4NuivARB),
+ NAME_FUNC_OFFSET(16919, glVertexAttrib4NusvARB, glVertexAttrib4NusvARB, NULL, _gloffset_VertexAttrib4NusvARB),
+ NAME_FUNC_OFFSET(16939, glVertexAttrib4bvARB, glVertexAttrib4bvARB, NULL, _gloffset_VertexAttrib4bvARB),
+ NAME_FUNC_OFFSET(16957, glVertexAttrib4dARB, glVertexAttrib4dARB, NULL, _gloffset_VertexAttrib4dARB),
+ NAME_FUNC_OFFSET(16974, glVertexAttrib4dvARB, glVertexAttrib4dvARB, NULL, _gloffset_VertexAttrib4dvARB),
+ NAME_FUNC_OFFSET(16992, glVertexAttrib4fARB, glVertexAttrib4fARB, NULL, _gloffset_VertexAttrib4fARB),
+ NAME_FUNC_OFFSET(17009, glVertexAttrib4fvARB, glVertexAttrib4fvARB, NULL, _gloffset_VertexAttrib4fvARB),
+ NAME_FUNC_OFFSET(17027, glVertexAttrib4ivARB, glVertexAttrib4ivARB, NULL, _gloffset_VertexAttrib4ivARB),
+ NAME_FUNC_OFFSET(17045, glVertexAttrib4sARB, glVertexAttrib4sARB, NULL, _gloffset_VertexAttrib4sARB),
+ NAME_FUNC_OFFSET(17062, glVertexAttrib4svARB, glVertexAttrib4svARB, NULL, _gloffset_VertexAttrib4svARB),
+ NAME_FUNC_OFFSET(17080, glVertexAttrib4ubvARB, glVertexAttrib4ubvARB, NULL, _gloffset_VertexAttrib4ubvARB),
+ NAME_FUNC_OFFSET(17099, glVertexAttrib4uivARB, glVertexAttrib4uivARB, NULL, _gloffset_VertexAttrib4uivARB),
+ NAME_FUNC_OFFSET(17118, glVertexAttrib4usvARB, glVertexAttrib4usvARB, NULL, _gloffset_VertexAttrib4usvARB),
+ NAME_FUNC_OFFSET(17137, glVertexAttribPointerARB, glVertexAttribPointerARB, NULL, _gloffset_VertexAttribPointerARB),
+ NAME_FUNC_OFFSET(17159, glBindBufferARB, glBindBufferARB, NULL, _gloffset_BindBufferARB),
+ NAME_FUNC_OFFSET(17172, glBufferDataARB, glBufferDataARB, NULL, _gloffset_BufferDataARB),
+ NAME_FUNC_OFFSET(17185, glBufferSubDataARB, glBufferSubDataARB, NULL, _gloffset_BufferSubDataARB),
+ NAME_FUNC_OFFSET(17201, glDeleteBuffersARB, glDeleteBuffersARB, NULL, _gloffset_DeleteBuffersARB),
+ NAME_FUNC_OFFSET(17217, glGenBuffersARB, glGenBuffersARB, NULL, _gloffset_GenBuffersARB),
+ NAME_FUNC_OFFSET(17230, glGetBufferParameterivARB, glGetBufferParameterivARB, NULL, _gloffset_GetBufferParameterivARB),
+ NAME_FUNC_OFFSET(17253, glGetBufferPointervARB, glGetBufferPointervARB, NULL, _gloffset_GetBufferPointervARB),
+ NAME_FUNC_OFFSET(17273, glGetBufferSubDataARB, glGetBufferSubDataARB, NULL, _gloffset_GetBufferSubDataARB),
+ NAME_FUNC_OFFSET(17292, glIsBufferARB, glIsBufferARB, NULL, _gloffset_IsBufferARB),
+ NAME_FUNC_OFFSET(17303, glMapBufferARB, glMapBufferARB, NULL, _gloffset_MapBufferARB),
+ NAME_FUNC_OFFSET(17315, glUnmapBufferARB, glUnmapBufferARB, NULL, _gloffset_UnmapBufferARB),
+ NAME_FUNC_OFFSET(17329, glBeginQueryARB, glBeginQueryARB, NULL, _gloffset_BeginQueryARB),
+ NAME_FUNC_OFFSET(17342, glDeleteQueriesARB, glDeleteQueriesARB, NULL, _gloffset_DeleteQueriesARB),
+ NAME_FUNC_OFFSET(17358, glEndQueryARB, glEndQueryARB, NULL, _gloffset_EndQueryARB),
+ NAME_FUNC_OFFSET(17369, glGenQueriesARB, glGenQueriesARB, NULL, _gloffset_GenQueriesARB),
+ NAME_FUNC_OFFSET(17382, glGetQueryObjectivARB, glGetQueryObjectivARB, NULL, _gloffset_GetQueryObjectivARB),
+ NAME_FUNC_OFFSET(17401, glGetQueryObjectuivARB, glGetQueryObjectuivARB, NULL, _gloffset_GetQueryObjectuivARB),
+ NAME_FUNC_OFFSET(17421, glGetQueryivARB, glGetQueryivARB, NULL, _gloffset_GetQueryivARB),
+ NAME_FUNC_OFFSET(17434, glIsQueryARB, glIsQueryARB, NULL, _gloffset_IsQueryARB),
+ NAME_FUNC_OFFSET(17444, glCompileShaderARB, glCompileShaderARB, NULL, _gloffset_CompileShaderARB),
+ NAME_FUNC_OFFSET(17460, glGetActiveUniformARB, glGetActiveUniformARB, NULL, _gloffset_GetActiveUniformARB),
+ NAME_FUNC_OFFSET(17479, glGetShaderSourceARB, glGetShaderSourceARB, NULL, _gloffset_GetShaderSourceARB),
+ NAME_FUNC_OFFSET(17497, glGetUniformLocationARB, glGetUniformLocationARB, NULL, _gloffset_GetUniformLocationARB),
+ NAME_FUNC_OFFSET(17518, glGetUniformfvARB, glGetUniformfvARB, NULL, _gloffset_GetUniformfvARB),
+ NAME_FUNC_OFFSET(17533, glGetUniformivARB, glGetUniformivARB, NULL, _gloffset_GetUniformivARB),
+ NAME_FUNC_OFFSET(17548, glLinkProgramARB, glLinkProgramARB, NULL, _gloffset_LinkProgramARB),
+ NAME_FUNC_OFFSET(17562, glShaderSourceARB, glShaderSourceARB, NULL, _gloffset_ShaderSourceARB),
+ NAME_FUNC_OFFSET(17577, glUniform1fARB, glUniform1fARB, NULL, _gloffset_Uniform1fARB),
+ NAME_FUNC_OFFSET(17589, glUniform1fvARB, glUniform1fvARB, NULL, _gloffset_Uniform1fvARB),
+ NAME_FUNC_OFFSET(17602, glUniform1iARB, glUniform1iARB, NULL, _gloffset_Uniform1iARB),
+ NAME_FUNC_OFFSET(17614, glUniform1ivARB, glUniform1ivARB, NULL, _gloffset_Uniform1ivARB),
+ NAME_FUNC_OFFSET(17627, glUniform2fARB, glUniform2fARB, NULL, _gloffset_Uniform2fARB),
+ NAME_FUNC_OFFSET(17639, glUniform2fvARB, glUniform2fvARB, NULL, _gloffset_Uniform2fvARB),
+ NAME_FUNC_OFFSET(17652, glUniform2iARB, glUniform2iARB, NULL, _gloffset_Uniform2iARB),
+ NAME_FUNC_OFFSET(17664, glUniform2ivARB, glUniform2ivARB, NULL, _gloffset_Uniform2ivARB),
+ NAME_FUNC_OFFSET(17677, glUniform3fARB, glUniform3fARB, NULL, _gloffset_Uniform3fARB),
+ NAME_FUNC_OFFSET(17689, glUniform3fvARB, glUniform3fvARB, NULL, _gloffset_Uniform3fvARB),
+ NAME_FUNC_OFFSET(17702, glUniform3iARB, glUniform3iARB, NULL, _gloffset_Uniform3iARB),
+ NAME_FUNC_OFFSET(17714, glUniform3ivARB, glUniform3ivARB, NULL, _gloffset_Uniform3ivARB),
+ NAME_FUNC_OFFSET(17727, glUniform4fARB, glUniform4fARB, NULL, _gloffset_Uniform4fARB),
+ NAME_FUNC_OFFSET(17739, glUniform4fvARB, glUniform4fvARB, NULL, _gloffset_Uniform4fvARB),
+ NAME_FUNC_OFFSET(17752, glUniform4iARB, glUniform4iARB, NULL, _gloffset_Uniform4iARB),
+ NAME_FUNC_OFFSET(17764, glUniform4ivARB, glUniform4ivARB, NULL, _gloffset_Uniform4ivARB),
+ NAME_FUNC_OFFSET(17777, glUniformMatrix2fvARB, glUniformMatrix2fvARB, NULL, _gloffset_UniformMatrix2fvARB),
+ NAME_FUNC_OFFSET(17796, glUniformMatrix3fvARB, glUniformMatrix3fvARB, NULL, _gloffset_UniformMatrix3fvARB),
+ NAME_FUNC_OFFSET(17815, glUniformMatrix4fvARB, glUniformMatrix4fvARB, NULL, _gloffset_UniformMatrix4fvARB),
+ NAME_FUNC_OFFSET(17834, glUseProgramObjectARB, glUseProgramObjectARB, NULL, _gloffset_UseProgramObjectARB),
+ NAME_FUNC_OFFSET(17847, glValidateProgramARB, glValidateProgramARB, NULL, _gloffset_ValidateProgramARB),
+ NAME_FUNC_OFFSET(17865, glBindAttribLocationARB, glBindAttribLocationARB, NULL, _gloffset_BindAttribLocationARB),
+ NAME_FUNC_OFFSET(17886, glGetActiveAttribARB, glGetActiveAttribARB, NULL, _gloffset_GetActiveAttribARB),
+ NAME_FUNC_OFFSET(17904, glGetAttribLocationARB, glGetAttribLocationARB, NULL, _gloffset_GetAttribLocationARB),
+ NAME_FUNC_OFFSET(17924, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+ NAME_FUNC_OFFSET(17938, glDrawBuffersARB, glDrawBuffersARB, NULL, _gloffset_DrawBuffersARB),
+ NAME_FUNC_OFFSET(17955, gl_dispatch_stub_584, gl_dispatch_stub_584, NULL, _gloffset_SampleMaskSGIS),
+ NAME_FUNC_OFFSET(17971, gl_dispatch_stub_585, gl_dispatch_stub_585, NULL, _gloffset_SamplePatternSGIS),
+ NAME_FUNC_OFFSET(17990, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+ NAME_FUNC_OFFSET(18008, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+ NAME_FUNC_OFFSET(18029, glPointParameterfEXT, glPointParameterfEXT, NULL, _gloffset_PointParameterfEXT),
+ NAME_FUNC_OFFSET(18051, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+ NAME_FUNC_OFFSET(18070, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+ NAME_FUNC_OFFSET(18092, glPointParameterfvEXT, glPointParameterfvEXT, NULL, _gloffset_PointParameterfvEXT),
+ NAME_FUNC_OFFSET(18115, glSecondaryColor3bEXT, glSecondaryColor3bEXT, NULL, _gloffset_SecondaryColor3bEXT),
+ NAME_FUNC_OFFSET(18134, glSecondaryColor3bvEXT, glSecondaryColor3bvEXT, NULL, _gloffset_SecondaryColor3bvEXT),
+ NAME_FUNC_OFFSET(18154, glSecondaryColor3dEXT, glSecondaryColor3dEXT, NULL, _gloffset_SecondaryColor3dEXT),
+ NAME_FUNC_OFFSET(18173, glSecondaryColor3dvEXT, glSecondaryColor3dvEXT, NULL, _gloffset_SecondaryColor3dvEXT),
+ NAME_FUNC_OFFSET(18193, glSecondaryColor3fEXT, glSecondaryColor3fEXT, NULL, _gloffset_SecondaryColor3fEXT),
+ NAME_FUNC_OFFSET(18212, glSecondaryColor3fvEXT, glSecondaryColor3fvEXT, NULL, _gloffset_SecondaryColor3fvEXT),
+ NAME_FUNC_OFFSET(18232, glSecondaryColor3iEXT, glSecondaryColor3iEXT, NULL, _gloffset_SecondaryColor3iEXT),
+ NAME_FUNC_OFFSET(18251, glSecondaryColor3ivEXT, glSecondaryColor3ivEXT, NULL, _gloffset_SecondaryColor3ivEXT),
+ NAME_FUNC_OFFSET(18271, glSecondaryColor3sEXT, glSecondaryColor3sEXT, NULL, _gloffset_SecondaryColor3sEXT),
+ NAME_FUNC_OFFSET(18290, glSecondaryColor3svEXT, glSecondaryColor3svEXT, NULL, _gloffset_SecondaryColor3svEXT),
+ NAME_FUNC_OFFSET(18310, glSecondaryColor3ubEXT, glSecondaryColor3ubEXT, NULL, _gloffset_SecondaryColor3ubEXT),
+ NAME_FUNC_OFFSET(18330, glSecondaryColor3ubvEXT, glSecondaryColor3ubvEXT, NULL, _gloffset_SecondaryColor3ubvEXT),
+ NAME_FUNC_OFFSET(18351, glSecondaryColor3uiEXT, glSecondaryColor3uiEXT, NULL, _gloffset_SecondaryColor3uiEXT),
+ NAME_FUNC_OFFSET(18371, glSecondaryColor3uivEXT, glSecondaryColor3uivEXT, NULL, _gloffset_SecondaryColor3uivEXT),
+ NAME_FUNC_OFFSET(18392, glSecondaryColor3usEXT, glSecondaryColor3usEXT, NULL, _gloffset_SecondaryColor3usEXT),
+ NAME_FUNC_OFFSET(18412, glSecondaryColor3usvEXT, glSecondaryColor3usvEXT, NULL, _gloffset_SecondaryColor3usvEXT),
+ NAME_FUNC_OFFSET(18433, glSecondaryColorPointerEXT, glSecondaryColorPointerEXT, NULL, _gloffset_SecondaryColorPointerEXT),
+ NAME_FUNC_OFFSET(18457, glMultiDrawArraysEXT, glMultiDrawArraysEXT, NULL, _gloffset_MultiDrawArraysEXT),
+ NAME_FUNC_OFFSET(18475, glMultiDrawElementsEXT, glMultiDrawElementsEXT, NULL, _gloffset_MultiDrawElementsEXT),
+ NAME_FUNC_OFFSET(18495, glFogCoordPointerEXT, glFogCoordPointerEXT, NULL, _gloffset_FogCoordPointerEXT),
+ NAME_FUNC_OFFSET(18513, glFogCoorddEXT, glFogCoorddEXT, NULL, _gloffset_FogCoorddEXT),
+ NAME_FUNC_OFFSET(18525, glFogCoorddvEXT, glFogCoorddvEXT, NULL, _gloffset_FogCoorddvEXT),
+ NAME_FUNC_OFFSET(18538, glFogCoordfEXT, glFogCoordfEXT, NULL, _gloffset_FogCoordfEXT),
+ NAME_FUNC_OFFSET(18550, glFogCoordfvEXT, glFogCoordfvEXT, NULL, _gloffset_FogCoordfvEXT),
+ NAME_FUNC_OFFSET(18563, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+ NAME_FUNC_OFFSET(18583, glBlendFuncSeparateEXT, glBlendFuncSeparateEXT, NULL, _gloffset_BlendFuncSeparateEXT),
+ NAME_FUNC_OFFSET(18607, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+ NAME_FUNC_OFFSET(18621, glWindowPos2dMESA, glWindowPos2dMESA, NULL, _gloffset_WindowPos2dMESA),
+ NAME_FUNC_OFFSET(18638, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+ NAME_FUNC_OFFSET(18653, glWindowPos2dvMESA, glWindowPos2dvMESA, NULL, _gloffset_WindowPos2dvMESA),
+ NAME_FUNC_OFFSET(18671, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+ NAME_FUNC_OFFSET(18685, glWindowPos2fMESA, glWindowPos2fMESA, NULL, _gloffset_WindowPos2fMESA),
+ NAME_FUNC_OFFSET(18702, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+ NAME_FUNC_OFFSET(18717, glWindowPos2fvMESA, glWindowPos2fvMESA, NULL, _gloffset_WindowPos2fvMESA),
+ NAME_FUNC_OFFSET(18735, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+ NAME_FUNC_OFFSET(18749, glWindowPos2iMESA, glWindowPos2iMESA, NULL, _gloffset_WindowPos2iMESA),
+ NAME_FUNC_OFFSET(18766, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+ NAME_FUNC_OFFSET(18781, glWindowPos2ivMESA, glWindowPos2ivMESA, NULL, _gloffset_WindowPos2ivMESA),
+ NAME_FUNC_OFFSET(18799, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+ NAME_FUNC_OFFSET(18813, glWindowPos2sMESA, glWindowPos2sMESA, NULL, _gloffset_WindowPos2sMESA),
+ NAME_FUNC_OFFSET(18830, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+ NAME_FUNC_OFFSET(18845, glWindowPos2svMESA, glWindowPos2svMESA, NULL, _gloffset_WindowPos2svMESA),
+ NAME_FUNC_OFFSET(18863, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+ NAME_FUNC_OFFSET(18877, glWindowPos3dMESA, glWindowPos3dMESA, NULL, _gloffset_WindowPos3dMESA),
+ NAME_FUNC_OFFSET(18894, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+ NAME_FUNC_OFFSET(18909, glWindowPos3dvMESA, glWindowPos3dvMESA, NULL, _gloffset_WindowPos3dvMESA),
+ NAME_FUNC_OFFSET(18927, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+ NAME_FUNC_OFFSET(18941, glWindowPos3fMESA, glWindowPos3fMESA, NULL, _gloffset_WindowPos3fMESA),
+ NAME_FUNC_OFFSET(18958, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+ NAME_FUNC_OFFSET(18973, glWindowPos3fvMESA, glWindowPos3fvMESA, NULL, _gloffset_WindowPos3fvMESA),
+ NAME_FUNC_OFFSET(18991, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+ NAME_FUNC_OFFSET(19005, glWindowPos3iMESA, glWindowPos3iMESA, NULL, _gloffset_WindowPos3iMESA),
+ NAME_FUNC_OFFSET(19022, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+ NAME_FUNC_OFFSET(19037, glWindowPos3ivMESA, glWindowPos3ivMESA, NULL, _gloffset_WindowPos3ivMESA),
+ NAME_FUNC_OFFSET(19055, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+ NAME_FUNC_OFFSET(19069, glWindowPos3sMESA, glWindowPos3sMESA, NULL, _gloffset_WindowPos3sMESA),
+ NAME_FUNC_OFFSET(19086, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+ NAME_FUNC_OFFSET(19101, glWindowPos3svMESA, glWindowPos3svMESA, NULL, _gloffset_WindowPos3svMESA),
+ NAME_FUNC_OFFSET(19119, glBindProgramNV, glBindProgramNV, NULL, _gloffset_BindProgramNV),
+ NAME_FUNC_OFFSET(19136, glDeleteProgramsNV, glDeleteProgramsNV, NULL, _gloffset_DeleteProgramsNV),
+ NAME_FUNC_OFFSET(19156, glGenProgramsNV, glGenProgramsNV, NULL, _gloffset_GenProgramsNV),
+ NAME_FUNC_OFFSET(19173, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+ NAME_FUNC_OFFSET(19199, glGetVertexAttribPointervNV, glGetVertexAttribPointervNV, NULL, _gloffset_GetVertexAttribPointervNV),
+ NAME_FUNC_OFFSET(19228, glIsProgramNV, glIsProgramNV, NULL, _gloffset_IsProgramNV),
+ NAME_FUNC_OFFSET(19243, glPointParameteriNV, glPointParameteriNV, NULL, _gloffset_PointParameteriNV),
+ NAME_FUNC_OFFSET(19261, glPointParameterivNV, glPointParameterivNV, NULL, _gloffset_PointParameterivNV),
+ NAME_FUNC_OFFSET(19280, gl_dispatch_stub_755, gl_dispatch_stub_755, NULL, _gloffset_DeleteVertexArraysAPPLE),
+ NAME_FUNC_OFFSET(19301, gl_dispatch_stub_757, gl_dispatch_stub_757, NULL, _gloffset_IsVertexArrayAPPLE),
+ NAME_FUNC_OFFSET(19317, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
+ NAME_FUNC_OFFSET(19341, gl_dispatch_stub_765, gl_dispatch_stub_765, NULL, _gloffset_BlendEquationSeparateEXT),
+ NAME_FUNC_OFFSET(19368, glBindFramebufferEXT, glBindFramebufferEXT, NULL, _gloffset_BindFramebufferEXT),
+ NAME_FUNC_OFFSET(19386, glBindRenderbufferEXT, glBindRenderbufferEXT, NULL, _gloffset_BindRenderbufferEXT),
+ NAME_FUNC_OFFSET(19405, glCheckFramebufferStatusEXT, glCheckFramebufferStatusEXT, NULL, _gloffset_CheckFramebufferStatusEXT),
+ NAME_FUNC_OFFSET(19430, glDeleteFramebuffersEXT, glDeleteFramebuffersEXT, NULL, _gloffset_DeleteFramebuffersEXT),
+ NAME_FUNC_OFFSET(19451, glDeleteRenderbuffersEXT, glDeleteRenderbuffersEXT, NULL, _gloffset_DeleteRenderbuffersEXT),
+ NAME_FUNC_OFFSET(19473, glFramebufferRenderbufferEXT, glFramebufferRenderbufferEXT, NULL, _gloffset_FramebufferRenderbufferEXT),
+ NAME_FUNC_OFFSET(19499, glFramebufferTexture1DEXT, glFramebufferTexture1DEXT, NULL, _gloffset_FramebufferTexture1DEXT),
+ NAME_FUNC_OFFSET(19522, glFramebufferTexture2DEXT, glFramebufferTexture2DEXT, NULL, _gloffset_FramebufferTexture2DEXT),
+ NAME_FUNC_OFFSET(19545, glFramebufferTexture3DEXT, glFramebufferTexture3DEXT, NULL, _gloffset_FramebufferTexture3DEXT),
+ NAME_FUNC_OFFSET(19568, glGenFramebuffersEXT, glGenFramebuffersEXT, NULL, _gloffset_GenFramebuffersEXT),
+ NAME_FUNC_OFFSET(19586, glGenRenderbuffersEXT, glGenRenderbuffersEXT, NULL, _gloffset_GenRenderbuffersEXT),
+ NAME_FUNC_OFFSET(19605, glGenerateMipmapEXT, glGenerateMipmapEXT, NULL, _gloffset_GenerateMipmapEXT),
+ NAME_FUNC_OFFSET(19622, glGetFramebufferAttachmentParameterivEXT, glGetFramebufferAttachmentParameterivEXT, NULL, _gloffset_GetFramebufferAttachmentParameterivEXT),
+ NAME_FUNC_OFFSET(19660, glGetRenderbufferParameterivEXT, glGetRenderbufferParameterivEXT, NULL, _gloffset_GetRenderbufferParameterivEXT),
+ NAME_FUNC_OFFSET(19689, glIsFramebufferEXT, glIsFramebufferEXT, NULL, _gloffset_IsFramebufferEXT),
+ NAME_FUNC_OFFSET(19705, glIsRenderbufferEXT, glIsRenderbufferEXT, NULL, _gloffset_IsRenderbufferEXT),
+ 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/glthread.c b/src/mesa/glapi/glthread.c
index e3abb0f4ae..737fd4d6a8 100644
--- a/src/mesa/glapi/glthread.c
+++ b/src/mesa/glapi/glthread.c
@@ -246,57 +246,6 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
#endif /* WIN32_THREADS */
-
-
-/*
- * XFree86 has its own thread wrapper, Xthreads.h
- * We wrap it again for GL.
- */
-#ifdef USE_XTHREADS
-
-unsigned long
-_glthread_GetID(void)
-{
- return (unsigned long) xthread_self();
-}
-
-
-void
-_glthread_InitTSD(_glthread_TSD *tsd)
-{
- if (xthread_key_create(&tsd->key, NULL) != 0) {
- perror(INIT_TSD_ERROR);
- exit(-1);
- }
- tsd->initMagic = INIT_MAGIC;
-}
-
-
-void *
-_glthread_GetTSD(_glthread_TSD *tsd)
-{
- void *ptr;
- if (tsd->initMagic != INIT_MAGIC) {
- _glthread_InitTSD(tsd);
- }
- xthread_get_specific(tsd->key, &ptr);
- return ptr;
-}
-
-
-void
-_glthread_SetTSD(_glthread_TSD *tsd, void *ptr)
-{
- if (tsd->initMagic != INIT_MAGIC) {
- _glthread_InitTSD(tsd);
- }
- xthread_set_specific(tsd->key, ptr);
-}
-
-#endif /* XTHREAD */
-
-
-
/*
* BeOS threads
*/
diff --git a/src/mesa/glapi/glthread.h b/src/mesa/glapi/glthread.h
index dfe09a9d59..8ec933a851 100644
--- a/src/mesa/glapi/glthread.h
+++ b/src/mesa/glapi/glthread.h
@@ -71,7 +71,7 @@
#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\
- defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \
+ defined(WIN32_THREADS) || defined(BEOS_THREADS)) \
&& !defined(THREADS)
# define THREADS
#endif
@@ -218,48 +218,6 @@ typedef CRITICAL_SECTION _glthread_Mutex;
#endif /* WIN32_THREADS */
-
-
-/*
- * XFree86 has its own thread wrapper, Xthreads.h
- * We wrap it again for GL.
- */
-#ifdef USE_XTHREADS
-#include <X11/Xthreads.h>
-
-typedef struct {
- xthread_key_t key;
- int initMagic;
-} _glthread_TSD;
-
-typedef xthread_t _glthread_Thread;
-
-typedef xmutex_rec _glthread_Mutex;
-
-#ifdef XMUTEX_INITIALIZER
-#define _glthread_DECLARE_STATIC_MUTEX(name) \
- static _glthread_Mutex name = XMUTEX_INITIALIZER
-#else
-#define _glthread_DECLARE_STATIC_MUTEX(name) \
- static _glthread_Mutex name
-#endif
-
-#define _glthread_INIT_MUTEX(name) \
- xmutex_init(&(name))
-
-#define _glthread_DESTROY_MUTEX(name) \
- xmutex_clear(&(name))
-
-#define _glthread_LOCK_MUTEX(name) \
- (void) xmutex_lock(&(name))
-
-#define _glthread_UNLOCK_MUTEX(name) \
- (void) xmutex_unlock(&(name))
-
-#endif /* USE_XTHREADS */
-
-
-
/*
* BeOS threads. R5.x required.
*/
diff --git a/src/mesa/glapi/mesadef.py b/src/mesa/glapi/mesadef.py
index 0f410fc482..342c9cde46 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_arrayelt.c b/src/mesa/main/api_arrayelt.c
index f5b7d1e138..2462a1b003 100644
--- a/src/mesa/main/api_arrayelt.c
+++ b/src/mesa/main/api_arrayelt.c
@@ -28,6 +28,7 @@
#include "glheader.h"
#include "api_arrayelt.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
@@ -1071,7 +1072,7 @@ void _ae_destroy_context( GLcontext *ctx )
static void check_vbo( AEcontext *actx,
struct gl_buffer_object *vbo )
{
- if (vbo->Name && !vbo->Pointer) {
+ if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo)) {
GLuint i;
for (i = 0; i < actx->nr_vbos; i++)
if (actx->vbo[i] == vbo)
diff --git a/src/mesa/main/api_exec.c b/src/mesa/main/api_exec.c
index e49cd041a6..02550ae108 100644
--- a/src/mesa/main/api_exec.c
+++ b/src/mesa/main/api_exec.c
@@ -107,6 +107,7 @@
#include "state.h"
#include "stencil.h"
#include "texenv.h"
+#include "texgetimage.h"
#include "teximage.h"
#if FEATURE_texgen
#include "texgen.h"
@@ -128,6 +129,9 @@
#if FEATURE_ARB_shader_objects
#include "shaders.h"
#endif
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+#endif
#include "debug.h"
#include "glapi/dispatch.h"
@@ -528,7 +532,6 @@ _mesa_init_exec_table(struct _glapi_table *exec)
/* 148. GL_EXT_multi_draw_arrays */
#if _HAVE_FULL_GL
SET_MultiDrawArraysEXT(exec, _mesa_MultiDrawArraysEXT);
- SET_MultiDrawElementsEXT(exec, _mesa_MultiDrawElementsEXT);
#endif
/* 173. GL_INGR_blend_func_separate */
@@ -823,6 +826,17 @@ _mesa_init_exec_table(struct _glapi_table *exec)
SET_GetAttribLocationARB(exec, _mesa_GetAttribLocationARB);
#endif /* FEATURE_ARB_vertex_shader */
+ /* GL_ARB_sync */
+#if FEATURE_ARB_sync
+ SET_IsSync(exec, _mesa_IsSync);
+ SET_DeleteSync(exec, _mesa_DeleteSync);
+ SET_FenceSync(exec, _mesa_FenceSync);
+ SET_ClientWaitSync(exec, _mesa_ClientWaitSync);
+ SET_WaitSync(exec, _mesa_WaitSync);
+ SET_GetInteger64v(exec, _mesa_GetInteger64v);
+ SET_GetSynciv(exec, _mesa_GetSynciv);
+#endif
+
/* GL_ATI_fragment_shader */
#if FEATURE_ATI_fragment_shader
SET_GenFragmentShadersATI(exec, _mesa_GenFragmentShadersATI);
diff --git a/src/mesa/main/api_noop.c b/src/mesa/main/api_noop.c
index 66f9c4e6bd..0b669e7e7f 100644
--- a/src/mesa/main/api_noop.c
+++ b/src/mesa/main/api_noop.c
@@ -731,7 +731,7 @@ _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
GET_CURRENT_CONTEXT(ctx);
GLint i;
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
return;
CALL_Begin(GET_DISPATCH(), (mode));
@@ -757,6 +757,43 @@ _mesa_noop_DrawElements(GLenum mode, GLsizei count, GLenum type,
CALL_End(GET_DISPATCH(), ());
}
+static void GLAPIENTRY
+_mesa_noop_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
+ basevertex ))
+ return;
+
+ CALL_Begin(GET_DISPATCH(), (mode));
+
+ switch (type) {
+ case GL_UNSIGNED_BYTE:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLubyte *)indices)[i] +
+ basevertex));
+ break;
+ case GL_UNSIGNED_SHORT:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLushort *)indices)[i] +
+ basevertex ));
+ break;
+ case GL_UNSIGNED_INT:
+ for (i = 0 ; i < count ; i++)
+ CALL_ArrayElement(GET_DISPATCH(), ( ((GLuint *)indices)[i] +
+ basevertex ));
+ break;
+ default:
+ _mesa_error( ctx, GL_INVALID_ENUM, "glDrawElementsBaseVertex(type)" );
+ break;
+ }
+
+ CALL_End(GET_DISPATCH(), ());
+}
+
static void GLAPIENTRY
_mesa_noop_DrawRangeElements(GLenum mode,
@@ -768,10 +805,58 @@ _mesa_noop_DrawRangeElements(GLenum mode,
if (_mesa_validate_DrawRangeElements( ctx, mode,
start, end,
- count, type, indices ))
+ count, type, indices, 0 ))
CALL_DrawElements(GET_DISPATCH(), (mode, count, type, indices));
}
+/* GL_EXT_multi_draw_arrays */
+void GLAPIENTRY
+_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount)
+{
+ GLsizei i;
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ CALL_DrawElements(GET_DISPATCH(), (mode, count[i], type, indices[i]));
+ }
+ }
+}
+
+static void GLAPIENTRY
+_mesa_noop_DrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (_mesa_validate_DrawRangeElements( ctx, mode,
+ start, end,
+ count, type, indices, basevertex ))
+ CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count, type, indices,
+ basevertex));
+}
+
+/* GL_EXT_multi_draw_arrays */
+void GLAPIENTRY
+_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount,
+ const GLint *basevertex)
+{
+ GLsizei i;
+
+ for (i = 0; i < primcount; i++) {
+ if (count[i] > 0) {
+ CALL_DrawElementsBaseVertex(GET_DISPATCH(), (mode, count[i], type,
+ indices[i],
+ basevertex[i]));
+ }
+ }
+}
+
/*
* Eval Mesh
*/
@@ -980,6 +1065,10 @@ _mesa_noop_vtxfmt_init( GLvertexformat *vfmt )
vfmt->DrawArrays = _mesa_noop_DrawArrays;
vfmt->DrawElements = _mesa_noop_DrawElements;
vfmt->DrawRangeElements = _mesa_noop_DrawRangeElements;
+ vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
+ vfmt->DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
+ vfmt->DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
+ vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
vfmt->EvalMesh1 = _mesa_noop_EvalMesh1;
vfmt->EvalMesh2 = _mesa_noop_EvalMesh2;
}
diff --git a/src/mesa/main/api_noop.h b/src/mesa/main/api_noop.h
index 8bf4660800..1150984d64 100644
--- a/src/mesa/main/api_noop.h
+++ b/src/mesa/main/api_noop.h
@@ -40,6 +40,17 @@ _mesa_noop_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2);
extern void GLAPIENTRY
_mesa_noop_Materialfv(GLenum face, GLenum pname, const GLfloat *param);
+extern void GLAPIENTRY
+_mesa_noop_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount);
+
+extern void GLAPIENTRY
+_mesa_noop_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount,
+ const GLint *basevertex);
+
extern void
_mesa_noop_vtxfmt_init(GLvertexformat *vfmt);
diff --git a/src/mesa/main/api_validate.c b/src/mesa/main/api_validate.c
index b2f11ffbfe..e71e5a6ce8 100644
--- a/src/mesa/main/api_validate.c
+++ b/src/mesa/main/api_validate.c
@@ -24,11 +24,12 @@
#include "glheader.h"
#include "api_validate.h"
+#include "bufferobj.h"
#include "context.h"
#include "imports.h"
#include "mtypes.h"
#include "state.h"
-
+#include "vbo/vbo.h"
/**
@@ -53,16 +54,16 @@ index_bytes(GLenum type, GLsizei count)
/**
* Find the max index in the given element/index buffer
*/
-static GLuint
-max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
- const void *indices,
- struct gl_buffer_object *elementBuf)
+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 (elementBuf->Name) {
+ 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);
@@ -96,14 +97,12 @@ max_buffer_index(GLcontext *ctx, GLuint count, GLenum type,
/**
- * Check if OK to render by examining framebuffer status and vertex arrays.
+ * Check if OK to draw arrays/elements.
*/
static GLboolean
-check_valid_to_render(GLcontext *ctx, char *function)
+check_valid_to_render(GLcontext *ctx, const char *function)
{
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDraw%s(incomplete framebuffer)", function);
+ if (!_mesa_valid_to_render(ctx, function)) {
return GL_FALSE;
}
@@ -125,6 +124,40 @@ check_valid_to_render(GLcontext *ctx, char *function)
return GL_TRUE;
}
+static GLboolean
+check_index_bounds(GLcontext *ctx, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ struct _mesa_prim prim;
+ struct _mesa_index_buffer ib;
+ GLuint min, max;
+
+ /* Only the X Server needs to do this -- otherwise, accessing outside
+ * array/BO bounds allows application termination.
+ */
+ if (!ctx->Const.CheckArrayBounds)
+ return GL_TRUE;
+
+ memset(&prim, 0, sizeof(prim));
+ prim.count = count;
+
+ memset(&ib, 0, sizeof(ib));
+ ib.type = type;
+ ib.ptr = indices;
+ ib.obj = ctx->Array.ElementArrayBufferObj;
+
+ vbo_get_minmax_index(ctx, &prim, &ib, &min, &max);
+
+ if (min + basevertex < 0 ||
+ max + basevertex > ctx->Array.ArrayObj->_MaxElement) {
+ /* the max element is out of bounds of one or more enabled arrays */
+ _mesa_warning(ctx, "glDrawElements() index=%u is "
+ "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
/**
* Error checking for glDrawElements(). Includes parameter checking
@@ -134,7 +167,7 @@ check_valid_to_render(GLcontext *ctx, char *function)
GLboolean
_mesa_validate_DrawElements(GLcontext *ctx,
GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices)
+ const GLvoid *indices, GLint basevertex)
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
@@ -160,11 +193,11 @@ _mesa_validate_DrawElements(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Elements"))
+ if (!check_valid_to_render(ctx, "glDrawElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -178,17 +211,8 @@ _mesa_validate_DrawElements(GLcontext *ctx,
return GL_FALSE;
}
- if (ctx->Const.CheckArrayBounds) {
- /* find max array index */
- GLuint max = max_buffer_index(ctx, count, type, indices,
- ctx->Array.ElementArrayBufferObj);
- if (max >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- _mesa_warning(ctx, "glDrawElements() index=%u is "
- "out of bounds (max=%u)", max, ctx->Array.ArrayObj->_MaxElement);
- return GL_FALSE;
- }
- }
+ if (!check_index_bounds(ctx, count, type, indices, basevertex))
+ return GL_FALSE;
return GL_TRUE;
}
@@ -203,7 +227,7 @@ GLboolean
_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type,
- const GLvoid *indices)
+ const GLvoid *indices, GLint basevertex)
{
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
@@ -233,11 +257,11 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "RangeElements"))
+ if (!check_valid_to_render(ctx, "glDrawRangeElements"))
return GL_FALSE;
/* Vertex buffer object tests */
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
/* use indices in the buffer object */
/* make sure count doesn't go outside buffer bounds */
if (index_bytes(type, count) > ctx->Array.ElementArrayBufferObj->Size) {
@@ -251,14 +275,8 @@ _mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
return GL_FALSE;
}
- if (ctx->Const.CheckArrayBounds) {
- GLuint max = max_buffer_index(ctx, count, type, indices,
- ctx->Array.ElementArrayBufferObj);
- if (max >= ctx->Array.ArrayObj->_MaxElement) {
- /* the max element is out of bounds of one or more enabled arrays */
- return GL_FALSE;
- }
- }
+ if (!check_index_bounds(ctx, count, type, indices, basevertex))
+ return GL_FALSE;
return GL_TRUE;
}
@@ -289,7 +307,7 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
if (ctx->NewState)
_mesa_update_state(ctx);
- if (!check_valid_to_render(ctx, "Arrays"))
+ if (!check_valid_to_render(ctx, "glDrawArrays"))
return GL_FALSE;
if (ctx->Const.CheckArrayBounds) {
diff --git a/src/mesa/main/api_validate.h b/src/mesa/main/api_validate.h
index 10f0c34e66..6064d15fe6 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);
@@ -37,13 +43,13 @@ _mesa_validate_DrawArrays(GLcontext *ctx,
extern GLboolean
_mesa_validate_DrawElements(GLcontext *ctx,
GLenum mode, GLsizei count, GLenum type,
- const GLvoid *indices);
+ const GLvoid *indices, GLint basevertex);
extern GLboolean
_mesa_validate_DrawRangeElements(GLcontext *ctx, GLenum mode,
GLuint start, GLuint end,
GLsizei count, GLenum type,
- const GLvoid *indices);
+ const GLvoid *indices, GLint basevertex);
#endif
diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c
index cb49c4cb07..0fb8fa3bba 100644
--- a/src/mesa/main/attrib.c
+++ b/src/mesa/main/attrib.c
@@ -74,6 +74,7 @@ struct gl_enable_attrib
GLboolean Convolution2D;
GLboolean Separable2D;
GLboolean CullFace;
+ GLboolean DepthClamp;
GLboolean DepthTest;
GLboolean Dither;
GLboolean Fog;
@@ -174,24 +175,30 @@ struct texture_state
/**
- * Allocate a new attribute state node. These nodes have a
- * "kind" value and a pointer to a struct of state data.
+ * Allocate new attribute node of given type/kind. Attach payload data.
+ * Insert it into the linked list named by 'head'.
*/
-static struct gl_attrib_node *
-new_attrib_node( GLbitfield kind )
+static void
+save_attrib_data(struct gl_attrib_node **head,
+ GLbitfield kind, void *payload)
{
- struct gl_attrib_node *an = MALLOC_STRUCT(gl_attrib_node);
- if (an) {
- an->kind = kind;
+ struct gl_attrib_node *n = MALLOC_STRUCT(gl_attrib_node);
+ if (n) {
+ n->kind = kind;
+ n->data = payload;
+ /* insert at head */
+ n->next = *head;
+ *head = n;
+ }
+ else {
+ /* out of memory! */
}
- return an;
}
void GLAPIENTRY
_mesa_PushAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -213,10 +220,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_accum_attrib *attr;
attr = MALLOC_STRUCT( gl_accum_attrib );
MEMCPY( attr, &ctx->Accum, sizeof(struct gl_accum_attrib) );
- newnode = new_attrib_node( GL_ACCUM_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ACCUM_BUFFER_BIT, attr);
}
if (mask & GL_COLOR_BUFFER_BIT) {
@@ -227,10 +231,7 @@ _mesa_PushAttrib(GLbitfield mask)
/* push the Draw FBO's DrawBuffer[] state, not ctx->Color.DrawBuffer[] */
for (i = 0; i < ctx->Const.MaxDrawBuffers; i ++)
attr->DrawBuffer[i] = ctx->DrawBuffer->ColorDrawBuffer[i];
- newnode = new_attrib_node( GL_COLOR_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_COLOR_BUFFER_BIT, attr);
}
if (mask & GL_CURRENT_BIT) {
@@ -238,20 +239,14 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT( ctx, 0 );
attr = MALLOC_STRUCT( gl_current_attrib );
MEMCPY( attr, &ctx->Current, sizeof(struct gl_current_attrib) );
- newnode = new_attrib_node( GL_CURRENT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CURRENT_BIT, attr);
}
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_depthbuffer_attrib *attr;
attr = MALLOC_STRUCT( gl_depthbuffer_attrib );
MEMCPY( attr, &ctx->Depth, sizeof(struct gl_depthbuffer_attrib) );
- newnode = new_attrib_node( GL_DEPTH_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_DEPTH_BUFFER_BIT, attr);
}
if (mask & GL_ENABLE_BIT) {
@@ -271,6 +266,7 @@ _mesa_PushAttrib(GLbitfield mask)
attr->Convolution2D = ctx->Pixel.Convolution2DEnabled;
attr->Separable2D = ctx->Pixel.Separable2DEnabled;
attr->CullFace = ctx->Polygon.CullFlag;
+ attr->DepthClamp = ctx->Transform.DepthClamp;
attr->DepthTest = ctx->Depth.Test;
attr->Dither = ctx->Color.DitherFlag;
attr->Fog = ctx->Fog.Enabled;
@@ -331,40 +327,28 @@ _mesa_PushAttrib(GLbitfield mask)
attr->VertexProgram = ctx->VertexProgram.Enabled;
attr->VertexProgramPointSize = ctx->VertexProgram.PointSizeEnabled;
attr->VertexProgramTwoSide = ctx->VertexProgram.TwoSideEnabled;
- newnode = new_attrib_node( GL_ENABLE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_ENABLE_BIT, attr);
}
if (mask & GL_EVAL_BIT) {
struct gl_eval_attrib *attr;
attr = MALLOC_STRUCT( gl_eval_attrib );
MEMCPY( attr, &ctx->Eval, sizeof(struct gl_eval_attrib) );
- newnode = new_attrib_node( GL_EVAL_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_EVAL_BIT, attr);
}
if (mask & GL_FOG_BIT) {
struct gl_fog_attrib *attr;
attr = MALLOC_STRUCT( gl_fog_attrib );
MEMCPY( attr, &ctx->Fog, sizeof(struct gl_fog_attrib) );
- newnode = new_attrib_node( GL_FOG_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_FOG_BIT, attr);
}
if (mask & GL_HINT_BIT) {
struct gl_hint_attrib *attr;
attr = MALLOC_STRUCT( gl_hint_attrib );
MEMCPY( attr, &ctx->Hint, sizeof(struct gl_hint_attrib) );
- newnode = new_attrib_node( GL_HINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_HINT_BIT, attr);
}
if (mask & GL_LIGHTING_BIT) {
@@ -372,30 +356,21 @@ _mesa_PushAttrib(GLbitfield mask)
FLUSH_CURRENT(ctx, 0); /* flush material changes */
attr = MALLOC_STRUCT( gl_light_attrib );
MEMCPY( attr, &ctx->Light, sizeof(struct gl_light_attrib) );
- newnode = new_attrib_node( GL_LIGHTING_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIGHTING_BIT, attr);
}
if (mask & GL_LINE_BIT) {
struct gl_line_attrib *attr;
attr = MALLOC_STRUCT( gl_line_attrib );
MEMCPY( attr, &ctx->Line, sizeof(struct gl_line_attrib) );
- newnode = new_attrib_node( GL_LINE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LINE_BIT, attr);
}
if (mask & GL_LIST_BIT) {
struct gl_list_attrib *attr;
attr = MALLOC_STRUCT( gl_list_attrib );
MEMCPY( attr, &ctx->List, sizeof(struct gl_list_attrib) );
- newnode = new_attrib_node( GL_LIST_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_LIST_BIT, attr);
}
if (mask & GL_PIXEL_MODE_BIT) {
@@ -404,60 +379,42 @@ _mesa_PushAttrib(GLbitfield mask)
MEMCPY( attr, &ctx->Pixel, sizeof(struct gl_pixel_attrib) );
/* push the Read FBO's ReadBuffer state, not ctx->Pixel.ReadBuffer */
attr->ReadBuffer = ctx->ReadBuffer->ColorReadBuffer;
- newnode = new_attrib_node( GL_PIXEL_MODE_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_PIXEL_MODE_BIT, attr);
}
if (mask & GL_POINT_BIT) {
struct gl_point_attrib *attr;
attr = MALLOC_STRUCT( gl_point_attrib );
MEMCPY( attr, &ctx->Point, sizeof(struct gl_point_attrib) );
- newnode = new_attrib_node( GL_POINT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POINT_BIT, attr);
}
if (mask & GL_POLYGON_BIT) {
struct gl_polygon_attrib *attr;
attr = MALLOC_STRUCT( gl_polygon_attrib );
MEMCPY( attr, &ctx->Polygon, sizeof(struct gl_polygon_attrib) );
- newnode = new_attrib_node( GL_POLYGON_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_BIT, attr);
}
if (mask & GL_POLYGON_STIPPLE_BIT) {
GLuint *stipple;
stipple = (GLuint *) MALLOC( 32*sizeof(GLuint) );
MEMCPY( stipple, ctx->PolygonStipple, 32*sizeof(GLuint) );
- newnode = new_attrib_node( GL_POLYGON_STIPPLE_BIT );
- newnode->data = stipple;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_POLYGON_STIPPLE_BIT, stipple);
}
if (mask & GL_SCISSOR_BIT) {
struct gl_scissor_attrib *attr;
attr = MALLOC_STRUCT( gl_scissor_attrib );
MEMCPY( attr, &ctx->Scissor, sizeof(struct gl_scissor_attrib) );
- newnode = new_attrib_node( GL_SCISSOR_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_SCISSOR_BIT, attr);
}
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_stencil_attrib *attr;
attr = MALLOC_STRUCT( gl_stencil_attrib );
MEMCPY( attr, &ctx->Stencil, sizeof(struct gl_stencil_attrib) );
- newnode = new_attrib_node( GL_STENCIL_BUFFER_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_STENCIL_BUFFER_BIT, attr);
}
if (mask & GL_TEXTURE_BIT) {
@@ -494,30 +451,21 @@ _mesa_PushAttrib(GLbitfield mask)
_mesa_unlock_context_textures(ctx);
- newnode = new_attrib_node( GL_TEXTURE_BIT );
- newnode->data = texstate;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TEXTURE_BIT, texstate);
}
if (mask & GL_TRANSFORM_BIT) {
struct gl_transform_attrib *attr;
attr = MALLOC_STRUCT( gl_transform_attrib );
MEMCPY( attr, &ctx->Transform, sizeof(struct gl_transform_attrib) );
- newnode = new_attrib_node( GL_TRANSFORM_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_TRANSFORM_BIT, attr);
}
if (mask & GL_VIEWPORT_BIT) {
struct gl_viewport_attrib *attr;
attr = MALLOC_STRUCT( gl_viewport_attrib );
MEMCPY( attr, &ctx->Viewport, sizeof(struct gl_viewport_attrib) );
- newnode = new_attrib_node( GL_VIEWPORT_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_VIEWPORT_BIT, attr);
}
/* GL_ARB_multisample */
@@ -525,10 +473,7 @@ _mesa_PushAttrib(GLbitfield mask)
struct gl_multisample_attrib *attr;
attr = MALLOC_STRUCT( gl_multisample_attrib );
MEMCPY( attr, &ctx->Multisample, sizeof(struct gl_multisample_attrib) );
- newnode = new_attrib_node( GL_MULTISAMPLE_BIT_ARB );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_MULTISAMPLE_BIT_ARB, attr);
}
end:
@@ -571,6 +516,8 @@ pop_enable_group(GLcontext *ctx, const struct gl_enable_attrib *enable)
enable->ColorTable[COLORTABLE_POSTCOLORMATRIX],
GL_POST_COLOR_MATRIX_COLOR_TABLE);
TEST_AND_UPDATE(ctx->Polygon.CullFlag, enable->CullFace, GL_CULL_FACE);
+ TEST_AND_UPDATE(ctx->Transform.DepthClamp, enable->DepthClamp,
+ GL_DEPTH_CLAMP);
TEST_AND_UPDATE(ctx->Depth.Test, enable->DepthTest, GL_DEPTH_TEST);
TEST_AND_UPDATE(ctx->Color.DitherFlag, enable->Dither, GL_DITHER);
TEST_AND_UPDATE(ctx->Pixel.Convolution1DEnabled, enable->Convolution1D,
@@ -1278,6 +1225,9 @@ _mesa_PopAttrib(void)
if (xform->RescaleNormals != ctx->Transform.RescaleNormals)
_mesa_set_enable(ctx, GL_RESCALE_NORMAL_EXT,
ctx->Transform.RescaleNormals);
+ if (xform->DepthClamp != ctx->Transform.DepthClamp)
+ _mesa_set_enable(ctx, GL_DEPTH_CLAMP,
+ ctx->Transform.DepthClamp);
}
break;
case GL_TEXTURE_BIT:
@@ -1373,7 +1323,6 @@ copy_pixelstore(GLcontext *ctx,
void GLAPIENTRY
_mesa_PushClientAttrib(GLbitfield mask)
{
- struct gl_attrib_node *newnode;
struct gl_attrib_node *head;
GET_CURRENT_CONTEXT(ctx);
@@ -1394,17 +1343,11 @@ _mesa_PushClientAttrib(GLbitfield mask)
/* packing attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Pack);
- newnode = new_attrib_node( GL_CLIENT_PACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_PACK_BIT, attr);
/* unpacking attribs */
attr = CALLOC_STRUCT( gl_pixelstore_attrib );
copy_pixelstore(ctx, attr, &ctx->Unpack);
- newnode = new_attrib_node( GL_CLIENT_UNPACK_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_UNPACK_BIT, attr);
}
if (mask & GL_CLIENT_VERTEX_ARRAY_BIT) {
@@ -1425,10 +1368,8 @@ _mesa_PushClientAttrib(GLbitfield mask)
attr->ArrayObj = obj;
- newnode = new_attrib_node( GL_CLIENT_VERTEX_ARRAY_BIT );
- newnode->data = attr;
- newnode->next = head;
- head = newnode;
+ save_attrib_data(&head, GL_CLIENT_VERTEX_ARRAY_BIT, attr);
+
/* bump reference counts on buffer objects */
adjust_buffer_object_ref_counts(ctx->Array.ArrayObj, 1);
}
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index d640f5358e..189b5e1655 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -156,7 +156,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
_mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", caller);
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
}
@@ -165,7 +165,7 @@ buffer_object_subdata_range_good( GLcontext * ctx, GLenum target,
"%s(size + offset > buffer size)", caller);
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Buffer is currently mapped */
_mesa_error(ctx, GL_INVALID_OPERATION, "%s", caller);
return NULL;
@@ -314,9 +314,10 @@ _mesa_initialize_buffer_object( struct gl_buffer_object *obj,
* \param usage Hints about how the data will be used.
* \param bufObj Object to be used.
*
+ * \return GL_TRUE for success, GL_FALSE for failure
* \sa glBufferDataARB, dd_function_table::BufferData.
*/
-static void
+static GLboolean
_mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
const GLvoid * data, GLenum usage,
struct gl_buffer_object * bufObj )
@@ -334,6 +335,11 @@ _mesa_buffer_data( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
if (data) {
_mesa_memcpy( bufObj->Data, data, size );
}
+
+ return GL_TRUE;
+ }
+ else {
+ return GL_FALSE;
}
}
@@ -423,11 +429,13 @@ _mesa_buffer_map( GLcontext *ctx, GLenum target, GLenum access,
(void) target;
(void) access;
/* Just return a direct pointer to the data */
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* already mapped! */
return NULL;
}
bufObj->Pointer = bufObj->Data;
+ bufObj->Length = bufObj->Size;
+ bufObj->Offset = 0;
return bufObj->Pointer;
}
@@ -443,11 +451,13 @@ _mesa_buffer_map_range( GLcontext *ctx, GLenum target, GLintptr offset,
{
(void) ctx;
(void) target;
- (void) access;
- (void) length;
- assert(!bufObj->Pointer);
+ assert(!_mesa_bufferobj_mapped(bufObj));
/* Just return a direct pointer to the data */
- return bufObj->Data + offset;
+ bufObj->Pointer = bufObj->Data + offset;
+ bufObj->Length = length;
+ bufObj->Offset = offset;
+ bufObj->AccessFlags = access;
+ return bufObj->Pointer;
}
@@ -484,6 +494,9 @@ _mesa_buffer_unmap( GLcontext *ctx, GLenum target,
(void) target;
/* XXX we might assert here that bufObj->Pointer is non-null */
bufObj->Pointer = NULL;
+ bufObj->Length = 0;
+ bufObj->Offset = 0;
+ bufObj->AccessFlags = 0x0;
return GL_TRUE;
}
@@ -502,8 +515,8 @@ _mesa_copy_buffer_subdata(GLcontext *ctx,
GLubyte *srcPtr, *dstPtr;
/* buffer should not already be mapped */
- assert(!src->Pointer);
- assert(!dst->Pointer);
+ assert(!_mesa_bufferobj_mapped(src));
+ assert(!_mesa_bufferobj_mapped(dst));
srcPtr = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_COPY_READ_BUFFER,
GL_READ_ONLY, src);
@@ -645,6 +658,8 @@ _mesa_update_default_objects_buffer_objects(GLcontext *ctx)
* currently mapped. Whoever calls this function should check for that.
* Remember, we can't use a PBO when it's mapped!
*
+ * If we're not using a PBO, this is a no-op.
+ *
* \param width width of image to read/write
* \param height height of image to read/write
* \param depth depth of image to read/write
@@ -663,7 +678,8 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLvoid *start, *end;
const GLubyte *sizeAddr; /* buffer size, cast to a pointer */
- ASSERT(pack->BufferObj->Name != 0);
+ if (!_mesa_is_bufferobj(pack->BufferObj))
+ return GL_TRUE; /* no PBO, OK */
if (pack->BufferObj->Size == 0)
/* no buffer! */
@@ -695,21 +711,22 @@ _mesa_validate_pbo_access(GLuint dimensions,
/**
- * If the source of glBitmap data is a PBO, check that we won't read out
- * of buffer bounds, then map the buffer.
- * If not sourcing from a PBO, just return the bitmap pointer.
- * This is a helper function for (some) drivers.
- * Return NULL if error.
- * If non-null return, must call _mesa_unmap_bitmap_pbo() when done.
+ * For commands that read from a PBO (glDrawPixels, glTexImage,
+ * glPolygonStipple, etc), if we're reading from a PBO, map it read-only
+ * and return the pointer into the PBO. If we're not reading from a
+ * PBO, return \p src as-is.
+ * If non-null return, must call _mesa_unmap_pbo_source() when done.
+ *
+ * \return NULL if error, else pointer to start of data
*/
-const GLubyte *
-_mesa_map_bitmap_pbo(GLcontext *ctx,
+const GLvoid *
+_mesa_map_pbo_source(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap)
+ const GLvoid *src)
{
const GLubyte *buf;
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
/* unpack from PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
GL_READ_ONLY_ARB,
@@ -717,11 +734,11 @@ _mesa_map_bitmap_pbo(GLcontext *ctx,
if (!buf)
return NULL;
- buf = ADD_POINTERS(buf, bitmap);
+ buf = ADD_POINTERS(buf, src);
}
else {
/* unpack from normal memory */
- buf = bitmap;
+ buf = src;
}
return buf;
@@ -729,57 +746,55 @@ _mesa_map_bitmap_pbo(GLcontext *ctx,
/**
- * Counterpart to _mesa_map_bitmap_pbo()
- * This is a helper function for (some) drivers.
- */
-void
-_mesa_unmap_bitmap_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack)
-{
- if (unpack->BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- unpack->BufferObj);
- }
-}
-
-
-/**
- * \sa _mesa_map_bitmap_pbo
+ * Combine PBO-read validation and mapping.
+ * If any GL errors are detected, they'll be recorded and NULL returned.
+ * \sa _mesa_validate_pbo_access
+ * \sa _mesa_map_pbo_source
+ * A call to this function should have a matching call to
+ * _mesa_unmap_pbo_source().
*/
const GLvoid *
-_mesa_map_drawpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels)
+_mesa_map_validate_pbo_source(GLcontext *ctx,
+ GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *ptr,
+ const char *where)
{
- const GLvoid *buf;
+ ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3);
- if (unpack->BufferObj->Name) {
- /* unpack from PBO */
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- unpack->BufferObj);
- if (!buf)
- return NULL;
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
+ /* non-PBO access: no validation to be done */
+ return ptr;
+ }
- buf = ADD_POINTERS(buf, pixels);
+ if (!_mesa_validate_pbo_access(dimensions, unpack,
+ width, height, depth, format, type, ptr)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(out of bounds PBO access)", where);
+ return NULL;
}
- else {
- /* unpack from normal memory */
- buf = pixels;
+
+ if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
+ return NULL;
}
- return buf;
+ ptr = _mesa_map_pbo_source(ctx, unpack, ptr);
+ return ptr;
}
/**
- * \sa _mesa_unmap_bitmap_pbo
+ * Counterpart to _mesa_map_pbo_source()
*/
void
-_mesa_unmap_drawpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack)
+_mesa_unmap_pbo_source(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ ASSERT(unpack != &ctx->Pack); /* catch pack/unpack mismatch */
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -787,18 +802,21 @@ _mesa_unmap_drawpix_pbo(GLcontext *ctx,
/**
- * If PBO is bound, map the buffer, return dest pointer in mapped buffer.
- * Call _mesa_unmap_readpix_pbo() when finished
- * \return NULL if error
+ * For commands that write to a PBO (glReadPixels, glGetColorTable, etc),
+ * if we're writing to a PBO, map it write-only and return the pointer
+ * into the PBO. If we're not writing to a PBO, return \p dst as-is.
+ * If non-null return, must call _mesa_unmap_pbo_dest() when done.
+ *
+ * \return NULL if error, else pointer to start of data
*/
void *
-_mesa_map_readpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *pack,
- GLvoid *dest)
+_mesa_map_pbo_dest(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest)
{
void *buf;
- if (pack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
/* pack into PBO */
buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
GL_WRITE_ONLY_ARB,
@@ -818,13 +836,55 @@ _mesa_map_readpix_pbo(GLcontext *ctx,
/**
- * Counterpart to _mesa_map_readpix_pbo()
+ * Combine PBO-write validation and mapping.
+ * If any GL errors are detected, they'll be recorded and NULL returned.
+ * \sa _mesa_validate_pbo_access
+ * \sa _mesa_map_pbo_dest
+ * A call to this function should have a matching call to
+ * _mesa_unmap_pbo_dest().
+ */
+GLvoid *
+_mesa_map_validate_pbo_dest(GLcontext *ctx,
+ GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLvoid *ptr,
+ const char *where)
+{
+ ASSERT(dimensions == 1 || dimensions == 2 || dimensions == 3);
+
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
+ /* non-PBO access: no validation to be done */
+ return ptr;
+ }
+
+ if (!_mesa_validate_pbo_access(dimensions, unpack,
+ width, height, depth, format, type, ptr)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(out of bounds PBO access)", where);
+ return NULL;
+ }
+
+ if (_mesa_bufferobj_mapped(unpack->BufferObj)) {
+ /* buffer is already mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "%s(PBO is mapped)", where);
+ return NULL;
+ }
+
+ ptr = _mesa_map_pbo_dest(ctx, unpack, ptr);
+ return ptr;
+}
+
+
+/**
+ * Counterpart to _mesa_map_pbo_dest()
*/
void
-_mesa_unmap_readpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *pack)
+_mesa_unmap_pbo_dest(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack)
{
- if (pack->BufferObj->Name) {
+ ASSERT(pack != &ctx->Unpack); /* catch pack/unpack mismatch */
+ if (_mesa_is_bufferobj(pack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT, pack->BufferObj);
}
}
@@ -932,7 +992,7 @@ _mesa_DeleteBuffersARB(GLsizei n, const GLuint *ids)
ASSERT(bufObj->Name == ids[i]);
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* if mapped, unmap it now */
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
@@ -1086,22 +1146,20 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
_mesa_error(ctx, GL_INVALID_ENUM, "glBufferDataARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glBufferDataARB(buffer 0)" );
return;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
/* Unmap the existing buffer. We'll replace it now. Not an error. */
ctx->Driver.UnmapBuffer(ctx, target, bufObj);
bufObj->AccessFlags = DEFAULT_ACCESS;
- bufObj->Pointer = NULL;
+ ASSERT(bufObj->Pointer == NULL);
}
FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
- ASSERT(ctx->Driver.BufferData);
-
bufObj->Written = GL_TRUE;
#ifdef VBO_DEBUG
@@ -1112,8 +1170,11 @@ _mesa_BufferDataARB(GLenum target, GLsizeiptrARB size,
#ifdef BOUNDS_CHECK
size += 100;
#endif
- /* Give the buffer object to the driver! <data> may be null! */
- ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj );
+
+ ASSERT(ctx->Driver.BufferData);
+ if (!ctx->Driver.BufferData( ctx, target, size, data, usage, bufObj )) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB()");
+ }
}
@@ -1165,6 +1226,8 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object * bufObj;
GLbitfield accessFlags;
+ void *map;
+
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
switch (access) {
@@ -1187,24 +1250,31 @@ _mesa_MapBufferARB(GLenum target, GLenum access)
_mesa_error(ctx, GL_INVALID_ENUM, "glMapBufferARB(target)" );
return NULL;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(buffer 0)" );
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glMapBufferARB(already mapped)");
return NULL;
}
ASSERT(ctx->Driver.MapBuffer);
- bufObj->Pointer = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
- if (!bufObj->Pointer) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(access)");
+ map = ctx->Driver.MapBuffer( ctx, target, access, bufObj );
+ if (!map) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
+ return NULL;
+ }
+ else {
+ /* The driver callback should have set these fields.
+ * This is important because other modules (like VBO) might call
+ * the driver function directly.
+ */
+ ASSERT(bufObj->Pointer == map);
+ ASSERT(bufObj->Length == bufObj->Size);
+ ASSERT(bufObj->Offset == 0);
+ bufObj->AccessFlags = accessFlags;
}
-
- bufObj->AccessFlags = accessFlags;
- bufObj->Offset = 0;
- bufObj->Length = bufObj->Size;
if (access == GL_WRITE_ONLY_ARB || access == GL_READ_WRITE_ARB)
bufObj->Written = GL_TRUE;
@@ -1248,11 +1318,11 @@ _mesa_UnmapBufferARB(GLenum target)
_mesa_error(ctx, GL_INVALID_ENUM, "glUnmapBufferARB(target)" );
return GL_FALSE;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB" );
return GL_FALSE;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glUnmapBufferARB");
return GL_FALSE;
}
@@ -1295,9 +1365,9 @@ _mesa_UnmapBufferARB(GLenum target)
status = ctx->Driver.UnmapBuffer( ctx, target, bufObj );
bufObj->AccessFlags = DEFAULT_ACCESS;
- bufObj->Pointer = NULL;
- bufObj->Offset = 0;
- bufObj->Length = 0;
+ ASSERT(bufObj->Pointer == NULL);
+ ASSERT(bufObj->Offset == 0);
+ ASSERT(bufObj->Length == 0);
return status;
}
@@ -1315,7 +1385,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
_mesa_error(ctx, GL_INVALID_ENUM, "GetBufferParameterivARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "GetBufferParameterivARB" );
return;
}
@@ -1331,7 +1401,7 @@ _mesa_GetBufferParameterivARB(GLenum target, GLenum pname, GLint *params)
*params = simplified_access_mode(bufObj->AccessFlags);
break;
case GL_BUFFER_MAPPED_ARB:
- *params = (bufObj->Pointer != NULL);
+ *params = _mesa_bufferobj_mapped(bufObj);
break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferParameterivARB(pname)");
@@ -1357,7 +1427,7 @@ _mesa_GetBufferPointervARB(GLenum target, GLenum pname, GLvoid **params)
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBufferPointervARB(target)" );
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glGetBufferPointervARB" );
return;
}
@@ -1376,26 +1446,26 @@ _mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget,
ASSERT_OUTSIDE_BEGIN_END(ctx);
src = get_buffer(ctx, readTarget);
- if (!src || src->Name == 0) {
+ if (!src || !_mesa_is_bufferobj(src)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(readTarget = 0x%x)", readTarget);
return;
}
dst = get_buffer(ctx, writeTarget);
- if (!dst || dst->Name == 0) {
+ if (!dst || !_mesa_is_bufferobj(dst)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glCopyBuffserSubData(writeTarget = 0x%x)", writeTarget);
return;
}
- if (src->Pointer) {
+ if (_mesa_bufferobj_mapped(src)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(readBuffer is mapped)");
return;
}
- if (dst->Pointer) {
+ if (_mesa_bufferobj_mapped(dst)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyBuffserSubData(writeBuffer is mapped)");
return;
@@ -1455,6 +1525,8 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
{
GET_CURRENT_CONTEXT(ctx);
struct gl_buffer_object *bufObj;
+ void *map;
+
ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, NULL);
if (!ctx->Extensions.ARB_map_buffer_range) {
@@ -1499,7 +1571,7 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
}
bufObj = get_buffer(ctx, target);
- if (!bufObj || bufObj->Name == 0) {
+ if (!bufObj || !_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_ENUM,
"glMapBufferRange(target = 0x%x)", target);
return NULL;
@@ -1511,21 +1583,30 @@ _mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length,
return NULL;
}
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer already mapped)");
return NULL;
}
ASSERT(ctx->Driver.MapBufferRange);
- bufObj->Pointer = ctx->Driver.MapBufferRange(ctx, target, offset, length,
- access, bufObj);
-
- bufObj->Offset = offset;
- bufObj->Length = length;
- bufObj->AccessFlags = access;
+ map = ctx->Driver.MapBufferRange(ctx, target, offset, length,
+ access, bufObj);
+ if (!map) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMapBufferARB(map failed)");
+ }
+ else {
+ /* The driver callback should have set all these fields.
+ * This is important because other modules (like VBO) might call
+ * the driver function directly.
+ */
+ ASSERT(bufObj->Pointer == map);
+ ASSERT(bufObj->Length == length);
+ ASSERT(bufObj->Offset == offset);
+ ASSERT(bufObj->AccessFlags == access);
+ }
- return bufObj->Pointer;
+ return map;
}
@@ -1564,13 +1645,13 @@ _mesa_FlushMappedBufferRange(GLenum target, GLintptr offset, GLsizeiptr length)
return;
}
- if (bufObj->Name == 0) {
+ if (!_mesa_is_bufferobj(bufObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(current buffer is 0)");
return;
}
- if (!bufObj->Pointer) {
+ if (!_mesa_bufferobj_mapped(bufObj)) {
/* buffer is not mapped */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glMapBufferRange(buffer is not mapped)");
diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h
index ef59ff83c8..9f732ec0c0 100644
--- a/src/mesa/main/bufferobj.h
+++ b/src/mesa/main/bufferobj.h
@@ -36,6 +36,26 @@
* Internal functions
*/
+
+/** Is the given buffer object currently mapped? */
+static INLINE GLboolean
+_mesa_bufferobj_mapped(const struct gl_buffer_object *obj)
+{
+ return obj->Pointer != NULL;
+}
+
+/**
+ * Is the given buffer object a user-created buffer object?
+ * Mesa uses default buffer objects in several places. Default buffers
+ * always have Name==0. User created buffers have Name!=0.
+ */
+static INLINE GLboolean
+_mesa_is_bufferobj(const struct gl_buffer_object *obj)
+{
+ return obj->Name != 0;
+}
+
+
extern void
_mesa_init_buffer_objects( GLcontext *ctx );
@@ -61,32 +81,39 @@ _mesa_validate_pbo_access(GLuint dimensions,
GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid *ptr);
-extern const GLubyte *
-_mesa_map_bitmap_pbo(GLcontext *ctx,
+extern const GLvoid *
+_mesa_map_pbo_source(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack,
- const GLubyte *bitmap);
-
-extern void
-_mesa_unmap_bitmap_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack);
+ const GLvoid *src);
extern const GLvoid *
-_mesa_map_drawpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack,
- const GLvoid *pixels);
+_mesa_map_validate_pbo_source(GLcontext *ctx,
+ GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, const GLvoid *ptr,
+ const char *where);
extern void
-_mesa_unmap_drawpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *unpack);
+_mesa_unmap_pbo_source(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *unpack);
extern void *
-_mesa_map_readpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *pack,
- GLvoid *dest);
+_mesa_map_pbo_dest(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack,
+ GLvoid *dest);
+
+extern GLvoid *
+_mesa_map_validate_pbo_dest(GLcontext *ctx,
+ GLuint dimensions,
+ const struct gl_pixelstore_attrib *unpack,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type, GLvoid *ptr,
+ const char *where);
extern void
-_mesa_unmap_readpix_pbo(GLcontext *ctx,
- const struct gl_pixelstore_attrib *pack);
+_mesa_unmap_pbo_dest(GLcontext *ctx,
+ const struct gl_pixelstore_attrib *pack);
extern void
diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c
index bd9cf438b4..5447eb18ef 100644
--- a/src/mesa/main/colortab.c
+++ b/src/mesa/main/colortab.c
@@ -31,6 +31,7 @@
#include "macros.h"
#include "state.h"
#include "teximage.h"
+#include "texstate.h"
/**
@@ -179,26 +180,12 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
GLfloat bScale, GLfloat bBias,
GLfloat aScale, GLfloat aBias)
{
- if (ctx->Unpack.BufferObj->Name) {
- /* Get/unpack the color table data from a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Unpack, count, 1, 1,
- format, type, data)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glColor[Sub]Table(bad PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glColor[Sub]Table(PBO mapped)");
- return;
- }
- data = ADD_POINTERS(buf, data);
- }
-
+ data = _mesa_map_validate_pbo_source(ctx,
+ 1, &ctx->Unpack, count, 1, 1,
+ format, type, data,
+ "glColor[Sub]Table");
+ if (!data)
+ return;
{
/* convert user-provided data to GLfloat values */
@@ -279,10 +266,7 @@ store_colortable_entries(GLcontext *ctx, struct gl_color_table *table,
}
}
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
}
@@ -295,7 +279,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;
@@ -460,7 +444,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;
@@ -559,7 +543,10 @@ _mesa_CopyColorTable(GLenum target, GLenum internalformat,
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 );
}
@@ -572,6 +559,10 @@ _mesa_CopyColorSubTable(GLenum target, GLsizei start,
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 );
}
@@ -582,7 +573,7 @@ _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);
@@ -696,34 +687,17 @@ _mesa_GetColorTable( GLenum target, GLenum format,
return;
}
- if (ctx->Pack.BufferObj->Name) {
- /* pack color table into PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Pack, table->Size, 1, 1,
- format, type, data)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetColorTable(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetColorTable(PBO is mapped)");
- return;
- }
- data = ADD_POINTERS(buf, data);
- }
+ data = _mesa_map_validate_pbo_dest(ctx,
+ 1, &ctx->Pack, table->Size, 1, 1,
+ format, type, data,
+ "glGetColorTable");
+ if (!data)
+ return;
_mesa_pack_rgba_span_float(ctx, table->Size, rgba,
format, type, data, &ctx->Pack, 0x0);
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
@@ -800,7 +774,7 @@ 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);
@@ -927,7 +901,7 @@ 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);
diff --git a/src/mesa/main/compiler.h b/src/mesa/main/compiler.h
index e79bbc2ac5..9319505a75 100644
--- a/src/mesa/main/compiler.h
+++ b/src/mesa/main/compiler.h
@@ -110,10 +110,8 @@ extern "C" {
#if defined(_WIN32) && !defined(__WIN32__) && !defined(__CYGWIN__) && !defined(BUILD_FOR_SNAP)
# define __WIN32__
# define finite _finite
-#endif
-#if defined(__WATCOMC__)
+#elif defined(__WATCOMC__)
# define finite _finite
-# pragma disable_message(201) /* Disable unreachable code warnings */
#endif
@@ -135,6 +133,10 @@ extern "C" {
# endif
# endif
#endif
+#if defined(__WATCOMC__)
+# pragma disable_message(201) /* Disable unreachable code warnings */
+#endif
+
/**
diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h
index f77a29a43e..8a09efdb53 100644
--- a/src/mesa/main/config.h
+++ b/src/mesa/main/config.h
@@ -138,9 +138,14 @@
/**
* Maximum viewport/image width. Must accomodate all texture sizes too.
*/
-#define MAX_WIDTH 4096
+
+#ifndef MAX_WIDTH
+# define MAX_WIDTH 4096
+#endif
/** Maximum viewport/image height */
-#define MAX_HEIGHT 4096
+#ifndef MAX_HEIGHT
+# define MAX_HEIGHT 4096
+#endif
/** Maxmimum size for CVA. May be overridden by the drivers. */
#define MAX_ARRAY_LOCK_SIZE 3000
@@ -165,9 +170,48 @@
/** For GL_EXT_texture_lod_bias (typically MAX_TEXTURE_LEVELS - 1) */
#define MAX_TEXTURE_LOD_BIAS 12.0
+/** For any program target/extension */
+/*@{*/
+#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024)
+
+/**
+ * Per-program constants (power of two)
+ *
+ * \c MAX_PROGRAM_LOCAL_PARAMS and \c MAX_UNIFORMS are just the assmebly shader
+ * and GLSL shader names for the same thing. They should \b always have the
+ * same value. Each refers to the number of vec4 values supplied as
+ * per-program parameters.
+ */
+/*@{*/
+#define MAX_PROGRAM_LOCAL_PARAMS 1024
+#define MAX_UNIFORMS 1024
+/*@}*/
+
+/**
+ * Per-context constants (power of two)
+ *
+ * \note
+ * This value should always be less than or equal to \c MAX_PROGRAM_LOCAL_PARAMS
+ * and \c MAX_VERTEX_PROGRAM_PARAMS. Otherwise some applications will make
+ * incorrect assumptions.
+ */
+#define MAX_PROGRAM_ENV_PARAMS 256
+
+#define MAX_PROGRAM_MATRICES 8
+#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
+#define MAX_PROGRAM_CALL_DEPTH 8
+#define MAX_PROGRAM_TEMPS 256
+#define MAX_PROGRAM_ADDRESS_REGS 2
+#define MAX_VARYING 16 /**< number of float[4] vectors */
+#define MAX_SAMPLERS MAX_TEXTURE_IMAGE_UNITS
+#define MAX_PROGRAM_INPUTS 32
+#define MAX_PROGRAM_OUTPUTS 32
+/*@}*/
+
/** For GL_ARB_vertex_program */
/*@{*/
#define MAX_VERTEX_PROGRAM_ADDRESS_REGS 1
+#define MAX_VERTEX_PROGRAM_PARAMS MAX_UNIFORMS
/*@}*/
/** For GL_ARB_fragment_program */
@@ -175,23 +219,6 @@
#define MAX_FRAGMENT_PROGRAM_ADDRESS_REGS 0
/*@}*/
-/** For any program target/extension */
-/*@{*/
-#define MAX_PROGRAM_INSTRUCTIONS (16 * 1024)
-#define MAX_PROGRAM_LOCAL_PARAMS 256 /**< per-program constants (power of two) */
-#define MAX_PROGRAM_ENV_PARAMS 256 /**< per-context constants (power of two) */
-#define MAX_PROGRAM_MATRICES 8
-#define MAX_PROGRAM_MATRIX_STACK_DEPTH 4
-#define MAX_PROGRAM_CALL_DEPTH 8
-#define MAX_PROGRAM_TEMPS 256
-#define MAX_PROGRAM_ADDRESS_REGS 2
-#define MAX_UNIFORMS 1024 /**< number of vec4 uniforms */
-#define MAX_VARYING 16 /**< number of float[4] vectors */
-#define MAX_SAMPLERS MAX_TEXTURE_IMAGE_UNITS
-#define MAX_PROGRAM_INPUTS 32
-#define MAX_PROGRAM_OUTPUTS 32
-/*@}*/
-
/** For GL_NV_vertex_program */
/*@{*/
#define MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS 128
diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c
index 415e339cb8..f6d4ac4595 100644
--- a/src/mesa/main/context.c
+++ b/src/mesa/main/context.c
@@ -129,6 +129,9 @@
#if FEATURE_ARB_occlusion_query
#include "queryobj.h"
#endif
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+#endif
#if FEATURE_drawpix
#include "rastpos.h"
#endif
@@ -150,6 +153,7 @@
#include "glapi/glapioffsets.h"
#include "glapi/glapitable.h"
#include "shader/program.h"
+#include "shader/prog_print.h"
#include "shader/shader_api.h"
#if FEATURE_ATI_fragment_shader
#include "shader/atifragshader.h"
@@ -486,7 +490,7 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
prog->MaxUniformComponents = 4 * MAX_UNIFORMS;
if (type == GL_VERTEX_PROGRAM_ARB) {
- prog->MaxParameters = MAX_NV_VERTEX_PROGRAM_PARAMS;
+ prog->MaxParameters = MAX_VERTEX_PROGRAM_PARAMS;
prog->MaxAttribs = MAX_NV_VERTEX_PROGRAM_INPUTS;
prog->MaxAddressRegs = MAX_VERTEX_PROGRAM_ADDRESS_REGS;
}
@@ -496,15 +500,17 @@ init_program_limits(GLenum type, struct gl_program_constants *prog)
prog->MaxAddressRegs = MAX_FRAGMENT_PROGRAM_ADDRESS_REGS;
}
- /* copy the above limits to init native limits */
- prog->MaxNativeInstructions = prog->MaxInstructions;
- prog->MaxNativeAluInstructions = prog->MaxAluInstructions;
- prog->MaxNativeTexInstructions = prog->MaxTexInstructions;
- prog->MaxNativeTexIndirections = prog->MaxTexIndirections;
- prog->MaxNativeAttribs = prog->MaxAttribs;
- prog->MaxNativeTemps = prog->MaxTemps;
- prog->MaxNativeAddressRegs = prog->MaxAddressRegs;
- prog->MaxNativeParameters = prog->MaxParameters;
+ /* Set the native limits to zero. This implies that there is no native
+ * support for shaders. Let the drivers fill in the actual values.
+ */
+ prog->MaxNativeInstructions = 0;
+ prog->MaxNativeAluInstructions = 0;
+ prog->MaxNativeTexInstructions = 0;
+ prog->MaxNativeTexIndirections = 0;
+ prog->MaxNativeAttribs = 0;
+ prog->MaxNativeTemps = 0;
+ prog->MaxNativeAddressRegs = 0;
+ prog->MaxNativeParameters = 0;
}
@@ -589,6 +595,9 @@ _mesa_init_constants(GLcontext *ctx)
/* GL_ARB_framebuffer_object */
ctx->Const.MaxSamples = 0;
+ /* GL_ARB_sync */
+ ctx->Const.MaxServerWaitTimeout = (GLuint64) ~0;
+
/* GL_ATI_envmap_bumpmap */
ctx->Const.SupportedBumpUnits = SUPPORTED_ATI_BUMP_UNITS;
@@ -712,6 +721,9 @@ init_attrib_groups(GLcontext *ctx)
#if FEATURE_ARB_occlusion_query
_mesa_init_query( ctx );
#endif
+#if FEATURE_ARB_sync
+ _mesa_init_sync( ctx );
+#endif
#if FEATURE_drawpix
_mesa_init_rastpos( ctx );
#endif
@@ -1011,6 +1023,9 @@ _mesa_free_context_data( GLcontext *ctx )
#if FEATURE_ARB_occlusion_query
_mesa_free_query_data(ctx);
#endif
+#if FEATURE_ARB_sync
+ _mesa_free_sync_data(ctx);
+#endif
_mesa_free_varray_data(ctx);
_mesa_delete_array_object(ctx, ctx->Array.DefaultArrayObj);
@@ -1576,4 +1591,82 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
}
+
+/**
+ * Prior to drawing anything with glBegin, glDrawArrays, etc. this function
+ * is called to see if it's valid to render. This involves checking that
+ * the current shader is valid and the framebuffer is complete.
+ * If an error is detected it'll be recorded here.
+ * \return GL_TRUE if OK to render, GL_FALSE if not
+ */
+GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where)
+{
+ if (ctx->Shader.CurrentProgram) {
+ /* using shaders */
+ if (!ctx->Shader.CurrentProgram->LinkStatus) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(shader not linked), where");
+ return GL_FALSE;
+ }
+#if 0 /* not normally enabled */
+ {
+ char errMsg[100];
+ if (!_mesa_validate_shader_program(ctx, ctx->Shader.CurrentProgram,
+ errMsg)) {
+ _mesa_warning(ctx, "Shader program %u is invalid: %s",
+ ctx->Shader.CurrentProgram->Name, errMsg);
+ }
+ }
+#endif
+ }
+ else {
+ if (ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(vertex program not valid)", where);
+ return GL_FALSE;
+ }
+ if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "%s(fragment program not valid)", where);
+ return GL_FALSE;
+ }
+ }
+
+ if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
+ _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
+ "%s(incomplete framebuffer)", where);
+ return GL_FALSE;
+ }
+
+#ifdef DEBUG
+ if (ctx->Shader.Flags & GLSL_LOG) {
+ struct gl_shader_program *shProg = ctx->Shader.CurrentProgram;
+ if (shProg) {
+ if (!shProg->_Used) {
+ /* This is the first time this shader is being used.
+ * Append shader's constants/uniforms to log file.
+ */
+ GLuint i;
+ for (i = 0; i < shProg->NumShaders; i++) {
+ struct gl_shader *sh = shProg->Shaders[i];
+ if (sh->Type == GL_VERTEX_SHADER) {
+ _mesa_append_uniforms_to_file(sh,
+ &shProg->VertexProgram->Base);
+ }
+ else if (sh->Type == GL_FRAGMENT_SHADER) {
+ _mesa_append_uniforms_to_file(sh,
+ &shProg->FragmentProgram->Base);
+ }
+ }
+ shProg->_Used = GL_TRUE;
+ }
+ }
+ }
+#endif
+
+ return GL_TRUE;
+}
+
+
/*@}*/
diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h
index 0531ae8ee8..5587695fa0 100644
--- a/src/mesa/main/context.h
+++ b/src/mesa/main/context.h
@@ -159,6 +159,11 @@ _mesa_set_mvp_with_dp4( GLcontext *ctx,
GLboolean flag );
+extern GLboolean
+_mesa_valid_to_render(GLcontext *ctx, const char *where);
+
+
+
/** \name Miscellaneous */
/*@{*/
@@ -174,7 +179,6 @@ _mesa_Flush( void );
/*@}*/
-
/**
* \name Macros for flushing buffered rendering commands before state changes,
* checking if inside glBegin/glEnd, etc.
diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c
index 814c6a0a5a..bf6f6619d4 100644
--- a/src/mesa/main/convolve.c
+++ b/src/mesa/main/convolve.c
@@ -144,39 +144,19 @@ _mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution1D.Width = width;
ctx->Convolution1D.Height = 1;
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack filter from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
- format, type, image)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glConvolutionFilter1D(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glConvolutionFilter1D(PBO is mapped)");
- return;
- }
- image = ADD_POINTERS(buf, image);
- }
- else if (!image) {
+ image = _mesa_map_validate_pbo_source(ctx,
+ 1, &ctx->Unpack, width, 1, 1,
+ format, type, image,
+ "glConvolutionFilter1D");
+ if (!image)
return;
- }
_mesa_unpack_color_span_float(ctx, width, GL_RGBA,
ctx->Convolution1D.Filter,
format, type, image, &ctx->Unpack,
0); /* transferOps */
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
_mesa_scale_and_bias_rgba(width,
(GLfloat (*)[4]) ctx->Convolution1D.Filter,
@@ -242,29 +222,12 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
ctx->Convolution2D.Width = width;
ctx->Convolution2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack filter from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
- format, type, image)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glConvolutionFilter2D(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glConvolutionFilter2D(PBO is mapped)");
- return;
- }
- image = ADD_POINTERS(buf, image);
- }
- else if (!image) {
+ image = _mesa_map_validate_pbo_source(ctx,
+ 2, &ctx->Unpack, width, height, 1,
+ format, type, image,
+ "glConvolutionFilter2D");
+ if (!image)
return;
- }
/* Unpack filter image. We always store filters in RGBA format. */
for (i = 0; i < height; i++) {
@@ -276,10 +239,7 @@ _mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, G
0); /* transferOps */
}
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
_mesa_scale_and_bias_rgba(width * height,
(GLfloat (*)[4]) ctx->Convolution2D.Filter,
@@ -522,6 +482,10 @@ _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);
}
@@ -554,6 +518,10 @@ _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 );
}
@@ -598,27 +566,12 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
return;
}
- if (ctx->Pack.BufferObj->Name) {
- /* Pack the filter into a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &ctx->Pack,
- filter->Width, filter->Height,
- 1, format, type, image)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetConvolutionFilter(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetConvolutionFilter(PBO is mapped)");
- return;
- }
- image = ADD_POINTERS(image, buf);
- }
+ image = _mesa_map_validate_pbo_dest(ctx, 2, &ctx->Pack,
+ filter->Width, filter->Height, 1,
+ format, type, image,
+ "glGetConvolutionFilter");
+ if (!image)
+ return;
for (row = 0; row < filter->Height; row++) {
GLvoid *dst = _mesa_image_address2d(&ctx->Pack, image, filter->Width,
@@ -629,10 +582,7 @@ _mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type,
format, type, dst, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
@@ -802,59 +752,35 @@ _mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type,
filter = &ctx->Separable2D;
- if (ctx->Pack.BufferObj->Name) {
- /* Pack filter into PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Width, 1, 1,
- format, type, row)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetSeparableFilter(invalid PBO access, width)");
- return;
- }
- if (!_mesa_validate_pbo_access(1, &ctx->Pack, filter->Height, 1, 1,
- format, type, column)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetSeparableFilter(invalid PBO access, height)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetSeparableFilter(PBO is mapped)");
- return;
- }
- row = ADD_POINTERS(buf, row);
- column = ADD_POINTERS(buf, column);
- }
-
- /* Row filter */
+ /* Get row filter */
+ row = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack,
+ filter->Width, 1, 1,
+ format, type, row,
+ "glGetConvolutionFilter");
if (row) {
GLvoid *dst = _mesa_image_address1d(&ctx->Pack, row, filter->Width,
format, type, 0);
_mesa_pack_rgba_span_float(ctx, filter->Width,
(GLfloat (*)[4]) filter->Filter,
format, type, dst, &ctx->Pack, 0x0);
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
- /* Column filter */
+ /* get column filter */
+ column = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack,
+ filter->Height, 1, 1,
+ format, type, column,
+ "glGetConvolutionFilter");
if (column) {
GLvoid *dst = _mesa_image_address1d(&ctx->Pack, column, filter->Height,
format, type, 0);
GLfloat (*src)[4] = (GLfloat (*)[4]) (filter->Filter + colStart);
_mesa_pack_rgba_span_float(ctx, filter->Height, src,
format, type, dst, &ctx->Pack, 0x0);
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
(void) span; /* unused at this time */
-
- if (ctx->Pack.BufferObj->Name) {
- /* Pack filter into PBO */
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
}
@@ -905,41 +831,16 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Separable2D.Width = width;
ctx->Separable2D.Height = height;
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack filter from PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Unpack, width, 1, 1,
- format, type, row)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glSeparableFilter2D(invalid PBO access, width)");
- return;
- }
- if (!_mesa_validate_pbo_access(1, &ctx->Unpack, height, 1, 1,
- format, type, column)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glSeparableFilter2D(invalid PBO access, height)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glSeparableFilter2D(PBO is mapped)");
- return;
- }
- row = ADD_POINTERS(buf, row);
- column = ADD_POINTERS(buf, column);
- }
-
/* unpack row filter */
+ row = _mesa_map_validate_pbo_source(ctx, 1, &ctx->Unpack,
+ width, 1, 1,
+ format, type, row,
+ "glSeparableFilter2D");
if (row) {
_mesa_unpack_color_span_float(ctx, width, GL_RGBA,
ctx->Separable2D.Filter,
format, type, row, &ctx->Unpack,
- 0); /* transferOps */
-
+ 0x0); /* transferOps */
_mesa_scale_and_bias_rgba(width,
(GLfloat (*)[4]) ctx->Separable2D.Filter,
ctx->Pixel.ConvolutionFilterScale[2][0],
@@ -950,9 +851,14 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Pixel.ConvolutionFilterBias[2][1],
ctx->Pixel.ConvolutionFilterBias[2][2],
ctx->Pixel.ConvolutionFilterBias[2][3]);
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
}
/* unpack column filter */
+ column = _mesa_map_validate_pbo_source(ctx, 1, &ctx->Unpack,
+ height, 1, 1,
+ format, type, column,
+ "glSeparableFilter2D");
if (column) {
_mesa_unpack_color_span_float(ctx, height, GL_RGBA,
&ctx->Separable2D.Filter[colStart],
@@ -969,9 +875,10 @@ _mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLs
ctx->Pixel.ConvolutionFilterBias[2][1],
ctx->Pixel.ConvolutionFilterBias[2][2],
ctx->Pixel.ConvolutionFilterBias[2][3]);
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
}
- if (ctx->Unpack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
ctx->Unpack.BufferObj);
}
diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h
index 1d92e510a4..ce5e158626 100644
--- a/src/mesa/main/dd.h
+++ b/src/mesa/main/dd.h
@@ -766,6 +766,8 @@ struct dd_function_table {
/** Return the value or values of a selected parameter */
GLboolean (*GetIntegerv)(GLcontext *ctx, GLenum pname, GLint *result);
/** Return the value or values of a selected parameter */
+ GLboolean (*GetInteger64v)(GLcontext *ctx, GLenum pname, GLint64 *result);
+ /** Return the value or values of a selected parameter */
GLboolean (*GetPointerv)(GLcontext *ctx, GLenum pname, GLvoid **result);
/*@}*/
@@ -783,9 +785,9 @@ struct dd_function_table {
void (*DeleteBuffer)( GLcontext *ctx, struct gl_buffer_object *obj );
- void (*BufferData)( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
- const GLvoid *data, GLenum usage,
- struct gl_buffer_object *obj );
+ GLboolean (*BufferData)( GLcontext *ctx, GLenum target, GLsizeiptrARB size,
+ const GLvoid *data, GLenum usage,
+ struct gl_buffer_object *obj );
void (*BufferSubData)( GLcontext *ctx, GLenum target, GLintptrARB offset,
GLsizeiptrARB size, const GLvoid *data,
@@ -1042,6 +1044,22 @@ struct dd_function_table {
*/
void (*EndCallList)( GLcontext *ctx );
+
+#if FEATURE_ARB_sync
+ /**
+ * \name GL_ARB_sync interfaces
+ */
+ /*@{*/
+ struct gl_sync_object * (*NewSyncObject)(GLcontext *, GLenum);
+ void (*FenceSync)(GLcontext *, struct gl_sync_object *, GLenum, GLbitfield);
+ void (*DeleteSyncObject)(GLcontext *, struct gl_sync_object *);
+ void (*CheckSync)(GLcontext *, struct gl_sync_object *);
+ void (*ClientWaitSync)(GLcontext *, struct gl_sync_object *,
+ GLbitfield, GLuint64);
+ void (*ServerWaitSync)(GLcontext *, struct gl_sync_object *,
+ GLbitfield, GLuint64);
+ /*@}*/
+#endif
};
@@ -1150,6 +1168,25 @@ typedef struct {
void (GLAPIENTRYP DrawRangeElements)( GLenum mode, GLuint start,
GLuint end, GLsizei count,
GLenum type, const GLvoid *indices );
+ void (GLAPIENTRYP MultiDrawElementsEXT)( GLenum mode, const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount);
+ void (GLAPIENTRYP DrawElementsBaseVertex)( GLenum mode, GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex );
+ void (GLAPIENTRYP DrawRangeElementsBaseVertex)( GLenum mode, GLuint start,
+ GLuint end, GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex);
+ void (GLAPIENTRYP MultiDrawElementsBaseVertex)( GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount,
+ const GLint *basevertex);
/*@}*/
/**
diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c
index 1c8c44fcb9..8492c8561d 100644
--- a/src/mesa/main/debug.c
+++ b/src/mesa/main/debug.c
@@ -33,6 +33,7 @@
#include "get.h"
#include "pixelstore.h"
#include "readpix.h"
+#include "texgetimage.h"
#include "texobj.h"
#include "texformat.h"
@@ -234,11 +235,11 @@ _mesa_init_debug( GLcontext *ctx )
*/
static void
write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
- int comps, int rcomp, int gcomp, int bcomp)
+ int comps, int rcomp, int gcomp, int bcomp, GLboolean invert)
{
FILE *f = fopen( filename, "w" );
if (f) {
- int i, x, y;
+ int x, y;
const GLubyte *ptr = buffer;
fprintf(f,"P6\n");
fprintf(f,"# ppm-file created by osdemo.c\n");
@@ -246,10 +247,11 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
fprintf(f,"255\n");
fclose(f);
f = fopen( filename, "ab" ); /* reopen in binary append mode */
- for (y=height-1; y>=0; y--) {
- for (x=0; x<width; x++) {
- i = (y*width + x) * comps;
- fputc(ptr[i+rcomp], f); /* write red */
+ for (y=0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int yy = invert ? (height - 1 - y) : y;
+ int i = (yy * width + x) * comps;
+ fputc(ptr[i+rcomp], f); /* write red */
fputc(ptr[i+gcomp], f); /* write green */
fputc(ptr[i+bcomp], f); /* write blue */
}
@@ -263,47 +265,34 @@ write_ppm(const char *filename, const GLubyte *buffer, int width, int height,
* Write level[0] image to a ppm file.
*/
static void
-write_texture_image(struct gl_texture_object *texObj)
+write_texture_image(struct gl_texture_object *texObj, GLuint face, GLuint level)
{
- const struct gl_texture_image *img = texObj->Image[0][0];
- if (img && img->Data) {
+ struct gl_texture_image *img = texObj->Image[face][level];
+ if (img) {
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_pixelstore_attrib store;
+ GLubyte *buffer;
char s[100];
+ buffer = (GLubyte *) _mesa_malloc(img->Width * img->Height
+ * img->Depth * 4);
+
+ store = ctx->Pack; /* save */
+ ctx->Pack = ctx->DefaultPacking;
+
+ ctx->Driver.GetTexImage(ctx, texObj->Target, level,
+ GL_RGBA, GL_UNSIGNED_BYTE,
+ buffer, texObj, img);
+
/* make filename */
- sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
-
- switch (img->TexFormat->MesaFormat) {
- case MESA_FORMAT_RGBA8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 3, 2, 1);
- break;
- case MESA_FORMAT_ARGB8888:
- write_ppm(s, img->Data, img->Width, img->Height, 4, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB888:
- write_ppm(s, img->Data, img->Width, img->Height, 3, 2, 1, 0);
- break;
- case MESA_FORMAT_RGB565:
- {
- GLubyte *buf2 = (GLubyte *) _mesa_malloc(img->Width * img->Height * 3);
- GLuint i;
- for (i = 0; i < img->Width * img->Height; i++) {
- GLint r, g, b;
- GLushort s = ((GLushort *) img->Data)[i];
- r = UBYTE_TO_CHAN( ((s >> 8) & 0xf8) | ((s >> 13) & 0x7) );
- g = UBYTE_TO_CHAN( ((s >> 3) & 0xfc) | ((s >> 9) & 0x3) );
- b = UBYTE_TO_CHAN( ((s << 3) & 0xf8) | ((s >> 2) & 0x7) );
- buf2[i*3+1] = r;
- buf2[i*3+2] = g;
- buf2[i*3+3] = b;
- }
- write_ppm(s, buf2, img->Width, img->Height, 3, 2, 1, 0);
- _mesa_free(buf2);
- }
- break;
- default:
- printf("XXXX unsupported mesa tex format %d in %s\n",
- img->TexFormat->MesaFormat, __FUNCTION__);
- }
+ _mesa_sprintf(s, "/tmp/teximage%u.ppm", texObj->Name);
+
+ _mesa_printf(" Writing image level %u to %s\n", level, s);
+ write_ppm(s, buffer, img->Width, img->Height, 4, 0, 1, 2, GL_FALSE);
+
+ ctx->Pack = store; /* restore */
+
+ _mesa_free(buffer);
}
}
@@ -316,17 +305,21 @@ dump_texture_cb(GLuint id, void *data, void *userData)
{
struct gl_texture_object *texObj = (struct gl_texture_object *) data;
int i;
+ GLboolean written = GL_FALSE;
(void) userData;
- printf("Texture %u\n", texObj->Name);
- printf(" Target 0x%x\n", texObj->Target);
+ _mesa_printf("Texture %u\n", texObj->Name);
+ _mesa_printf(" Target 0x%x\n", texObj->Target);
for (i = 0; i < MAX_TEXTURE_LEVELS; i++) {
struct gl_texture_image *texImg = texObj->Image[0][i];
if (texImg) {
- printf(" Image %u: %d x %d x %d at %p\n", i,
- texImg->Width, texImg->Height, texImg->Depth, texImg->Data);
- if (DumpImages && i == 0) {
- write_texture_image(texObj);
+ _mesa_printf(" Image %u: %d x %d x %d, format %u at %p\n", i,
+ texImg->Width, texImg->Height, texImg->Depth,
+ texImg->TexFormat->MesaFormat, texImg->Data);
+ if (DumpImages && !written) {
+ GLuint face = 0;
+ write_texture_image(texObj, face, i);
+ written = GL_TRUE;
}
}
}
@@ -368,7 +361,7 @@ _mesa_dump_color_buffer(const char *filename)
ctx->DrawBuffer->_ColorDrawBuffers[0],
ctx->DrawBuffer->ColorDrawBuffer[0]);
_mesa_printf("Writing %d x %d color buffer to %s\n", w, h, filename);
- write_ppm(filename, buf, w, h, 4, 0, 1, 2);
+ write_ppm(filename, buf, w, h, 4, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -403,7 +396,7 @@ _mesa_dump_depth_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d depth buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
@@ -438,7 +431,7 @@ _mesa_dump_stencil_buffer(const char *filename)
}
_mesa_printf("Writing %d x %d stencil buffer to %s\n", w, h, filename);
- write_ppm(filename, buf2, w, h, 3, 0, 1, 2);
+ write_ppm(filename, buf2, w, h, 3, 0, 1, 2, GL_TRUE);
_mesa_PopClientAttrib();
diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c
index 49f202daa1..9c25de4187 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);
@@ -683,24 +735,48 @@ translate_id(GLsizei n, GLenum type, const GLvoid * list)
/**
* Wrapper for _mesa_unpack_image() that handles pixel buffer objects.
- * \todo This won't suffice when the PBO is really in VRAM/GPU memory.
+ * If we run out of memory, GL_OUT_OF_MEMORY will be recorded.
*/
static GLvoid *
-unpack_image(GLuint dimensions, GLsizei width, GLsizei height, GLsizei depth,
+unpack_image(GLcontext *ctx, GLuint dimensions,
+ GLsizei width, GLsizei height, GLsizei depth,
GLenum format, GLenum type, const GLvoid * pixels,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, pixels, unpack);
+ GLvoid *image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, pixels, unpack);
+ if (pixels && !image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
- else
- if (_mesa_validate_pbo_access
- (dimensions, unpack, width, height, depth, format, type, pixels)) {
- const GLubyte *src = ADD_POINTERS(unpack->BufferObj->Data, pixels);
- return _mesa_unpack_image(dimensions, width, height, depth, format,
- type, src, unpack);
+ else if (_mesa_validate_pbo_access(dimensions, unpack, width, height, depth,
+ format, type, pixels)) {
+ const GLubyte *map, *src;
+ GLvoid *image;
+
+ map = (GLubyte *)
+ ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ GL_READ_ONLY_ARB, unpack->BufferObj);
+ if (!map) {
+ /* unable to map src buffer! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO");
+ return NULL;
+ }
+
+ src = ADD_POINTERS(map, pixels);
+ image = _mesa_unpack_image(dimensions, width, height, depth,
+ format, type, src, unpack);
+
+ ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
+ unpack->BufferObj);
+
+ if (!image) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction");
+ }
+ return image;
}
/* bad access! */
return NULL;
@@ -858,7 +934,6 @@ save_Bitmap(GLsizei width, GLsizei height,
GLfloat xmove, GLfloat ymove, const GLubyte * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_BITMAP, 7);
@@ -869,10 +944,7 @@ save_Bitmap(GLsizei width, GLsizei height,
n[4].f = yorig;
n[5].f = xmove;
n[6].f = ymove;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = _mesa_unpack_bitmap(width, height, pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_Bitmap(ctx->Exec, (width, height,
@@ -999,7 +1071,7 @@ _mesa_save_CallList(GLuint list)
void GLAPIENTRY
-_mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
+_mesa_save_CallLists(GLsizei num, GLenum type, const GLvoid * lists)
{
GET_CURRENT_CONTEXT(ctx);
GLint i;
@@ -1024,7 +1096,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
typeErrorFlag = GL_TRUE;
}
- for (i = 0; i < n; i++) {
+ for (i = 0; i < num; i++) {
GLint list = translate_id(i, type, lists);
Node *n = ALLOC_INSTRUCTION(ctx, OPCODE_CALL_LIST_OFFSET, 2);
if (n) {
@@ -1039,7 +1111,7 @@ _mesa_save_CallLists(GLsizei n, GLenum type, const GLvoid * lists)
invalidate_saved_current_state( ctx );
if (ctx->ExecuteFlag) {
- CALL_CallLists(ctx->Exec, (n, type, lists));
+ CALL_CallLists(ctx->Exec, (num, type, lists));
}
}
@@ -1217,8 +1289,6 @@ save_ColorTable(GLenum target, GLenum internalFormat,
format, type, table));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_TABLE, 6);
@@ -1228,10 +1298,8 @@ save_ColorTable(GLenum target, GLenum internalFormat,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorTable(ctx->Exec, (target, internalFormat, width,
@@ -1307,8 +1375,6 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
GLenum format, GLenum type, const GLvoid * table)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, count, 1, 1, format, type, table,
- &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_COLOR_SUB_TABLE, 6);
@@ -1318,10 +1384,8 @@ save_ColorSubTable(GLenum target, GLsizei start, GLsizei count,
n[3].i = count;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, count, 1, 1, format, type, table,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ColorSubTable(ctx->Exec,
@@ -1379,10 +1443,10 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
GLenum format, GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(1, width, 1, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_1D, 6);
if (n) {
n[1].e = target;
@@ -1390,10 +1454,8 @@ save_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width,
n[3].i = width;
n[4].e = format;
n[5].e = type;
- n[6].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[6].data = unpack_image(ctx, 1, width, 1, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter1D(ctx->Exec, (target, internalFormat, width,
@@ -1408,10 +1470,10 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
GLenum type, const GLvoid * filter)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type, filter,
- &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_CONVOLUTION_FILTER_2D, 7);
if (n) {
n[1].e = target;
@@ -1420,10 +1482,8 @@ save_ConvolutionFilter2D(GLenum target, GLenum internalFormat,
n[4].i = height;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 2, width, height, 1, format, type, filter,
+ &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_ConvolutionFilter2D(ctx->Exec,
@@ -1778,20 +1838,18 @@ save_DrawPixels(GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid * pixels)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_DRAW_PIXELS, 5);
if (n) {
n[1].i = width;
n[2].i = height;
n[3].e = format;
n[4].e = type;
- n[5].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[5].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels));
@@ -1880,7 +1938,10 @@ save_Fogfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_Fogf(GLenum pname, GLfloat param)
{
- save_Fogfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Fogfv(pname, parray);
}
@@ -1904,7 +1965,7 @@ save_Fogiv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_Fogfv(pname, p);
}
@@ -1913,7 +1974,10 @@ save_Fogiv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Fogi(GLenum pname, GLint param)
{
- save_Fogiv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Fogiv(pname, parray);
}
@@ -2077,9 +2141,12 @@ save_Lightfv(GLenum light, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
-save_Lightf(GLenum light, GLenum pname, GLfloat params)
+save_Lightf(GLenum light, GLenum pname, GLfloat param)
{
- save_Lightfv(light, pname, &params);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_Lightfv(light, pname, parray);
}
@@ -2125,7 +2192,10 @@ save_Lightiv(GLenum light, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_Lighti(GLenum light, GLenum pname, GLint param)
{
- save_Lightiv(light, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_Lightiv(light, pname, parray);
}
@@ -2152,7 +2222,10 @@ save_LightModelfv(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_LightModelf(GLenum pname, GLfloat param)
{
- save_LightModelfv(pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_LightModelfv(pname, parray);
}
@@ -2174,7 +2247,7 @@ save_LightModeliv(GLenum pname, const GLint *params)
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
save_LightModelfv(pname, fparam);
}
@@ -2183,7 +2256,10 @@ save_LightModeliv(GLenum pname, const GLint *params)
static void GLAPIENTRY
save_LightModeli(GLenum pname, GLint param)
{
- save_LightModeliv(pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_LightModeliv(pname, parray);
}
@@ -2698,21 +2774,28 @@ save_PointParameterfvEXT(GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_PointParameterfEXT(GLenum pname, GLfloat param)
{
- save_PointParameterfvEXT(pname, &param);
+ GLfloat parray[3];
+ parray[0] = param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameteriNV(GLenum pname, GLint param)
{
- GLfloat p = (GLfloat) param;
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
static void GLAPIENTRY
save_PointParameterivNV(GLenum pname, const GLint * param)
{
- GLfloat p = (GLfloat) param[0];
- save_PointParameterfvEXT(pname, &p);
+ GLfloat parray[3];
+ parray[0] = (GLfloat) param[0];
+ parray[1] = parray[2] = 0.0F;
+ save_PointParameterfvEXT(pname, parray);
}
@@ -2753,16 +2836,14 @@ static void GLAPIENTRY
save_PolygonStipple(const GLubyte * pattern)
{
GET_CURRENT_CONTEXT(ctx);
- GLvoid *image = unpack_image(2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
- pattern, &ctx->Unpack);
Node *n;
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_POLYGON_STIPPLE, 1);
if (n) {
- n[1].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[1].data = unpack_image(ctx, 2, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP,
+ pattern, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern));
@@ -3386,7 +3467,10 @@ save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexEnvf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexEnvfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexEnvfv(target, pname, parray);
}
@@ -3454,8 +3538,10 @@ save_TexGeniv(GLenum coord, GLenum pname, const GLint *params)
static void GLAPIENTRY
save_TexGend(GLenum coord, GLenum pname, GLdouble param)
{
- GLfloat p = (GLfloat) param;
- save_TexGenfv(coord, pname, &p);
+ GLfloat parray[4];
+ parray[0] = (GLfloat) param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
@@ -3474,14 +3560,20 @@ save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params)
static void GLAPIENTRY
save_TexGenf(GLenum coord, GLenum pname, GLfloat param)
{
- save_TexGenfv(coord, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexGenfv(coord, pname, parray);
}
static void GLAPIENTRY
save_TexGeni(GLenum coord, GLenum pname, GLint param)
{
- save_TexGeniv(coord, pname, &param);
+ GLint parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0;
+ save_TexGeniv(coord, pname, parray);
}
@@ -3509,7 +3601,10 @@ save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params)
static void GLAPIENTRY
save_TexParameterf(GLenum target, GLenum pname, GLfloat param)
{
- save_TexParameterfv(target, pname, &param);
+ GLfloat parray[4];
+ parray[0] = param;
+ parray[1] = parray[2] = parray[3] = 0.0F;
+ save_TexParameterfv(target, pname, parray);
}
@@ -3546,8 +3641,6 @@ save_TexImage1D(GLenum target,
border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE1D, 8);
@@ -3559,10 +3652,8 @@ save_TexImage1D(GLenum target,
n[5].i = border;
n[6].e = format;
n[7].e = type;
- n[8].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[8].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage1D(ctx->Exec, (target, level, components, width,
@@ -3585,8 +3676,6 @@ save_TexImage2D(GLenum target,
height, border, format, type, pixels));
}
else {
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
Node *n;
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE2D, 9);
@@ -3599,10 +3688,8 @@ save_TexImage2D(GLenum target,
n[6].i = border;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage2D(ctx->Exec, (target, level, components, width,
@@ -3628,8 +3715,6 @@ save_TexImage3D(GLenum target,
}
else {
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_IMAGE3D, 10);
if (n) {
@@ -3642,10 +3727,8 @@ save_TexImage3D(GLenum target,
n[7].i = border;
n[8].e = format;
n[9].e = type;
- n[10].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[10].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width,
@@ -3663,9 +3746,9 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(1, width, 1, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE1D, 7);
if (n) {
n[1].e = target;
@@ -3674,10 +3757,8 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset,
n[4].i = (GLint) width;
n[5].e = format;
n[6].e = type;
- n[7].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[7].data = unpack_image(ctx, 1, width, 1, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width,
@@ -3694,9 +3775,9 @@ save_TexSubImage2D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(2, width, height, 1, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE2D, 9);
if (n) {
n[1].e = target;
@@ -3707,10 +3788,8 @@ save_TexSubImage2D(GLenum target, GLint level,
n[6].i = (GLint) height;
n[7].e = format;
n[8].e = type;
- n[9].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[9].data = unpack_image(ctx, 2, width, height, 1, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset,
@@ -3727,9 +3806,9 @@ save_TexSubImage3D(GLenum target, GLint level,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLvoid *image = unpack_image(3, width, height, depth, format, type,
- pixels, &ctx->Unpack);
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TEX_SUB_IMAGE3D, 11);
if (n) {
n[1].e = target;
@@ -3742,10 +3821,8 @@ save_TexSubImage3D(GLenum target, GLint level,
n[8].i = (GLint) depth;
n[9].e = format;
n[10].e = type;
- n[11].data = image;
- }
- else if (image) {
- _mesa_free(image);
+ n[11].data = unpack_image(ctx, 3, width, height, depth, format, type,
+ pixels, &ctx->Unpack);
}
if (ctx->ExecuteFlag) {
CALL_TexSubImage3D(ctx->Exec, (target, level,
@@ -4458,18 +4535,17 @@ save_LoadProgramNV(GLenum target, GLuint id, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- return;
- }
- _mesa_memcpy(programCopy, program, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_LOAD_PROGRAM_NV, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ return;
+ }
+ _mesa_memcpy(programCopy, program, len);
n[1].e = target;
n[2].ui = id;
n[3].i = len;
@@ -4486,15 +4562,17 @@ save_RequestResidentProgramsNV(GLsizei num, const GLuint * ids)
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
- if (!idCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
- return;
- }
- _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
+
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_TRACK_MATRIX_NV, 2);
if (n) {
+ GLuint *idCopy = (GLuint *) _mesa_malloc(num * sizeof(GLuint));
+ if (!idCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glRequestResidentProgramsNV");
+ return;
+ }
+ _mesa_memcpy(idCopy, ids, num * sizeof(GLuint));
n[1].i = num;
n[2].data = idCopy;
}
@@ -4655,16 +4733,17 @@ save_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte * name,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
- if (!nameCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
- return;
- }
- _mesa_memcpy(nameCopy, name, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_NAMED_PARAMETER_NV, 6);
if (n) {
+ GLubyte *nameCopy = (GLubyte *) _mesa_malloc(len);
+ if (!nameCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramNamedParameter4fNV");
+ return;
+ }
+ _mesa_memcpy(nameCopy, name, len);
n[1].ui = id;
n[2].i = len;
n[3].data = nameCopy;
@@ -4753,18 +4832,17 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len,
{
GET_CURRENT_CONTEXT(ctx);
Node *n;
- GLubyte *programCopy;
-
- programCopy = (GLubyte *) _mesa_malloc(len);
- if (!programCopy) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
- return;
- }
- _mesa_memcpy(programCopy, string, len);
ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx);
+
n = ALLOC_INSTRUCTION(ctx, OPCODE_PROGRAM_STRING_ARB, 4);
if (n) {
+ GLubyte *programCopy = (GLubyte *) _mesa_malloc(len);
+ if (!programCopy) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return;
+ }
+ _mesa_memcpy(programCopy, string, len);
n[1].e = target;
n[2].e = format;
n[3].i = len;
@@ -5778,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.
@@ -6614,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];
@@ -7725,18 +8382,6 @@ exec_MultiDrawArraysEXT(GLenum mode, GLint * first,
CALL_MultiDrawArraysEXT(ctx->Exec, (mode, first, count, primcount));
}
-/* GL_EXT_multi_draw_arrays */
-static void GLAPIENTRY
-exec_MultiDrawElementsEXT(GLenum mode, const GLsizei * count,
- GLenum type, const GLvoid ** indices,
- GLsizei primcount)
-{
- GET_CURRENT_CONTEXT(ctx);
- FLUSH_VERTICES(ctx, 0);
- CALL_MultiDrawElementsEXT(ctx->Exec,
- (mode, count, type, indices, primcount));
-}
-
/* GL_IBM_multimode_draw_arrays */
static void GLAPIENTRY
exec_MultiModeDrawArraysIBM(const GLenum * mode, const GLint * first,
@@ -8082,7 +8727,6 @@ _mesa_init_dlist_table(struct _glapi_table *table)
/* 148. GL_EXT_multi_draw_arrays */
SET_MultiDrawArraysEXT(table, exec_MultiDrawArraysEXT);
- SET_MultiDrawElementsEXT(table, exec_MultiDrawElementsEXT);
/* 149. GL_EXT_fog_coord */
SET_FogCoordPointerEXT(table, exec_FogCoordPointerEXT);
@@ -8296,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);
@@ -8697,6 +9369,10 @@ _mesa_save_vtxfmt_init(GLvertexformat * vfmt)
vfmt->DrawArrays = 0;
vfmt->DrawElements = 0;
vfmt->DrawRangeElements = 0;
+ vfmt->MultiDrawElemementsEXT = 0;
+ vfmt->DrawElementsBaseVertex = 0;
+ vfmt->DrawRangeElementsBaseVertex = 0;
+ vfmt->MultiDrawElemementsBaseVertex = 0;
#endif
}
diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c
index 6682b5e725..aef6585641 100644
--- a/src/mesa/main/drawpix.c
+++ b/src/mesa/main/drawpix.c
@@ -27,6 +27,7 @@
#include "bufferobj.h"
#include "context.h"
#include "drawpix.h"
+#include "enums.h"
#include "feedback.h"
#include "framebuffer.h"
#include "image.h"
@@ -34,6 +35,18 @@
#include "state.h"
+
+/**
+ * If a fragment program is enabled, check that it's valid.
+ * \return GL_TRUE if valid, GL_FALSE otherwise
+ */
+static GLboolean
+valid_fragment_program(GLcontext *ctx)
+{
+ return !(ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled);
+}
+
+
#if _HAVE_FULL_GL
/*
@@ -51,29 +64,34 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
return;
}
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels (invalid fragment program)");
- return;
+ goto end;
}
if (_mesa_error_check_format_type(ctx, format, type, GL_TRUE)) {
- /* found an error */
- return;
+ /* the error was already recorded */
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glDrawPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -88,13 +106,13 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(invalid PBO access)");
- return;
+ goto end;
}
- if (ctx->Unpack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(PBO is mapped)");
- return;
+ goto end;
}
}
@@ -116,6 +134,9 @@ _mesa_DrawPixels( GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
@@ -126,37 +147,55 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+ if (width < 0 || height < 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
+ return;
+ }
+
+ /* Note: more detailed 'type' checking is done by the
+ * _mesa_source/dest_buffer_exists() calls below. That's where we
+ * check if the stencil buffer exists, etc.
+ */
+ if (type != GL_COLOR &&
+ type != GL_DEPTH &&
+ type != GL_STENCIL &&
+ type != GL_DEPTH_STENCIL) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glCopyPixels(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
+ return;
+ }
+
+ /* We're not using the current vertex program, and the driver may install
+ * it's own.
+ */
+ _mesa_set_vp_override(ctx, GL_TRUE);
+
if (ctx->NewState) {
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels (invalid fragment program)");
- return;
- }
-
- if (width < 0 || height < 0) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glCopyPixels(width or height < 0)");
- return;
+ goto end;
}
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT ||
ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
_mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
"glCopyPixels(incomplete framebuffer)" );
- return;
+ goto end;
}
if (!_mesa_source_buffer_exists(ctx, type) ||
!_mesa_dest_buffer_exists(ctx, type)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyPixels(missing source or dest buffer)");
- return;
+ goto end;
}
if (!ctx->Current.RasterPosValid || width ==0 || height == 0) {
- return;
+ goto end; /* no-op, not an error */
}
if (ctx->RenderMode == GL_RENDER) {
@@ -181,6 +220,9 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height,
ASSERT(ctx->RenderMode == GL_SELECT);
/* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
}
+
+end:
+ _mesa_set_vp_override(ctx, GL_FALSE);
}
#endif /* _HAVE_FULL_GL */
@@ -208,7 +250,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
_mesa_update_state(ctx);
}
- if (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled) {
+ if (!valid_fragment_program(ctx)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBitmap (invalid fragment program)");
return;
@@ -222,27 +264,30 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
if (ctx->RenderMode == GL_RENDER) {
/* Truncate, to satisfy conformance tests (matches SGI's OpenGL). */
- const GLfloat epsilon = 0.0001F;
- GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
- GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
-
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack from PBO */
- if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
- GL_COLOR_INDEX, GL_BITMAP,
- (GLvoid *) bitmap)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBitmap(invalid PBO access)");
- return;
- }
- if (ctx->Unpack.BufferObj->Pointer) {
- /* buffer is mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glBitmap(PBO is mapped)");
- return;
+ if (width > 0 && height > 0) {
+ const GLfloat epsilon = 0.0001F;
+ GLint x = IFLOOR(ctx->Current.RasterPos[0] + epsilon - xorig);
+ GLint y = IFLOOR(ctx->Current.RasterPos[1] + epsilon - yorig);
+
+ if (ctx->Unpack.BufferObj->Name) {
+ /* unpack from PBO */
+ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1,
+ GL_COLOR_INDEX, GL_BITMAP,
+ (GLvoid *) bitmap)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBitmap(invalid PBO access)");
+ return;
+ }
+ if (_mesa_bufferobj_mapped(ctx->Unpack.BufferObj)) {
+ /* buffer is mapped - that's an error */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glBitmap(PBO is mapped)");
+ return;
+ }
}
- }
- ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+ ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap );
+ }
}
#if _HAVE_FULL_GL
else if (ctx->RenderMode == GL_FEEDBACK) {
@@ -264,68 +309,3 @@ _mesa_Bitmap( GLsizei width, GLsizei height,
ctx->Current.RasterPos[0] += xmove;
ctx->Current.RasterPos[1] += ymove;
}
-
-
-
-#if 0 /* experimental */
-/*
- * Execute glDrawDepthPixelsMESA(). This function accepts both a color
- * image and depth (Z) image. Rasterization produces fragments with
- * color and Z taken from these images. This function is intended for
- * Z-compositing. Normally, this operation requires two glDrawPixels
- * calls with stencil testing.
- */
-void GLAPIENTRY
-_mesa_DrawDepthPixelsMESA( GLsizei width, GLsizei height,
- GLenum colorFormat, GLenum colorType,
- const GLvoid *colors,
- GLenum depthType, const GLvoid *depths )
-{
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- if (width < 0 || height < 0) {
- _mesa_error( ctx, GL_INVALID_VALUE,
- "glDrawDepthPixelsMESA(width or height < 0" );
- return;
- }
-
- if (!ctx->Current.RasterPosValid) {
- return;
- }
-
- if (ctx->NewState) {
- _mesa_update_state(ctx);
- }
-
- if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
- _mesa_error(ctx, GL_INVALID_FRAMEBUFFER_OPERATION_EXT,
- "glDrawDepthPixelsMESA(incomplete framebuffer)");
- return;
- }
-
- if (ctx->RenderMode == GL_RENDER) {
- /* Round, to satisfy conformance tests (matches SGI's OpenGL) */
- GLint x = IROUND(ctx->Current.RasterPos[0]);
- GLint y = IROUND(ctx->Current.RasterPos[1]);
- ctx->Driver.DrawDepthPixelsMESA(ctx, x, y, width, height,
- colorFormat, colorType, colors,
- depthType, depths, &ctx->Unpack);
- }
- else if (ctx->RenderMode == GL_FEEDBACK) {
- /* Feedback the current raster pos info */
- FLUSH_CURRENT( ctx, 0 );
- _mesa_feedback_token( ctx, (GLfloat) (GLint) GL_DRAW_PIXEL_TOKEN );
- _mesa_feedback_vertex( ctx,
- ctx->Current.RasterPos,
- ctx->Current.RasterColor,
- ctx->Current.RasterIndex,
- ctx->Current.RasterTexCoords[0] );
- }
- else {
- ASSERT(ctx->RenderMode == GL_SELECT);
- /* Do nothing. See OpenGL Spec, Appendix B, Corollary 6. */
- }
-}
-
-#endif
diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c
index 48268fcd27..4c1f46102d 100644
--- a/src/mesa/main/enable.c
+++ b/src/mesa/main/enable.c
@@ -36,7 +36,6 @@
#include "simple_list.h"
#include "mtypes.h"
#include "enums.h"
-#include "math/m_matrix.h"
#include "api_arrayelt.h"
@@ -947,6 +946,14 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
ctx->Depth.BoundsTest = state;
break;
+ case GL_DEPTH_CLAMP:
+ if (ctx->Transform.DepthClamp == state)
+ return;
+ CHECK_EXTENSION(ARB_depth_clamp, cap);
+ FLUSH_VERTICES(ctx, _NEW_TRANSFORM);
+ ctx->Transform.DepthClamp = state;
+ break;
+
#if FEATURE_ATI_fragment_shader
case GL_FRAGMENT_SHADER_ATI:
CHECK_EXTENSION(ATI_fragment_shader, cap);
@@ -972,6 +979,11 @@ _mesa_set_enable(GLcontext *ctx, GLenum cap, GLboolean state)
}
break;
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXTENSION(ARB_seamless_cube_map, cap);
+ ctx->Texture.CubeMapSeamless = state;
+ break;
+
default:
_mesa_error(ctx, GL_INVALID_ENUM,
"%s(0x%x)", state ? "glEnable" : "glDisable", cap);
@@ -1390,11 +1402,21 @@ _mesa_IsEnabled( GLenum cap )
CHECK_EXTENSION(EXT_depth_bounds_test);
return ctx->Depth.BoundsTest;
+ /* GL_ARB_depth_clamp */
+ case GL_DEPTH_CLAMP:
+ CHECK_EXTENSION(ARB_depth_clamp);
+ return ctx->Transform.DepthClamp;
+
#if FEATURE_ATI_fragment_shader
case GL_FRAGMENT_SHADER_ATI:
CHECK_EXTENSION(ATI_fragment_shader);
return ctx->ATIFragmentShader.Enabled;
#endif /* FEATURE_ATI_fragment_shader */
+
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXTENSION(ARB_seamless_cube_map);
+ return ctx->Texture.CubeMapSeamless;
+
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glIsEnabled(0x%x)", (int) cap);
return GL_FALSE;
diff --git a/src/mesa/main/enums.c b/src/mesa/main/enums.c
index 6e2adea636..606d50c59a 100644
--- a/src/mesa/main/enums.c
+++ b/src/mesa/main/enums.c
@@ -82,6 +82,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_ALPHA_TEST\0"
"GL_ALPHA_TEST_FUNC\0"
"GL_ALPHA_TEST_REF\0"
+ "GL_ALREADY_SIGNALED\0"
"GL_ALWAYS\0"
"GL_AMBIENT\0"
"GL_AMBIENT_AND_DIFFUSE\0"
@@ -139,10 +140,12 @@ LONGSTRING static const char enum_string_table[] =
"GL_BOOL_VEC4_ARB\0"
"GL_BUFFER_ACCESS\0"
"GL_BUFFER_ACCESS_ARB\0"
+ "GL_BUFFER_FLUSHING_UNMAP_APPLE\0"
"GL_BUFFER_MAPPED\0"
"GL_BUFFER_MAPPED_ARB\0"
"GL_BUFFER_MAP_POINTER\0"
"GL_BUFFER_MAP_POINTER_ARB\0"
+ "GL_BUFFER_SERIALIZED_MODIFY_APPLE\0"
"GL_BUFFER_SIZE\0"
"GL_BUFFER_SIZE_ARB\0"
"GL_BUFFER_USAGE\0"
@@ -303,6 +306,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_COMPRESSED_SRGB\0"
"GL_COMPRESSED_SRGB_ALPHA\0"
"GL_COMPRESSED_TEXTURE_FORMATS\0"
+ "GL_CONDITION_SATISFIED\0"
"GL_CONSTANT\0"
"GL_CONSTANT_ALPHA\0"
"GL_CONSTANT_ALPHA_EXT\0"
@@ -387,6 +391,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_DEPTH_BOUNDS_EXT\0"
"GL_DEPTH_BOUNDS_TEST_EXT\0"
"GL_DEPTH_BUFFER_BIT\0"
+ "GL_DEPTH_CLAMP\0"
"GL_DEPTH_CLAMP_NV\0"
"GL_DEPTH_CLEAR_VALUE\0"
"GL_DEPTH_COMPONENT\0"
@@ -514,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"
@@ -697,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"
@@ -942,6 +949,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_MAX_RECTANGLE_TEXTURE_SIZE_NV\0"
"GL_MAX_RENDERBUFFER_SIZE_EXT\0"
"GL_MAX_SAMPLES\0"
+ "GL_MAX_SERVER_WAIT_TIMEOUT\0"
"GL_MAX_SHININESS_NV\0"
"GL_MAX_SPOT_EXPONENT_NV\0"
"GL_MAX_TEXTURE_COORDS\0"
@@ -1070,6 +1078,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_OBJECT_PLANE\0"
"GL_OBJECT_SHADER_SOURCE_LENGTH_ARB\0"
"GL_OBJECT_SUBTYPE_ARB\0"
+ "GL_OBJECT_TYPE\0"
"GL_OBJECT_TYPE_ARB\0"
"GL_OBJECT_VALIDATE_STATUS_ARB\0"
"GL_OCCLUSION_TEST_HP\0"
@@ -1281,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"
@@ -1302,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"
@@ -1450,6 +1461,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_SHARED_TEXTURE_PALETTE_EXT\0"
"GL_SHININESS\0"
"GL_SHORT\0"
+ "GL_SIGNALED\0"
"GL_SIGNED_NORMALIZED\0"
"GL_SINGLE_COLOR\0"
"GL_SINGLE_COLOR_EXT\0"
@@ -1542,6 +1554,9 @@ LONGSTRING static const char enum_string_table[] =
"GL_STENCIL_VALUE_MASK\0"
"GL_STENCIL_WRITEMASK\0"
"GL_STEREO\0"
+ "GL_STORAGE_CACHED_APPLE\0"
+ "GL_STORAGE_PRIVATE_APPLE\0"
+ "GL_STORAGE_SHARED_APPLE\0"
"GL_STREAM_COPY\0"
"GL_STREAM_COPY_ARB\0"
"GL_STREAM_DRAW\0"
@@ -1551,6 +1566,12 @@ LONGSTRING static const char enum_string_table[] =
"GL_SUBPIXEL_BITS\0"
"GL_SUBTRACT\0"
"GL_SUBTRACT_ARB\0"
+ "GL_SYNC_CONDITION\0"
+ "GL_SYNC_FENCE\0"
+ "GL_SYNC_FLAGS\0"
+ "GL_SYNC_FLUSH_COMMANDS_BIT\0"
+ "GL_SYNC_GPU_COMMANDS_COMPLETE\0"
+ "GL_SYNC_STATUS\0"
"GL_T\0"
"GL_T2F_C3F_V3F\0"
"GL_T2F_C4F_N3F_V3F\0"
@@ -1691,6 +1712,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB\0"
"GL_TEXTURE_CUBE_MAP_POSITIVE_Z\0"
"GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB\0"
+ "GL_TEXTURE_CUBE_MAP_SEAMLESS\0"
"GL_TEXTURE_DEPTH\0"
"GL_TEXTURE_DEPTH_SIZE\0"
"GL_TEXTURE_DEPTH_SIZE_ARB\0"
@@ -1730,6 +1752,8 @@ LONGSTRING static const char enum_string_table[] =
"GL_TEXTURE_MIN_FILTER\0"
"GL_TEXTURE_MIN_LOD\0"
"GL_TEXTURE_PRIORITY\0"
+ "GL_TEXTURE_RANGE_LENGTH_APPLE\0"
+ "GL_TEXTURE_RANGE_POINTER_APPLE\0"
"GL_TEXTURE_RECTANGLE_ARB\0"
"GL_TEXTURE_RECTANGLE_NV\0"
"GL_TEXTURE_RED_SIZE\0"
@@ -1737,12 +1761,15 @@ LONGSTRING static const char enum_string_table[] =
"GL_TEXTURE_RESIDENT\0"
"GL_TEXTURE_STACK_DEPTH\0"
"GL_TEXTURE_STENCIL_SIZE\0"
+ "GL_TEXTURE_STORAGE_HINT_APPLE\0"
"GL_TEXTURE_TOO_LARGE_EXT\0"
"GL_TEXTURE_UNSIGNED_REMAP_MODE_NV\0"
"GL_TEXTURE_WIDTH\0"
"GL_TEXTURE_WRAP_R\0"
"GL_TEXTURE_WRAP_S\0"
"GL_TEXTURE_WRAP_T\0"
+ "GL_TIMEOUT_EXPIRED\0"
+ "GL_TIMEOUT_IGNORED\0"
"GL_TIME_ELAPSED_EXT\0"
"GL_TRACK_MATRIX_NV\0"
"GL_TRACK_MATRIX_TRANSFORM_NV\0"
@@ -1770,6 +1797,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_UNPACK_SKIP_PIXELS\0"
"GL_UNPACK_SKIP_ROWS\0"
"GL_UNPACK_SWAP_BYTES\0"
+ "GL_UNSIGNALED\0"
"GL_UNSIGNED_BYTE\0"
"GL_UNSIGNED_BYTE_2_3_3_REV\0"
"GL_UNSIGNED_BYTE_3_3_2\0"
@@ -1852,6 +1880,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_VERTEX_STATE_PROGRAM_NV\0"
"GL_VIEWPORT\0"
"GL_VIEWPORT_BIT\0"
+ "GL_WAIT_FAILED\0"
"GL_WEIGHT_ARRAY_ARB\0"
"GL_WEIGHT_ARRAY_BUFFER_BINDING\0"
"GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB\0"
@@ -1871,7 +1900,7 @@ LONGSTRING static const char enum_string_table[] =
"GL_ZOOM_Y\0"
;
-static const enum_elt all_enums[1833] =
+static const enum_elt all_enums[1862] =
{
{ 0, 0x00000600 }, /* GL_2D */
{ 6, 0x00001407 }, /* GL_2_BYTES */
@@ -1919,3122 +1948,3173 @@ static const enum_elt all_enums[1833] =
{ 728, 0x00000BC0 }, /* GL_ALPHA_TEST */
{ 742, 0x00000BC1 }, /* GL_ALPHA_TEST_FUNC */
{ 761, 0x00000BC2 }, /* GL_ALPHA_TEST_REF */
- { 779, 0x00000207 }, /* GL_ALWAYS */
- { 789, 0x00001200 }, /* GL_AMBIENT */
- { 800, 0x00001602 }, /* GL_AMBIENT_AND_DIFFUSE */
- { 823, 0x00001501 }, /* GL_AND */
- { 830, 0x00001504 }, /* GL_AND_INVERTED */
- { 846, 0x00001502 }, /* GL_AND_REVERSE */
- { 861, 0x00008892 }, /* GL_ARRAY_BUFFER */
- { 877, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING */
- { 901, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING_ARB */
- { 929, 0x00008B85 }, /* GL_ATTACHED_SHADERS */
- { 949, 0x00008645 }, /* GL_ATTRIB_ARRAY_POINTER_NV */
- { 976, 0x00008623 }, /* GL_ATTRIB_ARRAY_SIZE_NV */
- { 1000, 0x00008624 }, /* GL_ATTRIB_ARRAY_STRIDE_NV */
- { 1026, 0x00008625 }, /* GL_ATTRIB_ARRAY_TYPE_NV */
- { 1050, 0x00000BB0 }, /* GL_ATTRIB_STACK_DEPTH */
- { 1072, 0x00000D80 }, /* GL_AUTO_NORMAL */
- { 1087, 0x00000409 }, /* GL_AUX0 */
- { 1095, 0x0000040A }, /* GL_AUX1 */
- { 1103, 0x0000040B }, /* GL_AUX2 */
- { 1111, 0x0000040C }, /* GL_AUX3 */
- { 1119, 0x00000C00 }, /* GL_AUX_BUFFERS */
- { 1134, 0x00000405 }, /* GL_BACK */
- { 1142, 0x00000402 }, /* GL_BACK_LEFT */
- { 1155, 0x00000403 }, /* GL_BACK_RIGHT */
- { 1169, 0x000080E0 }, /* GL_BGR */
- { 1176, 0x000080E1 }, /* GL_BGRA */
- { 1184, 0x00001A00 }, /* GL_BITMAP */
- { 1194, 0x00000704 }, /* GL_BITMAP_TOKEN */
- { 1210, 0x00000BE2 }, /* GL_BLEND */
- { 1219, 0x00008005 }, /* GL_BLEND_COLOR */
- { 1234, 0x00008005 }, /* GL_BLEND_COLOR_EXT */
- { 1253, 0x00000BE0 }, /* GL_BLEND_DST */
- { 1266, 0x000080CA }, /* GL_BLEND_DST_ALPHA */
- { 1285, 0x000080C8 }, /* GL_BLEND_DST_RGB */
- { 1302, 0x00008009 }, /* GL_BLEND_EQUATION */
- { 1320, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA */
- { 1344, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA_EXT */
- { 1372, 0x00008009 }, /* GL_BLEND_EQUATION_EXT */
- { 1394, 0x00008009 }, /* GL_BLEND_EQUATION_RGB */
- { 1416, 0x00008009 }, /* GL_BLEND_EQUATION_RGB_EXT */
- { 1442, 0x00000BE1 }, /* GL_BLEND_SRC */
- { 1455, 0x000080CB }, /* GL_BLEND_SRC_ALPHA */
- { 1474, 0x000080C9 }, /* GL_BLEND_SRC_RGB */
- { 1491, 0x00001905 }, /* GL_BLUE */
- { 1499, 0x00000D1B }, /* GL_BLUE_BIAS */
- { 1512, 0x00000D54 }, /* GL_BLUE_BITS */
- { 1525, 0x00000D1A }, /* GL_BLUE_SCALE */
- { 1539, 0x00008B56 }, /* GL_BOOL */
- { 1547, 0x00008B56 }, /* GL_BOOL_ARB */
- { 1559, 0x00008B57 }, /* GL_BOOL_VEC2 */
- { 1572, 0x00008B57 }, /* GL_BOOL_VEC2_ARB */
- { 1589, 0x00008B58 }, /* GL_BOOL_VEC3 */
- { 1602, 0x00008B58 }, /* GL_BOOL_VEC3_ARB */
- { 1619, 0x00008B59 }, /* GL_BOOL_VEC4 */
- { 1632, 0x00008B59 }, /* GL_BOOL_VEC4_ARB */
- { 1649, 0x000088BB }, /* GL_BUFFER_ACCESS */
- { 1666, 0x000088BB }, /* GL_BUFFER_ACCESS_ARB */
- { 1687, 0x000088BC }, /* GL_BUFFER_MAPPED */
- { 1704, 0x000088BC }, /* GL_BUFFER_MAPPED_ARB */
- { 1725, 0x000088BD }, /* GL_BUFFER_MAP_POINTER */
- { 1747, 0x000088BD }, /* GL_BUFFER_MAP_POINTER_ARB */
- { 1773, 0x00008764 }, /* GL_BUFFER_SIZE */
- { 1788, 0x00008764 }, /* GL_BUFFER_SIZE_ARB */
- { 1807, 0x00008765 }, /* GL_BUFFER_USAGE */
- { 1823, 0x00008765 }, /* GL_BUFFER_USAGE_ARB */
- { 1843, 0x0000877B }, /* GL_BUMP_ENVMAP_ATI */
- { 1862, 0x00008777 }, /* GL_BUMP_NUM_TEX_UNITS_ATI */
- { 1888, 0x00008775 }, /* GL_BUMP_ROT_MATRIX_ATI */
- { 1911, 0x00008776 }, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
- { 1939, 0x0000877C }, /* GL_BUMP_TARGET_ATI */
- { 1958, 0x00008778 }, /* GL_BUMP_TEX_UNITS_ATI */
- { 1980, 0x00001400 }, /* GL_BYTE */
- { 1988, 0x00002A24 }, /* GL_C3F_V3F */
- { 1999, 0x00002A26 }, /* GL_C4F_N3F_V3F */
- { 2014, 0x00002A22 }, /* GL_C4UB_V2F */
- { 2026, 0x00002A23 }, /* GL_C4UB_V3F */
- { 2038, 0x00000901 }, /* GL_CCW */
- { 2045, 0x00002900 }, /* GL_CLAMP */
- { 2054, 0x0000812D }, /* GL_CLAMP_TO_BORDER */
- { 2073, 0x0000812D }, /* GL_CLAMP_TO_BORDER_ARB */
- { 2096, 0x0000812D }, /* GL_CLAMP_TO_BORDER_SGIS */
- { 2120, 0x0000812F }, /* GL_CLAMP_TO_EDGE */
- { 2137, 0x0000812F }, /* GL_CLAMP_TO_EDGE_SGIS */
- { 2159, 0x00001500 }, /* GL_CLEAR */
- { 2168, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE */
- { 2193, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE_ARB */
- { 2222, 0xFFFFFFFF }, /* GL_CLIENT_ALL_ATTRIB_BITS */
- { 2248, 0x00000BB1 }, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
- { 2277, 0x00000001 }, /* GL_CLIENT_PIXEL_STORE_BIT */
- { 2303, 0x00000002 }, /* GL_CLIENT_VERTEX_ARRAY_BIT */
- { 2330, 0x00003000 }, /* GL_CLIP_PLANE0 */
- { 2345, 0x00003001 }, /* GL_CLIP_PLANE1 */
- { 2360, 0x00003002 }, /* GL_CLIP_PLANE2 */
- { 2375, 0x00003003 }, /* GL_CLIP_PLANE3 */
- { 2390, 0x00003004 }, /* GL_CLIP_PLANE4 */
- { 2405, 0x00003005 }, /* GL_CLIP_PLANE5 */
- { 2420, 0x000080F0 }, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
- { 2453, 0x00000A00 }, /* GL_COEFF */
- { 2462, 0x00001800 }, /* GL_COLOR */
- { 2471, 0x00008076 }, /* GL_COLOR_ARRAY */
- { 2486, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING */
- { 2516, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING_ARB */
- { 2550, 0x00008090 }, /* GL_COLOR_ARRAY_POINTER */
- { 2573, 0x00008081 }, /* GL_COLOR_ARRAY_SIZE */
- { 2593, 0x00008083 }, /* GL_COLOR_ARRAY_STRIDE */
- { 2615, 0x00008082 }, /* GL_COLOR_ARRAY_TYPE */
- { 2635, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0 */
- { 2656, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0_EXT */
- { 2681, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1 */
- { 2702, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10 */
- { 2724, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10_EXT */
- { 2750, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11 */
- { 2772, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11_EXT */
- { 2798, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12 */
- { 2820, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12_EXT */
- { 2846, 0x00008CED }, /* GL_COLOR_ATTACHMENT13 */
- { 2868, 0x00008CED }, /* GL_COLOR_ATTACHMENT13_EXT */
- { 2894, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14 */
- { 2916, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14_EXT */
- { 2942, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15 */
- { 2964, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15_EXT */
- { 2990, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1_EXT */
- { 3015, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2 */
- { 3036, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2_EXT */
- { 3061, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3 */
- { 3082, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3_EXT */
- { 3107, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4 */
- { 3128, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4_EXT */
- { 3153, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5 */
- { 3174, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5_EXT */
- { 3199, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6 */
- { 3220, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6_EXT */
- { 3245, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7 */
- { 3266, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7_EXT */
- { 3291, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8 */
- { 3312, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8_EXT */
- { 3337, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9 */
- { 3358, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9_EXT */
- { 3383, 0x00004000 }, /* GL_COLOR_BUFFER_BIT */
- { 3403, 0x00000C22 }, /* GL_COLOR_CLEAR_VALUE */
- { 3424, 0x00001900 }, /* GL_COLOR_INDEX */
- { 3439, 0x00001603 }, /* GL_COLOR_INDEXES */
- { 3456, 0x00000BF2 }, /* GL_COLOR_LOGIC_OP */
- { 3474, 0x00000B57 }, /* GL_COLOR_MATERIAL */
- { 3492, 0x00000B55 }, /* GL_COLOR_MATERIAL_FACE */
- { 3515, 0x00000B56 }, /* GL_COLOR_MATERIAL_PARAMETER */
- { 3543, 0x000080B1 }, /* GL_COLOR_MATRIX */
- { 3559, 0x000080B1 }, /* GL_COLOR_MATRIX_SGI */
- { 3579, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH */
- { 3607, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH_SGI */
- { 3639, 0x00008458 }, /* GL_COLOR_SUM */
- { 3652, 0x00008458 }, /* GL_COLOR_SUM_ARB */
- { 3669, 0x000080D0 }, /* GL_COLOR_TABLE */
- { 3684, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE */
- { 3710, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_EXT */
- { 3740, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_SGI */
- { 3770, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS */
- { 3790, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS_SGI */
- { 3814, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE */
- { 3839, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_EXT */
- { 3868, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_SGI */
- { 3897, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT */
- { 3919, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_EXT */
- { 3945, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_SGI */
- { 3971, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE */
- { 3997, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_EXT */
- { 4027, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_SGI */
- { 4057, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE */
- { 4087, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_EXT */
- { 4121, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_SGI */
- { 4155, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
- { 4185, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_EXT */
- { 4219, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_SGI */
- { 4253, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE */
- { 4277, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_EXT */
- { 4305, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_SGI */
- { 4333, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE */
- { 4354, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE_SGI */
- { 4379, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH */
- { 4400, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_EXT */
- { 4425, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_SGI */
- { 4450, 0x00000C23 }, /* GL_COLOR_WRITEMASK */
- { 4469, 0x00008570 }, /* GL_COMBINE */
- { 4480, 0x00008503 }, /* GL_COMBINE4 */
- { 4492, 0x00008572 }, /* GL_COMBINE_ALPHA */
- { 4509, 0x00008572 }, /* GL_COMBINE_ALPHA_ARB */
- { 4530, 0x00008572 }, /* GL_COMBINE_ALPHA_EXT */
- { 4551, 0x00008570 }, /* GL_COMBINE_ARB */
- { 4566, 0x00008570 }, /* GL_COMBINE_EXT */
- { 4581, 0x00008571 }, /* GL_COMBINE_RGB */
- { 4596, 0x00008571 }, /* GL_COMBINE_RGB_ARB */
- { 4615, 0x00008571 }, /* GL_COMBINE_RGB_EXT */
- { 4634, 0x0000884E }, /* GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT */
- { 4670, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE */
- { 4694, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE_ARB */
- { 4722, 0x00001300 }, /* GL_COMPILE */
- { 4733, 0x00001301 }, /* GL_COMPILE_AND_EXECUTE */
- { 4756, 0x00008B81 }, /* GL_COMPILE_STATUS */
- { 4774, 0x000084E9 }, /* GL_COMPRESSED_ALPHA */
- { 4794, 0x000084E9 }, /* GL_COMPRESSED_ALPHA_ARB */
- { 4818, 0x000084EC }, /* GL_COMPRESSED_INTENSITY */
- { 4842, 0x000084EC }, /* GL_COMPRESSED_INTENSITY_ARB */
- { 4870, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE */
- { 4894, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA */
- { 4924, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA_ARB */
- { 4958, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE_ARB */
- { 4986, 0x000084ED }, /* GL_COMPRESSED_RGB */
- { 5004, 0x000084EE }, /* GL_COMPRESSED_RGBA */
- { 5023, 0x000084EE }, /* GL_COMPRESSED_RGBA_ARB */
- { 5046, 0x000086B1 }, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
- { 5075, 0x000083F1 }, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
- { 5108, 0x000083F2 }, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
- { 5141, 0x000083F3 }, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
- { 5174, 0x000084ED }, /* GL_COMPRESSED_RGB_ARB */
- { 5196, 0x000086B0 }, /* GL_COMPRESSED_RGB_FXT1_3DFX */
- { 5224, 0x000083F0 }, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
- { 5256, 0x00008C4A }, /* GL_COMPRESSED_SLUMINANCE */
- { 5281, 0x00008C4B }, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
- { 5312, 0x00008C48 }, /* GL_COMPRESSED_SRGB */
- { 5331, 0x00008C49 }, /* GL_COMPRESSED_SRGB_ALPHA */
- { 5356, 0x000086A3 }, /* GL_COMPRESSED_TEXTURE_FORMATS */
- { 5386, 0x00008576 }, /* GL_CONSTANT */
- { 5398, 0x00008003 }, /* GL_CONSTANT_ALPHA */
- { 5416, 0x00008003 }, /* GL_CONSTANT_ALPHA_EXT */
- { 5438, 0x00008576 }, /* GL_CONSTANT_ARB */
- { 5454, 0x00001207 }, /* GL_CONSTANT_ATTENUATION */
- { 5478, 0x00008151 }, /* GL_CONSTANT_BORDER_HP */
- { 5500, 0x00008001 }, /* GL_CONSTANT_COLOR */
- { 5518, 0x00008001 }, /* GL_CONSTANT_COLOR_EXT */
- { 5540, 0x00008576 }, /* GL_CONSTANT_EXT */
- { 5556, 0x00008010 }, /* GL_CONVOLUTION_1D */
- { 5574, 0x00008011 }, /* GL_CONVOLUTION_2D */
- { 5592, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR */
- { 5620, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR_HP */
- { 5651, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE */
- { 5678, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE_EXT */
- { 5709, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS */
- { 5736, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS_EXT */
- { 5767, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE */
- { 5795, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE_EXT */
- { 5827, 0x00008017 }, /* GL_CONVOLUTION_FORMAT */
- { 5849, 0x00008017 }, /* GL_CONVOLUTION_FORMAT_EXT */
- { 5875, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT */
- { 5897, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT_EXT */
- { 5923, 0x00008018 }, /* GL_CONVOLUTION_WIDTH */
- { 5944, 0x00008018 }, /* GL_CONVOLUTION_WIDTH_EXT */
- { 5969, 0x00008862 }, /* GL_COORD_REPLACE */
- { 5986, 0x00008862 }, /* GL_COORD_REPLACE_ARB */
- { 6007, 0x00008862 }, /* GL_COORD_REPLACE_NV */
- { 6027, 0x00001503 }, /* GL_COPY */
- { 6035, 0x0000150C }, /* GL_COPY_INVERTED */
- { 6052, 0x00000706 }, /* GL_COPY_PIXEL_TOKEN */
- { 6072, 0x00008F36 }, /* GL_COPY_READ_BUFFER */
- { 6092, 0x00008F37 }, /* GL_COPY_WRITE_BUFFER */
- { 6113, 0x00000B44 }, /* GL_CULL_FACE */
- { 6126, 0x00000B45 }, /* GL_CULL_FACE_MODE */
- { 6144, 0x000081AA }, /* GL_CULL_VERTEX_EXT */
- { 6163, 0x000081AC }, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
- { 6195, 0x000081AB }, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
- { 6230, 0x00008626 }, /* GL_CURRENT_ATTRIB_NV */
- { 6251, 0x00000001 }, /* GL_CURRENT_BIT */
- { 6266, 0x00000B00 }, /* GL_CURRENT_COLOR */
- { 6283, 0x00008453 }, /* GL_CURRENT_FOG_COORD */
- { 6304, 0x00008453 }, /* GL_CURRENT_FOG_COORDINATE */
- { 6330, 0x00000B01 }, /* GL_CURRENT_INDEX */
- { 6347, 0x00008641 }, /* GL_CURRENT_MATRIX_ARB */
- { 6369, 0x00008845 }, /* GL_CURRENT_MATRIX_INDEX_ARB */
- { 6397, 0x00008641 }, /* GL_CURRENT_MATRIX_NV */
- { 6418, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
- { 6452, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_NV */
- { 6485, 0x00000B02 }, /* GL_CURRENT_NORMAL */
- { 6503, 0x00008843 }, /* GL_CURRENT_PALETTE_MATRIX_ARB */
- { 6533, 0x00008B8D }, /* GL_CURRENT_PROGRAM */
- { 6552, 0x00008865 }, /* GL_CURRENT_QUERY */
- { 6569, 0x00008865 }, /* GL_CURRENT_QUERY_ARB */
- { 6590, 0x00000B04 }, /* GL_CURRENT_RASTER_COLOR */
- { 6614, 0x00000B09 }, /* GL_CURRENT_RASTER_DISTANCE */
- { 6641, 0x00000B05 }, /* GL_CURRENT_RASTER_INDEX */
- { 6665, 0x00000B07 }, /* GL_CURRENT_RASTER_POSITION */
- { 6692, 0x00000B08 }, /* GL_CURRENT_RASTER_POSITION_VALID */
- { 6725, 0x0000845F }, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
- { 6759, 0x00000B06 }, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
- { 6792, 0x00008459 }, /* GL_CURRENT_SECONDARY_COLOR */
- { 6819, 0x00000B03 }, /* GL_CURRENT_TEXTURE_COORDS */
- { 6845, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB */
- { 6870, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB_ARB */
- { 6899, 0x000086A8 }, /* GL_CURRENT_WEIGHT_ARB */
- { 6921, 0x00000900 }, /* GL_CW */
- { 6927, 0x0000875B }, /* GL_DEBUG_ASSERT_MESA */
- { 6948, 0x00008759 }, /* GL_DEBUG_OBJECT_MESA */
- { 6969, 0x0000875A }, /* GL_DEBUG_PRINT_MESA */
- { 6989, 0x00002101 }, /* GL_DECAL */
- { 6998, 0x00001E03 }, /* GL_DECR */
- { 7006, 0x00008508 }, /* GL_DECR_WRAP */
- { 7019, 0x00008508 }, /* GL_DECR_WRAP_EXT */
- { 7036, 0x00008B80 }, /* GL_DELETE_STATUS */
- { 7053, 0x00001801 }, /* GL_DEPTH */
- { 7062, 0x000088F0 }, /* GL_DEPTH24_STENCIL8 */
- { 7082, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT */
- { 7102, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */
- { 7126, 0x00000D1F }, /* GL_DEPTH_BIAS */
- { 7140, 0x00000D56 }, /* GL_DEPTH_BITS */
- { 7154, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
- { 7174, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
- { 7199, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */
- { 7219, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */
- { 7237, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
- { 7258, 0x00001902 }, /* GL_DEPTH_COMPONENT */
- { 7277, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
- { 7298, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */
- { 7323, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */
- { 7349, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
- { 7370, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */
- { 7395, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */
- { 7421, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
- { 7442, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */
- { 7467, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */
- { 7493, 0x00000B74 }, /* GL_DEPTH_FUNC */
- { 7507, 0x00000B70 }, /* GL_DEPTH_RANGE */
- { 7522, 0x00000D1E }, /* GL_DEPTH_SCALE */
- { 7537, 0x000084F9 }, /* GL_DEPTH_STENCIL */
- { 7554, 0x0000821A }, /* GL_DEPTH_STENCIL_ATTACHMENT */
- { 7582, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */
- { 7602, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
- { 7630, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
- { 7658, 0x00000B71 }, /* GL_DEPTH_TEST */
- { 7672, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
- { 7694, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */
- { 7720, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
- { 7739, 0x00001201 }, /* GL_DIFFUSE */
- { 7750, 0x00000BD0 }, /* GL_DITHER */
- { 7760, 0x00000A02 }, /* GL_DOMAIN */
- { 7770, 0x00001100 }, /* GL_DONT_CARE */
- { 7783, 0x000086AE }, /* GL_DOT3_RGB */
- { 7795, 0x000086AF }, /* GL_DOT3_RGBA */
- { 7808, 0x000086AF }, /* GL_DOT3_RGBA_ARB */
- { 7825, 0x00008741 }, /* GL_DOT3_RGBA_EXT */
- { 7842, 0x000086AE }, /* GL_DOT3_RGB_ARB */
- { 7858, 0x00008740 }, /* GL_DOT3_RGB_EXT */
- { 7874, 0x0000140A }, /* GL_DOUBLE */
- { 7884, 0x00000C32 }, /* GL_DOUBLEBUFFER */
- { 7900, 0x00000C01 }, /* GL_DRAW_BUFFER */
- { 7915, 0x00008825 }, /* GL_DRAW_BUFFER0 */
- { 7931, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */
- { 7951, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */
- { 7971, 0x00008826 }, /* GL_DRAW_BUFFER1 */
- { 7987, 0x0000882F }, /* GL_DRAW_BUFFER10 */
- { 8004, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */
- { 8025, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */
- { 8046, 0x00008830 }, /* GL_DRAW_BUFFER11 */
- { 8063, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */
- { 8084, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */
- { 8105, 0x00008831 }, /* GL_DRAW_BUFFER12 */
- { 8122, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */
- { 8143, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */
- { 8164, 0x00008832 }, /* GL_DRAW_BUFFER13 */
- { 8181, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */
- { 8202, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */
- { 8223, 0x00008833 }, /* GL_DRAW_BUFFER14 */
- { 8240, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */
- { 8261, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */
- { 8282, 0x00008834 }, /* GL_DRAW_BUFFER15 */
- { 8299, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */
- { 8320, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */
- { 8341, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */
- { 8361, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */
- { 8381, 0x00008827 }, /* GL_DRAW_BUFFER2 */
- { 8397, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */
- { 8417, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */
- { 8437, 0x00008828 }, /* GL_DRAW_BUFFER3 */
- { 8453, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */
- { 8473, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */
- { 8493, 0x00008829 }, /* GL_DRAW_BUFFER4 */
- { 8509, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */
- { 8529, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */
- { 8549, 0x0000882A }, /* GL_DRAW_BUFFER5 */
- { 8565, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */
- { 8585, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */
- { 8605, 0x0000882B }, /* GL_DRAW_BUFFER6 */
- { 8621, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */
- { 8641, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */
- { 8661, 0x0000882C }, /* GL_DRAW_BUFFER7 */
- { 8677, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */
- { 8697, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */
- { 8717, 0x0000882D }, /* GL_DRAW_BUFFER8 */
- { 8733, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */
- { 8753, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */
- { 8773, 0x0000882E }, /* GL_DRAW_BUFFER9 */
- { 8789, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */
- { 8809, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */
- { 8829, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER */
- { 8849, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
- { 8881, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER_EXT */
- { 8905, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
- { 8925, 0x00000304 }, /* GL_DST_ALPHA */
- { 8938, 0x00000306 }, /* GL_DST_COLOR */
- { 8951, 0x0000877A }, /* GL_DU8DV8_ATI */
- { 8965, 0x00008779 }, /* GL_DUDV_ATI */
- { 8977, 0x000088EA }, /* GL_DYNAMIC_COPY */
- { 8993, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */
- { 9013, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
- { 9029, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */
- { 9049, 0x000088E9 }, /* GL_DYNAMIC_READ */
- { 9065, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */
- { 9085, 0x00000B43 }, /* GL_EDGE_FLAG */
- { 9098, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
- { 9117, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
- { 9151, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */
- { 9189, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
- { 9216, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
- { 9242, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
- { 9266, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
- { 9298, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */
- { 9334, 0x00001600 }, /* GL_EMISSION */
- { 9346, 0x00002000 }, /* GL_ENABLE_BIT */
- { 9360, 0x00000202 }, /* GL_EQUAL */
- { 9369, 0x00001509 }, /* GL_EQUIV */
- { 9378, 0x00010000 }, /* GL_EVAL_BIT */
- { 9390, 0x00000800 }, /* GL_EXP */
- { 9397, 0x00000801 }, /* GL_EXP2 */
- { 9405, 0x00001F03 }, /* GL_EXTENSIONS */
- { 9419, 0x00002400 }, /* GL_EYE_LINEAR */
- { 9433, 0x00002502 }, /* GL_EYE_PLANE */
- { 9446, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
- { 9471, 0x0000855B }, /* GL_EYE_RADIAL_NV */
- { 9488, 0x00000000 }, /* GL_FALSE */
- { 9497, 0x00001101 }, /* GL_FASTEST */
- { 9508, 0x00001C01 }, /* GL_FEEDBACK */
- { 9520, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
- { 9547, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
- { 9571, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
- { 9595, 0x00001B02 }, /* GL_FILL */
- { 9603, 0x00008E4D }, /* GL_FIRST_VERTEX_CONVENTION_EXT */
- { 9634, 0x00001D00 }, /* GL_FLAT */
- { 9642, 0x00001406 }, /* GL_FLOAT */
- { 9651, 0x00008B5A }, /* GL_FLOAT_MAT2 */
- { 9665, 0x00008B5A }, /* GL_FLOAT_MAT2_ARB */
- { 9683, 0x00008B65 }, /* GL_FLOAT_MAT2x3 */
- { 9699, 0x00008B66 }, /* GL_FLOAT_MAT2x4 */
- { 9715, 0x00008B5B }, /* GL_FLOAT_MAT3 */
- { 9729, 0x00008B5B }, /* GL_FLOAT_MAT3_ARB */
- { 9747, 0x00008B67 }, /* GL_FLOAT_MAT3x2 */
- { 9763, 0x00008B68 }, /* GL_FLOAT_MAT3x4 */
- { 9779, 0x00008B5C }, /* GL_FLOAT_MAT4 */
- { 9793, 0x00008B5C }, /* GL_FLOAT_MAT4_ARB */
- { 9811, 0x00008B69 }, /* GL_FLOAT_MAT4x2 */
- { 9827, 0x00008B6A }, /* GL_FLOAT_MAT4x3 */
- { 9843, 0x00008B50 }, /* GL_FLOAT_VEC2 */
- { 9857, 0x00008B50 }, /* GL_FLOAT_VEC2_ARB */
- { 9875, 0x00008B51 }, /* GL_FLOAT_VEC3 */
- { 9889, 0x00008B51 }, /* GL_FLOAT_VEC3_ARB */
- { 9907, 0x00008B52 }, /* GL_FLOAT_VEC4 */
- { 9921, 0x00008B52 }, /* GL_FLOAT_VEC4_ARB */
- { 9939, 0x00000B60 }, /* GL_FOG */
- { 9946, 0x00000080 }, /* GL_FOG_BIT */
- { 9957, 0x00000B66 }, /* GL_FOG_COLOR */
- { 9970, 0x00008451 }, /* GL_FOG_COORD */
- { 9983, 0x00008451 }, /* GL_FOG_COORDINATE */
- { 10001, 0x00008457 }, /* GL_FOG_COORDINATE_ARRAY */
- { 10025, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
- { 10064, 0x0000889D }, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB */
- { 10107, 0x00008456 }, /* GL_FOG_COORDINATE_ARRAY_POINTER */
- { 10139, 0x00008455 }, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
- { 10170, 0x00008454 }, /* GL_FOG_COORDINATE_ARRAY_TYPE */
- { 10199, 0x00008450 }, /* GL_FOG_COORDINATE_SOURCE */
- { 10224, 0x00008457 }, /* GL_FOG_COORD_ARRAY */
- { 10243, 0x0000889D }, /* GL_FOG_COORD_ARRAY_BUFFER_BINDING */
- { 10277, 0x00008456 }, /* GL_FOG_COORD_ARRAY_POINTER */
- { 10304, 0x00008455 }, /* GL_FOG_COORD_ARRAY_STRIDE */
- { 10330, 0x00008454 }, /* GL_FOG_COORD_ARRAY_TYPE */
- { 10354, 0x00008450 }, /* GL_FOG_COORD_SRC */
- { 10371, 0x00000B62 }, /* GL_FOG_DENSITY */
- { 10386, 0x0000855A }, /* GL_FOG_DISTANCE_MODE_NV */
- { 10410, 0x00000B64 }, /* GL_FOG_END */
- { 10421, 0x00000C54 }, /* GL_FOG_HINT */
- { 10433, 0x00000B61 }, /* GL_FOG_INDEX */
- { 10446, 0x00000B65 }, /* GL_FOG_MODE */
- { 10458, 0x00008198 }, /* GL_FOG_OFFSET_SGIX */
- { 10477, 0x00008199 }, /* GL_FOG_OFFSET_VALUE_SGIX */
- { 10502, 0x00000B63 }, /* GL_FOG_START */
- { 10515, 0x00008452 }, /* GL_FRAGMENT_DEPTH */
- { 10533, 0x00008804 }, /* GL_FRAGMENT_PROGRAM_ARB */
- { 10557, 0x00008B30 }, /* GL_FRAGMENT_SHADER */
- { 10576, 0x00008B30 }, /* GL_FRAGMENT_SHADER_ARB */
- { 10599, 0x00008B8B }, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
- { 10634, 0x00008D40 }, /* GL_FRAMEBUFFER */
- { 10649, 0x00008215 }, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
- { 10686, 0x00008214 }, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
- { 10722, 0x00008210 }, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
- { 10763, 0x00008211 }, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
- { 10804, 0x00008216 }, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
- { 10841, 0x00008213 }, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
- { 10878, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
- { 10916, 0x00008CD1 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT */
- { 10958, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
- { 10996, 0x00008CD0 }, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT */
- { 11038, 0x00008212 }, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
- { 11073, 0x00008217 }, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
- { 11112, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT */
- { 11161, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
- { 11209, 0x00008CD3 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT */
- { 11261, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
- { 11301, 0x00008CD4 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT */
- { 11345, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
- { 11385, 0x00008CD2 }, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT */
- { 11429, 0x00008CA6 }, /* GL_FRAMEBUFFER_BINDING_EXT */
- { 11456, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE */
- { 11480, 0x00008CD5 }, /* GL_FRAMEBUFFER_COMPLETE_EXT */
- { 11508, 0x00008218 }, /* GL_FRAMEBUFFER_DEFAULT */
- { 11531, 0x00008D40 }, /* GL_FRAMEBUFFER_EXT */
- { 11550, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
- { 11587, 0x00008CD6 }, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT */
- { 11628, 0x00008CD9 }, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
- { 11669, 0x00008CDB }, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
- { 11711, 0x00008CD8 }, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
- { 11762, 0x00008CDA }, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
- { 11800, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
- { 11845, 0x00008CD7 }, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT */
- { 11894, 0x00008D56 }, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
- { 11932, 0x00008CDC }, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
- { 11974, 0x00008CDE }, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- { 12006, 0x00008219 }, /* GL_FRAMEBUFFER_UNDEFINED */
- { 12031, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED */
- { 12058, 0x00008CDD }, /* GL_FRAMEBUFFER_UNSUPPORTED_EXT */
- { 12089, 0x00000404 }, /* GL_FRONT */
- { 12098, 0x00000408 }, /* GL_FRONT_AND_BACK */
- { 12116, 0x00000B46 }, /* GL_FRONT_FACE */
- { 12130, 0x00000400 }, /* GL_FRONT_LEFT */
- { 12144, 0x00000401 }, /* GL_FRONT_RIGHT */
- { 12159, 0x00008006 }, /* GL_FUNC_ADD */
- { 12171, 0x00008006 }, /* GL_FUNC_ADD_EXT */
- { 12187, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT */
- { 12212, 0x0000800B }, /* GL_FUNC_REVERSE_SUBTRACT_EXT */
- { 12241, 0x0000800A }, /* GL_FUNC_SUBTRACT */
- { 12258, 0x0000800A }, /* GL_FUNC_SUBTRACT_EXT */
- { 12279, 0x00008191 }, /* GL_GENERATE_MIPMAP */
- { 12298, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT */
- { 12322, 0x00008192 }, /* GL_GENERATE_MIPMAP_HINT_SGIS */
- { 12351, 0x00008191 }, /* GL_GENERATE_MIPMAP_SGIS */
- { 12375, 0x00000206 }, /* GL_GEQUAL */
- { 12385, 0x00000204 }, /* GL_GREATER */
- { 12396, 0x00001904 }, /* GL_GREEN */
- { 12405, 0x00000D19 }, /* GL_GREEN_BIAS */
- { 12419, 0x00000D53 }, /* GL_GREEN_BITS */
- { 12433, 0x00000D18 }, /* GL_GREEN_SCALE */
- { 12448, 0x00008000 }, /* GL_HINT_BIT */
- { 12460, 0x00008024 }, /* GL_HISTOGRAM */
- { 12473, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE */
- { 12497, 0x0000802B }, /* GL_HISTOGRAM_ALPHA_SIZE_EXT */
- { 12525, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE */
- { 12548, 0x0000802A }, /* GL_HISTOGRAM_BLUE_SIZE_EXT */
- { 12575, 0x00008024 }, /* GL_HISTOGRAM_EXT */
- { 12592, 0x00008027 }, /* GL_HISTOGRAM_FORMAT */
- { 12612, 0x00008027 }, /* GL_HISTOGRAM_FORMAT_EXT */
- { 12636, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE */
- { 12660, 0x00008029 }, /* GL_HISTOGRAM_GREEN_SIZE_EXT */
- { 12688, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE */
- { 12716, 0x0000802C }, /* GL_HISTOGRAM_LUMINANCE_SIZE_EXT */
- { 12748, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE */
- { 12770, 0x00008028 }, /* GL_HISTOGRAM_RED_SIZE_EXT */
- { 12796, 0x0000802D }, /* GL_HISTOGRAM_SINK */
- { 12814, 0x0000802D }, /* GL_HISTOGRAM_SINK_EXT */
- { 12836, 0x00008026 }, /* GL_HISTOGRAM_WIDTH */
- { 12855, 0x00008026 }, /* GL_HISTOGRAM_WIDTH_EXT */
- { 12878, 0x0000862A }, /* GL_IDENTITY_NV */
- { 12893, 0x00008150 }, /* GL_IGNORE_BORDER_HP */
- { 12913, 0x00008B9B }, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
- { 12953, 0x00008B9A }, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
- { 12991, 0x00001E02 }, /* GL_INCR */
- { 12999, 0x00008507 }, /* GL_INCR_WRAP */
- { 13012, 0x00008507 }, /* GL_INCR_WRAP_EXT */
- { 13029, 0x00008222 }, /* GL_INDEX */
- { 13038, 0x00008077 }, /* GL_INDEX_ARRAY */
- { 13053, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING */
- { 13083, 0x00008899 }, /* GL_INDEX_ARRAY_BUFFER_BINDING_ARB */
- { 13117, 0x00008091 }, /* GL_INDEX_ARRAY_POINTER */
- { 13140, 0x00008086 }, /* GL_INDEX_ARRAY_STRIDE */
- { 13162, 0x00008085 }, /* GL_INDEX_ARRAY_TYPE */
- { 13182, 0x00000D51 }, /* GL_INDEX_BITS */
- { 13196, 0x00000C20 }, /* GL_INDEX_CLEAR_VALUE */
- { 13217, 0x00000BF1 }, /* GL_INDEX_LOGIC_OP */
- { 13235, 0x00000C30 }, /* GL_INDEX_MODE */
- { 13249, 0x00000D13 }, /* GL_INDEX_OFFSET */
- { 13265, 0x00000D12 }, /* GL_INDEX_SHIFT */
- { 13280, 0x00000C21 }, /* GL_INDEX_WRITEMASK */
- { 13299, 0x00008B84 }, /* GL_INFO_LOG_LENGTH */
- { 13318, 0x00001404 }, /* GL_INT */
- { 13325, 0x00008049 }, /* GL_INTENSITY */
- { 13338, 0x0000804C }, /* GL_INTENSITY12 */
- { 13353, 0x0000804C }, /* GL_INTENSITY12_EXT */
- { 13372, 0x0000804D }, /* GL_INTENSITY16 */
- { 13387, 0x0000804D }, /* GL_INTENSITY16_EXT */
- { 13406, 0x0000804A }, /* GL_INTENSITY4 */
- { 13420, 0x0000804A }, /* GL_INTENSITY4_EXT */
- { 13438, 0x0000804B }, /* GL_INTENSITY8 */
- { 13452, 0x0000804B }, /* GL_INTENSITY8_EXT */
- { 13470, 0x00008049 }, /* GL_INTENSITY_EXT */
- { 13487, 0x00008575 }, /* GL_INTERPOLATE */
- { 13502, 0x00008575 }, /* GL_INTERPOLATE_ARB */
- { 13521, 0x00008575 }, /* GL_INTERPOLATE_EXT */
- { 13540, 0x00008B53 }, /* GL_INT_VEC2 */
- { 13552, 0x00008B53 }, /* GL_INT_VEC2_ARB */
- { 13568, 0x00008B54 }, /* GL_INT_VEC3 */
- { 13580, 0x00008B54 }, /* GL_INT_VEC3_ARB */
- { 13596, 0x00008B55 }, /* GL_INT_VEC4 */
- { 13608, 0x00008B55 }, /* GL_INT_VEC4_ARB */
- { 13624, 0x00000500 }, /* GL_INVALID_ENUM */
- { 13640, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION */
- { 13673, 0x00000506 }, /* GL_INVALID_FRAMEBUFFER_OPERATION_EXT */
- { 13710, 0x00000502 }, /* GL_INVALID_OPERATION */
- { 13731, 0x00000501 }, /* GL_INVALID_VALUE */
- { 13748, 0x0000862B }, /* GL_INVERSE_NV */
- { 13762, 0x0000862D }, /* GL_INVERSE_TRANSPOSE_NV */
- { 13786, 0x0000150A }, /* GL_INVERT */
- { 13796, 0x00001E00 }, /* GL_KEEP */
- { 13804, 0x00008E4E }, /* GL_LAST_VERTEX_CONVENTION_EXT */
- { 13834, 0x00000406 }, /* GL_LEFT */
- { 13842, 0x00000203 }, /* GL_LEQUAL */
- { 13852, 0x00000201 }, /* GL_LESS */
- { 13860, 0x00004000 }, /* GL_LIGHT0 */
- { 13870, 0x00004001 }, /* GL_LIGHT1 */
- { 13880, 0x00004002 }, /* GL_LIGHT2 */
- { 13890, 0x00004003 }, /* GL_LIGHT3 */
- { 13900, 0x00004004 }, /* GL_LIGHT4 */
- { 13910, 0x00004005 }, /* GL_LIGHT5 */
- { 13920, 0x00004006 }, /* GL_LIGHT6 */
- { 13930, 0x00004007 }, /* GL_LIGHT7 */
- { 13940, 0x00000B50 }, /* GL_LIGHTING */
- { 13952, 0x00000040 }, /* GL_LIGHTING_BIT */
- { 13968, 0x00000B53 }, /* GL_LIGHT_MODEL_AMBIENT */
- { 13991, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL */
- { 14020, 0x000081F8 }, /* GL_LIGHT_MODEL_COLOR_CONTROL_EXT */
- { 14053, 0x00000B51 }, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
- { 14081, 0x00000B52 }, /* GL_LIGHT_MODEL_TWO_SIDE */
- { 14105, 0x00001B01 }, /* GL_LINE */
- { 14113, 0x00002601 }, /* GL_LINEAR */
- { 14123, 0x00001208 }, /* GL_LINEAR_ATTENUATION */
- { 14145, 0x00008170 }, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
- { 14175, 0x0000844F }, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
- { 14206, 0x00002703 }, /* GL_LINEAR_MIPMAP_LINEAR */
- { 14230, 0x00002701 }, /* GL_LINEAR_MIPMAP_NEAREST */
- { 14255, 0x00000001 }, /* GL_LINES */
- { 14264, 0x00000004 }, /* GL_LINE_BIT */
- { 14276, 0x00000002 }, /* GL_LINE_LOOP */
- { 14289, 0x00000707 }, /* GL_LINE_RESET_TOKEN */
- { 14309, 0x00000B20 }, /* GL_LINE_SMOOTH */
- { 14324, 0x00000C52 }, /* GL_LINE_SMOOTH_HINT */
- { 14344, 0x00000B24 }, /* GL_LINE_STIPPLE */
- { 14360, 0x00000B25 }, /* GL_LINE_STIPPLE_PATTERN */
- { 14384, 0x00000B26 }, /* GL_LINE_STIPPLE_REPEAT */
- { 14407, 0x00000003 }, /* GL_LINE_STRIP */
- { 14421, 0x00000702 }, /* GL_LINE_TOKEN */
- { 14435, 0x00000B21 }, /* GL_LINE_WIDTH */
- { 14449, 0x00000B23 }, /* GL_LINE_WIDTH_GRANULARITY */
- { 14475, 0x00000B22 }, /* GL_LINE_WIDTH_RANGE */
- { 14495, 0x00008B82 }, /* GL_LINK_STATUS */
- { 14510, 0x00000B32 }, /* GL_LIST_BASE */
- { 14523, 0x00020000 }, /* GL_LIST_BIT */
- { 14535, 0x00000B33 }, /* GL_LIST_INDEX */
- { 14549, 0x00000B30 }, /* GL_LIST_MODE */
- { 14562, 0x00000101 }, /* GL_LOAD */
- { 14570, 0x00000BF1 }, /* GL_LOGIC_OP */
- { 14582, 0x00000BF0 }, /* GL_LOGIC_OP_MODE */
- { 14599, 0x00008CA1 }, /* GL_LOWER_LEFT */
- { 14613, 0x00001909 }, /* GL_LUMINANCE */
- { 14626, 0x00008041 }, /* GL_LUMINANCE12 */
- { 14641, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12 */
- { 14664, 0x00008047 }, /* GL_LUMINANCE12_ALPHA12_EXT */
- { 14691, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4 */
- { 14713, 0x00008046 }, /* GL_LUMINANCE12_ALPHA4_EXT */
- { 14739, 0x00008041 }, /* GL_LUMINANCE12_EXT */
- { 14758, 0x00008042 }, /* GL_LUMINANCE16 */
- { 14773, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16 */
- { 14796, 0x00008048 }, /* GL_LUMINANCE16_ALPHA16_EXT */
- { 14823, 0x00008042 }, /* GL_LUMINANCE16_EXT */
- { 14842, 0x0000803F }, /* GL_LUMINANCE4 */
- { 14856, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4 */
- { 14877, 0x00008043 }, /* GL_LUMINANCE4_ALPHA4_EXT */
- { 14902, 0x0000803F }, /* GL_LUMINANCE4_EXT */
- { 14920, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2 */
- { 14941, 0x00008044 }, /* GL_LUMINANCE6_ALPHA2_EXT */
- { 14966, 0x00008040 }, /* GL_LUMINANCE8 */
- { 14980, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8 */
- { 15001, 0x00008045 }, /* GL_LUMINANCE8_ALPHA8_EXT */
- { 15026, 0x00008040 }, /* GL_LUMINANCE8_EXT */
- { 15044, 0x0000190A }, /* GL_LUMINANCE_ALPHA */
- { 15063, 0x00000D90 }, /* GL_MAP1_COLOR_4 */
- { 15079, 0x00000DD0 }, /* GL_MAP1_GRID_DOMAIN */
- { 15099, 0x00000DD1 }, /* GL_MAP1_GRID_SEGMENTS */
- { 15121, 0x00000D91 }, /* GL_MAP1_INDEX */
- { 15135, 0x00000D92 }, /* GL_MAP1_NORMAL */
- { 15150, 0x00000D93 }, /* GL_MAP1_TEXTURE_COORD_1 */
- { 15174, 0x00000D94 }, /* GL_MAP1_TEXTURE_COORD_2 */
- { 15198, 0x00000D95 }, /* GL_MAP1_TEXTURE_COORD_3 */
- { 15222, 0x00000D96 }, /* GL_MAP1_TEXTURE_COORD_4 */
- { 15246, 0x00000D97 }, /* GL_MAP1_VERTEX_3 */
- { 15263, 0x00000D98 }, /* GL_MAP1_VERTEX_4 */
- { 15280, 0x00008660 }, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
- { 15308, 0x0000866A }, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
- { 15337, 0x0000866B }, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
- { 15366, 0x0000866C }, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
- { 15395, 0x0000866D }, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
- { 15424, 0x0000866E }, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
- { 15453, 0x0000866F }, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
- { 15482, 0x00008661 }, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
- { 15510, 0x00008662 }, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
- { 15538, 0x00008663 }, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
- { 15566, 0x00008664 }, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
- { 15594, 0x00008665 }, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
- { 15622, 0x00008666 }, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
- { 15650, 0x00008667 }, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
- { 15678, 0x00008668 }, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
- { 15706, 0x00008669 }, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
- { 15734, 0x00000DB0 }, /* GL_MAP2_COLOR_4 */
- { 15750, 0x00000DD2 }, /* GL_MAP2_GRID_DOMAIN */
- { 15770, 0x00000DD3 }, /* GL_MAP2_GRID_SEGMENTS */
- { 15792, 0x00000DB1 }, /* GL_MAP2_INDEX */
- { 15806, 0x00000DB2 }, /* GL_MAP2_NORMAL */
- { 15821, 0x00000DB3 }, /* GL_MAP2_TEXTURE_COORD_1 */
- { 15845, 0x00000DB4 }, /* GL_MAP2_TEXTURE_COORD_2 */
- { 15869, 0x00000DB5 }, /* GL_MAP2_TEXTURE_COORD_3 */
- { 15893, 0x00000DB6 }, /* GL_MAP2_TEXTURE_COORD_4 */
- { 15917, 0x00000DB7 }, /* GL_MAP2_VERTEX_3 */
- { 15934, 0x00000DB8 }, /* GL_MAP2_VERTEX_4 */
- { 15951, 0x00008670 }, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
- { 15979, 0x0000867A }, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
- { 16008, 0x0000867B }, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
- { 16037, 0x0000867C }, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
- { 16066, 0x0000867D }, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
- { 16095, 0x0000867E }, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
- { 16124, 0x0000867F }, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
- { 16153, 0x00008671 }, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
- { 16181, 0x00008672 }, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
- { 16209, 0x00008673 }, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
- { 16237, 0x00008674 }, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
- { 16265, 0x00008675 }, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
- { 16293, 0x00008676 }, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
- { 16321, 0x00008677 }, /* GL_MAP2_VERTEX_ATTRIB7_4_NV */
- { 16349, 0x00008678 }, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
- { 16377, 0x00008679 }, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
- { 16405, 0x00000D10 }, /* GL_MAP_COLOR */
- { 16418, 0x00000010 }, /* GL_MAP_FLUSH_EXPLICIT_BIT */
- { 16444, 0x00000008 }, /* GL_MAP_INVALIDATE_BUFFER_BIT */
- { 16473, 0x00000004 }, /* GL_MAP_INVALIDATE_RANGE_BIT */
- { 16501, 0x00000001 }, /* GL_MAP_READ_BIT */
- { 16517, 0x00000D11 }, /* GL_MAP_STENCIL */
- { 16532, 0x00000020 }, /* GL_MAP_UNSYNCHRONIZED_BIT */
- { 16558, 0x00000002 }, /* GL_MAP_WRITE_BIT */
- { 16575, 0x000088C0 }, /* GL_MATRIX0_ARB */
- { 16590, 0x00008630 }, /* GL_MATRIX0_NV */
- { 16604, 0x000088CA }, /* GL_MATRIX10_ARB */
- { 16620, 0x000088CB }, /* GL_MATRIX11_ARB */
- { 16636, 0x000088CC }, /* GL_MATRIX12_ARB */
- { 16652, 0x000088CD }, /* GL_MATRIX13_ARB */
- { 16668, 0x000088CE }, /* GL_MATRIX14_ARB */
- { 16684, 0x000088CF }, /* GL_MATRIX15_ARB */
- { 16700, 0x000088D0 }, /* GL_MATRIX16_ARB */
- { 16716, 0x000088D1 }, /* GL_MATRIX17_ARB */
- { 16732, 0x000088D2 }, /* GL_MATRIX18_ARB */
- { 16748, 0x000088D3 }, /* GL_MATRIX19_ARB */
- { 16764, 0x000088C1 }, /* GL_MATRIX1_ARB */
- { 16779, 0x00008631 }, /* GL_MATRIX1_NV */
- { 16793, 0x000088D4 }, /* GL_MATRIX20_ARB */
- { 16809, 0x000088D5 }, /* GL_MATRIX21_ARB */
- { 16825, 0x000088D6 }, /* GL_MATRIX22_ARB */
- { 16841, 0x000088D7 }, /* GL_MATRIX23_ARB */
- { 16857, 0x000088D8 }, /* GL_MATRIX24_ARB */
- { 16873, 0x000088D9 }, /* GL_MATRIX25_ARB */
- { 16889, 0x000088DA }, /* GL_MATRIX26_ARB */
- { 16905, 0x000088DB }, /* GL_MATRIX27_ARB */
- { 16921, 0x000088DC }, /* GL_MATRIX28_ARB */
- { 16937, 0x000088DD }, /* GL_MATRIX29_ARB */
- { 16953, 0x000088C2 }, /* GL_MATRIX2_ARB */
- { 16968, 0x00008632 }, /* GL_MATRIX2_NV */
- { 16982, 0x000088DE }, /* GL_MATRIX30_ARB */
- { 16998, 0x000088DF }, /* GL_MATRIX31_ARB */
- { 17014, 0x000088C3 }, /* GL_MATRIX3_ARB */
- { 17029, 0x00008633 }, /* GL_MATRIX3_NV */
- { 17043, 0x000088C4 }, /* GL_MATRIX4_ARB */
- { 17058, 0x00008634 }, /* GL_MATRIX4_NV */
- { 17072, 0x000088C5 }, /* GL_MATRIX5_ARB */
- { 17087, 0x00008635 }, /* GL_MATRIX5_NV */
- { 17101, 0x000088C6 }, /* GL_MATRIX6_ARB */
- { 17116, 0x00008636 }, /* GL_MATRIX6_NV */
- { 17130, 0x000088C7 }, /* GL_MATRIX7_ARB */
- { 17145, 0x00008637 }, /* GL_MATRIX7_NV */
- { 17159, 0x000088C8 }, /* GL_MATRIX8_ARB */
- { 17174, 0x000088C9 }, /* GL_MATRIX9_ARB */
- { 17189, 0x00008844 }, /* GL_MATRIX_INDEX_ARRAY_ARB */
- { 17215, 0x00008849 }, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
- { 17249, 0x00008846 }, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
- { 17280, 0x00008848 }, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
- { 17313, 0x00008847 }, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
- { 17344, 0x00000BA0 }, /* GL_MATRIX_MODE */
- { 17359, 0x00008840 }, /* GL_MATRIX_PALETTE_ARB */
- { 17381, 0x00008008 }, /* GL_MAX */
- { 17388, 0x00008073 }, /* GL_MAX_3D_TEXTURE_SIZE */
- { 17411, 0x000088FF }, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
- { 17443, 0x00000D35 }, /* GL_MAX_ATTRIB_STACK_DEPTH */
- { 17469, 0x00000D3B }, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
- { 17502, 0x00008177 }, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
- { 17528, 0x00008178 }, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- { 17562, 0x00000D32 }, /* GL_MAX_CLIP_PLANES */
- { 17581, 0x00008CDF }, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
- { 17610, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
- { 17642, 0x000080B3 }, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI */
- { 17678, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
- { 17714, 0x00008B4D }, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB */
- { 17754, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT */
- { 17780, 0x0000801B }, /* GL_MAX_CONVOLUTION_HEIGHT_EXT */
- { 17810, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH */
- { 17835, 0x0000801A }, /* GL_MAX_CONVOLUTION_WIDTH_EXT */
- { 17864, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
- { 17893, 0x0000851C }, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB */
- { 17926, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS */
- { 17946, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ARB */
- { 17970, 0x00008824 }, /* GL_MAX_DRAW_BUFFERS_ATI */
- { 17994, 0x000080E9 }, /* GL_MAX_ELEMENTS_INDICES */
- { 18018, 0x000080E8 }, /* GL_MAX_ELEMENTS_VERTICES */
- { 18043, 0x00000D30 }, /* GL_MAX_EVAL_ORDER */
- { 18061, 0x00008008 }, /* GL_MAX_EXT */
- { 18072, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
- { 18107, 0x00008B49 }, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB */
- { 18146, 0x00000D31 }, /* GL_MAX_LIGHTS */
- { 18160, 0x00000B31 }, /* GL_MAX_LIST_NESTING */
- { 18180, 0x00008841 }, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
- { 18218, 0x00000D36 }, /* GL_MAX_MODELVIEW_STACK_DEPTH */
- { 18247, 0x00000D37 }, /* GL_MAX_NAME_STACK_DEPTH */
- { 18271, 0x00008842 }, /* GL_MAX_PALETTE_MATRICES_ARB */
- { 18299, 0x00000D34 }, /* GL_MAX_PIXEL_MAP_TABLE */
- { 18322, 0x000088B1 }, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
- { 18359, 0x0000880B }, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
- { 18395, 0x000088AD }, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
- { 18422, 0x000088F5 }, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
- { 18451, 0x000088B5 }, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
- { 18485, 0x000088F4 }, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
- { 18521, 0x000088F6 }, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
- { 18548, 0x000088A1 }, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
- { 18580, 0x000088B4 }, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
- { 18616, 0x000088F8 }, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
- { 18645, 0x000088F7 }, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
- { 18674, 0x0000862F }, /* GL_MAX_PROGRAM_MATRICES_ARB */
- { 18702, 0x0000862E }, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
- { 18740, 0x000088B3 }, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- { 18784, 0x0000880E }, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- { 18827, 0x000088AF }, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
- { 18861, 0x000088A3 }, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- { 18900, 0x000088AB }, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
- { 18937, 0x000088A7 }, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
- { 18975, 0x00008810 }, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- { 19018, 0x0000880F }, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- { 19061, 0x000088A9 }, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
- { 19091, 0x000088A5 }, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
- { 19122, 0x0000880D }, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
- { 19158, 0x0000880C }, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
- { 19194, 0x00000D38 }, /* GL_MAX_PROJECTION_STACK_DEPTH */
- { 19224, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
- { 19258, 0x000084F8 }, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_NV */
- { 19291, 0x000084E8 }, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
- { 19320, 0x00008D57 }, /* GL_MAX_SAMPLES */
- { 19335, 0x00008504 }, /* GL_MAX_SHININESS_NV */
- { 19355, 0x00008505 }, /* GL_MAX_SPOT_EXPONENT_NV */
- { 19379, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS */
- { 19401, 0x00008871 }, /* GL_MAX_TEXTURE_COORDS_ARB */
- { 19427, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS */
- { 19454, 0x00008872 }, /* GL_MAX_TEXTURE_IMAGE_UNITS_ARB */
- { 19485, 0x000084FD }, /* GL_MAX_TEXTURE_LOD_BIAS */
- { 19509, 0x000084FF }, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
- { 19543, 0x00000D33 }, /* GL_MAX_TEXTURE_SIZE */
- { 19563, 0x00000D39 }, /* GL_MAX_TEXTURE_STACK_DEPTH */
- { 19590, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS */
- { 19611, 0x000084E2 }, /* GL_MAX_TEXTURE_UNITS_ARB */
- { 19636, 0x0000862F }, /* GL_MAX_TRACK_MATRICES_NV */
- { 19661, 0x0000862E }, /* GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV */
- { 19696, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS */
- { 19718, 0x00008B4B }, /* GL_MAX_VARYING_FLOATS_ARB */
- { 19744, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS */
- { 19766, 0x00008869 }, /* GL_MAX_VERTEX_ATTRIBS_ARB */
- { 19792, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
- { 19826, 0x00008B4C }, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB */
- { 19864, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
- { 19897, 0x00008B4A }, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB */
- { 19934, 0x000086A4 }, /* GL_MAX_VERTEX_UNITS_ARB */
- { 19958, 0x00000D3A }, /* GL_MAX_VIEWPORT_DIMS */
- { 19979, 0x00008007 }, /* GL_MIN */
- { 19986, 0x0000802E }, /* GL_MINMAX */
- { 19996, 0x0000802E }, /* GL_MINMAX_EXT */
- { 20010, 0x0000802F }, /* GL_MINMAX_FORMAT */
- { 20027, 0x0000802F }, /* GL_MINMAX_FORMAT_EXT */
- { 20048, 0x00008030 }, /* GL_MINMAX_SINK */
- { 20063, 0x00008030 }, /* GL_MINMAX_SINK_EXT */
- { 20082, 0x00008007 }, /* GL_MIN_EXT */
- { 20093, 0x00008370 }, /* GL_MIRRORED_REPEAT */
- { 20112, 0x00008370 }, /* GL_MIRRORED_REPEAT_ARB */
- { 20135, 0x00008370 }, /* GL_MIRRORED_REPEAT_IBM */
- { 20158, 0x00008742 }, /* GL_MIRROR_CLAMP_ATI */
- { 20178, 0x00008742 }, /* GL_MIRROR_CLAMP_EXT */
- { 20198, 0x00008912 }, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
- { 20228, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_ATI */
- { 20256, 0x00008743 }, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
- { 20284, 0x00001700 }, /* GL_MODELVIEW */
- { 20297, 0x00001700 }, /* GL_MODELVIEW0_ARB */
- { 20315, 0x0000872A }, /* GL_MODELVIEW10_ARB */
- { 20334, 0x0000872B }, /* GL_MODELVIEW11_ARB */
- { 20353, 0x0000872C }, /* GL_MODELVIEW12_ARB */
- { 20372, 0x0000872D }, /* GL_MODELVIEW13_ARB */
- { 20391, 0x0000872E }, /* GL_MODELVIEW14_ARB */
- { 20410, 0x0000872F }, /* GL_MODELVIEW15_ARB */
- { 20429, 0x00008730 }, /* GL_MODELVIEW16_ARB */
- { 20448, 0x00008731 }, /* GL_MODELVIEW17_ARB */
- { 20467, 0x00008732 }, /* GL_MODELVIEW18_ARB */
- { 20486, 0x00008733 }, /* GL_MODELVIEW19_ARB */
- { 20505, 0x0000850A }, /* GL_MODELVIEW1_ARB */
- { 20523, 0x00008734 }, /* GL_MODELVIEW20_ARB */
- { 20542, 0x00008735 }, /* GL_MODELVIEW21_ARB */
- { 20561, 0x00008736 }, /* GL_MODELVIEW22_ARB */
- { 20580, 0x00008737 }, /* GL_MODELVIEW23_ARB */
- { 20599, 0x00008738 }, /* GL_MODELVIEW24_ARB */
- { 20618, 0x00008739 }, /* GL_MODELVIEW25_ARB */
- { 20637, 0x0000873A }, /* GL_MODELVIEW26_ARB */
- { 20656, 0x0000873B }, /* GL_MODELVIEW27_ARB */
- { 20675, 0x0000873C }, /* GL_MODELVIEW28_ARB */
- { 20694, 0x0000873D }, /* GL_MODELVIEW29_ARB */
- { 20713, 0x00008722 }, /* GL_MODELVIEW2_ARB */
- { 20731, 0x0000873E }, /* GL_MODELVIEW30_ARB */
- { 20750, 0x0000873F }, /* GL_MODELVIEW31_ARB */
- { 20769, 0x00008723 }, /* GL_MODELVIEW3_ARB */
- { 20787, 0x00008724 }, /* GL_MODELVIEW4_ARB */
- { 20805, 0x00008725 }, /* GL_MODELVIEW5_ARB */
- { 20823, 0x00008726 }, /* GL_MODELVIEW6_ARB */
- { 20841, 0x00008727 }, /* GL_MODELVIEW7_ARB */
- { 20859, 0x00008728 }, /* GL_MODELVIEW8_ARB */
- { 20877, 0x00008729 }, /* GL_MODELVIEW9_ARB */
- { 20895, 0x00000BA6 }, /* GL_MODELVIEW_MATRIX */
- { 20915, 0x00008629 }, /* GL_MODELVIEW_PROJECTION_NV */
- { 20942, 0x00000BA3 }, /* GL_MODELVIEW_STACK_DEPTH */
- { 20967, 0x00002100 }, /* GL_MODULATE */
- { 20979, 0x00008744 }, /* GL_MODULATE_ADD_ATI */
- { 20999, 0x00008745 }, /* GL_MODULATE_SIGNED_ADD_ATI */
- { 21026, 0x00008746 }, /* GL_MODULATE_SUBTRACT_ATI */
- { 21051, 0x00000103 }, /* GL_MULT */
- { 21059, 0x0000809D }, /* GL_MULTISAMPLE */
- { 21074, 0x000086B2 }, /* GL_MULTISAMPLE_3DFX */
- { 21094, 0x0000809D }, /* GL_MULTISAMPLE_ARB */
- { 21113, 0x20000000 }, /* GL_MULTISAMPLE_BIT */
- { 21132, 0x20000000 }, /* GL_MULTISAMPLE_BIT_3DFX */
- { 21156, 0x20000000 }, /* GL_MULTISAMPLE_BIT_ARB */
- { 21179, 0x00008534 }, /* GL_MULTISAMPLE_FILTER_HINT_NV */
- { 21209, 0x00002A25 }, /* GL_N3F_V3F */
- { 21220, 0x00000D70 }, /* GL_NAME_STACK_DEPTH */
- { 21240, 0x0000150E }, /* GL_NAND */
- { 21248, 0x00002600 }, /* GL_NEAREST */
- { 21259, 0x0000844E }, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
- { 21290, 0x0000844D }, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
- { 21322, 0x00002702 }, /* GL_NEAREST_MIPMAP_LINEAR */
- { 21347, 0x00002700 }, /* GL_NEAREST_MIPMAP_NEAREST */
- { 21373, 0x00000200 }, /* GL_NEVER */
- { 21382, 0x00001102 }, /* GL_NICEST */
- { 21392, 0x00000000 }, /* GL_NONE */
- { 21400, 0x00001505 }, /* GL_NOOP */
- { 21408, 0x00001508 }, /* GL_NOR */
- { 21415, 0x00000BA1 }, /* GL_NORMALIZE */
- { 21428, 0x00008075 }, /* GL_NORMAL_ARRAY */
- { 21444, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
- { 21475, 0x00008897 }, /* GL_NORMAL_ARRAY_BUFFER_BINDING_ARB */
- { 21510, 0x0000808F }, /* GL_NORMAL_ARRAY_POINTER */
- { 21534, 0x0000807F }, /* GL_NORMAL_ARRAY_STRIDE */
- { 21557, 0x0000807E }, /* GL_NORMAL_ARRAY_TYPE */
- { 21578, 0x00008511 }, /* GL_NORMAL_MAP */
- { 21592, 0x00008511 }, /* GL_NORMAL_MAP_ARB */
- { 21610, 0x00008511 }, /* GL_NORMAL_MAP_NV */
- { 21627, 0x00000205 }, /* GL_NOTEQUAL */
- { 21639, 0x00000000 }, /* GL_NO_ERROR */
- { 21651, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
- { 21685, 0x000086A2 }, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB */
- { 21723, 0x00008B89 }, /* GL_OBJECT_ACTIVE_ATTRIBUTES_ARB */
- { 21755, 0x00008B8A }, /* GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB */
- { 21797, 0x00008B86 }, /* GL_OBJECT_ACTIVE_UNIFORMS_ARB */
- { 21827, 0x00008B87 }, /* GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB */
- { 21867, 0x00008B85 }, /* GL_OBJECT_ATTACHED_OBJECTS_ARB */
- { 21898, 0x00008B81 }, /* GL_OBJECT_COMPILE_STATUS_ARB */
- { 21927, 0x00008B80 }, /* GL_OBJECT_DELETE_STATUS_ARB */
- { 21955, 0x00008B84 }, /* GL_OBJECT_INFO_LOG_LENGTH_ARB */
- { 21985, 0x00002401 }, /* GL_OBJECT_LINEAR */
- { 22002, 0x00008B82 }, /* GL_OBJECT_LINK_STATUS_ARB */
- { 22028, 0x00002501 }, /* GL_OBJECT_PLANE */
- { 22044, 0x00008B88 }, /* GL_OBJECT_SHADER_SOURCE_LENGTH_ARB */
- { 22079, 0x00008B4F }, /* GL_OBJECT_SUBTYPE_ARB */
- { 22101, 0x00008B4E }, /* GL_OBJECT_TYPE_ARB */
- { 22120, 0x00008B83 }, /* GL_OBJECT_VALIDATE_STATUS_ARB */
- { 22150, 0x00008165 }, /* GL_OCCLUSION_TEST_HP */
- { 22171, 0x00008166 }, /* GL_OCCLUSION_TEST_RESULT_HP */
- { 22199, 0x00000001 }, /* GL_ONE */
- { 22206, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA */
- { 22234, 0x00008004 }, /* GL_ONE_MINUS_CONSTANT_ALPHA_EXT */
- { 22266, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR */
- { 22294, 0x00008002 }, /* GL_ONE_MINUS_CONSTANT_COLOR_EXT */
- { 22326, 0x00000305 }, /* GL_ONE_MINUS_DST_ALPHA */
- { 22349, 0x00000307 }, /* GL_ONE_MINUS_DST_COLOR */
- { 22372, 0x00000303 }, /* GL_ONE_MINUS_SRC_ALPHA */
- { 22395, 0x00000301 }, /* GL_ONE_MINUS_SRC_COLOR */
- { 22418, 0x00008598 }, /* GL_OPERAND0_ALPHA */
- { 22436, 0x00008598 }, /* GL_OPERAND0_ALPHA_ARB */
- { 22458, 0x00008598 }, /* GL_OPERAND0_ALPHA_EXT */
- { 22480, 0x00008590 }, /* GL_OPERAND0_RGB */
- { 22496, 0x00008590 }, /* GL_OPERAND0_RGB_ARB */
- { 22516, 0x00008590 }, /* GL_OPERAND0_RGB_EXT */
- { 22536, 0x00008599 }, /* GL_OPERAND1_ALPHA */
- { 22554, 0x00008599 }, /* GL_OPERAND1_ALPHA_ARB */
- { 22576, 0x00008599 }, /* GL_OPERAND1_ALPHA_EXT */
- { 22598, 0x00008591 }, /* GL_OPERAND1_RGB */
- { 22614, 0x00008591 }, /* GL_OPERAND1_RGB_ARB */
- { 22634, 0x00008591 }, /* GL_OPERAND1_RGB_EXT */
- { 22654, 0x0000859A }, /* GL_OPERAND2_ALPHA */
- { 22672, 0x0000859A }, /* GL_OPERAND2_ALPHA_ARB */
- { 22694, 0x0000859A }, /* GL_OPERAND2_ALPHA_EXT */
- { 22716, 0x00008592 }, /* GL_OPERAND2_RGB */
- { 22732, 0x00008592 }, /* GL_OPERAND2_RGB_ARB */
- { 22752, 0x00008592 }, /* GL_OPERAND2_RGB_EXT */
- { 22772, 0x0000859B }, /* GL_OPERAND3_ALPHA_NV */
- { 22793, 0x00008593 }, /* GL_OPERAND3_RGB_NV */
- { 22812, 0x00001507 }, /* GL_OR */
- { 22818, 0x00000A01 }, /* GL_ORDER */
- { 22827, 0x0000150D }, /* GL_OR_INVERTED */
- { 22842, 0x0000150B }, /* GL_OR_REVERSE */
- { 22856, 0x00000505 }, /* GL_OUT_OF_MEMORY */
- { 22873, 0x00000D05 }, /* GL_PACK_ALIGNMENT */
- { 22891, 0x0000806C }, /* GL_PACK_IMAGE_HEIGHT */
- { 22912, 0x00008758 }, /* GL_PACK_INVERT_MESA */
- { 22932, 0x00000D01 }, /* GL_PACK_LSB_FIRST */
- { 22950, 0x00000D02 }, /* GL_PACK_ROW_LENGTH */
- { 22969, 0x0000806B }, /* GL_PACK_SKIP_IMAGES */
- { 22989, 0x00000D04 }, /* GL_PACK_SKIP_PIXELS */
- { 23009, 0x00000D03 }, /* GL_PACK_SKIP_ROWS */
- { 23027, 0x00000D00 }, /* GL_PACK_SWAP_BYTES */
- { 23046, 0x00008B92 }, /* GL_PALETTE4_R5_G6_B5_OES */
- { 23071, 0x00008B94 }, /* GL_PALETTE4_RGB5_A1_OES */
- { 23095, 0x00008B90 }, /* GL_PALETTE4_RGB8_OES */
- { 23116, 0x00008B93 }, /* GL_PALETTE4_RGBA4_OES */
- { 23138, 0x00008B91 }, /* GL_PALETTE4_RGBA8_OES */
- { 23160, 0x00008B97 }, /* GL_PALETTE8_R5_G6_B5_OES */
- { 23185, 0x00008B99 }, /* GL_PALETTE8_RGB5_A1_OES */
- { 23209, 0x00008B95 }, /* GL_PALETTE8_RGB8_OES */
- { 23230, 0x00008B98 }, /* GL_PALETTE8_RGBA4_OES */
- { 23252, 0x00008B96 }, /* GL_PALETTE8_RGBA8_OES */
- { 23274, 0x00000700 }, /* GL_PASS_THROUGH_TOKEN */
- { 23296, 0x00000C50 }, /* GL_PERSPECTIVE_CORRECTION_HINT */
- { 23327, 0x00000C79 }, /* GL_PIXEL_MAP_A_TO_A */
- { 23347, 0x00000CB9 }, /* GL_PIXEL_MAP_A_TO_A_SIZE */
- { 23372, 0x00000C78 }, /* GL_PIXEL_MAP_B_TO_B */
- { 23392, 0x00000CB8 }, /* GL_PIXEL_MAP_B_TO_B_SIZE */
- { 23417, 0x00000C77 }, /* GL_PIXEL_MAP_G_TO_G */
- { 23437, 0x00000CB7 }, /* GL_PIXEL_MAP_G_TO_G_SIZE */
- { 23462, 0x00000C75 }, /* GL_PIXEL_MAP_I_TO_A */
- { 23482, 0x00000CB5 }, /* GL_PIXEL_MAP_I_TO_A_SIZE */
- { 23507, 0x00000C74 }, /* GL_PIXEL_MAP_I_TO_B */
- { 23527, 0x00000CB4 }, /* GL_PIXEL_MAP_I_TO_B_SIZE */
- { 23552, 0x00000C73 }, /* GL_PIXEL_MAP_I_TO_G */
- { 23572, 0x00000CB3 }, /* GL_PIXEL_MAP_I_TO_G_SIZE */
- { 23597, 0x00000C70 }, /* GL_PIXEL_MAP_I_TO_I */
- { 23617, 0x00000CB0 }, /* GL_PIXEL_MAP_I_TO_I_SIZE */
- { 23642, 0x00000C72 }, /* GL_PIXEL_MAP_I_TO_R */
- { 23662, 0x00000CB2 }, /* GL_PIXEL_MAP_I_TO_R_SIZE */
- { 23687, 0x00000C76 }, /* GL_PIXEL_MAP_R_TO_R */
- { 23707, 0x00000CB6 }, /* GL_PIXEL_MAP_R_TO_R_SIZE */
- { 23732, 0x00000C71 }, /* GL_PIXEL_MAP_S_TO_S */
- { 23752, 0x00000CB1 }, /* GL_PIXEL_MAP_S_TO_S_SIZE */
- { 23777, 0x00000020 }, /* GL_PIXEL_MODE_BIT */
- { 23795, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER */
- { 23816, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING */
- { 23845, 0x000088ED }, /* GL_PIXEL_PACK_BUFFER_BINDING_EXT */
- { 23878, 0x000088EB }, /* GL_PIXEL_PACK_BUFFER_EXT */
- { 23903, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER */
- { 23926, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
- { 23957, 0x000088EF }, /* GL_PIXEL_UNPACK_BUFFER_BINDING_EXT */
- { 23992, 0x000088EC }, /* GL_PIXEL_UNPACK_BUFFER_EXT */
- { 24019, 0x00001B00 }, /* GL_POINT */
- { 24028, 0x00000000 }, /* GL_POINTS */
- { 24038, 0x00000002 }, /* GL_POINT_BIT */
- { 24051, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION */
- { 24081, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_ARB */
- { 24115, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_EXT */
- { 24149, 0x00008129 }, /* GL_POINT_DISTANCE_ATTENUATION_SGIS */
- { 24184, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE */
- { 24213, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_ARB */
- { 24246, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_EXT */
- { 24279, 0x00008128 }, /* GL_POINT_FADE_THRESHOLD_SIZE_SGIS */
- { 24313, 0x00000B11 }, /* GL_POINT_SIZE */
- { 24327, 0x00000B13 }, /* GL_POINT_SIZE_GRANULARITY */
- { 24353, 0x00008127 }, /* GL_POINT_SIZE_MAX */
- { 24371, 0x00008127 }, /* GL_POINT_SIZE_MAX_ARB */
- { 24393, 0x00008127 }, /* GL_POINT_SIZE_MAX_EXT */
- { 24415, 0x00008127 }, /* GL_POINT_SIZE_MAX_SGIS */
- { 24438, 0x00008126 }, /* GL_POINT_SIZE_MIN */
- { 24456, 0x00008126 }, /* GL_POINT_SIZE_MIN_ARB */
- { 24478, 0x00008126 }, /* GL_POINT_SIZE_MIN_EXT */
- { 24500, 0x00008126 }, /* GL_POINT_SIZE_MIN_SGIS */
- { 24523, 0x00000B12 }, /* GL_POINT_SIZE_RANGE */
- { 24543, 0x00000B10 }, /* GL_POINT_SMOOTH */
- { 24559, 0x00000C51 }, /* GL_POINT_SMOOTH_HINT */
- { 24580, 0x00008861 }, /* GL_POINT_SPRITE */
- { 24596, 0x00008861 }, /* GL_POINT_SPRITE_ARB */
- { 24616, 0x00008CA0 }, /* GL_POINT_SPRITE_COORD_ORIGIN */
- { 24645, 0x00008861 }, /* GL_POINT_SPRITE_NV */
- { 24664, 0x00008863 }, /* GL_POINT_SPRITE_R_MODE_NV */
- { 24690, 0x00000701 }, /* GL_POINT_TOKEN */
- { 24705, 0x00000009 }, /* GL_POLYGON */
- { 24716, 0x00000008 }, /* GL_POLYGON_BIT */
- { 24731, 0x00000B40 }, /* GL_POLYGON_MODE */
- { 24747, 0x00008039 }, /* GL_POLYGON_OFFSET_BIAS */
- { 24770, 0x00008038 }, /* GL_POLYGON_OFFSET_FACTOR */
- { 24795, 0x00008037 }, /* GL_POLYGON_OFFSET_FILL */
- { 24818, 0x00002A02 }, /* GL_POLYGON_OFFSET_LINE */
- { 24841, 0x00002A01 }, /* GL_POLYGON_OFFSET_POINT */
- { 24865, 0x00002A00 }, /* GL_POLYGON_OFFSET_UNITS */
- { 24889, 0x00000B41 }, /* GL_POLYGON_SMOOTH */
- { 24907, 0x00000C53 }, /* GL_POLYGON_SMOOTH_HINT */
- { 24930, 0x00000B42 }, /* GL_POLYGON_STIPPLE */
- { 24949, 0x00000010 }, /* GL_POLYGON_STIPPLE_BIT */
- { 24972, 0x00000703 }, /* GL_POLYGON_TOKEN */
- { 24989, 0x00001203 }, /* GL_POSITION */
- { 25001, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
- { 25033, 0x000080BB }, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI */
- { 25069, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
- { 25102, 0x000080B7 }, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI */
- { 25139, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
- { 25170, 0x000080BA }, /* GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI */
- { 25205, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
- { 25237, 0x000080B6 }, /* GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI */
- { 25273, 0x000080D2 }, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
- { 25306, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
- { 25338, 0x000080B9 }, /* GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI */
- { 25374, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
- { 25407, 0x000080B5 }, /* GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI */
- { 25444, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS */
- { 25474, 0x000080B8 }, /* GL_POST_COLOR_MATRIX_RED_BIAS_SGI */
- { 25508, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE */
- { 25539, 0x000080B4 }, /* GL_POST_COLOR_MATRIX_RED_SCALE_SGI */
- { 25574, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
- { 25605, 0x00008023 }, /* GL_POST_CONVOLUTION_ALPHA_BIAS_EXT */
- { 25640, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
- { 25672, 0x0000801F }, /* GL_POST_CONVOLUTION_ALPHA_SCALE_EXT */
- { 25708, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS */
- { 25738, 0x00008022 }, /* GL_POST_CONVOLUTION_BLUE_BIAS_EXT */
- { 25772, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE */
- { 25803, 0x0000801E }, /* GL_POST_CONVOLUTION_BLUE_SCALE_EXT */
- { 25838, 0x000080D1 }, /* GL_POST_CONVOLUTION_COLOR_TABLE */
- { 25870, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS */
- { 25901, 0x00008021 }, /* GL_POST_CONVOLUTION_GREEN_BIAS_EXT */
- { 25936, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE */
- { 25968, 0x0000801D }, /* GL_POST_CONVOLUTION_GREEN_SCALE_EXT */
- { 26004, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS */
- { 26033, 0x00008020 }, /* GL_POST_CONVOLUTION_RED_BIAS_EXT */
- { 26066, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE */
- { 26096, 0x0000801C }, /* GL_POST_CONVOLUTION_RED_SCALE_EXT */
- { 26130, 0x0000817B }, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
- { 26169, 0x00008179 }, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
- { 26202, 0x0000817C }, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
- { 26242, 0x0000817A }, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
- { 26276, 0x00008578 }, /* GL_PREVIOUS */
- { 26288, 0x00008578 }, /* GL_PREVIOUS_ARB */
- { 26304, 0x00008578 }, /* GL_PREVIOUS_EXT */
- { 26320, 0x00008577 }, /* GL_PRIMARY_COLOR */
- { 26337, 0x00008577 }, /* GL_PRIMARY_COLOR_ARB */
- { 26358, 0x00008577 }, /* GL_PRIMARY_COLOR_EXT */
- { 26379, 0x000088B0 }, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
- { 26412, 0x00008805 }, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
- { 26444, 0x000088AC }, /* GL_PROGRAM_ATTRIBS_ARB */
- { 26467, 0x00008677 }, /* GL_PROGRAM_BINDING_ARB */
- { 26490, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_ARB */
- { 26520, 0x0000864B }, /* GL_PROGRAM_ERROR_POSITION_NV */
- { 26549, 0x00008874 }, /* GL_PROGRAM_ERROR_STRING_ARB */
- { 26577, 0x00008876 }, /* GL_PROGRAM_FORMAT_ARB */
- { 26599, 0x00008875 }, /* GL_PROGRAM_FORMAT_ASCII_ARB */
- { 26627, 0x000088A0 }, /* GL_PROGRAM_INSTRUCTIONS_ARB */
- { 26655, 0x00008627 }, /* GL_PROGRAM_LENGTH_ARB */
- { 26677, 0x00008627 }, /* GL_PROGRAM_LENGTH_NV */
- { 26698, 0x000088B2 }, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- { 26738, 0x00008808 }, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- { 26777, 0x000088AE }, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
- { 26807, 0x000088A2 }, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- { 26842, 0x000088AA }, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
- { 26875, 0x000088A6 }, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
- { 26909, 0x0000880A }, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- { 26948, 0x00008809 }, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- { 26987, 0x00008B40 }, /* GL_PROGRAM_OBJECT_ARB */
- { 27009, 0x000088A8 }, /* GL_PROGRAM_PARAMETERS_ARB */
- { 27035, 0x00008644 }, /* GL_PROGRAM_PARAMETER_NV */
- { 27059, 0x00008647 }, /* GL_PROGRAM_RESIDENT_NV */
- { 27082, 0x00008628 }, /* GL_PROGRAM_STRING_ARB */
- { 27104, 0x00008628 }, /* GL_PROGRAM_STRING_NV */
- { 27125, 0x00008646 }, /* GL_PROGRAM_TARGET_NV */
- { 27146, 0x000088A4 }, /* GL_PROGRAM_TEMPORARIES_ARB */
- { 27173, 0x00008807 }, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
- { 27205, 0x00008806 }, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
- { 27237, 0x000088B6 }, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
- { 27272, 0x00001701 }, /* GL_PROJECTION */
- { 27286, 0x00000BA7 }, /* GL_PROJECTION_MATRIX */
- { 27307, 0x00000BA4 }, /* GL_PROJECTION_STACK_DEPTH */
- { 27333, 0x00008E4F }, /* GL_PROVOKING_VERTEX_EXT */
- { 27357, 0x000080D3 }, /* GL_PROXY_COLOR_TABLE */
- { 27378, 0x00008025 }, /* GL_PROXY_HISTOGRAM */
- { 27397, 0x00008025 }, /* GL_PROXY_HISTOGRAM_EXT */
- { 27420, 0x000080D5 }, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
- { 27459, 0x000080D4 }, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
- { 27497, 0x00008063 }, /* GL_PROXY_TEXTURE_1D */
- { 27517, 0x00008C19 }, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
- { 27547, 0x00008063 }, /* GL_PROXY_TEXTURE_1D_EXT */
- { 27571, 0x00008064 }, /* GL_PROXY_TEXTURE_2D */
- { 27591, 0x00008C1B }, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
- { 27621, 0x00008064 }, /* GL_PROXY_TEXTURE_2D_EXT */
- { 27645, 0x00008070 }, /* GL_PROXY_TEXTURE_3D */
- { 27665, 0x000080BD }, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
- { 27698, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP */
- { 27724, 0x0000851B }, /* GL_PROXY_TEXTURE_CUBE_MAP_ARB */
- { 27754, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
- { 27785, 0x000084F7 }, /* GL_PROXY_TEXTURE_RECTANGLE_NV */
- { 27815, 0x00002003 }, /* GL_Q */
- { 27820, 0x00001209 }, /* GL_QUADRATIC_ATTENUATION */
- { 27845, 0x00000007 }, /* GL_QUADS */
- { 27854, 0x00008E4C }, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
- { 27902, 0x00008614 }, /* GL_QUAD_MESH_SUN */
- { 27919, 0x00000008 }, /* GL_QUAD_STRIP */
- { 27933, 0x00008864 }, /* GL_QUERY_COUNTER_BITS */
- { 27955, 0x00008864 }, /* GL_QUERY_COUNTER_BITS_ARB */
- { 27981, 0x00008866 }, /* GL_QUERY_RESULT */
- { 27997, 0x00008866 }, /* GL_QUERY_RESULT_ARB */
- { 28017, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE */
- { 28043, 0x00008867 }, /* GL_QUERY_RESULT_AVAILABLE_ARB */
- { 28073, 0x00002002 }, /* GL_R */
- { 28078, 0x00002A10 }, /* GL_R3_G3_B2 */
- { 28090, 0x00019262 }, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
- { 28123, 0x00000C02 }, /* GL_READ_BUFFER */
- { 28138, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER */
- { 28158, 0x00008CAA }, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
- { 28190, 0x00008CA8 }, /* GL_READ_FRAMEBUFFER_EXT */
- { 28214, 0x000088B8 }, /* GL_READ_ONLY */
- { 28227, 0x000088B8 }, /* GL_READ_ONLY_ARB */
- { 28244, 0x000088BA }, /* GL_READ_WRITE */
- { 28258, 0x000088BA }, /* GL_READ_WRITE_ARB */
- { 28276, 0x00001903 }, /* GL_RED */
- { 28283, 0x00008016 }, /* GL_REDUCE */
- { 28293, 0x00008016 }, /* GL_REDUCE_EXT */
- { 28307, 0x00000D15 }, /* GL_RED_BIAS */
- { 28319, 0x00000D52 }, /* GL_RED_BITS */
- { 28331, 0x00000D14 }, /* GL_RED_SCALE */
- { 28344, 0x00008512 }, /* GL_REFLECTION_MAP */
- { 28362, 0x00008512 }, /* GL_REFLECTION_MAP_ARB */
- { 28384, 0x00008512 }, /* GL_REFLECTION_MAP_NV */
- { 28405, 0x00001C00 }, /* GL_RENDER */
- { 28415, 0x00008D41 }, /* GL_RENDERBUFFER */
- { 28431, 0x00008D53 }, /* GL_RENDERBUFFER_ALPHA_SIZE */
- { 28458, 0x00008CA7 }, /* GL_RENDERBUFFER_BINDING_EXT */
- { 28486, 0x00008D52 }, /* GL_RENDERBUFFER_BLUE_SIZE */
- { 28512, 0x00008D54 }, /* GL_RENDERBUFFER_DEPTH_SIZE */
- { 28539, 0x00008D41 }, /* GL_RENDERBUFFER_EXT */
- { 28559, 0x00008D51 }, /* GL_RENDERBUFFER_GREEN_SIZE */
- { 28586, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT */
- { 28609, 0x00008D43 }, /* GL_RENDERBUFFER_HEIGHT_EXT */
- { 28636, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
- { 28668, 0x00008D44 }, /* GL_RENDERBUFFER_INTERNAL_FORMAT_EXT */
- { 28704, 0x00008D50 }, /* GL_RENDERBUFFER_RED_SIZE */
- { 28729, 0x00008CAB }, /* GL_RENDERBUFFER_SAMPLES */
- { 28753, 0x00008D55 }, /* GL_RENDERBUFFER_STENCIL_SIZE */
- { 28782, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH */
- { 28804, 0x00008D42 }, /* GL_RENDERBUFFER_WIDTH_EXT */
- { 28830, 0x00001F01 }, /* GL_RENDERER */
- { 28842, 0x00000C40 }, /* GL_RENDER_MODE */
- { 28857, 0x00002901 }, /* GL_REPEAT */
- { 28867, 0x00001E01 }, /* GL_REPLACE */
- { 28878, 0x00008062 }, /* GL_REPLACE_EXT */
- { 28893, 0x00008153 }, /* GL_REPLICATE_BORDER_HP */
- { 28916, 0x0000803A }, /* GL_RESCALE_NORMAL */
- { 28934, 0x0000803A }, /* GL_RESCALE_NORMAL_EXT */
- { 28956, 0x00000102 }, /* GL_RETURN */
- { 28966, 0x00001907 }, /* GL_RGB */
- { 28973, 0x00008052 }, /* GL_RGB10 */
- { 28982, 0x00008059 }, /* GL_RGB10_A2 */
- { 28994, 0x00008059 }, /* GL_RGB10_A2_EXT */
- { 29010, 0x00008052 }, /* GL_RGB10_EXT */
- { 29023, 0x00008053 }, /* GL_RGB12 */
- { 29032, 0x00008053 }, /* GL_RGB12_EXT */
- { 29045, 0x00008054 }, /* GL_RGB16 */
- { 29054, 0x00008054 }, /* GL_RGB16_EXT */
- { 29067, 0x0000804E }, /* GL_RGB2_EXT */
- { 29079, 0x0000804F }, /* GL_RGB4 */
- { 29087, 0x0000804F }, /* GL_RGB4_EXT */
- { 29099, 0x000083A1 }, /* GL_RGB4_S3TC */
- { 29112, 0x00008050 }, /* GL_RGB5 */
- { 29120, 0x00008057 }, /* GL_RGB5_A1 */
- { 29131, 0x00008057 }, /* GL_RGB5_A1_EXT */
- { 29146, 0x00008050 }, /* GL_RGB5_EXT */
- { 29158, 0x00008051 }, /* GL_RGB8 */
- { 29166, 0x00008051 }, /* GL_RGB8_EXT */
- { 29178, 0x00001908 }, /* GL_RGBA */
- { 29186, 0x0000805A }, /* GL_RGBA12 */
- { 29196, 0x0000805A }, /* GL_RGBA12_EXT */
- { 29210, 0x0000805B }, /* GL_RGBA16 */
- { 29220, 0x0000805B }, /* GL_RGBA16_EXT */
- { 29234, 0x00008055 }, /* GL_RGBA2 */
- { 29243, 0x00008055 }, /* GL_RGBA2_EXT */
- { 29256, 0x00008056 }, /* GL_RGBA4 */
- { 29265, 0x000083A5 }, /* GL_RGBA4_DXT5_S3TC */
- { 29284, 0x00008056 }, /* GL_RGBA4_EXT */
- { 29297, 0x000083A3 }, /* GL_RGBA4_S3TC */
- { 29311, 0x00008058 }, /* GL_RGBA8 */
- { 29320, 0x00008058 }, /* GL_RGBA8_EXT */
- { 29333, 0x00008F97 }, /* GL_RGBA8_SNORM */
- { 29348, 0x000083A4 }, /* GL_RGBA_DXT5_S3TC */
- { 29366, 0x00000C31 }, /* GL_RGBA_MODE */
- { 29379, 0x000083A2 }, /* GL_RGBA_S3TC */
- { 29392, 0x00008F93 }, /* GL_RGBA_SNORM */
- { 29406, 0x000083A0 }, /* GL_RGB_S3TC */
- { 29418, 0x00008573 }, /* GL_RGB_SCALE */
- { 29431, 0x00008573 }, /* GL_RGB_SCALE_ARB */
- { 29448, 0x00008573 }, /* GL_RGB_SCALE_EXT */
- { 29465, 0x00000407 }, /* GL_RIGHT */
- { 29474, 0x00002000 }, /* GL_S */
- { 29479, 0x00008B5D }, /* GL_SAMPLER_1D */
- { 29493, 0x00008B61 }, /* GL_SAMPLER_1D_SHADOW */
- { 29514, 0x00008B5E }, /* GL_SAMPLER_2D */
- { 29528, 0x00008B62 }, /* GL_SAMPLER_2D_SHADOW */
- { 29549, 0x00008B5F }, /* GL_SAMPLER_3D */
- { 29563, 0x00008B60 }, /* GL_SAMPLER_CUBE */
- { 29579, 0x000080A9 }, /* GL_SAMPLES */
- { 29590, 0x000086B4 }, /* GL_SAMPLES_3DFX */
- { 29606, 0x000080A9 }, /* GL_SAMPLES_ARB */
- { 29621, 0x00008914 }, /* GL_SAMPLES_PASSED */
- { 29639, 0x00008914 }, /* GL_SAMPLES_PASSED_ARB */
- { 29661, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
- { 29689, 0x0000809E }, /* GL_SAMPLE_ALPHA_TO_COVERAGE_ARB */
- { 29721, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE */
- { 29744, 0x0000809F }, /* GL_SAMPLE_ALPHA_TO_ONE_ARB */
- { 29771, 0x000080A8 }, /* GL_SAMPLE_BUFFERS */
- { 29789, 0x000086B3 }, /* GL_SAMPLE_BUFFERS_3DFX */
- { 29812, 0x000080A8 }, /* GL_SAMPLE_BUFFERS_ARB */
- { 29834, 0x000080A0 }, /* GL_SAMPLE_COVERAGE */
- { 29853, 0x000080A0 }, /* GL_SAMPLE_COVERAGE_ARB */
- { 29876, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT */
- { 29902, 0x000080AB }, /* GL_SAMPLE_COVERAGE_INVERT_ARB */
- { 29932, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE */
- { 29957, 0x000080AA }, /* GL_SAMPLE_COVERAGE_VALUE_ARB */
- { 29986, 0x00080000 }, /* GL_SCISSOR_BIT */
- { 30001, 0x00000C10 }, /* GL_SCISSOR_BOX */
- { 30016, 0x00000C11 }, /* GL_SCISSOR_TEST */
- { 30032, 0x0000845E }, /* GL_SECONDARY_COLOR_ARRAY */
- { 30057, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
- { 30097, 0x0000889C }, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB */
- { 30141, 0x0000845D }, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
- { 30174, 0x0000845A }, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
- { 30204, 0x0000845C }, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
- { 30236, 0x0000845B }, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
- { 30266, 0x00001C02 }, /* GL_SELECT */
- { 30276, 0x00000DF3 }, /* GL_SELECTION_BUFFER_POINTER */
- { 30304, 0x00000DF4 }, /* GL_SELECTION_BUFFER_SIZE */
- { 30329, 0x00008012 }, /* GL_SEPARABLE_2D */
- { 30345, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR */
- { 30372, 0x000081FA }, /* GL_SEPARATE_SPECULAR_COLOR_EXT */
- { 30403, 0x0000150F }, /* GL_SET */
- { 30410, 0x00008B48 }, /* GL_SHADER_OBJECT_ARB */
- { 30431, 0x00008B88 }, /* GL_SHADER_SOURCE_LENGTH */
- { 30455, 0x00008B4F }, /* GL_SHADER_TYPE */
- { 30470, 0x00000B54 }, /* GL_SHADE_MODEL */
- { 30485, 0x00008B8C }, /* GL_SHADING_LANGUAGE_VERSION */
- { 30513, 0x000080BF }, /* GL_SHADOW_AMBIENT_SGIX */
- { 30536, 0x000081FB }, /* GL_SHARED_TEXTURE_PALETTE_EXT */
- { 30566, 0x00001601 }, /* GL_SHININESS */
- { 30579, 0x00001402 }, /* GL_SHORT */
- { 30588, 0x00008F9C }, /* GL_SIGNED_NORMALIZED */
- { 30609, 0x000081F9 }, /* GL_SINGLE_COLOR */
- { 30625, 0x000081F9 }, /* GL_SINGLE_COLOR_EXT */
- { 30645, 0x000085CC }, /* GL_SLICE_ACCUM_SUN */
- { 30664, 0x00008C46 }, /* GL_SLUMINANCE */
- { 30678, 0x00008C47 }, /* GL_SLUMINANCE8 */
- { 30693, 0x00008C45 }, /* GL_SLUMINANCE8_ALPHA8 */
- { 30715, 0x00008C44 }, /* GL_SLUMINANCE_ALPHA */
- { 30735, 0x00001D01 }, /* GL_SMOOTH */
- { 30745, 0x00000B23 }, /* GL_SMOOTH_LINE_WIDTH_GRANULARITY */
- { 30778, 0x00000B22 }, /* GL_SMOOTH_LINE_WIDTH_RANGE */
- { 30805, 0x00000B13 }, /* GL_SMOOTH_POINT_SIZE_GRANULARITY */
- { 30838, 0x00000B12 }, /* GL_SMOOTH_POINT_SIZE_RANGE */
- { 30865, 0x00008588 }, /* GL_SOURCE0_ALPHA */
- { 30882, 0x00008588 }, /* GL_SOURCE0_ALPHA_ARB */
- { 30903, 0x00008588 }, /* GL_SOURCE0_ALPHA_EXT */
- { 30924, 0x00008580 }, /* GL_SOURCE0_RGB */
- { 30939, 0x00008580 }, /* GL_SOURCE0_RGB_ARB */
- { 30958, 0x00008580 }, /* GL_SOURCE0_RGB_EXT */
- { 30977, 0x00008589 }, /* GL_SOURCE1_ALPHA */
- { 30994, 0x00008589 }, /* GL_SOURCE1_ALPHA_ARB */
- { 31015, 0x00008589 }, /* GL_SOURCE1_ALPHA_EXT */
- { 31036, 0x00008581 }, /* GL_SOURCE1_RGB */
- { 31051, 0x00008581 }, /* GL_SOURCE1_RGB_ARB */
- { 31070, 0x00008581 }, /* GL_SOURCE1_RGB_EXT */
- { 31089, 0x0000858A }, /* GL_SOURCE2_ALPHA */
- { 31106, 0x0000858A }, /* GL_SOURCE2_ALPHA_ARB */
- { 31127, 0x0000858A }, /* GL_SOURCE2_ALPHA_EXT */
- { 31148, 0x00008582 }, /* GL_SOURCE2_RGB */
- { 31163, 0x00008582 }, /* GL_SOURCE2_RGB_ARB */
- { 31182, 0x00008582 }, /* GL_SOURCE2_RGB_EXT */
- { 31201, 0x0000858B }, /* GL_SOURCE3_ALPHA_NV */
- { 31221, 0x00008583 }, /* GL_SOURCE3_RGB_NV */
- { 31239, 0x00001202 }, /* GL_SPECULAR */
- { 31251, 0x00002402 }, /* GL_SPHERE_MAP */
- { 31265, 0x00001206 }, /* GL_SPOT_CUTOFF */
- { 31280, 0x00001204 }, /* GL_SPOT_DIRECTION */
- { 31298, 0x00001205 }, /* GL_SPOT_EXPONENT */
- { 31315, 0x00008588 }, /* GL_SRC0_ALPHA */
- { 31329, 0x00008580 }, /* GL_SRC0_RGB */
- { 31341, 0x00008589 }, /* GL_SRC1_ALPHA */
- { 31355, 0x00008581 }, /* GL_SRC1_RGB */
- { 31367, 0x0000858A }, /* GL_SRC2_ALPHA */
- { 31381, 0x00008582 }, /* GL_SRC2_RGB */
- { 31393, 0x00000302 }, /* GL_SRC_ALPHA */
- { 31406, 0x00000308 }, /* GL_SRC_ALPHA_SATURATE */
- { 31428, 0x00000300 }, /* GL_SRC_COLOR */
- { 31441, 0x00008C40 }, /* GL_SRGB */
- { 31449, 0x00008C41 }, /* GL_SRGB8 */
- { 31458, 0x00008C43 }, /* GL_SRGB8_ALPHA8 */
- { 31474, 0x00008C42 }, /* GL_SRGB_ALPHA */
- { 31488, 0x00000503 }, /* GL_STACK_OVERFLOW */
- { 31506, 0x00000504 }, /* GL_STACK_UNDERFLOW */
- { 31525, 0x000088E6 }, /* GL_STATIC_COPY */
- { 31540, 0x000088E6 }, /* GL_STATIC_COPY_ARB */
- { 31559, 0x000088E4 }, /* GL_STATIC_DRAW */
- { 31574, 0x000088E4 }, /* GL_STATIC_DRAW_ARB */
- { 31593, 0x000088E5 }, /* GL_STATIC_READ */
- { 31608, 0x000088E5 }, /* GL_STATIC_READ_ARB */
- { 31627, 0x00001802 }, /* GL_STENCIL */
- { 31638, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT */
- { 31660, 0x00008D20 }, /* GL_STENCIL_ATTACHMENT_EXT */
- { 31686, 0x00008801 }, /* GL_STENCIL_BACK_FAIL */
- { 31707, 0x00008801 }, /* GL_STENCIL_BACK_FAIL_ATI */
- { 31732, 0x00008800 }, /* GL_STENCIL_BACK_FUNC */
- { 31753, 0x00008800 }, /* GL_STENCIL_BACK_FUNC_ATI */
- { 31778, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
- { 31810, 0x00008802 }, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI */
- { 31846, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
- { 31878, 0x00008803 }, /* GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI */
- { 31914, 0x00008CA3 }, /* GL_STENCIL_BACK_REF */
- { 31934, 0x00008CA4 }, /* GL_STENCIL_BACK_VALUE_MASK */
- { 31961, 0x00008CA5 }, /* GL_STENCIL_BACK_WRITEMASK */
- { 31987, 0x00000D57 }, /* GL_STENCIL_BITS */
- { 32003, 0x00000400 }, /* GL_STENCIL_BUFFER_BIT */
- { 32025, 0x00000B91 }, /* GL_STENCIL_CLEAR_VALUE */
- { 32048, 0x00000B94 }, /* GL_STENCIL_FAIL */
- { 32064, 0x00000B92 }, /* GL_STENCIL_FUNC */
- { 32080, 0x00001901 }, /* GL_STENCIL_INDEX */
- { 32097, 0x00008D49 }, /* GL_STENCIL_INDEX16_EXT */
- { 32120, 0x00008D46 }, /* GL_STENCIL_INDEX1_EXT */
- { 32142, 0x00008D47 }, /* GL_STENCIL_INDEX4_EXT */
- { 32164, 0x00008D48 }, /* GL_STENCIL_INDEX8_EXT */
- { 32186, 0x00008D45 }, /* GL_STENCIL_INDEX_EXT */
- { 32207, 0x00000B95 }, /* GL_STENCIL_PASS_DEPTH_FAIL */
- { 32234, 0x00000B96 }, /* GL_STENCIL_PASS_DEPTH_PASS */
- { 32261, 0x00000B97 }, /* GL_STENCIL_REF */
- { 32276, 0x00000B90 }, /* GL_STENCIL_TEST */
- { 32292, 0x00008910 }, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
- { 32321, 0x00000B93 }, /* GL_STENCIL_VALUE_MASK */
- { 32343, 0x00000B98 }, /* GL_STENCIL_WRITEMASK */
- { 32364, 0x00000C33 }, /* GL_STEREO */
- { 32374, 0x000088E2 }, /* GL_STREAM_COPY */
- { 32389, 0x000088E2 }, /* GL_STREAM_COPY_ARB */
- { 32408, 0x000088E0 }, /* GL_STREAM_DRAW */
- { 32423, 0x000088E0 }, /* GL_STREAM_DRAW_ARB */
- { 32442, 0x000088E1 }, /* GL_STREAM_READ */
- { 32457, 0x000088E1 }, /* GL_STREAM_READ_ARB */
- { 32476, 0x00000D50 }, /* GL_SUBPIXEL_BITS */
- { 32493, 0x000084E7 }, /* GL_SUBTRACT */
- { 32505, 0x000084E7 }, /* GL_SUBTRACT_ARB */
- { 32521, 0x00002001 }, /* GL_T */
- { 32526, 0x00002A2A }, /* GL_T2F_C3F_V3F */
- { 32541, 0x00002A2C }, /* GL_T2F_C4F_N3F_V3F */
- { 32560, 0x00002A29 }, /* GL_T2F_C4UB_V3F */
- { 32576, 0x00002A2B }, /* GL_T2F_N3F_V3F */
- { 32591, 0x00002A27 }, /* GL_T2F_V3F */
- { 32602, 0x00002A2D }, /* GL_T4F_C4F_N3F_V4F */
- { 32621, 0x00002A28 }, /* GL_T4F_V4F */
- { 32632, 0x00008031 }, /* GL_TABLE_TOO_LARGE_EXT */
- { 32655, 0x00001702 }, /* GL_TEXTURE */
- { 32666, 0x000084C0 }, /* GL_TEXTURE0 */
- { 32678, 0x000084C0 }, /* GL_TEXTURE0_ARB */
- { 32694, 0x000084C1 }, /* GL_TEXTURE1 */
- { 32706, 0x000084CA }, /* GL_TEXTURE10 */
- { 32719, 0x000084CA }, /* GL_TEXTURE10_ARB */
- { 32736, 0x000084CB }, /* GL_TEXTURE11 */
- { 32749, 0x000084CB }, /* GL_TEXTURE11_ARB */
- { 32766, 0x000084CC }, /* GL_TEXTURE12 */
- { 32779, 0x000084CC }, /* GL_TEXTURE12_ARB */
- { 32796, 0x000084CD }, /* GL_TEXTURE13 */
- { 32809, 0x000084CD }, /* GL_TEXTURE13_ARB */
- { 32826, 0x000084CE }, /* GL_TEXTURE14 */
- { 32839, 0x000084CE }, /* GL_TEXTURE14_ARB */
- { 32856, 0x000084CF }, /* GL_TEXTURE15 */
- { 32869, 0x000084CF }, /* GL_TEXTURE15_ARB */
- { 32886, 0x000084D0 }, /* GL_TEXTURE16 */
- { 32899, 0x000084D0 }, /* GL_TEXTURE16_ARB */
- { 32916, 0x000084D1 }, /* GL_TEXTURE17 */
- { 32929, 0x000084D1 }, /* GL_TEXTURE17_ARB */
- { 32946, 0x000084D2 }, /* GL_TEXTURE18 */
- { 32959, 0x000084D2 }, /* GL_TEXTURE18_ARB */
- { 32976, 0x000084D3 }, /* GL_TEXTURE19 */
- { 32989, 0x000084D3 }, /* GL_TEXTURE19_ARB */
- { 33006, 0x000084C1 }, /* GL_TEXTURE1_ARB */
- { 33022, 0x000084C2 }, /* GL_TEXTURE2 */
- { 33034, 0x000084D4 }, /* GL_TEXTURE20 */
- { 33047, 0x000084D4 }, /* GL_TEXTURE20_ARB */
- { 33064, 0x000084D5 }, /* GL_TEXTURE21 */
- { 33077, 0x000084D5 }, /* GL_TEXTURE21_ARB */
- { 33094, 0x000084D6 }, /* GL_TEXTURE22 */
- { 33107, 0x000084D6 }, /* GL_TEXTURE22_ARB */
- { 33124, 0x000084D7 }, /* GL_TEXTURE23 */
- { 33137, 0x000084D7 }, /* GL_TEXTURE23_ARB */
- { 33154, 0x000084D8 }, /* GL_TEXTURE24 */
- { 33167, 0x000084D8 }, /* GL_TEXTURE24_ARB */
- { 33184, 0x000084D9 }, /* GL_TEXTURE25 */
- { 33197, 0x000084D9 }, /* GL_TEXTURE25_ARB */
- { 33214, 0x000084DA }, /* GL_TEXTURE26 */
- { 33227, 0x000084DA }, /* GL_TEXTURE26_ARB */
- { 33244, 0x000084DB }, /* GL_TEXTURE27 */
- { 33257, 0x000084DB }, /* GL_TEXTURE27_ARB */
- { 33274, 0x000084DC }, /* GL_TEXTURE28 */
- { 33287, 0x000084DC }, /* GL_TEXTURE28_ARB */
- { 33304, 0x000084DD }, /* GL_TEXTURE29 */
- { 33317, 0x000084DD }, /* GL_TEXTURE29_ARB */
- { 33334, 0x000084C2 }, /* GL_TEXTURE2_ARB */
- { 33350, 0x000084C3 }, /* GL_TEXTURE3 */
- { 33362, 0x000084DE }, /* GL_TEXTURE30 */
- { 33375, 0x000084DE }, /* GL_TEXTURE30_ARB */
- { 33392, 0x000084DF }, /* GL_TEXTURE31 */
- { 33405, 0x000084DF }, /* GL_TEXTURE31_ARB */
- { 33422, 0x000084C3 }, /* GL_TEXTURE3_ARB */
- { 33438, 0x000084C4 }, /* GL_TEXTURE4 */
- { 33450, 0x000084C4 }, /* GL_TEXTURE4_ARB */
- { 33466, 0x000084C5 }, /* GL_TEXTURE5 */
- { 33478, 0x000084C5 }, /* GL_TEXTURE5_ARB */
- { 33494, 0x000084C6 }, /* GL_TEXTURE6 */
- { 33506, 0x000084C6 }, /* GL_TEXTURE6_ARB */
- { 33522, 0x000084C7 }, /* GL_TEXTURE7 */
- { 33534, 0x000084C7 }, /* GL_TEXTURE7_ARB */
- { 33550, 0x000084C8 }, /* GL_TEXTURE8 */
- { 33562, 0x000084C8 }, /* GL_TEXTURE8_ARB */
- { 33578, 0x000084C9 }, /* GL_TEXTURE9 */
- { 33590, 0x000084C9 }, /* GL_TEXTURE9_ARB */
- { 33606, 0x00000DE0 }, /* GL_TEXTURE_1D */
- { 33620, 0x00008C18 }, /* GL_TEXTURE_1D_ARRAY_EXT */
- { 33644, 0x00000DE1 }, /* GL_TEXTURE_2D */
- { 33658, 0x00008C1A }, /* GL_TEXTURE_2D_ARRAY_EXT */
- { 33682, 0x0000806F }, /* GL_TEXTURE_3D */
- { 33696, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE */
- { 33718, 0x0000805F }, /* GL_TEXTURE_ALPHA_SIZE_EXT */
- { 33744, 0x0000813C }, /* GL_TEXTURE_BASE_LEVEL */
- { 33766, 0x00008068 }, /* GL_TEXTURE_BINDING_1D */
- { 33788, 0x00008C1C }, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
- { 33820, 0x00008069 }, /* GL_TEXTURE_BINDING_2D */
- { 33842, 0x00008C1D }, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
- { 33874, 0x0000806A }, /* GL_TEXTURE_BINDING_3D */
- { 33896, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP */
- { 33924, 0x00008514 }, /* GL_TEXTURE_BINDING_CUBE_MAP_ARB */
- { 33956, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
- { 33989, 0x000084F6 }, /* GL_TEXTURE_BINDING_RECTANGLE_NV */
- { 34021, 0x00040000 }, /* GL_TEXTURE_BIT */
- { 34036, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE */
- { 34057, 0x0000805E }, /* GL_TEXTURE_BLUE_SIZE_EXT */
- { 34082, 0x00001005 }, /* GL_TEXTURE_BORDER */
- { 34100, 0x00001004 }, /* GL_TEXTURE_BORDER_COLOR */
- { 34124, 0x00008171 }, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
- { 34155, 0x00008176 }, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
- { 34185, 0x00008172 }, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
- { 34215, 0x00008175 }, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
- { 34250, 0x00008173 }, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
- { 34281, 0x00008174 }, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- { 34319, 0x000080BC }, /* GL_TEXTURE_COLOR_TABLE_SGI */
- { 34346, 0x000081EF }, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
- { 34378, 0x000080BF }, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
- { 34412, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC */
- { 34436, 0x0000884D }, /* GL_TEXTURE_COMPARE_FUNC_ARB */
- { 34464, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE */
- { 34488, 0x0000884C }, /* GL_TEXTURE_COMPARE_MODE_ARB */
- { 34516, 0x0000819B }, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
- { 34549, 0x0000819A }, /* GL_TEXTURE_COMPARE_SGIX */
- { 34573, 0x00001003 }, /* GL_TEXTURE_COMPONENTS */
- { 34595, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED */
- { 34617, 0x000086A1 }, /* GL_TEXTURE_COMPRESSED_ARB */
- { 34643, 0x000086A3 }, /* GL_TEXTURE_COMPRESSED_FORMATS_ARB */
- { 34677, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
- { 34710, 0x000086A0 }, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB */
- { 34747, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT */
- { 34775, 0x000084EF }, /* GL_TEXTURE_COMPRESSION_HINT_ARB */
- { 34807, 0x00008078 }, /* GL_TEXTURE_COORD_ARRAY */
- { 34830, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
- { 34868, 0x0000889A }, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB */
- { 34910, 0x00008092 }, /* GL_TEXTURE_COORD_ARRAY_POINTER */
- { 34941, 0x00008088 }, /* GL_TEXTURE_COORD_ARRAY_SIZE */
- { 34969, 0x0000808A }, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
- { 34999, 0x00008089 }, /* GL_TEXTURE_COORD_ARRAY_TYPE */
- { 35027, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP */
- { 35047, 0x00008513 }, /* GL_TEXTURE_CUBE_MAP_ARB */
- { 35071, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
- { 35102, 0x00008516 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB */
- { 35137, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
- { 35168, 0x00008518 }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB */
- { 35203, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
- { 35234, 0x0000851A }, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB */
- { 35269, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
- { 35300, 0x00008515 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB */
- { 35335, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
- { 35366, 0x00008517 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB */
- { 35401, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
- { 35432, 0x00008519 }, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB */
- { 35467, 0x00008071 }, /* GL_TEXTURE_DEPTH */
- { 35484, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE */
- { 35506, 0x0000884A }, /* GL_TEXTURE_DEPTH_SIZE_ARB */
- { 35532, 0x00002300 }, /* GL_TEXTURE_ENV */
- { 35547, 0x00002201 }, /* GL_TEXTURE_ENV_COLOR */
- { 35568, 0x00002200 }, /* GL_TEXTURE_ENV_MODE */
- { 35588, 0x00008500 }, /* GL_TEXTURE_FILTER_CONTROL */
- { 35614, 0x00002500 }, /* GL_TEXTURE_GEN_MODE */
- { 35634, 0x00000C63 }, /* GL_TEXTURE_GEN_Q */
- { 35651, 0x00000C62 }, /* GL_TEXTURE_GEN_R */
- { 35668, 0x00000C60 }, /* GL_TEXTURE_GEN_S */
- { 35685, 0x00000C61 }, /* GL_TEXTURE_GEN_T */
- { 35702, 0x0000819D }, /* GL_TEXTURE_GEQUAL_R_SGIX */
- { 35727, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE */
- { 35749, 0x0000805D }, /* GL_TEXTURE_GREEN_SIZE_EXT */
- { 35775, 0x00001001 }, /* GL_TEXTURE_HEIGHT */
- { 35793, 0x000080ED }, /* GL_TEXTURE_INDEX_SIZE_EXT */
- { 35819, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE */
- { 35845, 0x00008061 }, /* GL_TEXTURE_INTENSITY_SIZE_EXT */
- { 35875, 0x00001003 }, /* GL_TEXTURE_INTERNAL_FORMAT */
- { 35902, 0x0000819C }, /* GL_TEXTURE_LEQUAL_R_SGIX */
- { 35927, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS */
- { 35947, 0x00008501 }, /* GL_TEXTURE_LOD_BIAS_EXT */
- { 35971, 0x00008190 }, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
- { 35998, 0x0000818E }, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
- { 36025, 0x0000818F }, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
- { 36052, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE */
- { 36078, 0x00008060 }, /* GL_TEXTURE_LUMINANCE_SIZE_EXT */
- { 36108, 0x00002800 }, /* GL_TEXTURE_MAG_FILTER */
- { 36130, 0x00000BA8 }, /* GL_TEXTURE_MATRIX */
- { 36148, 0x000084FE }, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
- { 36178, 0x0000836B }, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
- { 36206, 0x00008369 }, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
- { 36234, 0x0000836A }, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
- { 36262, 0x0000813D }, /* GL_TEXTURE_MAX_LEVEL */
- { 36283, 0x0000813B }, /* GL_TEXTURE_MAX_LOD */
- { 36302, 0x00002801 }, /* GL_TEXTURE_MIN_FILTER */
- { 36324, 0x0000813A }, /* GL_TEXTURE_MIN_LOD */
- { 36343, 0x00008066 }, /* GL_TEXTURE_PRIORITY */
- { 36363, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_ARB */
- { 36388, 0x000084F5 }, /* GL_TEXTURE_RECTANGLE_NV */
- { 36412, 0x0000805C }, /* GL_TEXTURE_RED_SIZE */
- { 36432, 0x0000805C }, /* GL_TEXTURE_RED_SIZE_EXT */
- { 36456, 0x00008067 }, /* GL_TEXTURE_RESIDENT */
- { 36476, 0x00000BA5 }, /* GL_TEXTURE_STACK_DEPTH */
- { 36499, 0x000088F1 }, /* GL_TEXTURE_STENCIL_SIZE */
- { 36523, 0x00008065 }, /* GL_TEXTURE_TOO_LARGE_EXT */
- { 36548, 0x0000888F }, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
- { 36582, 0x00001000 }, /* GL_TEXTURE_WIDTH */
- { 36599, 0x00008072 }, /* GL_TEXTURE_WRAP_R */
- { 36617, 0x00002802 }, /* GL_TEXTURE_WRAP_S */
- { 36635, 0x00002803 }, /* GL_TEXTURE_WRAP_T */
- { 36653, 0x000088BF }, /* GL_TIME_ELAPSED_EXT */
- { 36673, 0x00008648 }, /* GL_TRACK_MATRIX_NV */
- { 36692, 0x00008649 }, /* GL_TRACK_MATRIX_TRANSFORM_NV */
- { 36721, 0x00001000 }, /* GL_TRANSFORM_BIT */
- { 36738, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX */
- { 36764, 0x000084E6 }, /* GL_TRANSPOSE_COLOR_MATRIX_ARB */
- { 36794, 0x000088B7 }, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
- { 36826, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
- { 36856, 0x000084E3 }, /* GL_TRANSPOSE_MODELVIEW_MATRIX_ARB */
- { 36890, 0x0000862C }, /* GL_TRANSPOSE_NV */
- { 36906, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX */
- { 36937, 0x000084E4 }, /* GL_TRANSPOSE_PROJECTION_MATRIX_ARB */
- { 36972, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX */
- { 37000, 0x000084E5 }, /* GL_TRANSPOSE_TEXTURE_MATRIX_ARB */
- { 37032, 0x00000004 }, /* GL_TRIANGLES */
- { 37045, 0x00000006 }, /* GL_TRIANGLE_FAN */
- { 37061, 0x00008615 }, /* GL_TRIANGLE_MESH_SUN */
- { 37082, 0x00000005 }, /* GL_TRIANGLE_STRIP */
- { 37100, 0x00000001 }, /* GL_TRUE */
- { 37108, 0x00000CF5 }, /* GL_UNPACK_ALIGNMENT */
- { 37128, 0x0000806E }, /* GL_UNPACK_IMAGE_HEIGHT */
- { 37151, 0x00000CF1 }, /* GL_UNPACK_LSB_FIRST */
- { 37171, 0x00000CF2 }, /* GL_UNPACK_ROW_LENGTH */
- { 37192, 0x0000806D }, /* GL_UNPACK_SKIP_IMAGES */
- { 37214, 0x00000CF4 }, /* GL_UNPACK_SKIP_PIXELS */
- { 37236, 0x00000CF3 }, /* GL_UNPACK_SKIP_ROWS */
- { 37256, 0x00000CF0 }, /* GL_UNPACK_SWAP_BYTES */
- { 37277, 0x00001401 }, /* GL_UNSIGNED_BYTE */
- { 37294, 0x00008362 }, /* GL_UNSIGNED_BYTE_2_3_3_REV */
- { 37321, 0x00008032 }, /* GL_UNSIGNED_BYTE_3_3_2 */
- { 37344, 0x00001405 }, /* GL_UNSIGNED_INT */
- { 37360, 0x00008036 }, /* GL_UNSIGNED_INT_10_10_10_2 */
- { 37387, 0x000084FA }, /* GL_UNSIGNED_INT_24_8 */
- { 37408, 0x000084FA }, /* GL_UNSIGNED_INT_24_8_NV */
- { 37432, 0x00008368 }, /* GL_UNSIGNED_INT_2_10_10_10_REV */
- { 37463, 0x00008035 }, /* GL_UNSIGNED_INT_8_8_8_8 */
- { 37487, 0x00008367 }, /* GL_UNSIGNED_INT_8_8_8_8_REV */
- { 37515, 0x00008C17 }, /* GL_UNSIGNED_NORMALIZED */
- { 37538, 0x00001403 }, /* GL_UNSIGNED_SHORT */
- { 37556, 0x00008366 }, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
- { 37586, 0x00008033 }, /* GL_UNSIGNED_SHORT_4_4_4_4 */
- { 37612, 0x00008365 }, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
- { 37642, 0x00008034 }, /* GL_UNSIGNED_SHORT_5_5_5_1 */
- { 37668, 0x00008363 }, /* GL_UNSIGNED_SHORT_5_6_5 */
- { 37692, 0x00008364 }, /* GL_UNSIGNED_SHORT_5_6_5_REV */
- { 37720, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_APPLE */
- { 37748, 0x000085BA }, /* GL_UNSIGNED_SHORT_8_8_MESA */
- { 37775, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
- { 37807, 0x000085BB }, /* GL_UNSIGNED_SHORT_8_8_REV_MESA */
- { 37838, 0x00008CA2 }, /* GL_UPPER_LEFT */
- { 37852, 0x00002A20 }, /* GL_V2F */
- { 37859, 0x00002A21 }, /* GL_V3F */
- { 37866, 0x00008B83 }, /* GL_VALIDATE_STATUS */
- { 37885, 0x00001F00 }, /* GL_VENDOR */
- { 37895, 0x00001F02 }, /* GL_VERSION */
- { 37906, 0x00008074 }, /* GL_VERTEX_ARRAY */
- { 37922, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING */
- { 37946, 0x000085B5 }, /* GL_VERTEX_ARRAY_BINDING_APPLE */
- { 37976, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
- { 38007, 0x00008896 }, /* GL_VERTEX_ARRAY_BUFFER_BINDING_ARB */
- { 38042, 0x0000808E }, /* GL_VERTEX_ARRAY_POINTER */
- { 38066, 0x0000807A }, /* GL_VERTEX_ARRAY_SIZE */
- { 38087, 0x0000807C }, /* GL_VERTEX_ARRAY_STRIDE */
- { 38110, 0x0000807B }, /* GL_VERTEX_ARRAY_TYPE */
- { 38131, 0x00008650 }, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
- { 38158, 0x0000865A }, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
- { 38186, 0x0000865B }, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
- { 38214, 0x0000865C }, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
- { 38242, 0x0000865D }, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
- { 38270, 0x0000865E }, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
- { 38298, 0x0000865F }, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
- { 38326, 0x00008651 }, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
- { 38353, 0x00008652 }, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
- { 38380, 0x00008653 }, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
- { 38407, 0x00008654 }, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
- { 38434, 0x00008655 }, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
- { 38461, 0x00008656 }, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
- { 38488, 0x00008657 }, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
- { 38515, 0x00008658 }, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
- { 38542, 0x00008659 }, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
- { 38569, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
- { 38607, 0x0000889F }, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB */
- { 38649, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
- { 38680, 0x00008622 }, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB */
- { 38715, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
- { 38749, 0x0000886A }, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB */
- { 38787, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
- { 38818, 0x00008645 }, /* GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB */
- { 38853, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
- { 38881, 0x00008623 }, /* GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB */
- { 38913, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
- { 38943, 0x00008624 }, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB */
- { 38977, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
- { 39005, 0x00008625 }, /* GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB */
- { 39037, 0x000086A7 }, /* GL_VERTEX_BLEND_ARB */
- { 39057, 0x00008620 }, /* GL_VERTEX_PROGRAM_ARB */
- { 39079, 0x0000864A }, /* GL_VERTEX_PROGRAM_BINDING_NV */
- { 39108, 0x00008620 }, /* GL_VERTEX_PROGRAM_NV */
- { 39129, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE */
- { 39158, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_ARB */
- { 39191, 0x00008642 }, /* GL_VERTEX_PROGRAM_POINT_SIZE_NV */
- { 39223, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE */
- { 39250, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_ARB */
- { 39281, 0x00008643 }, /* GL_VERTEX_PROGRAM_TWO_SIDE_NV */
- { 39311, 0x00008B31 }, /* GL_VERTEX_SHADER */
- { 39328, 0x00008B31 }, /* GL_VERTEX_SHADER_ARB */
- { 39349, 0x00008621 }, /* GL_VERTEX_STATE_PROGRAM_NV */
- { 39376, 0x00000BA2 }, /* GL_VIEWPORT */
- { 39388, 0x00000800 }, /* GL_VIEWPORT_BIT */
- { 39404, 0x000086AD }, /* GL_WEIGHT_ARRAY_ARB */
- { 39424, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
- { 39455, 0x0000889E }, /* GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB */
- { 39490, 0x000086AC }, /* GL_WEIGHT_ARRAY_POINTER_ARB */
- { 39518, 0x000086AB }, /* GL_WEIGHT_ARRAY_SIZE_ARB */
- { 39543, 0x000086AA }, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
- { 39570, 0x000086A9 }, /* GL_WEIGHT_ARRAY_TYPE_ARB */
- { 39595, 0x000086A6 }, /* GL_WEIGHT_SUM_UNITY_ARB */
- { 39619, 0x000081D4 }, /* GL_WRAP_BORDER_SUN */
- { 39638, 0x000088B9 }, /* GL_WRITE_ONLY */
- { 39652, 0x000088B9 }, /* GL_WRITE_ONLY_ARB */
- { 39670, 0x00001506 }, /* GL_XOR */
- { 39677, 0x000085B9 }, /* GL_YCBCR_422_APPLE */
- { 39696, 0x00008757 }, /* GL_YCBCR_MESA */
- { 39710, 0x00000000 }, /* GL_ZERO */
- { 39718, 0x00000D16 }, /* GL_ZOOM_X */
- { 39728, 0x00000D17 }, /* GL_ZOOM_Y */
+ { 779, 0x0000911A }, /* GL_ALREADY_SIGNALED */
+ { 799, 0x00000207 }, /* GL_ALWAYS */
+ { 809, 0x00001200 }, /* GL_AMBIENT */
+ { 820, 0x00001602 }, /* GL_AMBIENT_AND_DIFFUSE */
+ { 843, 0x00001501 }, /* GL_AND */
+ { 850, 0x00001504 }, /* GL_AND_INVERTED */
+ { 866, 0x00001502 }, /* GL_AND_REVERSE */
+ { 881, 0x00008892 }, /* GL_ARRAY_BUFFER */
+ { 897, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING */
+ { 921, 0x00008894 }, /* GL_ARRAY_BUFFER_BINDING_ARB */
+ { 949, 0x00008B85 }, /* GL_ATTACHED_SHADERS */
+ { 969, 0x00008645 }, /* GL_ATTRIB_ARRAY_POINTER_NV */
+ { 996, 0x00008623 }, /* GL_ATTRIB_ARRAY_SIZE_NV */
+ { 1020, 0x00008624 }, /* GL_ATTRIB_ARRAY_STRIDE_NV */
+ { 1046, 0x00008625 }, /* GL_ATTRIB_ARRAY_TYPE_NV */
+ { 1070, 0x00000BB0 }, /* GL_ATTRIB_STACK_DEPTH */
+ { 1092, 0x00000D80 }, /* GL_AUTO_NORMAL */
+ { 1107, 0x00000409 }, /* GL_AUX0 */
+ { 1115, 0x0000040A }, /* GL_AUX1 */
+ { 1123, 0x0000040B }, /* GL_AUX2 */
+ { 1131, 0x0000040C }, /* GL_AUX3 */
+ { 1139, 0x00000C00 }, /* GL_AUX_BUFFERS */
+ { 1154, 0x00000405 }, /* GL_BACK */
+ { 1162, 0x00000402 }, /* GL_BACK_LEFT */
+ { 1175, 0x00000403 }, /* GL_BACK_RIGHT */
+ { 1189, 0x000080E0 }, /* GL_BGR */
+ { 1196, 0x000080E1 }, /* GL_BGRA */
+ { 1204, 0x00001A00 }, /* GL_BITMAP */
+ { 1214, 0x00000704 }, /* GL_BITMAP_TOKEN */
+ { 1230, 0x00000BE2 }, /* GL_BLEND */
+ { 1239, 0x00008005 }, /* GL_BLEND_COLOR */
+ { 1254, 0x00008005 }, /* GL_BLEND_COLOR_EXT */
+ { 1273, 0x00000BE0 }, /* GL_BLEND_DST */
+ { 1286, 0x000080CA }, /* GL_BLEND_DST_ALPHA */
+ { 1305, 0x000080C8 }, /* GL_BLEND_DST_RGB */
+ { 1322, 0x00008009 }, /* GL_BLEND_EQUATION */
+ { 1340, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA */
+ { 1364, 0x0000883D }, /* GL_BLEND_EQUATION_ALPHA_EXT */
+ { 1392, 0x00008009 }, /* GL_BLEND_EQUATION_EXT */
+ { 1414, 0x00008009 }, /* GL_BLEND_EQUATION_RGB */
+ { 1436, 0x00008009 }, /* GL_BLEND_EQUATION_RGB_EXT */
+ { 1462, 0x00000BE1 }, /* GL_BLEND_SRC */
+ { 1475, 0x000080CB }, /* GL_BLEND_SRC_ALPHA */
+ { 1494, 0x000080C9 }, /* GL_BLEND_SRC_RGB */
+ { 1511, 0x00001905 }, /* GL_BLUE */
+ { 1519, 0x00000D1B }, /* GL_BLUE_BIAS */
+ { 1532, 0x00000D54 }, /* GL_BLUE_BITS */
+ { 1545, 0x00000D1A }, /* GL_BLUE_SCALE */
+ { 1559, 0x00008B56 }, /* GL_BOOL */
+ { 1567, 0x00008B56 }, /* GL_BOOL_ARB */
+ { 1579, 0x00008B57 }, /* GL_BOOL_VEC2 */
+ { 1592, 0x00008B57 }, /* GL_BOOL_VEC2_ARB */
+ { 1609, 0x00008B58 }, /* GL_BOOL_VEC3 */
+ { 1622, 0x00008B58 }, /* GL_BOOL_VEC3_ARB */
+ { 1639, 0x00008B59 }, /* GL_BOOL_VEC4 */
+ { 1652, 0x00008B59 }, /* GL_BOOL_VEC4_ARB */
+ { 1669, 0x000088BB }, /* GL_BUFFER_ACCESS */
+ { 1686, 0x000088BB }, /* GL_BUFFER_ACCESS_ARB */
+ { 1707, 0x00008A13 }, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
+ { 1738, 0x000088BC }, /* GL_BUFFER_MAPPED */
+ { 1755, 0x000088BC }, /* GL_BUFFER_MAPPED_ARB */
+ { 1776, 0x000088BD }, /* GL_BUFFER_MAP_POINTER */
+ { 1798, 0x000088BD }, /* GL_BUFFER_MAP_POINTER_ARB */
+ { 1824, 0x00008A12 }, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
+ { 1858, 0x00008764 }, /* GL_BUFFER_SIZE */
+ { 1873, 0x00008764 }, /* GL_BUFFER_SIZE_ARB */
+ { 1892, 0x00008765 }, /* GL_BUFFER_USAGE */
+ { 1908, 0x00008765 }, /* GL_BUFFER_USAGE_ARB */
+ { 1928, 0x0000877B }, /* GL_BUMP_ENVMAP_ATI */
+ { 1947, 0x00008777 }, /* GL_BUMP_NUM_TEX_UNITS_ATI */
+ { 1973, 0x00008775 }, /* GL_BUMP_ROT_MATRIX_ATI */
+ { 1996, 0x00008776 }, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
+ { 2024, 0x0000877C }, /* GL_BUMP_TARGET_ATI */
+ { 2043, 0x00008778 }, /* GL_BUMP_TEX_UNITS_ATI */
+ { 2065, 0x00001400 }, /* GL_BYTE */
+ { 2073, 0x00002A24 }, /* GL_C3F_V3F */
+ { 2084, 0x00002A26 }, /* GL_C4F_N3F_V3F */
+ { 2099, 0x00002A22 }, /* GL_C4UB_V2F */
+ { 2111, 0x00002A23 }, /* GL_C4UB_V3F */
+ { 2123, 0x00000901 }, /* GL_CCW */
+ { 2130, 0x00002900 }, /* GL_CLAMP */
+ { 2139, 0x0000812D }, /* GL_CLAMP_TO_BORDER */
+ { 2158, 0x0000812D }, /* GL_CLAMP_TO_BORDER_ARB */
+ { 2181, 0x0000812D }, /* GL_CLAMP_TO_BORDER_SGIS */
+ { 2205, 0x0000812F }, /* GL_CLAMP_TO_EDGE */
+ { 2222, 0x0000812F }, /* GL_CLAMP_TO_EDGE_SGIS */
+ { 2244, 0x00001500 }, /* GL_CLEAR */
+ { 2253, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE */
+ { 2278, 0x000084E1 }, /* GL_CLIENT_ACTIVE_TEXTURE_ARB */
+ { 2307, 0xFFFFFFFF }, /* GL_CLIENT_ALL_ATTRIB_BITS */
+ { 2333, 0x00000BB1 }, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
+ { 2362, 0x00000001 }, /* GL_CLIENT_PIXEL_STORE_BIT */
+ { 2388, 0x00000002 }, /* GL_CLIENT_VERTEX_ARRAY_BIT */
+ { 2415, 0x00003000 }, /* GL_CLIP_PLANE0 */
+ { 2430, 0x00003001 }, /* GL_CLIP_PLANE1 */
+ { 2445, 0x00003002 }, /* GL_CLIP_PLANE2 */
+ { 2460, 0x00003003 }, /* GL_CLIP_PLANE3 */
+ { 2475, 0x00003004 }, /* GL_CLIP_PLANE4 */
+ { 2490, 0x00003005 }, /* GL_CLIP_PLANE5 */
+ { 2505, 0x000080F0 }, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
+ { 2538, 0x00000A00 }, /* GL_COEFF */
+ { 2547, 0x00001800 }, /* GL_COLOR */
+ { 2556, 0x00008076 }, /* GL_COLOR_ARRAY */
+ { 2571, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING */
+ { 2601, 0x00008898 }, /* GL_COLOR_ARRAY_BUFFER_BINDING_ARB */
+ { 2635, 0x00008090 }, /* GL_COLOR_ARRAY_POINTER */
+ { 2658, 0x00008081 }, /* GL_COLOR_ARRAY_SIZE */
+ { 2678, 0x00008083 }, /* GL_COLOR_ARRAY_STRIDE */
+ { 2700, 0x00008082 }, /* GL_COLOR_ARRAY_TYPE */
+ { 2720, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0 */
+ { 2741, 0x00008CE0 }, /* GL_COLOR_ATTACHMENT0_EXT */
+ { 2766, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1 */
+ { 2787, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10 */
+ { 2809, 0x00008CEA }, /* GL_COLOR_ATTACHMENT10_EXT */
+ { 2835, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11 */
+ { 2857, 0x00008CEB }, /* GL_COLOR_ATTACHMENT11_EXT */
+ { 2883, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12 */
+ { 2905, 0x00008CEC }, /* GL_COLOR_ATTACHMENT12_EXT */
+ { 2931, 0x00008CED }, /* GL_COLOR_ATTACHMENT13 */
+ { 2953, 0x00008CED }, /* GL_COLOR_ATTACHMENT13_EXT */
+ { 2979, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14 */
+ { 3001, 0x00008CEE }, /* GL_COLOR_ATTACHMENT14_EXT */
+ { 3027, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15 */
+ { 3049, 0x00008CEF }, /* GL_COLOR_ATTACHMENT15_EXT */
+ { 3075, 0x00008CE1 }, /* GL_COLOR_ATTACHMENT1_EXT */
+ { 3100, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2 */
+ { 3121, 0x00008CE2 }, /* GL_COLOR_ATTACHMENT2_EXT */
+ { 3146, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3 */
+ { 3167, 0x00008CE3 }, /* GL_COLOR_ATTACHMENT3_EXT */
+ { 3192, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4 */
+ { 3213, 0x00008CE4 }, /* GL_COLOR_ATTACHMENT4_EXT */
+ { 3238, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5 */
+ { 3259, 0x00008CE5 }, /* GL_COLOR_ATTACHMENT5_EXT */
+ { 3284, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6 */
+ { 3305, 0x00008CE6 }, /* GL_COLOR_ATTACHMENT6_EXT */
+ { 3330, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7 */
+ { 3351, 0x00008CE7 }, /* GL_COLOR_ATTACHMENT7_EXT */
+ { 3376, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8 */
+ { 3397, 0x00008CE8 }, /* GL_COLOR_ATTACHMENT8_EXT */
+ { 3422, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9 */
+ { 3443, 0x00008CE9 }, /* GL_COLOR_ATTACHMENT9_EXT */
+ { 3468, 0x00004000 }, /* GL_COLOR_BUFFER_BIT */
+ { 3488, 0x00000C22 }, /* GL_COLOR_CLEAR_VALUE */
+ { 3509, 0x00001900 }, /* GL_COLOR_INDEX */
+ { 3524, 0x00001603 }, /* GL_COLOR_INDEXES */
+ { 3541, 0x00000BF2 }, /* GL_COLOR_LOGIC_OP */
+ { 3559, 0x00000B57 }, /* GL_COLOR_MATERIAL */
+ { 3577, 0x00000B55 }, /* GL_COLOR_MATERIAL_FACE */
+ { 3600, 0x00000B56 }, /* GL_COLOR_MATERIAL_PARAMETER */
+ { 3628, 0x000080B1 }, /* GL_COLOR_MATRIX */
+ { 3644, 0x000080B1 }, /* GL_COLOR_MATRIX_SGI */
+ { 3664, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH */
+ { 3692, 0x000080B2 }, /* GL_COLOR_MATRIX_STACK_DEPTH_SGI */
+ { 3724, 0x00008458 }, /* GL_COLOR_SUM */
+ { 3737, 0x00008458 }, /* GL_COLOR_SUM_ARB */
+ { 3754, 0x000080D0 }, /* GL_COLOR_TABLE */
+ { 3769, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE */
+ { 3795, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_EXT */
+ { 3825, 0x000080DD }, /* GL_COLOR_TABLE_ALPHA_SIZE_SGI */
+ { 3855, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS */
+ { 3875, 0x000080D7 }, /* GL_COLOR_TABLE_BIAS_SGI */
+ { 3899, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE */
+ { 3924, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_EXT */
+ { 3953, 0x000080DC }, /* GL_COLOR_TABLE_BLUE_SIZE_SGI */
+ { 3982, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT */
+ { 4004, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_EXT */
+ { 4030, 0x000080D8 }, /* GL_COLOR_TABLE_FORMAT_SGI */
+ { 4056, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE */
+ { 4082, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_EXT */
+ { 4112, 0x000080DB }, /* GL_COLOR_TABLE_GREEN_SIZE_SGI */
+ { 4142, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE */
+ { 4172, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_EXT */
+ { 4206, 0x000080DF }, /* GL_COLOR_TABLE_INTENSITY_SIZE_SGI */
+ { 4240, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
+ { 4270, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_EXT */
+ { 4304, 0x000080DE }, /* GL_COLOR_TABLE_LUMINANCE_SIZE_SGI */
+ { 4338, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE */
+ { 4362, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_EXT */
+ { 4390, 0x000080DA }, /* GL_COLOR_TABLE_RED_SIZE_SGI */
+ { 4418, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE */
+ { 4439, 0x000080D6 }, /* GL_COLOR_TABLE_SCALE_SGI */
+ { 4464, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH */
+ { 4485, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_EXT */
+ { 4510, 0x000080D9 }, /* GL_COLOR_TABLE_WIDTH_SGI */
+ { 4535, 0x00000C23 }, /* GL_COLOR_WRITEMASK */
+ { 4554, 0x00008570 }, /* GL_COMBINE */
+ { 4565, 0x00008503 }, /* GL_COMBINE4 */
+ { 4577, 0x00008572 }, /* GL_COMBINE_ALPHA */
+ { 4594, 0x00008572 }, /* GL_COMBINE_ALPHA_ARB */
+ { 4615, 0x00008572 }, /* GL_COMBINE_ALPHA_EXT */
+ { 4636, 0x00008570 }, /* GL_COMBINE_ARB */
+ { 4651, 0x00008570 }, /* GL_COMBINE_EXT */
+ { 4666, 0x00008571 }, /* GL_COMBINE_RGB */
+ { 4681, 0x00008571 }, /* GL_COMBINE_RGB_ARB */
+ { 4700, 0x00008571 }, /* GL_COMBINE_RGB_EXT */
+ { 4719, 0x0000884E }, /* GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT */
+ { 4755, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE */
+ { 4779, 0x0000884E }, /* GL_COMPARE_R_TO_TEXTURE_ARB */
+ { 4807, 0x00001300 }, /* GL_COMPILE */
+ { 4818, 0x00001301 }, /* GL_COMPILE_AND_EXECUTE */
+ { 4841, 0x00008B81 }, /* GL_COMPILE_STATUS */
+ { 4859, 0x000084E9 }, /* GL_COMPRESSED_ALPHA */
+ { 4879, 0x000084E9 }, /* GL_COMPRESSED_ALPHA_ARB */
+ { 4903, 0x000084EC }, /* GL_COMPRESSED_INTENSITY */
+ { 4927, 0x000084EC }, /* GL_COMPRESSED_INTENSITY_ARB */
+ { 4955, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE */
+ { 4979, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA */
+ { 5009, 0x000084EB }, /* GL_COMPRESSED_LUMINANCE_ALPHA_ARB */
+ { 5043, 0x000084EA }, /* GL_COMPRESSED_LUMINANCE_ARB */
+ { 5071, 0x000084ED }, /* GL_COMPRESSED_RGB */
+ { 5089, 0x000084EE }, /* GL_COMPRESSED_RGBA */
+ { 5108, 0x000084EE }, /* GL_COMPRESSED_RGBA_ARB */
+ { 5131, 0x000086B1 }, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
+ { 5160, 0x000083F1 }, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
+ { 5193, 0x000083F2 }, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
+ { 5226, 0x000083F3 }, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
+ { 5259, 0x000084ED }, /* GL_COMPRESSED_RGB_ARB */
+ { 5281, 0x000086B0 }, /* GL_COMPRESSED_RGB_FXT1_3DFX */
+ { 5309, 0x000083F0 }, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
+ { 5341, 0x00008C4A }, /* GL_COMPRESSED_SLUMINANCE */
+ { 5366, 0x00008C4B }, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
+ { 5397, 0x00008C48 }, /* GL_COMPRESSED_SRGB */
+ { 5416, 0x00008C49 }, /* GL_COMPRESSED_SRGB_ALPHA */
+ { 5441, 0x000086A3 }, /* GL_COMPRESSED_TEXTURE_FORMATS */
+ { 5471, 0x0000911C }, /* GL_CONDITION_SATISFIED */
+ { 5494, 0x00008576 }, /* GL_CONSTANT */
+ { 5506, 0x00008003 }, /* GL_CONSTANT_ALPHA */
+ { 5524, 0x00008003 }, /* GL_CONSTANT_ALPHA_EXT */
+ { 5546, 0x00008576 }, /* GL_CONSTANT_ARB */
+ { 5562, 0x00001207 }, /* GL_CONSTANT_ATTENUATION */
+ { 5586, 0x00008151 }, /* GL_CONSTANT_BORDER_HP */
+ { 5608, 0x00008001 }, /* GL_CONSTANT_COLOR */
+ { 5626, 0x00008001 }, /* GL_CONSTANT_COLOR_EXT */
+ { 5648, 0x00008576 }, /* GL_CONSTANT_EXT */
+ { 5664, 0x00008010 }, /* GL_CONVOLUTION_1D */
+ { 5682, 0x00008011 }, /* GL_CONVOLUTION_2D */
+ { 5700, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR */
+ { 5728, 0x00008154 }, /* GL_CONVOLUTION_BORDER_COLOR_HP */
+ { 5759, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE */
+ { 5786, 0x00008013 }, /* GL_CONVOLUTION_BORDER_MODE_EXT */
+ { 5817, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS */
+ { 5844, 0x00008015 }, /* GL_CONVOLUTION_FILTER_BIAS_EXT */
+ { 5875, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE */
+ { 5903, 0x00008014 }, /* GL_CONVOLUTION_FILTER_SCALE_EXT */
+ { 5935, 0x00008017 }, /* GL_CONVOLUTION_FORMAT */
+ { 5957, 0x00008017 }, /* GL_CONVOLUTION_FORMAT_EXT */
+ { 5983, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT */
+ { 6005, 0x00008019 }, /* GL_CONVOLUTION_HEIGHT_EXT */
+ { 6031, 0x00008018 }, /* GL_CONVOLUTION_WIDTH */
+ { 6052, 0x00008018 }, /* GL_CONVOLUTION_WIDTH_EXT */
+ { 6077, 0x00008862 }, /* GL_COORD_REPLACE */
+ { 6094, 0x00008862 }, /* GL_COORD_REPLACE_ARB */
+ { 6115, 0x00008862 }, /* GL_COORD_REPLACE_NV */
+ { 6135, 0x00001503 }, /* GL_COPY */
+ { 6143, 0x0000150C }, /* GL_COPY_INVERTED */
+ { 6160, 0x00000706 }, /* GL_COPY_PIXEL_TOKEN */
+ { 6180, 0x00008F36 }, /* GL_COPY_READ_BUFFER */
+ { 6200, 0x00008F37 }, /* GL_COPY_WRITE_BUFFER */
+ { 6221, 0x00000B44 }, /* GL_CULL_FACE */
+ { 6234, 0x00000B45 }, /* GL_CULL_FACE_MODE */
+ { 6252, 0x000081AA }, /* GL_CULL_VERTEX_EXT */
+ { 6271, 0x000081AC }, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
+ { 6303, 0x000081AB }, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
+ { 6338, 0x00008626 }, /* GL_CURRENT_ATTRIB_NV */
+ { 6359, 0x00000001 }, /* GL_CURRENT_BIT */
+ { 6374, 0x00000B00 }, /* GL_CURRENT_COLOR */
+ { 6391, 0x00008453 }, /* GL_CURRENT_FOG_COORD */
+ { 6412, 0x00008453 }, /* GL_CURRENT_FOG_COORDINATE */
+ { 6438, 0x00000B01 }, /* GL_CURRENT_INDEX */
+ { 6455, 0x00008641 }, /* GL_CURRENT_MATRIX_ARB */
+ { 6477, 0x00008845 }, /* GL_CURRENT_MATRIX_INDEX_ARB */
+ { 6505, 0x00008641 }, /* GL_CURRENT_MATRIX_NV */
+ { 6526, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
+ { 6560, 0x00008640 }, /* GL_CURRENT_MATRIX_STACK_DEPTH_NV */
+ { 6593, 0x00000B02 }, /* GL_CURRENT_NORMAL */
+ { 6611, 0x00008843 }, /* GL_CURRENT_PALETTE_MATRIX_ARB */
+ { 6641, 0x00008B8D }, /* GL_CURRENT_PROGRAM */
+ { 6660, 0x00008865 }, /* GL_CURRENT_QUERY */
+ { 6677, 0x00008865 }, /* GL_CURRENT_QUERY_ARB */
+ { 6698, 0x00000B04 }, /* GL_CURRENT_RASTER_COLOR */
+ { 6722, 0x00000B09 }, /* GL_CURRENT_RASTER_DISTANCE */
+ { 6749, 0x00000B05 }, /* GL_CURRENT_RASTER_INDEX */
+ { 6773, 0x00000B07 }, /* GL_CURRENT_RASTER_POSITION */
+ { 6800, 0x00000B08 }, /* GL_CURRENT_RASTER_POSITION_VALID */
+ { 6833, 0x0000845F }, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
+ { 6867, 0x00000B06 }, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
+ { 6900, 0x00008459 }, /* GL_CURRENT_SECONDARY_COLOR */
+ { 6927, 0x00000B03 }, /* GL_CURRENT_TEXTURE_COORDS */
+ { 6953, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB */
+ { 6978, 0x00008626 }, /* GL_CURRENT_VERTEX_ATTRIB_ARB */
+ { 7007, 0x000086A8 }, /* GL_CURRENT_WEIGHT_ARB */
+ { 7029, 0x00000900 }, /* GL_CW */
+ { 7035, 0x0000875B }, /* GL_DEBUG_ASSERT_MESA */
+ { 7056, 0x00008759 }, /* GL_DEBUG_OBJECT_MESA */
+ { 7077, 0x0000875A }, /* GL_DEBUG_PRINT_MESA */
+ { 7097, 0x00002101 }, /* GL_DECAL */
+ { 7106, 0x00001E03 }, /* GL_DECR */
+ { 7114, 0x00008508 }, /* GL_DECR_WRAP */
+ { 7127, 0x00008508 }, /* GL_DECR_WRAP_EXT */
+ { 7144, 0x00008B80 }, /* GL_DELETE_STATUS */
+ { 7161, 0x00001801 }, /* GL_DEPTH */
+ { 7170, 0x000088F0 }, /* GL_DEPTH24_STENCIL8 */
+ { 7190, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT */
+ { 7210, 0x00008D00 }, /* GL_DEPTH_ATTACHMENT_EXT */
+ { 7234, 0x00000D1F }, /* GL_DEPTH_BIAS */
+ { 7248, 0x00000D56 }, /* GL_DEPTH_BITS */
+ { 7262, 0x00008891 }, /* GL_DEPTH_BOUNDS_EXT */
+ { 7282, 0x00008890 }, /* GL_DEPTH_BOUNDS_TEST_EXT */
+ { 7307, 0x00000100 }, /* GL_DEPTH_BUFFER_BIT */
+ { 7327, 0x0000864F }, /* GL_DEPTH_CLAMP */
+ { 7342, 0x0000864F }, /* GL_DEPTH_CLAMP_NV */
+ { 7360, 0x00000B73 }, /* GL_DEPTH_CLEAR_VALUE */
+ { 7381, 0x00001902 }, /* GL_DEPTH_COMPONENT */
+ { 7400, 0x000081A5 }, /* GL_DEPTH_COMPONENT16 */
+ { 7421, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_ARB */
+ { 7446, 0x000081A5 }, /* GL_DEPTH_COMPONENT16_SGIX */
+ { 7472, 0x000081A6 }, /* GL_DEPTH_COMPONENT24 */
+ { 7493, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_ARB */
+ { 7518, 0x000081A6 }, /* GL_DEPTH_COMPONENT24_SGIX */
+ { 7544, 0x000081A7 }, /* GL_DEPTH_COMPONENT32 */
+ { 7565, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_ARB */
+ { 7590, 0x000081A7 }, /* GL_DEPTH_COMPONENT32_SGIX */
+ { 7616, 0x00000B74 }, /* GL_DEPTH_FUNC */
+ { 7630, 0x00000B70 }, /* GL_DEPTH_RANGE */
+ { 7645, 0x00000D1E }, /* GL_DEPTH_SCALE */
+ { 7660, 0x000084F9 }, /* GL_DEPTH_STENCIL */
+ { 7677, 0x0000821A }, /* GL_DEPTH_STENCIL_ATTACHMENT */
+ { 7705, 0x000084F9 }, /* GL_DEPTH_STENCIL_NV */
+ { 7725, 0x0000886F }, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
+ { 7753, 0x0000886E }, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
+ { 7781, 0x00000B71 }, /* GL_DEPTH_TEST */
+ { 7795, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE */
+ { 7817, 0x0000884B }, /* GL_DEPTH_TEXTURE_MODE_ARB */
+ { 7843, 0x00000B72 }, /* GL_DEPTH_WRITEMASK */
+ { 7862, 0x00001201 }, /* GL_DIFFUSE */
+ { 7873, 0x00000BD0 }, /* GL_DITHER */
+ { 7883, 0x00000A02 }, /* GL_DOMAIN */
+ { 7893, 0x00001100 }, /* GL_DONT_CARE */
+ { 7906, 0x000086AE }, /* GL_DOT3_RGB */
+ { 7918, 0x000086AF }, /* GL_DOT3_RGBA */
+ { 7931, 0x000086AF }, /* GL_DOT3_RGBA_ARB */
+ { 7948, 0x00008741 }, /* GL_DOT3_RGBA_EXT */
+ { 7965, 0x000086AE }, /* GL_DOT3_RGB_ARB */
+ { 7981, 0x00008740 }, /* GL_DOT3_RGB_EXT */
+ { 7997, 0x0000140A }, /* GL_DOUBLE */
+ { 8007, 0x00000C32 }, /* GL_DOUBLEBUFFER */
+ { 8023, 0x00000C01 }, /* GL_DRAW_BUFFER */
+ { 8038, 0x00008825 }, /* GL_DRAW_BUFFER0 */
+ { 8054, 0x00008825 }, /* GL_DRAW_BUFFER0_ARB */
+ { 8074, 0x00008825 }, /* GL_DRAW_BUFFER0_ATI */
+ { 8094, 0x00008826 }, /* GL_DRAW_BUFFER1 */
+ { 8110, 0x0000882F }, /* GL_DRAW_BUFFER10 */
+ { 8127, 0x0000882F }, /* GL_DRAW_BUFFER10_ARB */
+ { 8148, 0x0000882F }, /* GL_DRAW_BUFFER10_ATI */
+ { 8169, 0x00008830 }, /* GL_DRAW_BUFFER11 */
+ { 8186, 0x00008830 }, /* GL_DRAW_BUFFER11_ARB */
+ { 8207, 0x00008830 }, /* GL_DRAW_BUFFER11_ATI */
+ { 8228, 0x00008831 }, /* GL_DRAW_BUFFER12 */
+ { 8245, 0x00008831 }, /* GL_DRAW_BUFFER12_ARB */
+ { 8266, 0x00008831 }, /* GL_DRAW_BUFFER12_ATI */
+ { 8287, 0x00008832 }, /* GL_DRAW_BUFFER13 */
+ { 8304, 0x00008832 }, /* GL_DRAW_BUFFER13_ARB */
+ { 8325, 0x00008832 }, /* GL_DRAW_BUFFER13_ATI */
+ { 8346, 0x00008833 }, /* GL_DRAW_BUFFER14 */
+ { 8363, 0x00008833 }, /* GL_DRAW_BUFFER14_ARB */
+ { 8384, 0x00008833 }, /* GL_DRAW_BUFFER14_ATI */
+ { 8405, 0x00008834 }, /* GL_DRAW_BUFFER15 */
+ { 8422, 0x00008834 }, /* GL_DRAW_BUFFER15_ARB */
+ { 8443, 0x00008834 }, /* GL_DRAW_BUFFER15_ATI */
+ { 8464, 0x00008826 }, /* GL_DRAW_BUFFER1_ARB */
+ { 8484, 0x00008826 }, /* GL_DRAW_BUFFER1_ATI */
+ { 8504, 0x00008827 }, /* GL_DRAW_BUFFER2 */
+ { 8520, 0x00008827 }, /* GL_DRAW_BUFFER2_ARB */
+ { 8540, 0x00008827 }, /* GL_DRAW_BUFFER2_ATI */
+ { 8560, 0x00008828 }, /* GL_DRAW_BUFFER3 */
+ { 8576, 0x00008828 }, /* GL_DRAW_BUFFER3_ARB */
+ { 8596, 0x00008828 }, /* GL_DRAW_BUFFER3_ATI */
+ { 8616, 0x00008829 }, /* GL_DRAW_BUFFER4 */
+ { 8632, 0x00008829 }, /* GL_DRAW_BUFFER4_ARB */
+ { 8652, 0x00008829 }, /* GL_DRAW_BUFFER4_ATI */
+ { 8672, 0x0000882A }, /* GL_DRAW_BUFFER5 */
+ { 8688, 0x0000882A }, /* GL_DRAW_BUFFER5_ARB */
+ { 8708, 0x0000882A }, /* GL_DRAW_BUFFER5_ATI */
+ { 8728, 0x0000882B }, /* GL_DRAW_BUFFER6 */
+ { 8744, 0x0000882B }, /* GL_DRAW_BUFFER6_ARB */
+ { 8764, 0x0000882B }, /* GL_DRAW_BUFFER6_ATI */
+ { 8784, 0x0000882C }, /* GL_DRAW_BUFFER7 */
+ { 8800, 0x0000882C }, /* GL_DRAW_BUFFER7_ARB */
+ { 8820, 0x0000882C }, /* GL_DRAW_BUFFER7_ATI */
+ { 8840, 0x0000882D }, /* GL_DRAW_BUFFER8 */
+ { 8856, 0x0000882D }, /* GL_DRAW_BUFFER8_ARB */
+ { 8876, 0x0000882D }, /* GL_DRAW_BUFFER8_ATI */
+ { 8896, 0x0000882E }, /* GL_DRAW_BUFFER9 */
+ { 8912, 0x0000882E }, /* GL_DRAW_BUFFER9_ARB */
+ { 8932, 0x0000882E }, /* GL_DRAW_BUFFER9_ATI */
+ { 8952, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER */
+ { 8972, 0x00008CA6 }, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
+ { 9004, 0x00008CA9 }, /* GL_DRAW_FRAMEBUFFER_EXT */
+ { 9028, 0x00000705 }, /* GL_DRAW_PIXEL_TOKEN */
+ { 9048, 0x00000304 }, /* GL_DST_ALPHA */
+ { 9061, 0x00000306 }, /* GL_DST_COLOR */
+ { 9074, 0x0000877A }, /* GL_DU8DV8_ATI */
+ { 9088, 0x00008779 }, /* GL_DUDV_ATI */
+ { 9100, 0x000088EA }, /* GL_DYNAMIC_COPY */
+ { 9116, 0x000088EA }, /* GL_DYNAMIC_COPY_ARB */
+ { 9136, 0x000088E8 }, /* GL_DYNAMIC_DRAW */
+ { 9152, 0x000088E8 }, /* GL_DYNAMIC_DRAW_ARB */
+ { 9172, 0x000088E9 }, /* GL_DYNAMIC_READ */
+ { 9188, 0x000088E9 }, /* GL_DYNAMIC_READ_ARB */
+ { 9208, 0x00000B43 }, /* GL_EDGE_FLAG */
+ { 9221, 0x00008079 }, /* GL_EDGE_FLAG_ARRAY */
+ { 9240, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+ { 9274, 0x0000889B }, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB */
+ { 9312, 0x00008093 }, /* GL_EDGE_FLAG_ARRAY_POINTER */
+ { 9339, 0x0000808C }, /* GL_EDGE_FLAG_ARRAY_STRIDE */
+ { 9365, 0x00008893 }, /* GL_ELEMENT_ARRAY_BUFFER */
+ { 9389, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
+ { 9421, 0x00008895 }, /* GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB */
+ { 9457, 0x00001600 }, /* GL_EMISSION */
+ { 9469, 0x00002000 }, /* GL_ENABLE_BIT */
+ { 9483, 0x00000202 }, /* GL_EQUAL */
+ { 9492, 0x00001509 }, /* GL_EQUIV */
+ { 9501, 0x00010000 }, /* GL_EVAL_BIT */
+ { 9513, 0x00000800 }, /* GL_EXP */
+ { 9520, 0x00000801 }, /* GL_EXP2 */
+ { 9528, 0x00001F03 }, /* GL_EXTENSIONS */
+ { 9542, 0x00002400 }, /* GL_EYE_LINEAR */
+ { 9556, 0x00002502 }, /* GL_EYE_PLANE */
+ { 9569, 0x0000855C }, /* GL_EYE_PLANE_ABSOLUTE_NV */
+ { 9594, 0x0000855B }, /* GL_EYE_RADIAL_NV */
+ { 9611, 0x00000000 }, /* GL_FALSE */
+ { 9620, 0x00001101 }, /* GL_FASTEST */
+ { 9631, 0x00001C01 }, /* GL_FEEDBACK */
+ { 9643, 0x00000DF0 }, /* GL_FEEDBACK_BUFFER_POINTER */
+ { 9670, 0x00000DF1 }, /* GL_FEEDBACK_BUFFER_SIZE */
+ { 9694, 0x00000DF2 }, /* GL_FEEDBACK_BUFFER_TYPE */
+ { 9718, 0x00001B02 }, /* GL_FILL */
+ { 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[1325] =
+static const unsigned reduced_enums[1347] =
{
- 471, /* GL_FALSE */
- 687, /* GL_LINES */
- 689, /* GL_LINE_LOOP */
- 696, /* GL_LINE_STRIP */
- 1721, /* GL_TRIANGLES */
- 1724, /* GL_TRIANGLE_STRIP */
- 1722, /* GL_TRIANGLE_FAN */
- 1265, /* GL_QUADS */
- 1268, /* GL_QUAD_STRIP */
- 1152, /* GL_POLYGON */
- 1164, /* GL_POLYGON_STIPPLE_BIT */
- 1113, /* GL_PIXEL_MODE_BIT */
- 674, /* GL_LIGHTING_BIT */
- 500, /* GL_FOG_BIT */
+ 476, /* GL_FALSE */
+ 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 */
- 706, /* GL_LOAD */
- 1320, /* GL_RETURN */
- 986, /* GL_MULT */
+ 713, /* GL_LOAD */
+ 1331, /* GL_RETURN */
+ 994, /* GL_MULT */
23, /* GL_ADD */
- 1002, /* GL_NEVER */
- 664, /* GL_LESS */
- 461, /* GL_EQUAL */
- 663, /* GL_LEQUAL */
- 586, /* GL_GREATER */
- 1017, /* GL_NOTEQUAL */
- 585, /* GL_GEQUAL */
- 46, /* GL_ALWAYS */
- 1460, /* GL_SRC_COLOR */
- 1046, /* GL_ONE_MINUS_SRC_COLOR */
- 1458, /* GL_SRC_ALPHA */
- 1045, /* GL_ONE_MINUS_SRC_ALPHA */
- 440, /* GL_DST_ALPHA */
- 1043, /* GL_ONE_MINUS_DST_ALPHA */
- 441, /* GL_DST_COLOR */
- 1044, /* GL_ONE_MINUS_DST_COLOR */
- 1459, /* GL_SRC_ALPHA_SATURATE */
- 573, /* GL_FRONT_LEFT */
- 574, /* GL_FRONT_RIGHT */
- 68, /* GL_BACK_LEFT */
- 69, /* GL_BACK_RIGHT */
- 570, /* GL_FRONT */
- 67, /* GL_BACK */
- 662, /* GL_LEFT */
- 1362, /* GL_RIGHT */
- 571, /* GL_FRONT_AND_BACK */
- 62, /* GL_AUX0 */
- 63, /* GL_AUX1 */
- 64, /* GL_AUX2 */
- 65, /* GL_AUX3 */
- 652, /* GL_INVALID_ENUM */
- 656, /* GL_INVALID_VALUE */
- 655, /* GL_INVALID_OPERATION */
- 1465, /* GL_STACK_OVERFLOW */
- 1466, /* GL_STACK_UNDERFLOW */
- 1071, /* GL_OUT_OF_MEMORY */
- 653, /* GL_INVALID_FRAMEBUFFER_OPERATION */
+ 1010, /* GL_NEVER */
+ 671, /* GL_LESS */
+ 466, /* GL_EQUAL */
+ 670, /* GL_LEQUAL */
+ 592, /* GL_GREATER */
+ 1025, /* GL_NOTEQUAL */
+ 591, /* GL_GEQUAL */
+ 47, /* GL_ALWAYS */
+ 1472, /* GL_SRC_COLOR */
+ 1055, /* GL_ONE_MINUS_SRC_COLOR */
+ 1470, /* GL_SRC_ALPHA */
+ 1054, /* GL_ONE_MINUS_SRC_ALPHA */
+ 445, /* GL_DST_ALPHA */
+ 1052, /* GL_ONE_MINUS_DST_ALPHA */
+ 446, /* GL_DST_COLOR */
+ 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 */
+ 576, /* GL_FRONT */
+ 68, /* GL_BACK */
+ 669, /* GL_LEFT */
+ 1373, /* GL_RIGHT */
+ 577, /* GL_FRONT_AND_BACK */
+ 63, /* GL_AUX0 */
+ 64, /* GL_AUX1 */
+ 65, /* GL_AUX2 */
+ 66, /* GL_AUX3 */
+ 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 */
- 1091, /* GL_PASS_THROUGH_TOKEN */
- 1151, /* GL_POINT_TOKEN */
- 697, /* GL_LINE_TOKEN */
- 1165, /* GL_POLYGON_TOKEN */
- 73, /* GL_BITMAP_TOKEN */
- 439, /* GL_DRAW_PIXEL_TOKEN */
- 297, /* GL_COPY_PIXEL_TOKEN */
- 690, /* GL_LINE_RESET_TOKEN */
- 464, /* GL_EXP */
- 465, /* GL_EXP2 */
- 333, /* GL_CW */
- 122, /* GL_CCW */
- 143, /* GL_COEFF */
- 1068, /* GL_ORDER */
- 377, /* GL_DOMAIN */
- 307, /* GL_CURRENT_COLOR */
- 310, /* GL_CURRENT_INDEX */
- 316, /* GL_CURRENT_NORMAL */
- 329, /* GL_CURRENT_TEXTURE_COORDS */
- 321, /* GL_CURRENT_RASTER_COLOR */
- 323, /* GL_CURRENT_RASTER_INDEX */
- 327, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
- 324, /* GL_CURRENT_RASTER_POSITION */
- 325, /* GL_CURRENT_RASTER_POSITION_VALID */
- 322, /* GL_CURRENT_RASTER_DISTANCE */
- 1144, /* GL_POINT_SMOOTH */
- 1133, /* GL_POINT_SIZE */
- 1143, /* GL_POINT_SIZE_RANGE */
- 1134, /* GL_POINT_SIZE_GRANULARITY */
- 691, /* GL_LINE_SMOOTH */
- 698, /* GL_LINE_WIDTH */
- 700, /* GL_LINE_WIDTH_RANGE */
- 699, /* GL_LINE_WIDTH_GRANULARITY */
- 693, /* GL_LINE_STIPPLE */
- 694, /* GL_LINE_STIPPLE_PATTERN */
- 695, /* GL_LINE_STIPPLE_REPEAT */
- 705, /* GL_LIST_MODE */
- 870, /* GL_MAX_LIST_NESTING */
- 702, /* GL_LIST_BASE */
- 704, /* GL_LIST_INDEX */
- 1154, /* GL_POLYGON_MODE */
- 1161, /* GL_POLYGON_SMOOTH */
- 1163, /* GL_POLYGON_STIPPLE */
- 450, /* GL_EDGE_FLAG */
- 300, /* GL_CULL_FACE */
- 301, /* GL_CULL_FACE_MODE */
- 572, /* GL_FRONT_FACE */
- 673, /* GL_LIGHTING */
- 678, /* GL_LIGHT_MODEL_LOCAL_VIEWER */
- 679, /* GL_LIGHT_MODEL_TWO_SIDE */
- 675, /* GL_LIGHT_MODEL_AMBIENT */
- 1408, /* GL_SHADE_MODEL */
- 190, /* GL_COLOR_MATERIAL_FACE */
- 191, /* GL_COLOR_MATERIAL_PARAMETER */
- 189, /* GL_COLOR_MATERIAL */
- 499, /* GL_FOG */
- 521, /* GL_FOG_INDEX */
- 517, /* GL_FOG_DENSITY */
- 525, /* GL_FOG_START */
- 519, /* GL_FOG_END */
- 522, /* GL_FOG_MODE */
- 501, /* GL_FOG_COLOR */
- 364, /* GL_DEPTH_RANGE */
- 371, /* GL_DEPTH_TEST */
- 374, /* GL_DEPTH_WRITEMASK */
- 352, /* GL_DEPTH_CLEAR_VALUE */
- 363, /* GL_DEPTH_FUNC */
+ 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 */
+ 697, /* GL_LINE_RESET_TOKEN */
+ 469, /* GL_EXP */
+ 470, /* GL_EXP2 */
+ 337, /* GL_CW */
+ 125, /* GL_CCW */
+ 146, /* GL_COEFF */
+ 1077, /* GL_ORDER */
+ 382, /* GL_DOMAIN */
+ 311, /* GL_CURRENT_COLOR */
+ 314, /* GL_CURRENT_INDEX */
+ 320, /* GL_CURRENT_NORMAL */
+ 333, /* GL_CURRENT_TEXTURE_COORDS */
+ 325, /* GL_CURRENT_RASTER_COLOR */
+ 327, /* GL_CURRENT_RASTER_INDEX */
+ 331, /* GL_CURRENT_RASTER_TEXTURE_COORDS */
+ 328, /* GL_CURRENT_RASTER_POSITION */
+ 329, /* GL_CURRENT_RASTER_POSITION_VALID */
+ 326, /* GL_CURRENT_RASTER_DISTANCE */
+ 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 */
+ 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 */
+ 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 */
- 1501, /* GL_STENCIL_TEST */
- 1489, /* GL_STENCIL_CLEAR_VALUE */
- 1491, /* GL_STENCIL_FUNC */
- 1503, /* GL_STENCIL_VALUE_MASK */
- 1490, /* GL_STENCIL_FAIL */
- 1498, /* GL_STENCIL_PASS_DEPTH_FAIL */
- 1499, /* GL_STENCIL_PASS_DEPTH_PASS */
- 1500, /* GL_STENCIL_REF */
- 1504, /* GL_STENCIL_WRITEMASK */
- 839, /* GL_MATRIX_MODE */
- 1007, /* GL_NORMALIZE */
- 1814, /* GL_VIEWPORT */
- 981, /* GL_MODELVIEW_STACK_DEPTH */
- 1244, /* GL_PROJECTION_STACK_DEPTH */
- 1699, /* GL_TEXTURE_STACK_DEPTH */
- 979, /* GL_MODELVIEW_MATRIX */
- 1243, /* GL_PROJECTION_MATRIX */
- 1684, /* GL_TEXTURE_MATRIX */
- 60, /* GL_ATTRIB_STACK_DEPTH */
- 133, /* GL_CLIENT_ATTRIB_STACK_DEPTH */
+ 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 */
44, /* GL_ALPHA_TEST_FUNC */
45, /* GL_ALPHA_TEST_REF */
- 376, /* GL_DITHER */
- 77, /* GL_BLEND_DST */
- 86, /* GL_BLEND_SRC */
- 74, /* GL_BLEND */
- 708, /* GL_LOGIC_OP_MODE */
- 626, /* GL_INDEX_LOGIC_OP */
- 188, /* GL_COLOR_LOGIC_OP */
- 66, /* GL_AUX_BUFFERS */
- 387, /* GL_DRAW_BUFFER */
- 1278, /* GL_READ_BUFFER */
- 1389, /* GL_SCISSOR_BOX */
- 1390, /* GL_SCISSOR_TEST */
- 625, /* GL_INDEX_CLEAR_VALUE */
- 630, /* GL_INDEX_WRITEMASK */
- 185, /* GL_COLOR_CLEAR_VALUE */
- 227, /* GL_COLOR_WRITEMASK */
- 627, /* GL_INDEX_MODE */
- 1355, /* GL_RGBA_MODE */
- 386, /* GL_DOUBLEBUFFER */
- 1505, /* GL_STEREO */
- 1313, /* GL_RENDER_MODE */
- 1092, /* GL_PERSPECTIVE_CORRECTION_HINT */
- 1145, /* GL_POINT_SMOOTH_HINT */
- 692, /* GL_LINE_SMOOTH_HINT */
- 1162, /* GL_POLYGON_SMOOTH_HINT */
- 520, /* GL_FOG_HINT */
- 1665, /* GL_TEXTURE_GEN_S */
- 1666, /* GL_TEXTURE_GEN_T */
- 1664, /* GL_TEXTURE_GEN_R */
- 1663, /* GL_TEXTURE_GEN_Q */
- 1105, /* GL_PIXEL_MAP_I_TO_I */
- 1111, /* GL_PIXEL_MAP_S_TO_S */
- 1107, /* GL_PIXEL_MAP_I_TO_R */
- 1103, /* GL_PIXEL_MAP_I_TO_G */
- 1101, /* GL_PIXEL_MAP_I_TO_B */
- 1099, /* GL_PIXEL_MAP_I_TO_A */
- 1109, /* GL_PIXEL_MAP_R_TO_R */
- 1097, /* GL_PIXEL_MAP_G_TO_G */
- 1095, /* GL_PIXEL_MAP_B_TO_B */
- 1093, /* GL_PIXEL_MAP_A_TO_A */
- 1106, /* GL_PIXEL_MAP_I_TO_I_SIZE */
- 1112, /* GL_PIXEL_MAP_S_TO_S_SIZE */
- 1108, /* GL_PIXEL_MAP_I_TO_R_SIZE */
- 1104, /* GL_PIXEL_MAP_I_TO_G_SIZE */
- 1102, /* GL_PIXEL_MAP_I_TO_B_SIZE */
- 1100, /* GL_PIXEL_MAP_I_TO_A_SIZE */
- 1110, /* GL_PIXEL_MAP_R_TO_R_SIZE */
- 1098, /* GL_PIXEL_MAP_G_TO_G_SIZE */
- 1096, /* GL_PIXEL_MAP_B_TO_B_SIZE */
- 1094, /* GL_PIXEL_MAP_A_TO_A_SIZE */
- 1733, /* GL_UNPACK_SWAP_BYTES */
- 1728, /* GL_UNPACK_LSB_FIRST */
- 1729, /* GL_UNPACK_ROW_LENGTH */
- 1732, /* GL_UNPACK_SKIP_ROWS */
- 1731, /* GL_UNPACK_SKIP_PIXELS */
- 1726, /* GL_UNPACK_ALIGNMENT */
- 1080, /* GL_PACK_SWAP_BYTES */
- 1075, /* GL_PACK_LSB_FIRST */
- 1076, /* GL_PACK_ROW_LENGTH */
- 1079, /* GL_PACK_SKIP_ROWS */
- 1078, /* GL_PACK_SKIP_PIXELS */
- 1072, /* GL_PACK_ALIGNMENT */
- 786, /* GL_MAP_COLOR */
- 791, /* GL_MAP_STENCIL */
- 629, /* GL_INDEX_SHIFT */
- 628, /* GL_INDEX_OFFSET */
- 1291, /* GL_RED_SCALE */
- 1289, /* GL_RED_BIAS */
- 1831, /* GL_ZOOM_X */
- 1832, /* GL_ZOOM_Y */
- 590, /* GL_GREEN_SCALE */
- 588, /* GL_GREEN_BIAS */
- 92, /* GL_BLUE_SCALE */
- 90, /* GL_BLUE_BIAS */
+ 381, /* GL_DITHER */
+ 78, /* GL_BLEND_DST */
+ 87, /* GL_BLEND_SRC */
+ 75, /* GL_BLEND */
+ 715, /* GL_LOGIC_OP_MODE */
+ 632, /* GL_INDEX_LOGIC_OP */
+ 191, /* GL_COLOR_LOGIC_OP */
+ 67, /* GL_AUX_BUFFERS */
+ 392, /* GL_DRAW_BUFFER */
+ 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 */
+ 633, /* GL_INDEX_MODE */
+ 1366, /* GL_RGBA_MODE */
+ 391, /* GL_DOUBLEBUFFER */
+ 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 */
- 365, /* GL_DEPTH_SCALE */
- 346, /* GL_DEPTH_BIAS */
- 865, /* GL_MAX_EVAL_ORDER */
- 869, /* GL_MAX_LIGHTS */
- 848, /* GL_MAX_CLIP_PLANES */
- 914, /* GL_MAX_TEXTURE_SIZE */
- 875, /* GL_MAX_PIXEL_MAP_TABLE */
- 844, /* GL_MAX_ATTRIB_STACK_DEPTH */
- 872, /* GL_MAX_MODELVIEW_STACK_DEPTH */
- 873, /* GL_MAX_NAME_STACK_DEPTH */
- 901, /* GL_MAX_PROJECTION_STACK_DEPTH */
- 915, /* GL_MAX_TEXTURE_STACK_DEPTH */
- 929, /* GL_MAX_VIEWPORT_DIMS */
- 845, /* GL_MAX_CLIENT_ATTRIB_STACK_DEPTH */
- 1512, /* GL_SUBPIXEL_BITS */
- 624, /* GL_INDEX_BITS */
- 1290, /* GL_RED_BITS */
- 589, /* GL_GREEN_BITS */
- 91, /* GL_BLUE_BITS */
+ 370, /* GL_DEPTH_SCALE */
+ 350, /* GL_DEPTH_BIAS */
+ 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 */
- 347, /* GL_DEPTH_BITS */
- 1487, /* GL_STENCIL_BITS */
+ 351, /* GL_DEPTH_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 */
- 995, /* GL_NAME_STACK_DEPTH */
- 61, /* GL_AUTO_NORMAL */
- 732, /* GL_MAP1_COLOR_4 */
- 735, /* GL_MAP1_INDEX */
- 736, /* GL_MAP1_NORMAL */
- 737, /* GL_MAP1_TEXTURE_COORD_1 */
- 738, /* GL_MAP1_TEXTURE_COORD_2 */
- 739, /* GL_MAP1_TEXTURE_COORD_3 */
- 740, /* GL_MAP1_TEXTURE_COORD_4 */
- 741, /* GL_MAP1_VERTEX_3 */
- 742, /* GL_MAP1_VERTEX_4 */
- 759, /* GL_MAP2_COLOR_4 */
- 762, /* GL_MAP2_INDEX */
- 763, /* GL_MAP2_NORMAL */
- 764, /* GL_MAP2_TEXTURE_COORD_1 */
- 765, /* GL_MAP2_TEXTURE_COORD_2 */
- 766, /* GL_MAP2_TEXTURE_COORD_3 */
- 767, /* GL_MAP2_TEXTURE_COORD_4 */
- 768, /* GL_MAP2_VERTEX_3 */
- 769, /* GL_MAP2_VERTEX_4 */
- 733, /* GL_MAP1_GRID_DOMAIN */
- 734, /* GL_MAP1_GRID_SEGMENTS */
- 760, /* GL_MAP2_GRID_DOMAIN */
- 761, /* GL_MAP2_GRID_SEGMENTS */
- 1589, /* GL_TEXTURE_1D */
- 1591, /* GL_TEXTURE_2D */
- 474, /* GL_FEEDBACK_BUFFER_POINTER */
- 475, /* GL_FEEDBACK_BUFFER_SIZE */
- 476, /* GL_FEEDBACK_BUFFER_TYPE */
- 1399, /* GL_SELECTION_BUFFER_POINTER */
- 1400, /* GL_SELECTION_BUFFER_SIZE */
- 1703, /* GL_TEXTURE_WIDTH */
- 1670, /* GL_TEXTURE_HEIGHT */
- 1626, /* GL_TEXTURE_COMPONENTS */
- 1610, /* GL_TEXTURE_BORDER_COLOR */
- 1609, /* GL_TEXTURE_BORDER */
- 378, /* GL_DONT_CARE */
- 472, /* GL_FASTEST */
- 1003, /* GL_NICEST */
- 47, /* GL_AMBIENT */
- 375, /* GL_DIFFUSE */
- 1447, /* GL_SPECULAR */
- 1166, /* GL_POSITION */
- 1450, /* GL_SPOT_DIRECTION */
- 1451, /* GL_SPOT_EXPONENT */
- 1449, /* GL_SPOT_CUTOFF */
- 271, /* GL_CONSTANT_ATTENUATION */
- 682, /* GL_LINEAR_ATTENUATION */
- 1264, /* GL_QUADRATIC_ATTENUATION */
- 241, /* GL_COMPILE */
- 242, /* GL_COMPILE_AND_EXECUTE */
- 117, /* GL_BYTE */
- 1734, /* GL_UNSIGNED_BYTE */
- 1413, /* GL_SHORT */
- 1745, /* GL_UNSIGNED_SHORT */
- 632, /* GL_INT */
- 1737, /* GL_UNSIGNED_INT */
- 480, /* GL_FLOAT */
+ 1003, /* GL_NAME_STACK_DEPTH */
+ 62, /* GL_AUTO_NORMAL */
+ 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 */
+ 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 */
+ 1011, /* GL_NICEST */
+ 48, /* GL_AMBIENT */
+ 380, /* GL_DIFFUSE */
+ 1459, /* GL_SPECULAR */
+ 1175, /* GL_POSITION */
+ 1462, /* GL_SPOT_DIRECTION */
+ 1463, /* GL_SPOT_EXPONENT */
+ 1461, /* GL_SPOT_CUTOFF */
+ 275, /* GL_CONSTANT_ATTENUATION */
+ 689, /* GL_LINEAR_ATTENUATION */
+ 1274, /* GL_QUADRATIC_ATTENUATION */
+ 244, /* GL_COMPILE */
+ 245, /* GL_COMPILE_AND_EXECUTE */
+ 120, /* GL_BYTE */
+ 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 */
- 385, /* GL_DOUBLE */
- 129, /* GL_CLEAR */
- 49, /* GL_AND */
- 51, /* GL_AND_REVERSE */
- 295, /* GL_COPY */
- 50, /* GL_AND_INVERTED */
- 1005, /* GL_NOOP */
- 1827, /* GL_XOR */
- 1067, /* GL_OR */
- 1006, /* GL_NOR */
- 462, /* GL_EQUIV */
- 659, /* GL_INVERT */
- 1070, /* GL_OR_REVERSE */
- 296, /* GL_COPY_INVERTED */
- 1069, /* GL_OR_INVERTED */
- 996, /* GL_NAND */
- 1404, /* GL_SET */
- 459, /* GL_EMISSION */
- 1412, /* GL_SHININESS */
- 48, /* GL_AMBIENT_AND_DIFFUSE */
- 187, /* GL_COLOR_INDEXES */
- 946, /* GL_MODELVIEW */
- 1242, /* GL_PROJECTION */
- 1524, /* GL_TEXTURE */
- 144, /* GL_COLOR */
- 342, /* GL_DEPTH */
- 1473, /* GL_STENCIL */
- 186, /* GL_COLOR_INDEX */
- 1492, /* GL_STENCIL_INDEX */
- 353, /* GL_DEPTH_COMPONENT */
- 1286, /* GL_RED */
- 587, /* GL_GREEN */
- 89, /* GL_BLUE */
+ 390, /* GL_DOUBLE */
+ 132, /* GL_CLEAR */
+ 50, /* GL_AND */
+ 52, /* GL_AND_REVERSE */
+ 299, /* GL_COPY */
+ 51, /* GL_AND_INVERTED */
+ 1013, /* GL_NOOP */
+ 1856, /* GL_XOR */
+ 1076, /* GL_OR */
+ 1014, /* GL_NOR */
+ 467, /* GL_EQUIV */
+ 665, /* GL_INVERT */
+ 1079, /* GL_OR_REVERSE */
+ 300, /* GL_COPY_INVERTED */
+ 1078, /* GL_OR_INVERTED */
+ 1004, /* GL_NAND */
+ 1415, /* GL_SET */
+ 464, /* GL_EMISSION */
+ 1423, /* GL_SHININESS */
+ 49, /* GL_AMBIENT_AND_DIFFUSE */
+ 190, /* GL_COLOR_INDEXES */
+ 954, /* GL_MODELVIEW */
+ 1251, /* GL_PROJECTION */
+ 1545, /* GL_TEXTURE */
+ 147, /* GL_COLOR */
+ 346, /* GL_DEPTH */
+ 1485, /* GL_STENCIL */
+ 189, /* GL_COLOR_INDEX */
+ 1504, /* GL_STENCIL_INDEX */
+ 358, /* GL_DEPTH_COMPONENT */
+ 1297, /* GL_RED */
+ 593, /* GL_GREEN */
+ 90, /* GL_BLUE */
31, /* GL_ALPHA */
- 1321, /* GL_RGB */
- 1340, /* GL_RGBA */
- 710, /* GL_LUMINANCE */
- 731, /* GL_LUMINANCE_ALPHA */
- 72, /* GL_BITMAP */
- 1122, /* GL_POINT */
- 680, /* GL_LINE */
- 477, /* GL_FILL */
- 1295, /* GL_RENDER */
- 473, /* GL_FEEDBACK */
- 1398, /* GL_SELECT */
- 479, /* GL_FLAT */
- 1422, /* GL_SMOOTH */
- 660, /* GL_KEEP */
- 1315, /* GL_REPLACE */
- 614, /* GL_INCR */
- 338, /* GL_DECR */
- 1760, /* GL_VENDOR */
- 1312, /* GL_RENDERER */
- 1761, /* GL_VERSION */
- 466, /* GL_EXTENSIONS */
- 1363, /* GL_S */
- 1515, /* GL_T */
- 1275, /* GL_R */
- 1263, /* GL_Q */
- 982, /* GL_MODULATE */
- 337, /* GL_DECAL */
- 1660, /* GL_TEXTURE_ENV_MODE */
- 1659, /* GL_TEXTURE_ENV_COLOR */
- 1658, /* GL_TEXTURE_ENV */
- 467, /* GL_EYE_LINEAR */
- 1029, /* GL_OBJECT_LINEAR */
- 1448, /* GL_SPHERE_MAP */
- 1662, /* GL_TEXTURE_GEN_MODE */
- 1031, /* GL_OBJECT_PLANE */
- 468, /* GL_EYE_PLANE */
- 997, /* GL_NEAREST */
- 681, /* GL_LINEAR */
- 1001, /* GL_NEAREST_MIPMAP_NEAREST */
- 686, /* GL_LINEAR_MIPMAP_NEAREST */
- 1000, /* GL_NEAREST_MIPMAP_LINEAR */
- 685, /* GL_LINEAR_MIPMAP_LINEAR */
- 1683, /* GL_TEXTURE_MAG_FILTER */
- 1691, /* GL_TEXTURE_MIN_FILTER */
- 1705, /* GL_TEXTURE_WRAP_S */
- 1706, /* GL_TEXTURE_WRAP_T */
- 123, /* GL_CLAMP */
- 1314, /* GL_REPEAT */
- 1160, /* GL_POLYGON_OFFSET_UNITS */
- 1159, /* GL_POLYGON_OFFSET_POINT */
- 1158, /* GL_POLYGON_OFFSET_LINE */
- 1276, /* GL_R3_G3_B2 */
- 1757, /* GL_V2F */
- 1758, /* GL_V3F */
- 120, /* GL_C4UB_V2F */
- 121, /* GL_C4UB_V3F */
- 118, /* GL_C3F_V3F */
- 994, /* GL_N3F_V3F */
- 119, /* GL_C4F_N3F_V3F */
- 1520, /* GL_T2F_V3F */
- 1522, /* GL_T4F_V4F */
- 1518, /* GL_T2F_C4UB_V3F */
- 1516, /* GL_T2F_C3F_V3F */
- 1519, /* GL_T2F_N3F_V3F */
- 1517, /* GL_T2F_C4F_N3F_V3F */
- 1521, /* GL_T4F_C4F_N3F_V4F */
- 136, /* GL_CLIP_PLANE0 */
- 137, /* GL_CLIP_PLANE1 */
- 138, /* GL_CLIP_PLANE2 */
- 139, /* GL_CLIP_PLANE3 */
- 140, /* GL_CLIP_PLANE4 */
- 141, /* GL_CLIP_PLANE5 */
- 665, /* GL_LIGHT0 */
- 666, /* GL_LIGHT1 */
- 667, /* GL_LIGHT2 */
- 668, /* GL_LIGHT3 */
- 669, /* GL_LIGHT4 */
- 670, /* GL_LIGHT5 */
- 671, /* GL_LIGHT6 */
- 672, /* GL_LIGHT7 */
- 591, /* GL_HINT_BIT */
- 273, /* GL_CONSTANT_COLOR */
- 1041, /* GL_ONE_MINUS_CONSTANT_COLOR */
- 268, /* GL_CONSTANT_ALPHA */
- 1039, /* GL_ONE_MINUS_CONSTANT_ALPHA */
- 75, /* GL_BLEND_COLOR */
- 575, /* GL_FUNC_ADD */
- 930, /* GL_MIN */
- 841, /* GL_MAX */
- 80, /* GL_BLEND_EQUATION */
- 579, /* GL_FUNC_SUBTRACT */
- 577, /* GL_FUNC_REVERSE_SUBTRACT */
- 276, /* GL_CONVOLUTION_1D */
- 277, /* GL_CONVOLUTION_2D */
- 1401, /* GL_SEPARABLE_2D */
- 280, /* GL_CONVOLUTION_BORDER_MODE */
- 284, /* GL_CONVOLUTION_FILTER_SCALE */
- 282, /* GL_CONVOLUTION_FILTER_BIAS */
- 1287, /* GL_REDUCE */
- 286, /* GL_CONVOLUTION_FORMAT */
- 290, /* GL_CONVOLUTION_WIDTH */
- 288, /* GL_CONVOLUTION_HEIGHT */
- 856, /* GL_MAX_CONVOLUTION_WIDTH */
- 854, /* GL_MAX_CONVOLUTION_HEIGHT */
- 1199, /* GL_POST_CONVOLUTION_RED_SCALE */
- 1195, /* GL_POST_CONVOLUTION_GREEN_SCALE */
- 1190, /* GL_POST_CONVOLUTION_BLUE_SCALE */
- 1186, /* GL_POST_CONVOLUTION_ALPHA_SCALE */
- 1197, /* GL_POST_CONVOLUTION_RED_BIAS */
- 1193, /* GL_POST_CONVOLUTION_GREEN_BIAS */
- 1188, /* GL_POST_CONVOLUTION_BLUE_BIAS */
- 1184, /* GL_POST_CONVOLUTION_ALPHA_BIAS */
- 592, /* GL_HISTOGRAM */
- 1247, /* GL_PROXY_HISTOGRAM */
- 608, /* GL_HISTOGRAM_WIDTH */
- 598, /* GL_HISTOGRAM_FORMAT */
- 604, /* GL_HISTOGRAM_RED_SIZE */
- 600, /* GL_HISTOGRAM_GREEN_SIZE */
- 595, /* GL_HISTOGRAM_BLUE_SIZE */
- 593, /* GL_HISTOGRAM_ALPHA_SIZE */
- 602, /* GL_HISTOGRAM_LUMINANCE_SIZE */
- 606, /* GL_HISTOGRAM_SINK */
- 931, /* GL_MINMAX */
- 933, /* GL_MINMAX_FORMAT */
- 935, /* GL_MINMAX_SINK */
- 1523, /* GL_TABLE_TOO_LARGE_EXT */
- 1736, /* GL_UNSIGNED_BYTE_3_3_2 */
- 1747, /* GL_UNSIGNED_SHORT_4_4_4_4 */
- 1749, /* GL_UNSIGNED_SHORT_5_5_5_1 */
- 1742, /* GL_UNSIGNED_INT_8_8_8_8 */
- 1738, /* GL_UNSIGNED_INT_10_10_10_2 */
- 1157, /* GL_POLYGON_OFFSET_FILL */
- 1156, /* GL_POLYGON_OFFSET_FACTOR */
- 1155, /* GL_POLYGON_OFFSET_BIAS */
- 1318, /* GL_RESCALE_NORMAL */
+ 1332, /* GL_RGB */
+ 1351, /* GL_RGBA */
+ 717, /* GL_LUMINANCE */
+ 738, /* GL_LUMINANCE_ALPHA */
+ 73, /* GL_BITMAP */
+ 1131, /* GL_POINT */
+ 687, /* GL_LINE */
+ 482, /* GL_FILL */
+ 1306, /* GL_RENDER */
+ 478, /* GL_FEEDBACK */
+ 1409, /* GL_SELECT */
+ 485, /* GL_FLAT */
+ 1434, /* GL_SMOOTH */
+ 666, /* GL_KEEP */
+ 1326, /* GL_REPLACE */
+ 620, /* GL_INCR */
+ 342, /* GL_DECR */
+ 1788, /* GL_VENDOR */
+ 1323, /* GL_RENDERER */
+ 1789, /* GL_VERSION */
+ 471, /* GL_EXTENSIONS */
+ 1374, /* GL_S */
+ 1536, /* GL_T */
+ 1286, /* GL_R */
+ 1273, /* GL_Q */
+ 990, /* GL_MODULATE */
+ 341, /* GL_DECAL */
+ 1682, /* GL_TEXTURE_ENV_MODE */
+ 1681, /* GL_TEXTURE_ENV_COLOR */
+ 1680, /* GL_TEXTURE_ENV */
+ 472, /* GL_EYE_LINEAR */
+ 1037, /* GL_OBJECT_LINEAR */
+ 1460, /* GL_SPHERE_MAP */
+ 1684, /* GL_TEXTURE_GEN_MODE */
+ 1039, /* GL_OBJECT_PLANE */
+ 473, /* GL_EYE_PLANE */
+ 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 */
+ 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 */
+ 1002, /* GL_N3F_V3F */
+ 122, /* GL_C4F_N3F_V3F */
+ 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 */
+ 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 */
+ 1050, /* GL_ONE_MINUS_CONSTANT_COLOR */
+ 272, /* GL_CONSTANT_ALPHA */
+ 1048, /* GL_ONE_MINUS_CONSTANT_ALPHA */
+ 76, /* GL_BLEND_COLOR */
+ 581, /* GL_FUNC_ADD */
+ 938, /* GL_MIN */
+ 848, /* GL_MAX */
+ 81, /* GL_BLEND_EQUATION */
+ 585, /* GL_FUNC_SUBTRACT */
+ 583, /* GL_FUNC_REVERSE_SUBTRACT */
+ 280, /* GL_CONVOLUTION_1D */
+ 281, /* GL_CONVOLUTION_2D */
+ 1412, /* GL_SEPARABLE_2D */
+ 284, /* GL_CONVOLUTION_BORDER_MODE */
+ 288, /* GL_CONVOLUTION_FILTER_SCALE */
+ 286, /* GL_CONVOLUTION_FILTER_BIAS */
+ 1298, /* GL_REDUCE */
+ 290, /* GL_CONVOLUTION_FORMAT */
+ 294, /* GL_CONVOLUTION_WIDTH */
+ 292, /* GL_CONVOLUTION_HEIGHT */
+ 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 */
- 721, /* GL_LUMINANCE4 */
- 727, /* GL_LUMINANCE8 */
- 711, /* GL_LUMINANCE12 */
- 717, /* GL_LUMINANCE16 */
- 722, /* GL_LUMINANCE4_ALPHA4 */
- 725, /* GL_LUMINANCE6_ALPHA2 */
- 728, /* GL_LUMINANCE8_ALPHA8 */
- 714, /* GL_LUMINANCE12_ALPHA4 */
- 712, /* GL_LUMINANCE12_ALPHA12 */
- 718, /* GL_LUMINANCE16_ALPHA16 */
- 633, /* GL_INTENSITY */
- 638, /* GL_INTENSITY4 */
- 640, /* GL_INTENSITY8 */
- 634, /* GL_INTENSITY12 */
- 636, /* GL_INTENSITY16 */
- 1330, /* GL_RGB2_EXT */
- 1331, /* GL_RGB4 */
- 1334, /* GL_RGB5 */
- 1338, /* GL_RGB8 */
- 1322, /* GL_RGB10 */
- 1326, /* GL_RGB12 */
- 1328, /* GL_RGB16 */
- 1345, /* GL_RGBA2 */
- 1347, /* GL_RGBA4 */
- 1335, /* GL_RGB5_A1 */
- 1351, /* GL_RGBA8 */
- 1323, /* GL_RGB10_A2 */
- 1341, /* GL_RGBA12 */
- 1343, /* GL_RGBA16 */
- 1696, /* GL_TEXTURE_RED_SIZE */
- 1668, /* GL_TEXTURE_GREEN_SIZE */
- 1607, /* GL_TEXTURE_BLUE_SIZE */
- 1594, /* GL_TEXTURE_ALPHA_SIZE */
- 1681, /* GL_TEXTURE_LUMINANCE_SIZE */
- 1672, /* GL_TEXTURE_INTENSITY_SIZE */
- 1316, /* GL_REPLACE_EXT */
- 1251, /* GL_PROXY_TEXTURE_1D */
- 1254, /* GL_PROXY_TEXTURE_2D */
- 1701, /* GL_TEXTURE_TOO_LARGE_EXT */
- 1693, /* GL_TEXTURE_PRIORITY */
- 1698, /* GL_TEXTURE_RESIDENT */
- 1597, /* GL_TEXTURE_BINDING_1D */
- 1599, /* GL_TEXTURE_BINDING_2D */
- 1601, /* GL_TEXTURE_BINDING_3D */
- 1077, /* GL_PACK_SKIP_IMAGES */
- 1073, /* GL_PACK_IMAGE_HEIGHT */
- 1730, /* GL_UNPACK_SKIP_IMAGES */
- 1727, /* GL_UNPACK_IMAGE_HEIGHT */
- 1593, /* GL_TEXTURE_3D */
- 1257, /* GL_PROXY_TEXTURE_3D */
- 1655, /* GL_TEXTURE_DEPTH */
- 1704, /* GL_TEXTURE_WRAP_R */
- 842, /* GL_MAX_3D_TEXTURE_SIZE */
- 1762, /* GL_VERTEX_ARRAY */
- 1008, /* GL_NORMAL_ARRAY */
- 145, /* GL_COLOR_ARRAY */
- 618, /* GL_INDEX_ARRAY */
- 1634, /* GL_TEXTURE_COORD_ARRAY */
- 451, /* GL_EDGE_FLAG_ARRAY */
- 1768, /* GL_VERTEX_ARRAY_SIZE */
- 1770, /* GL_VERTEX_ARRAY_TYPE */
- 1769, /* GL_VERTEX_ARRAY_STRIDE */
- 1013, /* GL_NORMAL_ARRAY_TYPE */
- 1012, /* GL_NORMAL_ARRAY_STRIDE */
- 149, /* GL_COLOR_ARRAY_SIZE */
- 151, /* GL_COLOR_ARRAY_TYPE */
- 150, /* GL_COLOR_ARRAY_STRIDE */
- 623, /* GL_INDEX_ARRAY_TYPE */
- 622, /* GL_INDEX_ARRAY_STRIDE */
- 1638, /* GL_TEXTURE_COORD_ARRAY_SIZE */
- 1640, /* GL_TEXTURE_COORD_ARRAY_TYPE */
- 1639, /* GL_TEXTURE_COORD_ARRAY_STRIDE */
- 455, /* GL_EDGE_FLAG_ARRAY_STRIDE */
- 1767, /* GL_VERTEX_ARRAY_POINTER */
- 1011, /* GL_NORMAL_ARRAY_POINTER */
- 148, /* GL_COLOR_ARRAY_POINTER */
- 621, /* GL_INDEX_ARRAY_POINTER */
- 1637, /* GL_TEXTURE_COORD_ARRAY_POINTER */
- 454, /* GL_EDGE_FLAG_ARRAY_POINTER */
- 987, /* GL_MULTISAMPLE */
- 1375, /* GL_SAMPLE_ALPHA_TO_COVERAGE */
- 1377, /* GL_SAMPLE_ALPHA_TO_ONE */
- 1382, /* GL_SAMPLE_COVERAGE */
- 1379, /* GL_SAMPLE_BUFFERS */
- 1370, /* GL_SAMPLES */
- 1386, /* GL_SAMPLE_COVERAGE_VALUE */
- 1384, /* GL_SAMPLE_COVERAGE_INVERT */
- 192, /* GL_COLOR_MATRIX */
- 194, /* GL_COLOR_MATRIX_STACK_DEPTH */
- 850, /* GL_MAX_COLOR_MATRIX_STACK_DEPTH */
- 1182, /* GL_POST_COLOR_MATRIX_RED_SCALE */
- 1178, /* GL_POST_COLOR_MATRIX_GREEN_SCALE */
- 1173, /* GL_POST_COLOR_MATRIX_BLUE_SCALE */
- 1169, /* GL_POST_COLOR_MATRIX_ALPHA_SCALE */
- 1180, /* GL_POST_COLOR_MATRIX_RED_BIAS */
- 1176, /* GL_POST_COLOR_MATRIX_GREEN_BIAS */
- 1171, /* GL_POST_COLOR_MATRIX_BLUE_BIAS */
- 1167, /* GL_POST_COLOR_MATRIX_ALPHA_BIAS */
- 1617, /* GL_TEXTURE_COLOR_TABLE_SGI */
- 1258, /* GL_PROXY_TEXTURE_COLOR_TABLE_SGI */
- 1619, /* GL_TEXTURE_COMPARE_FAIL_VALUE_ARB */
- 79, /* GL_BLEND_DST_RGB */
- 88, /* GL_BLEND_SRC_RGB */
- 78, /* GL_BLEND_DST_ALPHA */
- 87, /* GL_BLEND_SRC_ALPHA */
- 198, /* GL_COLOR_TABLE */
- 1192, /* GL_POST_CONVOLUTION_COLOR_TABLE */
- 1175, /* GL_POST_COLOR_MATRIX_COLOR_TABLE */
- 1246, /* GL_PROXY_COLOR_TABLE */
- 1250, /* GL_PROXY_POST_CONVOLUTION_COLOR_TABLE */
- 1249, /* GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE */
- 222, /* GL_COLOR_TABLE_SCALE */
- 202, /* GL_COLOR_TABLE_BIAS */
- 207, /* GL_COLOR_TABLE_FORMAT */
- 224, /* GL_COLOR_TABLE_WIDTH */
- 219, /* GL_COLOR_TABLE_RED_SIZE */
- 210, /* GL_COLOR_TABLE_GREEN_SIZE */
- 204, /* GL_COLOR_TABLE_BLUE_SIZE */
- 199, /* GL_COLOR_TABLE_ALPHA_SIZE */
- 216, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
- 213, /* GL_COLOR_TABLE_INTENSITY_SIZE */
- 70, /* GL_BGR */
- 71, /* GL_BGRA */
- 864, /* GL_MAX_ELEMENTS_VERTICES */
- 863, /* GL_MAX_ELEMENTS_INDICES */
- 1671, /* GL_TEXTURE_INDEX_SIZE_EXT */
- 142, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
- 1139, /* GL_POINT_SIZE_MIN */
- 1135, /* GL_POINT_SIZE_MAX */
- 1129, /* GL_POINT_FADE_THRESHOLD_SIZE */
- 1125, /* GL_POINT_DISTANCE_ATTENUATION */
- 124, /* GL_CLAMP_TO_BORDER */
- 127, /* GL_CLAMP_TO_EDGE */
- 1692, /* GL_TEXTURE_MIN_LOD */
- 1690, /* GL_TEXTURE_MAX_LOD */
- 1596, /* GL_TEXTURE_BASE_LEVEL */
- 1689, /* GL_TEXTURE_MAX_LEVEL */
- 611, /* GL_IGNORE_BORDER_HP */
- 272, /* GL_CONSTANT_BORDER_HP */
- 1317, /* GL_REPLICATE_BORDER_HP */
- 278, /* GL_CONVOLUTION_BORDER_COLOR */
- 1036, /* GL_OCCLUSION_TEST_HP */
- 1037, /* GL_OCCLUSION_TEST_RESULT_HP */
- 683, /* GL_LINEAR_CLIPMAP_LINEAR_SGIX */
- 1611, /* GL_TEXTURE_CLIPMAP_CENTER_SGIX */
- 1613, /* GL_TEXTURE_CLIPMAP_FRAME_SGIX */
- 1615, /* GL_TEXTURE_CLIPMAP_OFFSET_SGIX */
- 1616, /* GL_TEXTURE_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- 1614, /* GL_TEXTURE_CLIPMAP_LOD_OFFSET_SGIX */
- 1612, /* GL_TEXTURE_CLIPMAP_DEPTH_SGIX */
- 846, /* GL_MAX_CLIPMAP_DEPTH_SGIX */
- 847, /* GL_MAX_CLIPMAP_VIRTUAL_DEPTH_SGIX */
- 1202, /* GL_POST_TEXTURE_FILTER_BIAS_SGIX */
- 1204, /* GL_POST_TEXTURE_FILTER_SCALE_SGIX */
- 1201, /* GL_POST_TEXTURE_FILTER_BIAS_RANGE_SGIX */
- 1203, /* GL_POST_TEXTURE_FILTER_SCALE_RANGE_SGIX */
- 1679, /* GL_TEXTURE_LOD_BIAS_S_SGIX */
- 1680, /* GL_TEXTURE_LOD_BIAS_T_SGIX */
- 1678, /* GL_TEXTURE_LOD_BIAS_R_SGIX */
- 581, /* GL_GENERATE_MIPMAP */
- 582, /* GL_GENERATE_MIPMAP_HINT */
- 523, /* GL_FOG_OFFSET_SGIX */
- 524, /* GL_FOG_OFFSET_VALUE_SGIX */
- 1625, /* GL_TEXTURE_COMPARE_SGIX */
- 1624, /* GL_TEXTURE_COMPARE_OPERATOR_SGIX */
- 1675, /* GL_TEXTURE_LEQUAL_R_SGIX */
- 1667, /* GL_TEXTURE_GEQUAL_R_SGIX */
- 354, /* GL_DEPTH_COMPONENT16 */
- 357, /* GL_DEPTH_COMPONENT24 */
- 360, /* GL_DEPTH_COMPONENT32 */
- 302, /* GL_CULL_VERTEX_EXT */
- 304, /* GL_CULL_VERTEX_OBJECT_POSITION_EXT */
- 303, /* GL_CULL_VERTEX_EYE_POSITION_EXT */
- 1824, /* GL_WRAP_BORDER_SUN */
- 1618, /* GL_TEXTURE_COLOR_WRITEMASK_SGIS */
- 676, /* GL_LIGHT_MODEL_COLOR_CONTROL */
- 1415, /* GL_SINGLE_COLOR */
- 1402, /* GL_SEPARATE_SPECULAR_COLOR */
- 1411, /* GL_SHARED_TEXTURE_PALETTE_EXT */
- 534, /* GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING */
- 535, /* GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE */
- 542, /* GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE */
- 537, /* GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE */
- 533, /* GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE */
- 532, /* GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE */
- 536, /* GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE */
- 543, /* GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE */
- 554, /* GL_FRAMEBUFFER_DEFAULT */
- 567, /* GL_FRAMEBUFFER_UNDEFINED */
- 367, /* GL_DEPTH_STENCIL_ATTACHMENT */
- 617, /* GL_INDEX */
- 1735, /* GL_UNSIGNED_BYTE_2_3_3_REV */
- 1750, /* GL_UNSIGNED_SHORT_5_6_5 */
- 1751, /* GL_UNSIGNED_SHORT_5_6_5_REV */
- 1748, /* GL_UNSIGNED_SHORT_4_4_4_4_REV */
- 1746, /* GL_UNSIGNED_SHORT_1_5_5_5_REV */
- 1743, /* GL_UNSIGNED_INT_8_8_8_8_REV */
- 1741, /* GL_UNSIGNED_INT_2_10_10_10_REV */
- 1687, /* GL_TEXTURE_MAX_CLAMP_S_SGIX */
- 1688, /* GL_TEXTURE_MAX_CLAMP_T_SGIX */
- 1686, /* GL_TEXTURE_MAX_CLAMP_R_SGIX */
- 938, /* GL_MIRRORED_REPEAT */
- 1358, /* GL_RGB_S3TC */
- 1333, /* GL_RGB4_S3TC */
- 1356, /* GL_RGBA_S3TC */
- 1350, /* GL_RGBA4_S3TC */
- 1354, /* GL_RGBA_DXT5_S3TC */
- 1348, /* GL_RGBA4_DXT5_S3TC */
- 261, /* GL_COMPRESSED_RGB_S3TC_DXT1_EXT */
- 256, /* GL_COMPRESSED_RGBA_S3TC_DXT1_EXT */
- 257, /* GL_COMPRESSED_RGBA_S3TC_DXT3_EXT */
- 258, /* GL_COMPRESSED_RGBA_S3TC_DXT5_EXT */
- 999, /* GL_NEAREST_CLIPMAP_NEAREST_SGIX */
- 998, /* GL_NEAREST_CLIPMAP_LINEAR_SGIX */
- 684, /* GL_LINEAR_CLIPMAP_NEAREST_SGIX */
- 510, /* GL_FOG_COORDINATE_SOURCE */
- 502, /* GL_FOG_COORD */
- 526, /* GL_FRAGMENT_DEPTH */
- 308, /* GL_CURRENT_FOG_COORD */
- 509, /* GL_FOG_COORDINATE_ARRAY_TYPE */
- 508, /* GL_FOG_COORDINATE_ARRAY_STRIDE */
- 507, /* GL_FOG_COORDINATE_ARRAY_POINTER */
- 504, /* GL_FOG_COORDINATE_ARRAY */
- 196, /* GL_COLOR_SUM */
- 328, /* GL_CURRENT_SECONDARY_COLOR */
- 1395, /* GL_SECONDARY_COLOR_ARRAY_SIZE */
- 1397, /* GL_SECONDARY_COLOR_ARRAY_TYPE */
- 1396, /* GL_SECONDARY_COLOR_ARRAY_STRIDE */
- 1394, /* GL_SECONDARY_COLOR_ARRAY_POINTER */
- 1391, /* GL_SECONDARY_COLOR_ARRAY */
- 326, /* GL_CURRENT_RASTER_SECONDARY_COLOR */
+ 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 */
+ 624, /* GL_INDEX_ARRAY */
+ 1655, /* GL_TEXTURE_COORD_ARRAY */
+ 456, /* GL_EDGE_FLAG_ARRAY */
+ 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 */
+ 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 */
+ 1795, /* GL_VERTEX_ARRAY_POINTER */
+ 1019, /* GL_NORMAL_ARRAY_POINTER */
+ 151, /* GL_COLOR_ARRAY_POINTER */
+ 627, /* GL_INDEX_ARRAY_POINTER */
+ 1658, /* GL_TEXTURE_COORD_ARRAY_POINTER */
+ 459, /* GL_EDGE_FLAG_ARRAY_POINTER */
+ 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 */
+ 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 */
+ 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 */
+ 227, /* GL_COLOR_TABLE_WIDTH */
+ 222, /* GL_COLOR_TABLE_RED_SIZE */
+ 213, /* GL_COLOR_TABLE_GREEN_SIZE */
+ 207, /* GL_COLOR_TABLE_BLUE_SIZE */
+ 202, /* GL_COLOR_TABLE_ALPHA_SIZE */
+ 219, /* GL_COLOR_TABLE_LUMINANCE_SIZE */
+ 216, /* GL_COLOR_TABLE_INTENSITY_SIZE */
+ 71, /* GL_BGR */
+ 72, /* GL_BGRA */
+ 871, /* GL_MAX_ELEMENTS_VERTICES */
+ 870, /* GL_MAX_ELEMENTS_INDICES */
+ 1693, /* GL_TEXTURE_INDEX_SIZE_EXT */
+ 145, /* GL_CLIP_VOLUME_CLIPPING_HINT_EXT */
+ 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 */
+ 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 */
+ 1328, /* GL_REPLICATE_BORDER_HP */
+ 282, /* GL_CONVOLUTION_BORDER_COLOR */
+ 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 */
+ 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 */
+ 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 */
+ 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 */
+ 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 */
+ 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 */
- 1525, /* GL_TEXTURE0 */
- 1527, /* GL_TEXTURE1 */
- 1549, /* GL_TEXTURE2 */
- 1571, /* GL_TEXTURE3 */
- 1577, /* GL_TEXTURE4 */
- 1579, /* GL_TEXTURE5 */
- 1581, /* GL_TEXTURE6 */
- 1583, /* GL_TEXTURE7 */
- 1585, /* GL_TEXTURE8 */
- 1587, /* GL_TEXTURE9 */
- 1528, /* GL_TEXTURE10 */
- 1530, /* GL_TEXTURE11 */
- 1532, /* GL_TEXTURE12 */
- 1534, /* GL_TEXTURE13 */
- 1536, /* GL_TEXTURE14 */
- 1538, /* GL_TEXTURE15 */
- 1540, /* GL_TEXTURE16 */
- 1542, /* GL_TEXTURE17 */
- 1544, /* GL_TEXTURE18 */
- 1546, /* GL_TEXTURE19 */
- 1550, /* GL_TEXTURE20 */
- 1552, /* GL_TEXTURE21 */
- 1554, /* GL_TEXTURE22 */
- 1556, /* GL_TEXTURE23 */
- 1558, /* GL_TEXTURE24 */
- 1560, /* GL_TEXTURE25 */
- 1562, /* GL_TEXTURE26 */
- 1564, /* GL_TEXTURE27 */
- 1566, /* GL_TEXTURE28 */
- 1568, /* GL_TEXTURE29 */
- 1572, /* GL_TEXTURE30 */
- 1574, /* 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 */
- 130, /* GL_CLIENT_ACTIVE_TEXTURE */
- 916, /* GL_MAX_TEXTURE_UNITS */
- 1714, /* GL_TRANSPOSE_MODELVIEW_MATRIX */
- 1717, /* GL_TRANSPOSE_PROJECTION_MATRIX */
- 1719, /* GL_TRANSPOSE_TEXTURE_MATRIX */
- 1711, /* GL_TRANSPOSE_COLOR_MATRIX */
- 1513, /* GL_SUBTRACT */
- 904, /* GL_MAX_RENDERBUFFER_SIZE_EXT */
- 244, /* GL_COMPRESSED_ALPHA */
- 248, /* GL_COMPRESSED_LUMINANCE */
- 249, /* GL_COMPRESSED_LUMINANCE_ALPHA */
- 246, /* GL_COMPRESSED_INTENSITY */
- 252, /* GL_COMPRESSED_RGB */
- 253, /* GL_COMPRESSED_RGBA */
- 1632, /* GL_TEXTURE_COMPRESSION_HINT */
- 1694, /* GL_TEXTURE_RECTANGLE_ARB */
- 1604, /* GL_TEXTURE_BINDING_RECTANGLE_ARB */
- 1261, /* GL_PROXY_TEXTURE_RECTANGLE_ARB */
- 902, /* GL_MAX_RECTANGLE_TEXTURE_SIZE_ARB */
- 366, /* GL_DEPTH_STENCIL */
- 1739, /* GL_UNSIGNED_INT_24_8 */
- 912, /* GL_MAX_TEXTURE_LOD_BIAS */
- 1685, /* GL_TEXTURE_MAX_ANISOTROPY_EXT */
- 913, /* GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT */
- 1661, /* GL_TEXTURE_FILTER_CONTROL */
- 1676, /* GL_TEXTURE_LOD_BIAS */
- 229, /* GL_COMBINE4 */
- 906, /* GL_MAX_SHININESS_NV */
- 907, /* GL_MAX_SPOT_EXPONENT_NV */
- 615, /* GL_INCR_WRAP */
- 339, /* GL_DECR_WRAP */
- 958, /* GL_MODELVIEW1_ARB */
- 1014, /* GL_NORMAL_MAP */
- 1292, /* GL_REFLECTION_MAP */
- 1641, /* GL_TEXTURE_CUBE_MAP */
- 1602, /* GL_TEXTURE_BINDING_CUBE_MAP */
- 1649, /* GL_TEXTURE_CUBE_MAP_POSITIVE_X */
- 1643, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_X */
- 1651, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Y */
- 1645, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Y */
- 1653, /* GL_TEXTURE_CUBE_MAP_POSITIVE_Z */
- 1647, /* GL_TEXTURE_CUBE_MAP_NEGATIVE_Z */
- 1259, /* GL_PROXY_TEXTURE_CUBE_MAP */
- 858, /* GL_MAX_CUBE_MAP_TEXTURE_SIZE */
- 993, /* GL_MULTISAMPLE_FILTER_HINT_NV */
- 518, /* GL_FOG_DISTANCE_MODE_NV */
- 470, /* GL_EYE_RADIAL_NV */
- 469, /* GL_EYE_PLANE_ABSOLUTE_NV */
- 228, /* GL_COMBINE */
- 235, /* GL_COMBINE_RGB */
- 230, /* GL_COMBINE_ALPHA */
- 1359, /* GL_RGB_SCALE */
+ 133, /* GL_CLIENT_ACTIVE_TEXTURE */
+ 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 */
+ 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 */
+ 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 */
+ 914, /* GL_MAX_SHININESS_NV */
+ 915, /* GL_MAX_SPOT_EXPONENT_NV */
+ 621, /* GL_INCR_WRAP */
+ 343, /* GL_DECR_WRAP */
+ 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 */
+ 1370, /* GL_RGB_SCALE */
24, /* GL_ADD_SIGNED */
- 643, /* GL_INTERPOLATE */
- 267, /* GL_CONSTANT */
- 1208, /* GL_PRIMARY_COLOR */
- 1205, /* GL_PREVIOUS */
- 1430, /* GL_SOURCE0_RGB */
- 1436, /* GL_SOURCE1_RGB */
- 1442, /* GL_SOURCE2_RGB */
- 1446, /* GL_SOURCE3_RGB_NV */
- 1427, /* GL_SOURCE0_ALPHA */
- 1433, /* GL_SOURCE1_ALPHA */
- 1439, /* GL_SOURCE2_ALPHA */
- 1445, /* GL_SOURCE3_ALPHA_NV */
- 1050, /* GL_OPERAND0_RGB */
- 1056, /* GL_OPERAND1_RGB */
- 1062, /* GL_OPERAND2_RGB */
- 1066, /* GL_OPERAND3_RGB_NV */
- 1047, /* GL_OPERAND0_ALPHA */
- 1053, /* GL_OPERAND1_ALPHA */
- 1059, /* GL_OPERAND2_ALPHA */
- 1065, /* GL_OPERAND3_ALPHA_NV */
- 1763, /* GL_VERTEX_ARRAY_BINDING */
- 1828, /* GL_YCBCR_422_APPLE */
- 1752, /* GL_UNSIGNED_SHORT_8_8_APPLE */
- 1754, /* GL_UNSIGNED_SHORT_8_8_REV_APPLE */
- 1417, /* GL_SLICE_ACCUM_SUN */
- 1267, /* GL_QUAD_MESH_SUN */
- 1723, /* GL_TRIANGLE_MESH_SUN */
- 1802, /* GL_VERTEX_PROGRAM_ARB */
- 1813, /* GL_VERTEX_STATE_PROGRAM_NV */
- 1789, /* GL_VERTEX_ATTRIB_ARRAY_ENABLED */
- 1795, /* GL_VERTEX_ATTRIB_ARRAY_SIZE */
- 1797, /* GL_VERTEX_ATTRIB_ARRAY_STRIDE */
- 1799, /* GL_VERTEX_ATTRIB_ARRAY_TYPE */
- 330, /* GL_CURRENT_VERTEX_ATTRIB */
- 1221, /* GL_PROGRAM_LENGTH_ARB */
- 1235, /* GL_PROGRAM_STRING_ARB */
- 980, /* GL_MODELVIEW_PROJECTION_NV */
- 610, /* GL_IDENTITY_NV */
- 657, /* GL_INVERSE_NV */
- 1716, /* GL_TRANSPOSE_NV */
- 658, /* GL_INVERSE_TRANSPOSE_NV */
- 888, /* GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB */
- 887, /* GL_MAX_PROGRAM_MATRICES_ARB */
- 795, /* GL_MATRIX0_NV */
- 807, /* GL_MATRIX1_NV */
- 819, /* GL_MATRIX2_NV */
- 823, /* GL_MATRIX3_NV */
- 825, /* GL_MATRIX4_NV */
- 827, /* GL_MATRIX5_NV */
- 829, /* GL_MATRIX6_NV */
- 831, /* GL_MATRIX7_NV */
- 314, /* GL_CURRENT_MATRIX_STACK_DEPTH_ARB */
- 311, /* GL_CURRENT_MATRIX_ARB */
- 1805, /* GL_VERTEX_PROGRAM_POINT_SIZE */
- 1808, /* GL_VERTEX_PROGRAM_TWO_SIDE */
- 1233, /* GL_PROGRAM_PARAMETER_NV */
- 1793, /* GL_VERTEX_ATTRIB_ARRAY_POINTER */
- 1237, /* GL_PROGRAM_TARGET_NV */
- 1234, /* GL_PROGRAM_RESIDENT_NV */
- 1708, /* GL_TRACK_MATRIX_NV */
- 1709, /* GL_TRACK_MATRIX_TRANSFORM_NV */
- 1803, /* GL_VERTEX_PROGRAM_BINDING_NV */
- 1215, /* GL_PROGRAM_ERROR_POSITION_ARB */
- 351, /* GL_DEPTH_CLAMP_NV */
- 1771, /* GL_VERTEX_ATTRIB_ARRAY0_NV */
- 1778, /* GL_VERTEX_ATTRIB_ARRAY1_NV */
- 1779, /* GL_VERTEX_ATTRIB_ARRAY2_NV */
- 1780, /* GL_VERTEX_ATTRIB_ARRAY3_NV */
- 1781, /* GL_VERTEX_ATTRIB_ARRAY4_NV */
- 1782, /* GL_VERTEX_ATTRIB_ARRAY5_NV */
- 1783, /* GL_VERTEX_ATTRIB_ARRAY6_NV */
- 1784, /* GL_VERTEX_ATTRIB_ARRAY7_NV */
- 1785, /* GL_VERTEX_ATTRIB_ARRAY8_NV */
- 1786, /* GL_VERTEX_ATTRIB_ARRAY9_NV */
- 1772, /* GL_VERTEX_ATTRIB_ARRAY10_NV */
- 1773, /* GL_VERTEX_ATTRIB_ARRAY11_NV */
- 1774, /* GL_VERTEX_ATTRIB_ARRAY12_NV */
- 1775, /* GL_VERTEX_ATTRIB_ARRAY13_NV */
- 1776, /* GL_VERTEX_ATTRIB_ARRAY14_NV */
- 1777, /* GL_VERTEX_ATTRIB_ARRAY15_NV */
- 743, /* GL_MAP1_VERTEX_ATTRIB0_4_NV */
- 750, /* GL_MAP1_VERTEX_ATTRIB1_4_NV */
- 751, /* GL_MAP1_VERTEX_ATTRIB2_4_NV */
- 752, /* GL_MAP1_VERTEX_ATTRIB3_4_NV */
- 753, /* GL_MAP1_VERTEX_ATTRIB4_4_NV */
- 754, /* GL_MAP1_VERTEX_ATTRIB5_4_NV */
- 755, /* GL_MAP1_VERTEX_ATTRIB6_4_NV */
- 756, /* GL_MAP1_VERTEX_ATTRIB7_4_NV */
- 757, /* GL_MAP1_VERTEX_ATTRIB8_4_NV */
- 758, /* GL_MAP1_VERTEX_ATTRIB9_4_NV */
- 744, /* GL_MAP1_VERTEX_ATTRIB10_4_NV */
- 745, /* GL_MAP1_VERTEX_ATTRIB11_4_NV */
- 746, /* GL_MAP1_VERTEX_ATTRIB12_4_NV */
- 747, /* GL_MAP1_VERTEX_ATTRIB13_4_NV */
- 748, /* GL_MAP1_VERTEX_ATTRIB14_4_NV */
- 749, /* GL_MAP1_VERTEX_ATTRIB15_4_NV */
- 770, /* GL_MAP2_VERTEX_ATTRIB0_4_NV */
- 777, /* GL_MAP2_VERTEX_ATTRIB1_4_NV */
- 778, /* GL_MAP2_VERTEX_ATTRIB2_4_NV */
- 779, /* GL_MAP2_VERTEX_ATTRIB3_4_NV */
- 780, /* GL_MAP2_VERTEX_ATTRIB4_4_NV */
- 781, /* GL_MAP2_VERTEX_ATTRIB5_4_NV */
- 782, /* GL_MAP2_VERTEX_ATTRIB6_4_NV */
- 1214, /* GL_PROGRAM_BINDING_ARB */
- 784, /* GL_MAP2_VERTEX_ATTRIB8_4_NV */
- 785, /* GL_MAP2_VERTEX_ATTRIB9_4_NV */
- 771, /* GL_MAP2_VERTEX_ATTRIB10_4_NV */
- 772, /* GL_MAP2_VERTEX_ATTRIB11_4_NV */
- 773, /* GL_MAP2_VERTEX_ATTRIB12_4_NV */
- 774, /* GL_MAP2_VERTEX_ATTRIB13_4_NV */
- 775, /* GL_MAP2_VERTEX_ATTRIB14_4_NV */
- 776, /* GL_MAP2_VERTEX_ATTRIB15_4_NV */
- 1630, /* GL_TEXTURE_COMPRESSED_IMAGE_SIZE */
- 1627, /* GL_TEXTURE_COMPRESSED */
- 1019, /* GL_NUM_COMPRESSED_TEXTURE_FORMATS */
- 266, /* GL_COMPRESSED_TEXTURE_FORMATS */
- 928, /* GL_MAX_VERTEX_UNITS_ARB */
+ 649, /* GL_INTERPOLATE */
+ 271, /* GL_CONSTANT */
+ 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 */
+ 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 */
+ 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 */
+ 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 */
+ 936, /* GL_MAX_VERTEX_UNITS_ARB */
22, /* GL_ACTIVE_VERTEX_UNITS_ARB */
- 1823, /* GL_WEIGHT_SUM_UNITY_ARB */
- 1801, /* GL_VERTEX_BLEND_ARB */
- 332, /* GL_CURRENT_WEIGHT_ARB */
- 1822, /* GL_WEIGHT_ARRAY_TYPE_ARB */
- 1821, /* GL_WEIGHT_ARRAY_STRIDE_ARB */
- 1820, /* GL_WEIGHT_ARRAY_SIZE_ARB */
- 1819, /* GL_WEIGHT_ARRAY_POINTER_ARB */
- 1816, /* GL_WEIGHT_ARRAY_ARB */
- 379, /* GL_DOT3_RGB */
- 380, /* GL_DOT3_RGBA */
- 260, /* GL_COMPRESSED_RGB_FXT1_3DFX */
- 255, /* GL_COMPRESSED_RGBA_FXT1_3DFX */
- 988, /* GL_MULTISAMPLE_3DFX */
- 1380, /* GL_SAMPLE_BUFFERS_3DFX */
- 1371, /* GL_SAMPLES_3DFX */
- 969, /* GL_MODELVIEW2_ARB */
- 972, /* GL_MODELVIEW3_ARB */
- 973, /* GL_MODELVIEW4_ARB */
- 974, /* GL_MODELVIEW5_ARB */
- 975, /* GL_MODELVIEW6_ARB */
- 976, /* GL_MODELVIEW7_ARB */
- 977, /* GL_MODELVIEW8_ARB */
- 978, /* GL_MODELVIEW9_ARB */
- 948, /* GL_MODELVIEW10_ARB */
- 949, /* GL_MODELVIEW11_ARB */
- 950, /* GL_MODELVIEW12_ARB */
- 951, /* GL_MODELVIEW13_ARB */
- 952, /* GL_MODELVIEW14_ARB */
- 953, /* GL_MODELVIEW15_ARB */
- 954, /* GL_MODELVIEW16_ARB */
- 955, /* GL_MODELVIEW17_ARB */
- 956, /* GL_MODELVIEW18_ARB */
- 957, /* GL_MODELVIEW19_ARB */
- 959, /* GL_MODELVIEW20_ARB */
- 960, /* GL_MODELVIEW21_ARB */
- 961, /* GL_MODELVIEW22_ARB */
- 962, /* GL_MODELVIEW23_ARB */
- 963, /* GL_MODELVIEW24_ARB */
- 964, /* GL_MODELVIEW25_ARB */
- 965, /* GL_MODELVIEW26_ARB */
- 966, /* GL_MODELVIEW27_ARB */
- 967, /* GL_MODELVIEW28_ARB */
- 968, /* GL_MODELVIEW29_ARB */
- 970, /* GL_MODELVIEW30_ARB */
- 971, /* GL_MODELVIEW31_ARB */
- 384, /* GL_DOT3_RGB_EXT */
- 382, /* GL_DOT3_RGBA_EXT */
- 942, /* GL_MIRROR_CLAMP_EXT */
- 945, /* GL_MIRROR_CLAMP_TO_EDGE_EXT */
- 983, /* GL_MODULATE_ADD_ATI */
- 984, /* GL_MODULATE_SIGNED_ADD_ATI */
- 985, /* GL_MODULATE_SUBTRACT_ATI */
- 1829, /* GL_YCBCR_MESA */
- 1074, /* GL_PACK_INVERT_MESA */
- 335, /* GL_DEBUG_OBJECT_MESA */
- 336, /* GL_DEBUG_PRINT_MESA */
- 334, /* GL_DEBUG_ASSERT_MESA */
- 107, /* GL_BUFFER_SIZE */
- 109, /* GL_BUFFER_USAGE */
- 113, /* GL_BUMP_ROT_MATRIX_ATI */
- 114, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
- 112, /* GL_BUMP_NUM_TEX_UNITS_ATI */
- 116, /* GL_BUMP_TEX_UNITS_ATI */
- 443, /* GL_DUDV_ATI */
- 442, /* GL_DU8DV8_ATI */
- 111, /* GL_BUMP_ENVMAP_ATI */
- 115, /* GL_BUMP_TARGET_ATI */
- 1478, /* GL_STENCIL_BACK_FUNC */
- 1476, /* GL_STENCIL_BACK_FAIL */
- 1480, /* GL_STENCIL_BACK_PASS_DEPTH_FAIL */
- 1482, /* GL_STENCIL_BACK_PASS_DEPTH_PASS */
- 527, /* GL_FRAGMENT_PROGRAM_ARB */
- 1212, /* GL_PROGRAM_ALU_INSTRUCTIONS_ARB */
- 1240, /* GL_PROGRAM_TEX_INSTRUCTIONS_ARB */
- 1239, /* GL_PROGRAM_TEX_INDIRECTIONS_ARB */
- 1224, /* GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- 1230, /* GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- 1229, /* GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- 877, /* GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB */
- 900, /* GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB */
- 899, /* GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB */
- 890, /* GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB */
- 896, /* GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB */
- 895, /* GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB */
- 860, /* GL_MAX_DRAW_BUFFERS */
- 388, /* GL_DRAW_BUFFER0 */
- 391, /* GL_DRAW_BUFFER1 */
- 412, /* GL_DRAW_BUFFER2 */
- 415, /* GL_DRAW_BUFFER3 */
- 418, /* GL_DRAW_BUFFER4 */
- 421, /* GL_DRAW_BUFFER5 */
- 424, /* GL_DRAW_BUFFER6 */
- 427, /* GL_DRAW_BUFFER7 */
- 430, /* GL_DRAW_BUFFER8 */
- 433, /* GL_DRAW_BUFFER9 */
- 392, /* GL_DRAW_BUFFER10 */
- 395, /* GL_DRAW_BUFFER11 */
- 398, /* GL_DRAW_BUFFER12 */
- 401, /* GL_DRAW_BUFFER13 */
- 404, /* GL_DRAW_BUFFER14 */
- 407, /* GL_DRAW_BUFFER15 */
- 81, /* GL_BLEND_EQUATION_ALPHA */
- 840, /* GL_MATRIX_PALETTE_ARB */
- 871, /* GL_MAX_MATRIX_PALETTE_STACK_DEPTH_ARB */
- 874, /* GL_MAX_PALETTE_MATRICES_ARB */
- 317, /* GL_CURRENT_PALETTE_MATRIX_ARB */
- 834, /* GL_MATRIX_INDEX_ARRAY_ARB */
- 312, /* GL_CURRENT_MATRIX_INDEX_ARB */
- 836, /* GL_MATRIX_INDEX_ARRAY_SIZE_ARB */
- 838, /* GL_MATRIX_INDEX_ARRAY_TYPE_ARB */
- 837, /* GL_MATRIX_INDEX_ARRAY_STRIDE_ARB */
- 835, /* GL_MATRIX_INDEX_ARRAY_POINTER_ARB */
- 1656, /* GL_TEXTURE_DEPTH_SIZE */
- 372, /* GL_DEPTH_TEXTURE_MODE */
- 1622, /* GL_TEXTURE_COMPARE_MODE */
- 1620, /* GL_TEXTURE_COMPARE_FUNC */
- 239, /* GL_COMPARE_R_TO_TEXTURE */
- 1146, /* GL_POINT_SPRITE */
- 292, /* GL_COORD_REPLACE */
- 1150, /* GL_POINT_SPRITE_R_MODE_NV */
- 1269, /* GL_QUERY_COUNTER_BITS */
- 319, /* GL_CURRENT_QUERY */
- 1271, /* GL_QUERY_RESULT */
- 1273, /* GL_QUERY_RESULT_AVAILABLE */
- 922, /* GL_MAX_VERTEX_ATTRIBS */
- 1791, /* GL_VERTEX_ATTRIB_ARRAY_NORMALIZED */
- 370, /* GL_DEPTH_STENCIL_TO_RGBA_NV */
- 369, /* GL_DEPTH_STENCIL_TO_BGRA_NV */
- 908, /* GL_MAX_TEXTURE_COORDS */
- 910, /* GL_MAX_TEXTURE_IMAGE_UNITS */
- 1217, /* GL_PROGRAM_ERROR_STRING_ARB */
- 1219, /* GL_PROGRAM_FORMAT_ASCII_ARB */
- 1218, /* GL_PROGRAM_FORMAT_ARB */
- 1702, /* GL_TEXTURE_UNSIGNED_REMAP_MODE_NV */
- 349, /* GL_DEPTH_BOUNDS_TEST_EXT */
- 348, /* GL_DEPTH_BOUNDS_EXT */
- 52, /* GL_ARRAY_BUFFER */
- 456, /* GL_ELEMENT_ARRAY_BUFFER */
- 53, /* GL_ARRAY_BUFFER_BINDING */
- 457, /* GL_ELEMENT_ARRAY_BUFFER_BINDING */
- 1765, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
- 1009, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
- 146, /* GL_COLOR_ARRAY_BUFFER_BINDING */
- 619, /* GL_INDEX_ARRAY_BUFFER_BINDING */
- 1635, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
- 452, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
- 1392, /* GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING */
- 505, /* GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING */
- 1817, /* GL_WEIGHT_ARRAY_BUFFER_BINDING */
- 1787, /* GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING */
- 1220, /* GL_PROGRAM_INSTRUCTIONS_ARB */
- 883, /* GL_MAX_PROGRAM_INSTRUCTIONS_ARB */
- 1226, /* GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- 892, /* GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB */
- 1238, /* GL_PROGRAM_TEMPORARIES_ARB */
- 898, /* GL_MAX_PROGRAM_TEMPORARIES_ARB */
- 1228, /* GL_PROGRAM_NATIVE_TEMPORARIES_ARB */
- 894, /* GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB */
- 1232, /* GL_PROGRAM_PARAMETERS_ARB */
- 897, /* GL_MAX_PROGRAM_PARAMETERS_ARB */
- 1227, /* GL_PROGRAM_NATIVE_PARAMETERS_ARB */
- 893, /* GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB */
- 1213, /* GL_PROGRAM_ATTRIBS_ARB */
- 878, /* GL_MAX_PROGRAM_ATTRIBS_ARB */
- 1225, /* GL_PROGRAM_NATIVE_ATTRIBS_ARB */
- 891, /* GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB */
- 1211, /* GL_PROGRAM_ADDRESS_REGISTERS_ARB */
- 876, /* GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB */
- 1223, /* GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- 889, /* GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB */
- 884, /* GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB */
- 880, /* GL_MAX_PROGRAM_ENV_PARAMETERS_ARB */
- 1241, /* GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB */
- 1713, /* GL_TRANSPOSE_CURRENT_MATRIX_ARB */
- 1282, /* GL_READ_ONLY */
- 1825, /* GL_WRITE_ONLY */
- 1284, /* GL_READ_WRITE */
- 101, /* GL_BUFFER_ACCESS */
- 103, /* GL_BUFFER_MAPPED */
- 105, /* GL_BUFFER_MAP_POINTER */
- 1707, /* GL_TIME_ELAPSED_EXT */
- 794, /* GL_MATRIX0_ARB */
- 806, /* GL_MATRIX1_ARB */
- 818, /* GL_MATRIX2_ARB */
- 822, /* GL_MATRIX3_ARB */
- 824, /* GL_MATRIX4_ARB */
- 826, /* GL_MATRIX5_ARB */
- 828, /* GL_MATRIX6_ARB */
- 830, /* GL_MATRIX7_ARB */
- 832, /* GL_MATRIX8_ARB */
- 833, /* GL_MATRIX9_ARB */
- 796, /* GL_MATRIX10_ARB */
- 797, /* GL_MATRIX11_ARB */
- 798, /* GL_MATRIX12_ARB */
- 799, /* GL_MATRIX13_ARB */
- 800, /* GL_MATRIX14_ARB */
- 801, /* GL_MATRIX15_ARB */
- 802, /* GL_MATRIX16_ARB */
- 803, /* GL_MATRIX17_ARB */
- 804, /* GL_MATRIX18_ARB */
- 805, /* GL_MATRIX19_ARB */
- 808, /* GL_MATRIX20_ARB */
- 809, /* GL_MATRIX21_ARB */
- 810, /* GL_MATRIX22_ARB */
- 811, /* GL_MATRIX23_ARB */
- 812, /* GL_MATRIX24_ARB */
- 813, /* GL_MATRIX25_ARB */
- 814, /* GL_MATRIX26_ARB */
- 815, /* GL_MATRIX27_ARB */
- 816, /* GL_MATRIX28_ARB */
- 817, /* GL_MATRIX29_ARB */
- 820, /* GL_MATRIX30_ARB */
- 821, /* GL_MATRIX31_ARB */
- 1508, /* GL_STREAM_DRAW */
- 1510, /* GL_STREAM_READ */
- 1506, /* GL_STREAM_COPY */
- 1469, /* GL_STATIC_DRAW */
- 1471, /* GL_STATIC_READ */
- 1467, /* GL_STATIC_COPY */
- 446, /* GL_DYNAMIC_DRAW */
- 448, /* GL_DYNAMIC_READ */
- 444, /* GL_DYNAMIC_COPY */
- 1114, /* GL_PIXEL_PACK_BUFFER */
- 1118, /* GL_PIXEL_UNPACK_BUFFER */
- 1115, /* GL_PIXEL_PACK_BUFFER_BINDING */
- 1119, /* GL_PIXEL_UNPACK_BUFFER_BINDING */
- 343, /* GL_DEPTH24_STENCIL8 */
- 1700, /* GL_TEXTURE_STENCIL_SIZE */
- 881, /* GL_MAX_PROGRAM_EXEC_INSTRUCTIONS_NV */
- 879, /* GL_MAX_PROGRAM_CALL_DEPTH_NV */
- 882, /* GL_MAX_PROGRAM_IF_DEPTH_NV */
- 886, /* GL_MAX_PROGRAM_LOOP_DEPTH_NV */
- 885, /* GL_MAX_PROGRAM_LOOP_COUNT_NV */
- 843, /* GL_MAX_ARRAY_TEXTURE_LAYERS_EXT */
- 1502, /* GL_STENCIL_TEST_TWO_SIDE_EXT */
+ 1852, /* GL_WEIGHT_SUM_UNITY_ARB */
+ 1829, /* GL_VERTEX_BLEND_ARB */
+ 336, /* GL_CURRENT_WEIGHT_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 */
+ 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 */
+ 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 */
+ 110, /* GL_BUFFER_SIZE */
+ 112, /* GL_BUFFER_USAGE */
+ 116, /* GL_BUMP_ROT_MATRIX_ATI */
+ 117, /* GL_BUMP_ROT_MATRIX_SIZE_ATI */
+ 115, /* GL_BUMP_NUM_TEX_UNITS_ATI */
+ 119, /* GL_BUMP_TEX_UNITS_ATI */
+ 448, /* GL_DUDV_ATI */
+ 447, /* GL_DU8DV8_ATI */
+ 114, /* GL_BUMP_ENVMAP_ATI */
+ 118, /* GL_BUMP_TARGET_ATI */
+ 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 */
+ 420, /* GL_DRAW_BUFFER3 */
+ 423, /* GL_DRAW_BUFFER4 */
+ 426, /* GL_DRAW_BUFFER5 */
+ 429, /* GL_DRAW_BUFFER6 */
+ 432, /* GL_DRAW_BUFFER7 */
+ 435, /* GL_DRAW_BUFFER8 */
+ 438, /* GL_DRAW_BUFFER9 */
+ 397, /* GL_DRAW_BUFFER10 */
+ 400, /* GL_DRAW_BUFFER11 */
+ 403, /* GL_DRAW_BUFFER12 */
+ 406, /* GL_DRAW_BUFFER13 */
+ 409, /* GL_DRAW_BUFFER14 */
+ 412, /* GL_DRAW_BUFFER15 */
+ 82, /* GL_BLEND_EQUATION_ALPHA */
+ 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 */
+ 841, /* GL_MATRIX_INDEX_ARRAY_ARB */
+ 316, /* GL_CURRENT_MATRIX_INDEX_ARB */
+ 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 */
+ 1643, /* GL_TEXTURE_COMPARE_MODE */
+ 1641, /* GL_TEXTURE_COMPARE_FUNC */
+ 242, /* GL_COMPARE_R_TO_TEXTURE */
+ 1155, /* GL_POINT_SPRITE */
+ 296, /* GL_COORD_REPLACE */
+ 1159, /* GL_POINT_SPRITE_R_MODE_NV */
+ 1280, /* GL_QUERY_COUNTER_BITS */
+ 323, /* GL_CURRENT_QUERY */
+ 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 */
+ 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 */
+ 1793, /* GL_VERTEX_ARRAY_BUFFER_BINDING */
+ 1017, /* GL_NORMAL_ARRAY_BUFFER_BINDING */
+ 149, /* GL_COLOR_ARRAY_BUFFER_BINDING */
+ 625, /* GL_INDEX_ARRAY_BUFFER_BINDING */
+ 1656, /* GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING */
+ 457, /* GL_EDGE_FLAG_ARRAY_BUFFER_BINDING */
+ 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 */
+ 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 */
+ 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 */
+ 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 */
- 943, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
- 1373, /* GL_SAMPLES_PASSED */
- 528, /* GL_FRAGMENT_SHADER */
- 1811, /* GL_VERTEX_SHADER */
- 1231, /* GL_PROGRAM_OBJECT_ARB */
- 1405, /* GL_SHADER_OBJECT_ARB */
- 867, /* GL_MAX_FRAGMENT_UNIFORM_COMPONENTS */
- 926, /* GL_MAX_VERTEX_UNIFORM_COMPONENTS */
- 920, /* GL_MAX_VARYING_FLOATS */
- 924, /* GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS */
- 852, /* GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS */
- 1034, /* GL_OBJECT_TYPE_ARB */
- 1407, /* GL_SHADER_TYPE */
- 493, /* GL_FLOAT_VEC2 */
- 495, /* GL_FLOAT_VEC3 */
- 497, /* GL_FLOAT_VEC4 */
- 646, /* GL_INT_VEC2 */
- 648, /* GL_INT_VEC3 */
- 650, /* GL_INT_VEC4 */
- 93, /* GL_BOOL */
- 95, /* GL_BOOL_VEC2 */
- 97, /* GL_BOOL_VEC3 */
- 99, /* GL_BOOL_VEC4 */
- 481, /* GL_FLOAT_MAT2 */
- 485, /* GL_FLOAT_MAT3 */
- 489, /* GL_FLOAT_MAT4 */
- 1364, /* GL_SAMPLER_1D */
- 1366, /* GL_SAMPLER_2D */
- 1368, /* GL_SAMPLER_3D */
- 1369, /* GL_SAMPLER_CUBE */
- 1365, /* GL_SAMPLER_1D_SHADOW */
- 1367, /* GL_SAMPLER_2D_SHADOW */
- 483, /* GL_FLOAT_MAT2x3 */
- 484, /* GL_FLOAT_MAT2x4 */
- 487, /* GL_FLOAT_MAT3x2 */
- 488, /* GL_FLOAT_MAT3x4 */
- 491, /* GL_FLOAT_MAT4x2 */
- 492, /* GL_FLOAT_MAT4x3 */
- 341, /* GL_DELETE_STATUS */
- 243, /* GL_COMPILE_STATUS */
- 701, /* GL_LINK_STATUS */
- 1759, /* GL_VALIDATE_STATUS */
- 631, /* GL_INFO_LOG_LENGTH */
- 55, /* GL_ATTACHED_SHADERS */
+ 951, /* GL_MIRROR_CLAMP_TO_BORDER_EXT */
+ 1384, /* GL_SAMPLES_PASSED */
+ 109, /* GL_BUFFER_SERIALIZED_MODIFY_APPLE */
+ 104, /* GL_BUFFER_FLUSHING_UNMAP_APPLE */
+ 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 */
+ 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 */
+ 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 */
- 1406, /* GL_SHADER_SOURCE_LENGTH */
+ 1417, /* GL_SHADER_SOURCE_LENGTH */
15, /* GL_ACTIVE_ATTRIBUTES */
16, /* GL_ACTIVE_ATTRIBUTE_MAX_LENGTH */
- 530, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
- 1409, /* GL_SHADING_LANGUAGE_VERSION */
- 318, /* GL_CURRENT_PROGRAM */
- 1083, /* GL_PALETTE4_RGB8_OES */
- 1085, /* GL_PALETTE4_RGBA8_OES */
- 1081, /* GL_PALETTE4_R5_G6_B5_OES */
- 1084, /* GL_PALETTE4_RGBA4_OES */
- 1082, /* GL_PALETTE4_RGB5_A1_OES */
- 1088, /* GL_PALETTE8_RGB8_OES */
- 1090, /* GL_PALETTE8_RGBA8_OES */
- 1086, /* GL_PALETTE8_R5_G6_B5_OES */
- 1089, /* GL_PALETTE8_RGBA4_OES */
- 1087, /* GL_PALETTE8_RGB5_A1_OES */
- 613, /* GL_IMPLEMENTATION_COLOR_READ_TYPE_OES */
- 612, /* GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES */
- 1744, /* GL_UNSIGNED_NORMALIZED */
- 1590, /* GL_TEXTURE_1D_ARRAY_EXT */
- 1252, /* GL_PROXY_TEXTURE_1D_ARRAY_EXT */
- 1592, /* GL_TEXTURE_2D_ARRAY_EXT */
- 1255, /* GL_PROXY_TEXTURE_2D_ARRAY_EXT */
- 1598, /* GL_TEXTURE_BINDING_1D_ARRAY_EXT */
- 1600, /* GL_TEXTURE_BINDING_2D_ARRAY_EXT */
- 1461, /* GL_SRGB */
- 1462, /* GL_SRGB8 */
- 1464, /* GL_SRGB_ALPHA */
- 1463, /* GL_SRGB8_ALPHA8 */
- 1421, /* GL_SLUMINANCE_ALPHA */
- 1420, /* GL_SLUMINANCE8_ALPHA8 */
- 1418, /* GL_SLUMINANCE */
- 1419, /* GL_SLUMINANCE8 */
- 264, /* GL_COMPRESSED_SRGB */
- 265, /* GL_COMPRESSED_SRGB_ALPHA */
- 262, /* GL_COMPRESSED_SLUMINANCE */
- 263, /* GL_COMPRESSED_SLUMINANCE_ALPHA */
- 1148, /* GL_POINT_SPRITE_COORD_ORIGIN */
- 709, /* GL_LOWER_LEFT */
- 1756, /* GL_UPPER_LEFT */
- 1484, /* GL_STENCIL_BACK_REF */
- 1485, /* GL_STENCIL_BACK_VALUE_MASK */
- 1486, /* GL_STENCIL_BACK_WRITEMASK */
- 437, /* GL_DRAW_FRAMEBUFFER_BINDING_EXT */
- 1298, /* GL_RENDERBUFFER_BINDING_EXT */
- 1279, /* GL_READ_FRAMEBUFFER */
- 436, /* GL_DRAW_FRAMEBUFFER */
- 1280, /* GL_READ_FRAMEBUFFER_BINDING_EXT */
- 1308, /* GL_RENDERBUFFER_SAMPLES */
- 540, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE */
- 538, /* GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME */
- 549, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL */
- 545, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE */
- 547, /* GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER */
- 552, /* GL_FRAMEBUFFER_COMPLETE */
- 556, /* GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT */
- 562, /* GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT */
- 560, /* GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT */
- 558, /* GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT */
- 561, /* GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT */
- 559, /* GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT */
- 565, /* GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT */
- 568, /* GL_FRAMEBUFFER_UNSUPPORTED */
- 566, /* GL_FRAMEBUFFER_STATUS_ERROR_EXT */
- 849, /* GL_MAX_COLOR_ATTACHMENTS_EXT */
- 152, /* GL_COLOR_ATTACHMENT0 */
- 154, /* GL_COLOR_ATTACHMENT1 */
- 168, /* GL_COLOR_ATTACHMENT2 */
- 170, /* GL_COLOR_ATTACHMENT3 */
- 172, /* GL_COLOR_ATTACHMENT4 */
- 174, /* GL_COLOR_ATTACHMENT5 */
- 176, /* GL_COLOR_ATTACHMENT6 */
- 178, /* GL_COLOR_ATTACHMENT7 */
- 180, /* GL_COLOR_ATTACHMENT8 */
- 182, /* GL_COLOR_ATTACHMENT9 */
- 155, /* GL_COLOR_ATTACHMENT10 */
- 157, /* GL_COLOR_ATTACHMENT11 */
- 159, /* GL_COLOR_ATTACHMENT12 */
- 161, /* GL_COLOR_ATTACHMENT13 */
- 163, /* GL_COLOR_ATTACHMENT14 */
- 165, /* GL_COLOR_ATTACHMENT15 */
- 344, /* GL_DEPTH_ATTACHMENT */
- 1474, /* GL_STENCIL_ATTACHMENT */
- 531, /* GL_FRAMEBUFFER */
- 1296, /* GL_RENDERBUFFER */
- 1310, /* GL_RENDERBUFFER_WIDTH */
- 1303, /* GL_RENDERBUFFER_HEIGHT */
- 1305, /* GL_RENDERBUFFER_INTERNAL_FORMAT */
- 1497, /* GL_STENCIL_INDEX_EXT */
- 1494, /* GL_STENCIL_INDEX1_EXT */
- 1495, /* GL_STENCIL_INDEX4_EXT */
- 1496, /* GL_STENCIL_INDEX8_EXT */
- 1493, /* GL_STENCIL_INDEX16_EXT */
- 1307, /* GL_RENDERBUFFER_RED_SIZE */
- 1302, /* GL_RENDERBUFFER_GREEN_SIZE */
- 1299, /* GL_RENDERBUFFER_BLUE_SIZE */
- 1297, /* GL_RENDERBUFFER_ALPHA_SIZE */
- 1300, /* GL_RENDERBUFFER_DEPTH_SIZE */
- 1309, /* GL_RENDERBUFFER_STENCIL_SIZE */
- 564, /* GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE */
- 905, /* GL_MAX_SAMPLES */
- 1266, /* GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT */
- 478, /* GL_FIRST_VERTEX_CONVENTION_EXT */
- 661, /* GL_LAST_VERTEX_CONVENTION_EXT */
- 1245, /* GL_PROVOKING_VERTEX_EXT */
- 298, /* GL_COPY_READ_BUFFER */
- 299, /* GL_COPY_WRITE_BUFFER */
- 1357, /* GL_RGBA_SNORM */
- 1353, /* GL_RGBA8_SNORM */
- 1414, /* GL_SIGNED_NORMALIZED */
- 463, /* GL_EVAL_BIT */
- 1277, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
- 703, /* GL_LIST_BIT */
- 1606, /* GL_TEXTURE_BIT */
- 1388, /* GL_SCISSOR_BIT */
+ 536, /* GL_FRAGMENT_SHADER_DERIVATIVE_HINT */
+ 1420, /* GL_SHADING_LANGUAGE_VERSION */
+ 322, /* GL_CURRENT_PROGRAM */
+ 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 */
+ 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 */
+ 1309, /* GL_RENDERBUFFER_BINDING_EXT */
+ 1290, /* GL_READ_FRAMEBUFFER */
+ 441, /* GL_DRAW_FRAMEBUFFER */
+ 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 */
+ 173, /* GL_COLOR_ATTACHMENT3 */
+ 175, /* GL_COLOR_ATTACHMENT4 */
+ 177, /* GL_COLOR_ATTACHMENT5 */
+ 179, /* GL_COLOR_ATTACHMENT6 */
+ 181, /* GL_COLOR_ATTACHMENT7 */
+ 183, /* GL_COLOR_ATTACHMENT8 */
+ 185, /* GL_COLOR_ATTACHMENT9 */
+ 158, /* GL_COLOR_ATTACHMENT10 */
+ 160, /* GL_COLOR_ATTACHMENT11 */
+ 162, /* GL_COLOR_ATTACHMENT12 */
+ 164, /* GL_COLOR_ATTACHMENT13 */
+ 166, /* GL_COLOR_ATTACHMENT14 */
+ 168, /* GL_COLOR_ATTACHMENT15 */
+ 348, /* GL_DEPTH_ATTACHMENT */
+ 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 */
+ 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 */
+ 1732, /* GL_TIMEOUT_EXPIRED */
+ 270, /* GL_CONDITION_SATISFIED */
+ 1844, /* GL_WAIT_FAILED */
+ 468, /* GL_EVAL_BIT */
+ 1288, /* GL_RASTER_POSITION_UNCLIPPED_IBM */
+ 710, /* GL_LIST_BIT */
+ 1627, /* GL_TEXTURE_BIT */
+ 1399, /* GL_SCISSOR_BIT */
29, /* GL_ALL_ATTRIB_BITS */
- 990, /* GL_MULTISAMPLE_BIT */
+ 998, /* GL_MULTISAMPLE_BIT */
30, /* GL_ALL_CLIENT_ATTRIB_BITS */
+ 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 57c1e117c8..4c6139985f 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 c60b58a492..6b11aceb5c 100644
--- a/src/mesa/main/extensions.c
+++ b/src/mesa/main/extensions.c
@@ -47,7 +47,9 @@ static const struct {
} default_extensions[] = {
{ OFF, "GL_ARB_copy_buffer", F(ARB_copy_buffer) },
{ OFF, "GL_ARB_depth_texture", F(ARB_depth_texture) },
+ { OFF, "GL_ARB_depth_clamp", F(ARB_depth_clamp) },
{ ON, "GL_ARB_draw_buffers", F(ARB_draw_buffers) },
+ { OFF, "GL_ARB_draw_elements_base_vertex", F(ARB_draw_elements_base_vertex) },
{ OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) },
{ OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) },
{ OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) },
@@ -61,11 +63,14 @@ 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) },
{ OFF, "GL_ARB_shading_language_120", F(ARB_shading_language_120) },
{ OFF, "GL_ARB_shadow", F(ARB_shadow) },
{ OFF, "GL_ARB_shadow_ambient", F(ARB_shadow_ambient) },
+ { OFF, "GL_ARB_sync", F(ARB_sync) },
{ OFF, "GL_ARB_texture_border_clamp", F(ARB_texture_border_clamp) },
{ ON, "GL_ARB_texture_compression", F(ARB_texture_compression) },
{ OFF, "GL_ARB_texture_cube_map", F(ARB_texture_cube_map) },
@@ -78,6 +83,7 @@ static const struct {
{ OFF, "GL_ARB_texture_non_power_of_two", F(ARB_texture_non_power_of_two)},
{ OFF, "GL_ARB_texture_rectangle", F(NV_texture_rectangle) },
{ ON, "GL_ARB_transpose_matrix", F(ARB_transpose_matrix) },
+ { OFF, "GL_ARB_vertex_array_bgra", F(EXT_vertex_array_bgra) },
{ OFF, "GL_ARB_vertex_array_object", F(ARB_vertex_array_object) },
{ ON, "GL_ARB_vertex_buffer_object", F(ARB_vertex_buffer_object) },
{ OFF, "GL_ARB_vertex_program", F(ARB_vertex_program) },
@@ -159,6 +165,7 @@ static const struct {
{ OFF, "GL_MESA_ycbcr_texture", F(MESA_ycbcr_texture) },
{ ON, "GL_MESA_window_pos", F(ARB_window_pos) },
{ OFF, "GL_NV_blend_square", F(NV_blend_square) },
+ { OFF, "GL_NV_depth_clamp", F(ARB_depth_clamp) },
{ OFF, "GL_NV_fragment_program", F(NV_fragment_program) },
{ ON, "GL_NV_light_max_exponent", F(NV_light_max_exponent) },
{ OFF, "GL_NV_point_sprite", F(NV_point_sprite) },
@@ -189,8 +196,10 @@ void
_mesa_enable_sw_extensions(GLcontext *ctx)
{
ctx->Extensions.ARB_copy_buffer = GL_TRUE;
+ ctx->Extensions.ARB_depth_clamp = GL_TRUE;
ctx->Extensions.ARB_depth_texture = GL_TRUE;
/*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/
+ ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE;
#if FEATURE_ARB_fragment_program
ctx->Extensions.ARB_fragment_program = GL_TRUE;
ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE;
@@ -238,6 +247,9 @@ _mesa_enable_sw_extensions(GLcontext *ctx)
#if FEATURE_ARB_vertex_buffer_object
/*ctx->Extensions.ARB_vertex_buffer_object = GL_TRUE;*/
#endif
+#if FEATURE_ARB_sync
+ ctx->Extensions.ARB_sync = GL_TRUE;
+#endif
ctx->Extensions.APPLE_vertex_array_object = GL_TRUE;
ctx->Extensions.ATI_envmap_bumpmap = GL_TRUE;
#if FEATURE_ATI_fragment_shader
@@ -413,6 +425,7 @@ _mesa_enable_2_0_extensions(GLcontext *ctx)
ctx->Extensions.ARB_fragment_shader = GL_TRUE;
#endif
ctx->Extensions.ARB_point_sprite = GL_TRUE;
+ ctx->Extensions.EXT_blend_equation_separate = GL_TRUE;
ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE;
#if FEATURE_ARB_shader_objects
ctx->Extensions.ARB_shader_objects = GL_TRUE;
diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c
index 83301f1e62..13f49da5a7 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,14 +312,31 @@ _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
+}
+
+
+/**
+ * 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,
@@ -417,21 +438,22 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
if (format == GL_COLOR) {
if (att->Renderbuffer->_BaseFormat != GL_RGB &&
att->Renderbuffer->_BaseFormat != GL_RGBA) {
- ASSERT(att->Renderbuffer->RedBits);
- ASSERT(att->Renderbuffer->GreenBits);
- ASSERT(att->Renderbuffer->BlueBits);
att_incomplete("bad renderbuffer color format");
att->Complete = GL_FALSE;
return;
}
+ ASSERT(att->Renderbuffer->RedBits);
+ ASSERT(att->Renderbuffer->GreenBits);
+ ASSERT(att->Renderbuffer->BlueBits);
}
else if (format == GL_DEPTH) {
- ASSERT(att->Renderbuffer->DepthBits);
if (att->Renderbuffer->_BaseFormat == GL_DEPTH_COMPONENT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->DepthBits);
/* OK */
}
else {
@@ -442,12 +464,13 @@ test_attachment_completeness(const GLcontext *ctx, GLenum format,
}
else {
assert(format == GL_STENCIL);
- ASSERT(att->Renderbuffer->StencilBits);
if (att->Renderbuffer->_BaseFormat == GL_STENCIL_INDEX) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else if (ctx->Extensions.EXT_packed_depth_stencil &&
att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL_EXT) {
+ ASSERT(att->Renderbuffer->StencilBits);
/* OK */
}
else {
@@ -466,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
@@ -1951,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);
@@ -2038,7 +2047,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_STENCIL_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_StencilBuffer;
struct gl_renderbuffer *drawRb = drawFb->_StencilBuffer;
- if (readRb->StencilBits != drawRb->StencilBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->StencilBits != drawRb->StencilBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(stencil buffer size mismatch");
return;
@@ -2048,7 +2059,9 @@ _mesa_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
if (mask & GL_DEPTH_BUFFER_BIT) {
struct gl_renderbuffer *readRb = readFb->_DepthBuffer;
struct gl_renderbuffer *drawRb = drawFb->_DepthBuffer;
- if (readRb->DepthBits != drawRb->DepthBits) {
+ if (!readRb ||
+ !drawRb ||
+ readRb->DepthBits != drawRb->DepthBits) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBlitFramebufferEXT(depth buffer size mismatch");
return;
diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c
index 80dde4b5aa..356476e35a 100644
--- a/src/mesa/main/ffvertex_prog.c
+++ b/src/mesa/main/ffvertex_prog.c
@@ -46,6 +46,9 @@
#include "shader/prog_statevars.h"
+/** Max of number of lights and texture coord units */
+#define NUM_UNITS MAX2(MAX_TEXTURE_COORD_UNITS, MAX_LIGHTS)
+
struct state_key {
unsigned light_color_material_mask:12;
unsigned light_global_enabled:1;
@@ -77,7 +80,7 @@ struct state_key {
unsigned texgen_mode1:4;
unsigned texgen_mode2:4;
unsigned texgen_mode3:4;
- } unit[8];
+ } unit[NUM_UNITS];
};
@@ -1306,7 +1309,9 @@ static void build_fog( struct tnl_program *p )
input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X);
}
+ /* result.fog = {abs(f),0,0,1}; */
emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input);
+ emit_op1(p, OPCODE_MOV, fog, WRITEMASK_YZW, get_identity_param(p));
}
diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c
index 50a61bd84b..4323d3db82 100644
--- a/src/mesa/main/fog.c
+++ b/src/mesa/main/fog.c
@@ -67,7 +67,7 @@ _mesa_Fogiv(GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in _mesa_Fogfv */
- ;
+ ASSIGN_4V(p, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_Fogfv(pname, p);
}
diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c
index 5a13c88a7a..dc79b8ca61 100644
--- a/src/mesa/main/framebuffer.c
+++ b/src/mesa/main/framebuffer.c
@@ -817,7 +817,7 @@ _mesa_update_framebuffer(GLcontext *ctx)
/**
* Check if the renderbuffer for a read operation (glReadPixels, glCopyPixels,
- * glCopyTex[Sub]Image, etc. exists.
+ * glCopyTex[Sub]Image, etc) exists.
* \param format a basic image format such as GL_RGB, GL_RGBA, GL_ALPHA,
* GL_DEPTH_COMPONENT, etc. or GL_COLOR, GL_DEPTH, GL_STENCIL.
* \return GL_TRUE if buffer exists, GL_FALSE otherwise
@@ -825,8 +825,12 @@ _mesa_update_framebuffer(GLcontext *ctx)
GLboolean
_mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->ReadBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->ReadBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->ReadBuffer);
+ }
if (ctx->ReadBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -850,10 +854,8 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
if (ctx->ReadBuffer->_ColorReadBuffer == NULL) {
return GL_FALSE;
}
- /* XXX enable this post 6.5 release:
ASSERT(ctx->ReadBuffer->_ColorReadBuffer->RedBits > 0 ||
ctx->ReadBuffer->_ColorReadBuffer->IndexBits > 0);
- */
break;
case GL_DEPTH:
case GL_DEPTH_COMPONENT:
@@ -891,13 +893,17 @@ _mesa_source_buffer_exists(GLcontext *ctx, GLenum format)
/**
* As above, but for drawing operations.
- * XXX code do some code merging w/ above function.
+ * XXX could do some code merging w/ above function.
*/
GLboolean
_mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
{
- const struct gl_renderbuffer_attachment *att
- = ctx->ReadBuffer->Attachment;
+ const struct gl_renderbuffer_attachment *att = ctx->DrawBuffer->Attachment;
+
+ /* If we don't know the framebuffer status, update it now */
+ if (ctx->DrawBuffer->_Status == 0) {
+ _mesa_test_framebuffer_completeness(ctx, ctx->DrawBuffer);
+ }
if (ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) {
return GL_FALSE;
@@ -918,7 +924,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
case GL_BGRA:
case GL_ABGR_EXT:
case GL_COLOR_INDEX:
- /* nothing special */
+ /* Nothing special since GL_DRAW_BUFFER could be GL_NONE. */
/* Could assert that colorbuffer has RedBits > 0 */
break;
case GL_DEPTH:
@@ -945,7 +951,7 @@ _mesa_dest_buffer_exists(GLcontext *ctx, GLenum format)
break;
default:
_mesa_problem(ctx,
- "Unexpected format 0x%x in _mesa_source_buffer_exists",
+ "Unexpected format 0x%x in _mesa_dest_buffer_exists",
format);
return GL_FALSE;
}
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index 516159bbf2..a6e004a816 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -19,9 +19,15 @@
#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_INT(I) ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
+
#define BOOLEAN_TO_INT(B) ( (GLint) (B) )
+#define BOOLEAN_TO_INT64(B) ( (GLint64) (B) )
#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F )
+#define ENUM_TO_INT64(E) ( (GLint64) (E) )
+
/*
* Check if named extension is enabled, if not generate error and return.
@@ -276,6 +282,7 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
case GL_CURRENT_TEXTURE_COORDS:
{
const GLuint texUnit = ctx->Texture.CurrentUnit;
+ FLUSH_CURRENT(ctx, 0);
params[0] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
params[1] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
params[2] = FLOAT_TO_BOOLEAN(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
@@ -1715,6 +1722,10 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
params[0] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMin);
params[1] = FLOAT_TO_BOOLEAN(ctx->Depth.BoundsMax);
break;
+ case GL_DEPTH_CLAMP:
+ CHECK_EXT1(ARB_depth_clamp, "GetBooleanv");
+ params[0] = ctx->Transform.DepthClamp;
+ break;
case GL_MAX_DRAW_BUFFERS_ARB:
params[0] = INT_TO_BOOLEAN(ctx->Const.MaxDrawBuffers);
break;
@@ -1879,6 +1890,14 @@ _mesa_GetBooleanv( GLenum pname, GLboolean *params )
CHECK_EXT1(APPLE_vertex_array_object, "GetBooleanv");
params[0] = INT_TO_BOOLEAN(ctx->Array.ArrayObj->Name);
break;
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXT1(ARB_seamless_cube_map, "GetBooleanv");
+ params[0] = ctx->Texture.CubeMapSeamless;
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ CHECK_EXT1(ARB_sync, "GetBooleanv");
+ params[0] = INT64_TO_BOOLEAN(ctx->Const.MaxServerWaitTimeout);
+ break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetBooleanv(pname=0x%x)", pname);
}
@@ -2098,6 +2117,7 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
case GL_CURRENT_TEXTURE_COORDS:
{
const GLuint texUnit = ctx->Texture.CurrentUnit;
+ FLUSH_CURRENT(ctx, 0);
params[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0];
params[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1];
params[2] = ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2];
@@ -3537,6 +3557,10 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
params[0] = ctx->Depth.BoundsMin;
params[1] = ctx->Depth.BoundsMax;
break;
+ case GL_DEPTH_CLAMP:
+ CHECK_EXT1(ARB_depth_clamp, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Transform.DepthClamp);
+ break;
case GL_MAX_DRAW_BUFFERS_ARB:
params[0] = (GLfloat)(ctx->Const.MaxDrawBuffers);
break;
@@ -3701,6 +3725,14 @@ _mesa_GetFloatv( GLenum pname, GLfloat *params )
CHECK_EXT1(APPLE_vertex_array_object, "GetFloatv");
params[0] = (GLfloat)(ctx->Array.ArrayObj->Name);
break;
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXT1(ARB_seamless_cube_map, "GetFloatv");
+ params[0] = BOOLEAN_TO_FLOAT(ctx->Texture.CubeMapSeamless);
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ CHECK_EXT1(ARB_sync, "GetFloatv");
+ params[0] = (GLfloat)(ctx->Const.MaxServerWaitTimeout);
+ break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetFloatv(pname=0x%x)", pname);
}
@@ -3920,6 +3952,7 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
case GL_CURRENT_TEXTURE_COORDS:
{
const GLuint texUnit = ctx->Texture.CurrentUnit;
+ FLUSH_CURRENT(ctx, 0);
params[0] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
params[1] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
params[2] = IROUND(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
@@ -5359,6 +5392,10 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
params[0] = IROUND(ctx->Depth.BoundsMin);
params[1] = IROUND(ctx->Depth.BoundsMax);
break;
+ case GL_DEPTH_CLAMP:
+ CHECK_EXT1(ARB_depth_clamp, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Transform.DepthClamp);
+ break;
case GL_MAX_DRAW_BUFFERS_ARB:
params[0] = ctx->Const.MaxDrawBuffers;
break;
@@ -5523,11 +5560,1856 @@ _mesa_GetIntegerv( GLenum pname, GLint *params )
CHECK_EXT1(APPLE_vertex_array_object, "GetIntegerv");
params[0] = ctx->Array.ArrayObj->Name;
break;
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXT1(ARB_seamless_cube_map, "GetIntegerv");
+ params[0] = BOOLEAN_TO_INT(ctx->Texture.CubeMapSeamless);
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ CHECK_EXT1(ARB_sync, "GetIntegerv");
+ params[0] = INT64_TO_INT(ctx->Const.MaxServerWaitTimeout);
+ break;
default:
_mesa_error(ctx, GL_INVALID_ENUM, "glGetIntegerv(pname=0x%x)", pname);
}
}
+#if FEATURE_ARB_sync
+void GLAPIENTRY
+_mesa_GetInteger64v( GLenum pname, GLint64 *params )
+{
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!params)
+ return;
+
+ if (ctx->NewState)
+ _mesa_update_state(ctx);
+
+ if (ctx->Driver.GetInteger64v &&
+ ctx->Driver.GetInteger64v(ctx, pname, params))
+ return;
+
+ switch (pname) {
+ case GL_ACCUM_RED_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumRedBits;
+ break;
+ case GL_ACCUM_GREEN_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumGreenBits;
+ break;
+ case GL_ACCUM_BLUE_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumBlueBits;
+ break;
+ case GL_ACCUM_ALPHA_BITS:
+ params[0] = ctx->DrawBuffer->Visual.accumAlphaBits;
+ break;
+ case GL_ACCUM_CLEAR_VALUE:
+ params[0] = FLOAT_TO_INT64(ctx->Accum.ClearColor[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Accum.ClearColor[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Accum.ClearColor[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Accum.ClearColor[3]);
+ break;
+ case GL_ALPHA_BIAS:
+ params[0] = IROUND64(ctx->Pixel.AlphaBias);
+ break;
+ case GL_ALPHA_BITS:
+ params[0] = ctx->DrawBuffer->Visual.alphaBits;
+ break;
+ case GL_ALPHA_SCALE:
+ params[0] = IROUND64(ctx->Pixel.AlphaScale);
+ break;
+ case GL_ALPHA_TEST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Color.AlphaEnabled);
+ break;
+ case GL_ALPHA_TEST_FUNC:
+ params[0] = ENUM_TO_INT64(ctx->Color.AlphaFunc);
+ break;
+ case GL_ALPHA_TEST_REF:
+ params[0] = FLOAT_TO_INT64(ctx->Color.AlphaRef);
+ break;
+ case GL_ATTRIB_STACK_DEPTH:
+ params[0] = ctx->AttribStackDepth;
+ break;
+ case GL_AUTO_NORMAL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.AutoNormal);
+ break;
+ case GL_AUX_BUFFERS:
+ params[0] = ctx->DrawBuffer->Visual.numAuxBuffers;
+ break;
+ case GL_BLEND:
+ params[0] = BOOLEAN_TO_INT64(ctx->Color.BlendEnabled);
+ break;
+ case GL_BLEND_DST:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_SRC_RGB_EXT:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendSrcRGB);
+ break;
+ case GL_BLEND_DST_RGB_EXT:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendDstRGB);
+ break;
+ case GL_BLEND_SRC_ALPHA_EXT:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendSrcA);
+ break;
+ case GL_BLEND_DST_ALPHA_EXT:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendDstA);
+ break;
+ case GL_BLEND_EQUATION:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendEquationRGB );
+ break;
+ case GL_BLEND_EQUATION_ALPHA_EXT:
+ params[0] = ENUM_TO_INT64(ctx->Color.BlendEquationA );
+ break;
+ case GL_BLEND_COLOR_EXT:
+ params[0] = FLOAT_TO_INT64(ctx->Color.BlendColor[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Color.BlendColor[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Color.BlendColor[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Color.BlendColor[3]);
+ break;
+ case GL_BLUE_BIAS:
+ params[0] = IROUND64(ctx->Pixel.BlueBias);
+ break;
+ case GL_BLUE_BITS:
+ params[0] = ctx->DrawBuffer->Visual.blueBits;
+ break;
+ case GL_BLUE_SCALE:
+ params[0] = IROUND64(ctx->Pixel.BlueScale);
+ break;
+ case GL_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = ctx->ClientAttribStackDepth;
+ break;
+ case GL_CLIP_PLANE0:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 0) & 1);
+ break;
+ case GL_CLIP_PLANE1:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 1) & 1);
+ break;
+ case GL_CLIP_PLANE2:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 2) & 1);
+ break;
+ case GL_CLIP_PLANE3:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 3) & 1);
+ break;
+ case GL_CLIP_PLANE4:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 4) & 1);
+ break;
+ case GL_CLIP_PLANE5:
+ params[0] = BOOLEAN_TO_INT64((ctx->Transform.ClipPlanesEnabled >> 5) & 1);
+ break;
+ case GL_COLOR_CLEAR_VALUE:
+ params[0] = FLOAT_TO_INT64(ctx->Color.ClearColor[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Color.ClearColor[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Color.ClearColor[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Color.ClearColor[3]);
+ break;
+ case GL_COLOR_MATERIAL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.ColorMaterialEnabled);
+ break;
+ case GL_COLOR_MATERIAL_FACE:
+ params[0] = ENUM_TO_INT64(ctx->Light.ColorMaterialFace);
+ break;
+ case GL_COLOR_MATERIAL_PARAMETER:
+ params[0] = ENUM_TO_INT64(ctx->Light.ColorMaterialMode);
+ break;
+ case GL_COLOR_WRITEMASK:
+ params[0] = ctx->Color.ColorMask[RCOMP] ? 1 : 0;
+ params[1] = ctx->Color.ColorMask[GCOMP] ? 1 : 0;
+ params[2] = ctx->Color.ColorMask[BCOMP] ? 1 : 0;
+ params[3] = ctx->Color.ColorMask[ACOMP] ? 1 : 0;
+ break;
+ case GL_CULL_FACE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.CullFlag);
+ break;
+ case GL_CULL_FACE_MODE:
+ params[0] = ENUM_TO_INT64(ctx->Polygon.CullFaceMode);
+ break;
+ case GL_CURRENT_COLOR:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]);
+ params[1] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]);
+ params[2] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]);
+ params[3] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]);
+ }
+ break;
+ case GL_CURRENT_INDEX:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_COLOR_INDEX][0]);
+ }
+ break;
+ case GL_CURRENT_NORMAL:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][0]);
+ params[1] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][1]);
+ params[2] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_NORMAL][2]);
+ }
+ break;
+ case GL_CURRENT_RASTER_COLOR:
+ params[0] = FLOAT_TO_INT64(ctx->Current.RasterColor[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Current.RasterColor[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Current.RasterColor[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Current.RasterColor[3]);
+ break;
+ case GL_CURRENT_RASTER_DISTANCE:
+ params[0] = IROUND64(ctx->Current.RasterDistance);
+ break;
+ case GL_CURRENT_RASTER_INDEX:
+ params[0] = IROUND64(ctx->Current.RasterIndex);
+ break;
+ case GL_CURRENT_RASTER_POSITION:
+ params[0] = IROUND64(ctx->Current.RasterPos[0]);
+ params[1] = IROUND64(ctx->Current.RasterPos[1]);
+ params[2] = IROUND64(ctx->Current.RasterPos[2]);
+ params[3] = IROUND64(ctx->Current.RasterPos[3]);
+ break;
+ case GL_CURRENT_RASTER_SECONDARY_COLOR:
+ params[0] = FLOAT_TO_INT64(ctx->Current.RasterSecondaryColor[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Current.RasterSecondaryColor[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Current.RasterSecondaryColor[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Current.RasterSecondaryColor[3]);
+ break;
+ case GL_CURRENT_RASTER_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ params[0] = IROUND64(ctx->Current.RasterTexCoords[texUnit][0]);
+ params[1] = IROUND64(ctx->Current.RasterTexCoords[texUnit][1]);
+ params[2] = IROUND64(ctx->Current.RasterTexCoords[texUnit][2]);
+ params[3] = IROUND64(ctx->Current.RasterTexCoords[texUnit][3]);
+ }
+ break;
+ case GL_CURRENT_RASTER_POSITION_VALID:
+ params[0] = BOOLEAN_TO_INT64(ctx->Current.RasterPosValid);
+ break;
+ case GL_CURRENT_TEXTURE_COORDS:
+ {
+ const GLuint texUnit = ctx->Texture.CurrentUnit;
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][0]);
+ params[1] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]);
+ params[2] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]);
+ params[3] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]);
+ }
+ break;
+ case GL_DEPTH_BIAS:
+ params[0] = IROUND64(ctx->Pixel.DepthBias);
+ break;
+ case GL_DEPTH_BITS:
+ params[0] = ctx->DrawBuffer->Visual.depthBits;
+ break;
+ case GL_DEPTH_CLEAR_VALUE:
+ params[0] = FLOAT_TO_INT64(((GLfloat) ctx->Depth.Clear));
+ break;
+ case GL_DEPTH_FUNC:
+ params[0] = ENUM_TO_INT64(ctx->Depth.Func);
+ break;
+ case GL_DEPTH_RANGE:
+ params[0] = FLOAT_TO_INT64(ctx->Viewport.Near);
+ params[1] = FLOAT_TO_INT64(ctx->Viewport.Far);
+ break;
+ case GL_DEPTH_SCALE:
+ params[0] = IROUND64(ctx->Pixel.DepthScale);
+ break;
+ case GL_DEPTH_TEST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Depth.Test);
+ break;
+ case GL_DEPTH_WRITEMASK:
+ params[0] = BOOLEAN_TO_INT64(ctx->Depth.Mask);
+ break;
+ case GL_DITHER:
+ params[0] = BOOLEAN_TO_INT64(ctx->Color.DitherFlag);
+ break;
+ case GL_DOUBLEBUFFER:
+ params[0] = BOOLEAN_TO_INT64(ctx->DrawBuffer->Visual.doubleBufferMode);
+ break;
+ case GL_DRAW_BUFFER:
+ params[0] = ENUM_TO_INT64(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_EDGE_FLAG:
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = BOOLEAN_TO_INT64((ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0] == 1.0));
+ }
+ break;
+ case GL_FEEDBACK_BUFFER_SIZE:
+ params[0] = ctx->Feedback.BufferSize;
+ break;
+ case GL_FEEDBACK_BUFFER_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Feedback.Type);
+ break;
+ case GL_FOG:
+ params[0] = BOOLEAN_TO_INT64(ctx->Fog.Enabled);
+ break;
+ case GL_FOG_COLOR:
+ params[0] = FLOAT_TO_INT64(ctx->Fog.Color[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Fog.Color[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Fog.Color[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Fog.Color[3]);
+ break;
+ case GL_FOG_DENSITY:
+ params[0] = IROUND64(ctx->Fog.Density);
+ break;
+ case GL_FOG_END:
+ params[0] = IROUND64(ctx->Fog.End);
+ break;
+ case GL_FOG_HINT:
+ params[0] = ENUM_TO_INT64(ctx->Hint.Fog);
+ break;
+ case GL_FOG_INDEX:
+ params[0] = IROUND64(ctx->Fog.Index);
+ break;
+ case GL_FOG_MODE:
+ params[0] = ENUM_TO_INT64(ctx->Fog.Mode);
+ break;
+ case GL_FOG_START:
+ params[0] = IROUND64(ctx->Fog.Start);
+ break;
+ case GL_FRONT_FACE:
+ params[0] = ENUM_TO_INT64(ctx->Polygon.FrontFace);
+ break;
+ case GL_GREEN_BIAS:
+ params[0] = IROUND64(ctx->Pixel.GreenBias);
+ break;
+ case GL_GREEN_BITS:
+ params[0] = ctx->DrawBuffer->Visual.greenBits;
+ break;
+ case GL_GREEN_SCALE:
+ params[0] = IROUND64(ctx->Pixel.GreenScale);
+ break;
+ case GL_INDEX_BITS:
+ params[0] = ctx->DrawBuffer->Visual.indexBits;
+ break;
+ case GL_INDEX_CLEAR_VALUE:
+ params[0] = ctx->Color.ClearIndex;
+ break;
+ case GL_INDEX_MODE:
+ params[0] = BOOLEAN_TO_INT64(!ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_INDEX_OFFSET:
+ params[0] = ctx->Pixel.IndexOffset;
+ break;
+ case GL_INDEX_SHIFT:
+ params[0] = ctx->Pixel.IndexShift;
+ break;
+ case GL_INDEX_WRITEMASK:
+ params[0] = ctx->Color.IndexMask;
+ break;
+ case GL_LIGHT0:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[0].Enabled);
+ break;
+ case GL_LIGHT1:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[1].Enabled);
+ break;
+ case GL_LIGHT2:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[2].Enabled);
+ break;
+ case GL_LIGHT3:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[3].Enabled);
+ break;
+ case GL_LIGHT4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[4].Enabled);
+ break;
+ case GL_LIGHT5:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[5].Enabled);
+ break;
+ case GL_LIGHT6:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[6].Enabled);
+ break;
+ case GL_LIGHT7:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Light[7].Enabled);
+ break;
+ case GL_LIGHTING:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Enabled);
+ break;
+ case GL_LIGHT_MODEL_AMBIENT:
+ params[0] = FLOAT_TO_INT64(ctx->Light.Model.Ambient[0]);
+ params[1] = FLOAT_TO_INT64(ctx->Light.Model.Ambient[1]);
+ params[2] = FLOAT_TO_INT64(ctx->Light.Model.Ambient[2]);
+ params[3] = FLOAT_TO_INT64(ctx->Light.Model.Ambient[3]);
+ break;
+ case GL_LIGHT_MODEL_COLOR_CONTROL:
+ params[0] = ENUM_TO_INT64(ctx->Light.Model.ColorControl);
+ break;
+ case GL_LIGHT_MODEL_LOCAL_VIEWER:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Model.LocalViewer);
+ break;
+ case GL_LIGHT_MODEL_TWO_SIDE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.Model.TwoSide);
+ break;
+ case GL_LINE_SMOOTH:
+ params[0] = BOOLEAN_TO_INT64(ctx->Line.SmoothFlag);
+ break;
+ case GL_LINE_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT64(ctx->Hint.LineSmooth);
+ break;
+ case GL_LINE_STIPPLE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Line.StippleFlag);
+ break;
+ case GL_LINE_STIPPLE_PATTERN:
+ params[0] = ctx->Line.StipplePattern;
+ break;
+ case GL_LINE_STIPPLE_REPEAT:
+ params[0] = ctx->Line.StippleFactor;
+ break;
+ case GL_LINE_WIDTH:
+ params[0] = IROUND64(ctx->Line.Width);
+ break;
+ case GL_LINE_WIDTH_GRANULARITY:
+ params[0] = IROUND64(ctx->Const.LineWidthGranularity);
+ break;
+ case GL_LINE_WIDTH_RANGE:
+ params[0] = IROUND64(ctx->Const.MinLineWidthAA);
+ params[1] = IROUND64(ctx->Const.MaxLineWidthAA);
+ break;
+ case GL_ALIASED_LINE_WIDTH_RANGE:
+ params[0] = IROUND64(ctx->Const.MinLineWidth);
+ params[1] = IROUND64(ctx->Const.MaxLineWidth);
+ break;
+ case GL_LIST_BASE:
+ params[0] = ctx->List.ListBase;
+ break;
+ case GL_LIST_INDEX:
+ params[0] = (ctx->ListState.CurrentList ? ctx->ListState.CurrentList->Name : 0);
+ break;
+ case GL_LIST_MODE:
+ {
+ GLenum mode;
+ if (!ctx->CompileFlag)
+ mode = 0;
+ else if (ctx->ExecuteFlag)
+ mode = GL_COMPILE_AND_EXECUTE;
+ else
+ mode = GL_COMPILE;
+ params[0] = ENUM_TO_INT64(mode);
+ }
+ break;
+ case GL_INDEX_LOGIC_OP:
+ params[0] = BOOLEAN_TO_INT64(ctx->Color.IndexLogicOpEnabled);
+ break;
+ case GL_COLOR_LOGIC_OP:
+ params[0] = BOOLEAN_TO_INT64(ctx->Color.ColorLogicOpEnabled);
+ break;
+ case GL_LOGIC_OP_MODE:
+ params[0] = ENUM_TO_INT64(ctx->Color.LogicOp);
+ break;
+ case GL_MAP1_COLOR_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Color4);
+ break;
+ case GL_MAP1_GRID_DOMAIN:
+ params[0] = IROUND64(ctx->Eval.MapGrid1u1);
+ params[1] = IROUND64(ctx->Eval.MapGrid1u2);
+ break;
+ case GL_MAP1_GRID_SEGMENTS:
+ params[0] = ctx->Eval.MapGrid1un;
+ break;
+ case GL_MAP1_INDEX:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Index);
+ break;
+ case GL_MAP1_NORMAL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Normal);
+ break;
+ case GL_MAP1_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1TextureCoord1);
+ break;
+ case GL_MAP1_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1TextureCoord2);
+ break;
+ case GL_MAP1_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1TextureCoord3);
+ break;
+ case GL_MAP1_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1TextureCoord4);
+ break;
+ case GL_MAP1_VERTEX_3:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Vertex3);
+ break;
+ case GL_MAP1_VERTEX_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Vertex4);
+ break;
+ case GL_MAP2_COLOR_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2Color4);
+ break;
+ case GL_MAP2_GRID_DOMAIN:
+ params[0] = IROUND64(ctx->Eval.MapGrid2u1);
+ params[1] = IROUND64(ctx->Eval.MapGrid2u2);
+ params[2] = IROUND64(ctx->Eval.MapGrid2v1);
+ params[3] = IROUND64(ctx->Eval.MapGrid2v2);
+ break;
+ case GL_MAP2_GRID_SEGMENTS:
+ params[0] = ctx->Eval.MapGrid2un;
+ params[1] = ctx->Eval.MapGrid2vn;
+ break;
+ case GL_MAP2_INDEX:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2Index);
+ break;
+ case GL_MAP2_NORMAL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2Normal);
+ break;
+ case GL_MAP2_TEXTURE_COORD_1:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2TextureCoord1);
+ break;
+ case GL_MAP2_TEXTURE_COORD_2:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2TextureCoord2);
+ break;
+ case GL_MAP2_TEXTURE_COORD_3:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2TextureCoord3);
+ break;
+ case GL_MAP2_TEXTURE_COORD_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2TextureCoord4);
+ break;
+ case GL_MAP2_VERTEX_3:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2Vertex3);
+ break;
+ case GL_MAP2_VERTEX_4:
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map2Vertex4);
+ break;
+ case GL_MAP_COLOR:
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.MapColorFlag);
+ break;
+ case GL_MAP_STENCIL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.MapStencilFlag);
+ break;
+ case GL_MATRIX_MODE:
+ params[0] = ENUM_TO_INT64(ctx->Transform.MatrixMode);
+ break;
+ case GL_MAX_ATTRIB_STACK_DEPTH:
+ params[0] = MAX_ATTRIB_STACK_DEPTH;
+ break;
+ case GL_MAX_CLIENT_ATTRIB_STACK_DEPTH:
+ params[0] = MAX_CLIENT_ATTRIB_STACK_DEPTH;
+ break;
+ case GL_MAX_CLIP_PLANES:
+ params[0] = ctx->Const.MaxClipPlanes;
+ break;
+ case GL_MAX_ELEMENTS_VERTICES:
+ params[0] = ctx->Const.MaxArrayLockSize;
+ break;
+ case GL_MAX_ELEMENTS_INDICES:
+ params[0] = ctx->Const.MaxArrayLockSize;
+ break;
+ case GL_MAX_EVAL_ORDER:
+ params[0] = MAX_EVAL_ORDER;
+ break;
+ case GL_MAX_LIGHTS:
+ params[0] = ctx->Const.MaxLights;
+ break;
+ case GL_MAX_LIST_NESTING:
+ params[0] = MAX_LIST_NESTING;
+ break;
+ case GL_MAX_MODELVIEW_STACK_DEPTH:
+ params[0] = MAX_MODELVIEW_STACK_DEPTH;
+ break;
+ case GL_MAX_NAME_STACK_DEPTH:
+ params[0] = MAX_NAME_STACK_DEPTH;
+ break;
+ case GL_MAX_PIXEL_MAP_TABLE:
+ params[0] = MAX_PIXEL_MAP_TABLE;
+ break;
+ case GL_MAX_PROJECTION_STACK_DEPTH:
+ params[0] = MAX_PROJECTION_STACK_DEPTH;
+ break;
+ case GL_MAX_TEXTURE_SIZE:
+ params[0] = 1 << (ctx->Const.MaxTextureLevels - 1);
+ break;
+ case GL_MAX_3D_TEXTURE_SIZE:
+ params[0] = 1 << (ctx->Const.Max3DTextureLevels - 1);
+ break;
+ case GL_MAX_TEXTURE_STACK_DEPTH:
+ params[0] = MAX_TEXTURE_STACK_DEPTH;
+ break;
+ case GL_MAX_VIEWPORT_DIMS:
+ params[0] = ctx->Const.MaxViewportWidth;
+ params[1] = ctx->Const.MaxViewportHeight;
+ break;
+ case GL_MODELVIEW_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[1]);
+ params[2] = IROUND64(matrix[2]);
+ params[3] = IROUND64(matrix[3]);
+ params[4] = IROUND64(matrix[4]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[6]);
+ params[7] = IROUND64(matrix[7]);
+ params[8] = IROUND64(matrix[8]);
+ params[9] = IROUND64(matrix[9]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[11]);
+ params[12] = IROUND64(matrix[12]);
+ params[13] = IROUND64(matrix[13]);
+ params[14] = IROUND64(matrix[14]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_MODELVIEW_STACK_DEPTH:
+ params[0] = ctx->ModelviewMatrixStack.Depth + 1;
+ break;
+ case GL_NAME_STACK_DEPTH:
+ params[0] = ctx->Select.NameStackDepth;
+ break;
+ case GL_NORMALIZE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Transform.Normalize);
+ break;
+ case GL_PACK_ALIGNMENT:
+ params[0] = ctx->Pack.Alignment;
+ break;
+ case GL_PACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Pack.LsbFirst);
+ break;
+ case GL_PACK_ROW_LENGTH:
+ params[0] = ctx->Pack.RowLength;
+ break;
+ case GL_PACK_SKIP_PIXELS:
+ params[0] = ctx->Pack.SkipPixels;
+ break;
+ case GL_PACK_SKIP_ROWS:
+ params[0] = ctx->Pack.SkipRows;
+ break;
+ case GL_PACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_INT64(ctx->Pack.SwapBytes);
+ break;
+ case GL_PACK_SKIP_IMAGES_EXT:
+ params[0] = ctx->Pack.SkipImages;
+ break;
+ case GL_PACK_IMAGE_HEIGHT_EXT:
+ params[0] = ctx->Pack.ImageHeight;
+ break;
+ case GL_PACK_INVERT_MESA:
+ params[0] = BOOLEAN_TO_INT64(ctx->Pack.Invert);
+ break;
+ case GL_PERSPECTIVE_CORRECTION_HINT:
+ params[0] = ENUM_TO_INT64(ctx->Hint.PerspectiveCorrection);
+ break;
+ case GL_PIXEL_MAP_A_TO_A_SIZE:
+ params[0] = ctx->PixelMaps.AtoA.Size;
+ break;
+ case GL_PIXEL_MAP_B_TO_B_SIZE:
+ params[0] = ctx->PixelMaps.BtoB.Size;
+ break;
+ case GL_PIXEL_MAP_G_TO_G_SIZE:
+ params[0] = ctx->PixelMaps.GtoG.Size;
+ break;
+ case GL_PIXEL_MAP_I_TO_A_SIZE:
+ params[0] = ctx->PixelMaps.ItoA.Size;
+ break;
+ case GL_PIXEL_MAP_I_TO_B_SIZE:
+ params[0] = ctx->PixelMaps.ItoB.Size;
+ break;
+ case GL_PIXEL_MAP_I_TO_G_SIZE:
+ params[0] = ctx->PixelMaps.ItoG.Size;
+ break;
+ case GL_PIXEL_MAP_I_TO_I_SIZE:
+ params[0] = ctx->PixelMaps.ItoI.Size;
+ break;
+ case GL_PIXEL_MAP_I_TO_R_SIZE:
+ params[0] = ctx->PixelMaps.ItoR.Size;
+ break;
+ case GL_PIXEL_MAP_R_TO_R_SIZE:
+ params[0] = ctx->PixelMaps.RtoR.Size;
+ break;
+ case GL_PIXEL_MAP_S_TO_S_SIZE:
+ params[0] = ctx->PixelMaps.StoS.Size;
+ break;
+ case GL_POINT_SIZE:
+ params[0] = IROUND64(ctx->Point.Size);
+ break;
+ case GL_POINT_SIZE_GRANULARITY:
+ params[0] = IROUND64(ctx->Const.PointSizeGranularity);
+ break;
+ case GL_POINT_SIZE_RANGE:
+ params[0] = IROUND64(ctx->Const.MinPointSizeAA);
+ params[1] = IROUND64(ctx->Const.MaxPointSizeAA);
+ break;
+ case GL_ALIASED_POINT_SIZE_RANGE:
+ params[0] = IROUND64(ctx->Const.MinPointSize);
+ params[1] = IROUND64(ctx->Const.MaxPointSize);
+ break;
+ case GL_POINT_SMOOTH:
+ params[0] = BOOLEAN_TO_INT64(ctx->Point.SmoothFlag);
+ break;
+ case GL_POINT_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT64(ctx->Hint.PointSmooth);
+ break;
+ case GL_POINT_SIZE_MIN_EXT:
+ params[0] = IROUND64(ctx->Point.MinSize);
+ break;
+ case GL_POINT_SIZE_MAX_EXT:
+ params[0] = IROUND64(ctx->Point.MaxSize);
+ break;
+ case GL_POINT_FADE_THRESHOLD_SIZE_EXT:
+ params[0] = IROUND64(ctx->Point.Threshold);
+ break;
+ case GL_DISTANCE_ATTENUATION_EXT:
+ params[0] = IROUND64(ctx->Point.Params[0]);
+ params[1] = IROUND64(ctx->Point.Params[1]);
+ params[2] = IROUND64(ctx->Point.Params[2]);
+ break;
+ case GL_POLYGON_MODE:
+ params[0] = ENUM_TO_INT64(ctx->Polygon.FrontMode);
+ params[1] = ENUM_TO_INT64(ctx->Polygon.BackMode);
+ break;
+ case GL_POLYGON_OFFSET_BIAS_EXT:
+ params[0] = IROUND64(ctx->Polygon.OffsetUnits);
+ break;
+ case GL_POLYGON_OFFSET_FACTOR:
+ params[0] = IROUND64(ctx->Polygon.OffsetFactor );
+ break;
+ case GL_POLYGON_OFFSET_UNITS:
+ params[0] = IROUND64(ctx->Polygon.OffsetUnits );
+ break;
+ case GL_POLYGON_OFFSET_POINT:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.OffsetPoint);
+ break;
+ case GL_POLYGON_OFFSET_LINE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.OffsetLine);
+ break;
+ case GL_POLYGON_OFFSET_FILL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.OffsetFill);
+ break;
+ case GL_POLYGON_SMOOTH:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.SmoothFlag);
+ break;
+ case GL_POLYGON_SMOOTH_HINT:
+ params[0] = ENUM_TO_INT64(ctx->Hint.PolygonSmooth);
+ break;
+ case GL_POLYGON_STIPPLE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Polygon.StippleFlag);
+ break;
+ case GL_PROJECTION_MATRIX:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[1]);
+ params[2] = IROUND64(matrix[2]);
+ params[3] = IROUND64(matrix[3]);
+ params[4] = IROUND64(matrix[4]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[6]);
+ params[7] = IROUND64(matrix[7]);
+ params[8] = IROUND64(matrix[8]);
+ params[9] = IROUND64(matrix[9]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[11]);
+ params[12] = IROUND64(matrix[12]);
+ params[13] = IROUND64(matrix[13]);
+ params[14] = IROUND64(matrix[14]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_PROJECTION_STACK_DEPTH:
+ params[0] = ctx->ProjectionMatrixStack.Depth + 1;
+ break;
+ case GL_READ_BUFFER:
+ params[0] = ENUM_TO_INT64(ctx->ReadBuffer->ColorReadBuffer);
+ break;
+ case GL_RED_BIAS:
+ params[0] = IROUND64(ctx->Pixel.RedBias);
+ break;
+ case GL_RED_BITS:
+ params[0] = ctx->DrawBuffer->Visual.redBits;
+ break;
+ case GL_RED_SCALE:
+ params[0] = IROUND64(ctx->Pixel.RedScale);
+ break;
+ case GL_RENDER_MODE:
+ params[0] = ENUM_TO_INT64(ctx->RenderMode);
+ break;
+ case GL_RESCALE_NORMAL:
+ params[0] = BOOLEAN_TO_INT64(ctx->Transform.RescaleNormals);
+ break;
+ case GL_RGBA_MODE:
+ params[0] = BOOLEAN_TO_INT64(ctx->DrawBuffer->Visual.rgbMode);
+ break;
+ case GL_SCISSOR_BOX:
+ params[0] = ctx->Scissor.X;
+ params[1] = ctx->Scissor.Y;
+ params[2] = ctx->Scissor.Width;
+ params[3] = ctx->Scissor.Height;
+ break;
+ case GL_SCISSOR_TEST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Scissor.Enabled);
+ break;
+ case GL_SELECTION_BUFFER_SIZE:
+ params[0] = ctx->Select.BufferSize;
+ break;
+ case GL_SHADE_MODEL:
+ params[0] = ENUM_TO_INT64(ctx->Light.ShadeModel);
+ break;
+ case GL_SHARED_TEXTURE_PALETTE_EXT:
+ params[0] = BOOLEAN_TO_INT64(ctx->Texture.SharedPalette);
+ break;
+ case GL_STENCIL_BITS:
+ params[0] = ctx->DrawBuffer->Visual.stencilBits;
+ break;
+ case GL_STENCIL_CLEAR_VALUE:
+ params[0] = ctx->Stencil.Clear;
+ break;
+ case GL_STENCIL_FAIL:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.FailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_FUNC:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.Function[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.ZFailFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.ZPassFunc[ctx->Stencil.ActiveFace]);
+ break;
+ case GL_STENCIL_REF:
+ params[0] = ctx->Stencil.Ref[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STENCIL_TEST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Stencil.Enabled);
+ break;
+ case GL_STENCIL_VALUE_MASK:
+ params[0] = ctx->Stencil.ValueMask[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STENCIL_WRITEMASK:
+ params[0] = ctx->Stencil.WriteMask[ctx->Stencil.ActiveFace];
+ break;
+ case GL_STEREO:
+ params[0] = BOOLEAN_TO_INT64(ctx->DrawBuffer->Visual.stereoMode);
+ break;
+ case GL_SUBPIXEL_BITS:
+ params[0] = ctx->Const.SubPixelBits;
+ break;
+ case GL_TEXTURE_1D:
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_1D));
+ break;
+ case GL_TEXTURE_2D:
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_2D));
+ break;
+ case GL_TEXTURE_3D:
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_3D));
+ break;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_1D_ARRAY_EXT));
+ break;
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_2D_ARRAY_EXT));
+ break;
+ case GL_TEXTURE_BINDING_1D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_1D_INDEX]->Name;
+ break;
+ case GL_TEXTURE_BINDING_2D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_2D_INDEX]->Name;
+ break;
+ case GL_TEXTURE_BINDING_3D:
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_3D_INDEX]->Name;
+ break;
+ case GL_TEXTURE_BINDING_1D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetInteger64v");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_1D_ARRAY_INDEX]->Name;
+ break;
+ case GL_TEXTURE_BINDING_2D_ARRAY_EXT:
+ CHECK_EXT1(MESA_texture_array, "GetInteger64v");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_2D_ARRAY_INDEX]->Name;
+ break;
+ case GL_TEXTURE_GEN_S:
+ params[0] = BOOLEAN_TO_INT64(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & S_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_T:
+ params[0] = BOOLEAN_TO_INT64(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & T_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_R:
+ params[0] = BOOLEAN_TO_INT64(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & R_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_GEN_Q:
+ params[0] = BOOLEAN_TO_INT64(((ctx->Texture.Unit[ctx->Texture.CurrentUnit].TexGenEnabled & Q_BIT) ? 1 : 0));
+ break;
+ case GL_TEXTURE_MATRIX:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[1]);
+ params[2] = IROUND64(matrix[2]);
+ params[3] = IROUND64(matrix[3]);
+ params[4] = IROUND64(matrix[4]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[6]);
+ params[7] = IROUND64(matrix[7]);
+ params[8] = IROUND64(matrix[8]);
+ params[9] = IROUND64(matrix[9]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[11]);
+ params[12] = IROUND64(matrix[12]);
+ params[13] = IROUND64(matrix[13]);
+ params[14] = IROUND64(matrix[14]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_TEXTURE_STACK_DEPTH:
+ params[0] = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Depth + 1;
+ break;
+ case GL_UNPACK_ALIGNMENT:
+ params[0] = ctx->Unpack.Alignment;
+ break;
+ case GL_UNPACK_LSB_FIRST:
+ params[0] = BOOLEAN_TO_INT64(ctx->Unpack.LsbFirst);
+ break;
+ case GL_UNPACK_ROW_LENGTH:
+ params[0] = ctx->Unpack.RowLength;
+ break;
+ case GL_UNPACK_SKIP_PIXELS:
+ params[0] = ctx->Unpack.SkipPixels;
+ break;
+ case GL_UNPACK_SKIP_ROWS:
+ params[0] = ctx->Unpack.SkipRows;
+ break;
+ case GL_UNPACK_SWAP_BYTES:
+ params[0] = BOOLEAN_TO_INT64(ctx->Unpack.SwapBytes);
+ break;
+ case GL_UNPACK_SKIP_IMAGES_EXT:
+ params[0] = ctx->Unpack.SkipImages;
+ break;
+ case GL_UNPACK_IMAGE_HEIGHT_EXT:
+ params[0] = ctx->Unpack.ImageHeight;
+ break;
+ case GL_UNPACK_CLIENT_STORAGE_APPLE:
+ params[0] = BOOLEAN_TO_INT64(ctx->Unpack.ClientStorage);
+ break;
+ case GL_VIEWPORT:
+ params[0] = ctx->Viewport.X;
+ params[1] = ctx->Viewport.Y;
+ params[2] = ctx->Viewport.Width;
+ params[3] = ctx->Viewport.Height;
+ break;
+ case GL_ZOOM_X:
+ params[0] = IROUND64(ctx->Pixel.ZoomX);
+ break;
+ case GL_ZOOM_Y:
+ params[0] = IROUND64(ctx->Pixel.ZoomY);
+ break;
+ case GL_VERTEX_ARRAY:
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->Vertex.Enabled);
+ break;
+ case GL_VERTEX_ARRAY_SIZE:
+ params[0] = ctx->Array.ArrayObj->Vertex.Size;
+ break;
+ case GL_VERTEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->Vertex.Type);
+ break;
+ case GL_VERTEX_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->Vertex.Stride;
+ break;
+ case GL_VERTEX_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_NORMAL_ARRAY:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->Normal.Enabled);
+ break;
+ case GL_NORMAL_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->Normal.Type);
+ break;
+ case GL_NORMAL_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->Normal.Stride;
+ break;
+ case GL_NORMAL_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_COLOR_ARRAY:
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->Color.Enabled);
+ break;
+ case GL_COLOR_ARRAY_SIZE:
+ params[0] = ctx->Array.ArrayObj->Color.Size;
+ break;
+ case GL_COLOR_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->Color.Type);
+ break;
+ case GL_COLOR_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->Color.Stride;
+ break;
+ case GL_COLOR_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_INDEX_ARRAY:
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->Index.Enabled);
+ break;
+ case GL_INDEX_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->Index.Type);
+ break;
+ case GL_INDEX_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->Index.Stride;
+ break;
+ case GL_INDEX_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_TEXTURE_COORD_ARRAY:
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Enabled);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_SIZE:
+ params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Size;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_TYPE:
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Type);
+ break;
+ case GL_TEXTURE_COORD_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].Stride;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_EDGE_FLAG_ARRAY:
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->EdgeFlag.Enabled);
+ break;
+ case GL_EDGE_FLAG_ARRAY_STRIDE:
+ params[0] = ctx->Array.ArrayObj->EdgeFlag.Stride;
+ break;
+ case GL_EDGE_FLAG_ARRAY_COUNT_EXT:
+ params[0] = 0;
+ break;
+ case GL_MAX_TEXTURE_UNITS_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetInteger64v");
+ params[0] = ctx->Const.MaxTextureUnits;
+ break;
+ case GL_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetInteger64v");
+ params[0] = GL_TEXTURE0_ARB + ctx->Texture.CurrentUnit;
+ break;
+ case GL_CLIENT_ACTIVE_TEXTURE_ARB:
+ CHECK_EXT1(ARB_multitexture, "GetInteger64v");
+ params[0] = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture;
+ break;
+ case GL_TEXTURE_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_CUBE_MAP_ARB));
+ break;
+ case GL_TEXTURE_BINDING_CUBE_MAP_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetInteger64v");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_CUBE_INDEX]->Name;
+ break;
+ case GL_MAX_CUBE_MAP_TEXTURE_SIZE_ARB:
+ CHECK_EXT1(ARB_texture_cube_map, "GetInteger64v");
+ params[0] = (1 << (ctx->Const.MaxCubeTextureLevels - 1));
+ break;
+ case GL_TEXTURE_COMPRESSION_HINT_ARB:
+ params[0] = ctx->Hint.TextureCompression;
+ break;
+ case GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB:
+ params[0] = _mesa_get_compressed_formats(ctx, NULL, GL_FALSE);
+ break;
+ case GL_COMPRESSED_TEXTURE_FORMATS_ARB:
+ {
+ GLint formats[100];
+ GLuint i, n = _mesa_get_compressed_formats(ctx, formats, GL_FALSE);
+ ASSERT(n <= 100);
+ for (i = 0; i < n; i++)
+ params[i] = ENUM_TO_INT64(formats[i]);
+ }
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_FIRST_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetInteger64v");
+ params[0] = ctx->Array.LockFirst;
+ break;
+ case GL_ARRAY_ELEMENT_LOCK_COUNT_EXT:
+ CHECK_EXT1(EXT_compiled_vertex_array, "GetInteger64v");
+ params[0] = ctx->Array.LockCount;
+ break;
+ case GL_TRANSPOSE_COLOR_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[4]);
+ params[2] = IROUND64(matrix[8]);
+ params[3] = IROUND64(matrix[12]);
+ params[4] = IROUND64(matrix[1]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[9]);
+ params[7] = IROUND64(matrix[13]);
+ params[8] = IROUND64(matrix[2]);
+ params[9] = IROUND64(matrix[6]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[14]);
+ params[12] = IROUND64(matrix[3]);
+ params[13] = IROUND64(matrix[7]);
+ params[14] = IROUND64(matrix[11]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_MODELVIEW_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ModelviewMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[4]);
+ params[2] = IROUND64(matrix[8]);
+ params[3] = IROUND64(matrix[12]);
+ params[4] = IROUND64(matrix[1]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[9]);
+ params[7] = IROUND64(matrix[13]);
+ params[8] = IROUND64(matrix[2]);
+ params[9] = IROUND64(matrix[6]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[14]);
+ params[12] = IROUND64(matrix[3]);
+ params[13] = IROUND64(matrix[7]);
+ params[14] = IROUND64(matrix[11]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_PROJECTION_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->ProjectionMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[4]);
+ params[2] = IROUND64(matrix[8]);
+ params[3] = IROUND64(matrix[12]);
+ params[4] = IROUND64(matrix[1]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[9]);
+ params[7] = IROUND64(matrix[13]);
+ params[8] = IROUND64(matrix[2]);
+ params[9] = IROUND64(matrix[6]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[14]);
+ params[12] = IROUND64(matrix[3]);
+ params[13] = IROUND64(matrix[7]);
+ params[14] = IROUND64(matrix[11]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_TEXTURE_MATRIX_ARB:
+ {
+ const GLfloat *matrix = ctx->TextureMatrixStack[ctx->Texture.CurrentUnit].Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[4]);
+ params[2] = IROUND64(matrix[8]);
+ params[3] = IROUND64(matrix[12]);
+ params[4] = IROUND64(matrix[1]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[9]);
+ params[7] = IROUND64(matrix[13]);
+ params[8] = IROUND64(matrix[2]);
+ params[9] = IROUND64(matrix[6]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[14]);
+ params[12] = IROUND64(matrix[3]);
+ params[13] = IROUND64(matrix[7]);
+ params[14] = IROUND64(matrix[11]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_SGI:
+ {
+ const GLfloat *matrix = ctx->ColorMatrixStack.Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[1]);
+ params[2] = IROUND64(matrix[2]);
+ params[3] = IROUND64(matrix[3]);
+ params[4] = IROUND64(matrix[4]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[6]);
+ params[7] = IROUND64(matrix[7]);
+ params[8] = IROUND64(matrix[8]);
+ params[9] = IROUND64(matrix[9]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[11]);
+ params[12] = IROUND64(matrix[12]);
+ params[13] = IROUND64(matrix[13]);
+ params[14] = IROUND64(matrix[14]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = ctx->ColorMatrixStack.Depth + 1;
+ break;
+ case GL_MAX_COLOR_MATRIX_STACK_DEPTH_SGI:
+ params[0] = MAX_COLOR_STACK_DEPTH;
+ break;
+ case GL_POST_COLOR_MATRIX_RED_SCALE_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixScale[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_SCALE_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixScale[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_SCALE_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixScale[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_SCALE_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixScale[3]);
+ break;
+ case GL_POST_COLOR_MATRIX_RED_BIAS_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixBias[0]);
+ break;
+ case GL_POST_COLOR_MATRIX_GREEN_BIAS_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixBias[1]);
+ break;
+ case GL_POST_COLOR_MATRIX_BLUE_BIAS_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixBias[2]);
+ break;
+ case GL_POST_COLOR_MATRIX_ALPHA_BIAS_SGI:
+ params[0] = IROUND64(ctx->Pixel.PostColorMatrixBias[3]);
+ break;
+ case GL_CONVOLUTION_1D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.Convolution1DEnabled);
+ break;
+ case GL_CONVOLUTION_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.Convolution2DEnabled);
+ break;
+ case GL_SEPARABLE_2D_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.Separable2DEnabled);
+ break;
+ case GL_POST_CONVOLUTION_RED_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionScale[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionScale[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionScale[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_SCALE_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionScale[3]);
+ break;
+ case GL_POST_CONVOLUTION_RED_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionBias[0]);
+ break;
+ case GL_POST_CONVOLUTION_GREEN_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionBias[1]);
+ break;
+ case GL_POST_CONVOLUTION_BLUE_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionBias[2]);
+ break;
+ case GL_POST_CONVOLUTION_ALPHA_BIAS_EXT:
+ CHECK_EXT1(EXT_convolution, "GetInteger64v");
+ params[0] = IROUND64(ctx->Pixel.PostConvolutionBias[3]);
+ break;
+ case GL_HISTOGRAM:
+ CHECK_EXT1(EXT_histogram, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.HistogramEnabled);
+ break;
+ case GL_MINMAX:
+ CHECK_EXT1(EXT_histogram, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.MinMaxEnabled);
+ break;
+ case GL_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.ColorTableEnabled[COLORTABLE_PRECONVOLUTION]);
+ break;
+ case GL_POST_CONVOLUTION_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCONVOLUTION]);
+ break;
+ case GL_POST_COLOR_MATRIX_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_color_table, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Pixel.ColorTableEnabled[COLORTABLE_POSTCOLORMATRIX]);
+ break;
+ case GL_TEXTURE_COLOR_TABLE_SGI:
+ CHECK_EXT1(SGI_texture_color_table, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Texture.Unit[ctx->Texture.CurrentUnit].ColorTableEnabled);
+ break;
+ case GL_COLOR_SUM_EXT:
+ CHECK_EXT2(EXT_secondary_color, ARB_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Fog.ColorSumEnabled);
+ break;
+ case GL_CURRENT_SECONDARY_COLOR_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetInteger64v");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][0]);
+ params[1] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][1]);
+ params[2] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][2]);
+ params[3] = FLOAT_TO_INT64(ctx->Current.Attrib[VERT_ATTRIB_COLOR1][3]);
+ }
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->SecondaryColor.Enabled);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->SecondaryColor.Type);
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetInteger64v");
+ params[0] = ctx->Array.ArrayObj->SecondaryColor.Stride;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_SIZE_EXT:
+ CHECK_EXT1(EXT_secondary_color, "GetInteger64v");
+ params[0] = ctx->Array.ArrayObj->SecondaryColor.Size;
+ break;
+ case GL_CURRENT_FOG_COORDINATE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetInteger64v");
+ {
+ FLUSH_CURRENT(ctx, 0);
+ params[0] = IROUND64(ctx->Current.Attrib[VERT_ATTRIB_FOG][0]);
+ }
+ break;
+ case GL_FOG_COORDINATE_ARRAY_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->FogCoord.Enabled);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_TYPE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Array.ArrayObj->FogCoord.Type);
+ break;
+ case GL_FOG_COORDINATE_ARRAY_STRIDE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetInteger64v");
+ params[0] = ctx->Array.ArrayObj->FogCoord.Stride;
+ break;
+ case GL_FOG_COORDINATE_SOURCE_EXT:
+ CHECK_EXT1(EXT_fog_coord, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Fog.FogCoordinateSource);
+ break;
+ case GL_MAX_TEXTURE_LOD_BIAS_EXT:
+ CHECK_EXT1(EXT_texture_lod_bias, "GetInteger64v");
+ params[0] = IROUND64(ctx->Const.MaxTextureLodBias);
+ break;
+ case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
+ CHECK_EXT1(EXT_texture_filter_anisotropic, "GetInteger64v");
+ params[0] = IROUND64(ctx->Const.MaxTextureMaxAnisotropy);
+ break;
+ case GL_MULTISAMPLE_ARB:
+ params[0] = BOOLEAN_TO_INT64(ctx->Multisample.Enabled);
+ break;
+ case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB:
+ params[0] = BOOLEAN_TO_INT64(ctx->Multisample.SampleAlphaToCoverage);
+ break;
+ case GL_SAMPLE_ALPHA_TO_ONE_ARB:
+ params[0] = BOOLEAN_TO_INT64(ctx->Multisample.SampleAlphaToOne);
+ break;
+ case GL_SAMPLE_COVERAGE_ARB:
+ params[0] = BOOLEAN_TO_INT64(ctx->Multisample.SampleCoverage);
+ break;
+ case GL_SAMPLE_COVERAGE_VALUE_ARB:
+ params[0] = IROUND64(ctx->Multisample.SampleCoverageValue);
+ break;
+ case GL_SAMPLE_COVERAGE_INVERT_ARB:
+ params[0] = BOOLEAN_TO_INT64(ctx->Multisample.SampleCoverageInvert);
+ break;
+ case GL_SAMPLE_BUFFERS_ARB:
+ params[0] = ctx->DrawBuffer->Visual.sampleBuffers;
+ break;
+ case GL_SAMPLES_ARB:
+ params[0] = ctx->DrawBuffer->Visual.samples;
+ break;
+ case GL_RASTER_POSITION_UNCLIPPED_IBM:
+ CHECK_EXT1(IBM_rasterpos_clip, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Transform.RasterPositionUnclipped);
+ break;
+ case GL_POINT_SPRITE_NV:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Point.PointSprite);
+ break;
+ case GL_POINT_SPRITE_R_MODE_NV:
+ CHECK_EXT1(NV_point_sprite, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Point.SpriteRMode);
+ break;
+ case GL_POINT_SPRITE_COORD_ORIGIN:
+ CHECK_EXT2(NV_point_sprite, ARB_point_sprite, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Point.SpriteOrigin);
+ break;
+ case GL_GENERATE_MIPMAP_HINT_SGIS:
+ CHECK_EXT1(SGIS_generate_mipmap, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Hint.GenerateMipmap);
+ break;
+ case GL_VERTEX_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = (ctx->VertexProgram.Current ? ctx->VertexProgram.Current->Base.Id : 0);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY0_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[0].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY1_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[1].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY2_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[2].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY3_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[3].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[4].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY5_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[5].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY6_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[6].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY7_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[7].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY8_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[8].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY9_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[9].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY10_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[10].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY11_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[11].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY12_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[12].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY13_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[13].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY14_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[14].Enabled);
+ break;
+ case GL_VERTEX_ATTRIB_ARRAY15_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Array.ArrayObj->VertexAttrib[15].Enabled);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB0_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[0]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB1_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[1]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB2_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[2]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB3_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[3]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB4_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[4]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB5_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[5]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB6_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[6]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB7_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[7]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB8_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[8]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB9_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[9]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB10_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[10]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB11_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[11]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB12_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[12]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB13_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[13]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB14_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[14]);
+ break;
+ case GL_MAP1_VERTEX_ATTRIB15_4_NV:
+ CHECK_EXT1(NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Eval.Map1Attrib[15]);
+ break;
+ case GL_FRAGMENT_PROGRAM_NV:
+ CHECK_EXT1(NV_fragment_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_FRAGMENT_PROGRAM_BINDING_NV:
+ CHECK_EXT1(NV_fragment_program, "GetInteger64v");
+ params[0] = ctx->FragmentProgram.Current ? ctx->FragmentProgram.Current->Base.Id : 0;
+ break;
+ case GL_MAX_FRAGMENT_PROGRAM_LOCAL_PARAMETERS_NV:
+ CHECK_EXT1(NV_fragment_program, "GetInteger64v");
+ params[0] = MAX_NV_FRAGMENT_PROGRAM_PARAMS;
+ break;
+ case GL_TEXTURE_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(_mesa_IsEnabled(GL_TEXTURE_RECTANGLE_NV));
+ break;
+ case GL_TEXTURE_BINDING_RECTANGLE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetInteger64v");
+ params[0] = ctx->Texture.Unit[ctx->Texture.CurrentUnit].CurrentTex[TEXTURE_RECT_INDEX]->Name;
+ break;
+ case GL_MAX_RECTANGLE_TEXTURE_SIZE_NV:
+ CHECK_EXT1(NV_texture_rectangle, "GetInteger64v");
+ params[0] = ctx->Const.MaxTextureRectSize;
+ break;
+ case GL_STENCIL_TEST_TWO_SIDE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Stencil.TestTwoSide);
+ break;
+ case GL_ACTIVE_STENCIL_FACE_EXT:
+ CHECK_EXT1(EXT_stencil_two_side, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Stencil.ActiveFace ? GL_BACK : GL_FRONT);
+ break;
+ case GL_MAX_SHININESS_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetInteger64v");
+ params[0] = IROUND64(ctx->Const.MaxShininess);
+ break;
+ case GL_MAX_SPOT_EXPONENT_NV:
+ CHECK_EXT1(NV_light_max_exponent, "GetInteger64v");
+ params[0] = IROUND64(ctx->Const.MaxSpotExponent);
+ break;
+ case GL_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayBufferObj->Name;
+ break;
+ case GL_VERTEX_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->Vertex.BufferObj->Name;
+ break;
+ case GL_NORMAL_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->Normal.BufferObj->Name;
+ break;
+ case GL_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->Color.BufferObj->Name;
+ break;
+ case GL_INDEX_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->Index.BufferObj->Name;
+ break;
+ case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->TexCoord[ctx->Array.ActiveTexture].BufferObj->Name;
+ break;
+ case GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->EdgeFlag.BufferObj->Name;
+ break;
+ case GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->SecondaryColor.BufferObj->Name;
+ break;
+ case GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ArrayObj->FogCoord.BufferObj->Name;
+ break;
+ case GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB:
+ params[0] = ctx->Array.ElementArrayBufferObj->Name;
+ break;
+ case GL_PIXEL_PACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetInteger64v");
+ params[0] = ctx->Pack.BufferObj->Name;
+ break;
+ case GL_PIXEL_UNPACK_BUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_pixel_buffer_object, "GetInteger64v");
+ params[0] = ctx->Unpack.BufferObj->Name;
+ break;
+ case GL_VERTEX_PROGRAM_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->VertexProgram.Enabled);
+ break;
+ case GL_VERTEX_PROGRAM_POINT_SIZE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->VertexProgram.PointSizeEnabled);
+ break;
+ case GL_VERTEX_PROGRAM_TWO_SIDE_ARB:
+ CHECK_EXT2(ARB_vertex_program, NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->VertexProgram.TwoSideEnabled);
+ break;
+ case GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetInteger64v");
+ params[0] = ctx->Const.MaxProgramMatrixStackDepth;
+ break;
+ case GL_MAX_PROGRAM_MATRICES_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetInteger64v");
+ params[0] = ctx->Const.MaxProgramMatrices;
+ break;
+ case GL_CURRENT_MATRIX_STACK_DEPTH_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_vertex_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->CurrentStack->Depth + 1);
+ break;
+ case GL_CURRENT_MATRIX_ARB:
+ CHECK_EXT3(ARB_vertex_program, ARB_fragment_program, NV_fragment_program, "GetInteger64v");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[1]);
+ params[2] = IROUND64(matrix[2]);
+ params[3] = IROUND64(matrix[3]);
+ params[4] = IROUND64(matrix[4]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[6]);
+ params[7] = IROUND64(matrix[7]);
+ params[8] = IROUND64(matrix[8]);
+ params[9] = IROUND64(matrix[9]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[11]);
+ params[12] = IROUND64(matrix[12]);
+ params[13] = IROUND64(matrix[13]);
+ params[14] = IROUND64(matrix[14]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_TRANSPOSE_CURRENT_MATRIX_ARB:
+ CHECK_EXT2(ARB_vertex_program, ARB_fragment_program, "GetInteger64v");
+ {
+ const GLfloat *matrix = ctx->CurrentStack->Top->m;
+ params[0] = IROUND64(matrix[0]);
+ params[1] = IROUND64(matrix[4]);
+ params[2] = IROUND64(matrix[8]);
+ params[3] = IROUND64(matrix[12]);
+ params[4] = IROUND64(matrix[1]);
+ params[5] = IROUND64(matrix[5]);
+ params[6] = IROUND64(matrix[9]);
+ params[7] = IROUND64(matrix[13]);
+ params[8] = IROUND64(matrix[2]);
+ params[9] = IROUND64(matrix[6]);
+ params[10] = IROUND64(matrix[10]);
+ params[11] = IROUND64(matrix[14]);
+ params[12] = IROUND64(matrix[3]);
+ params[13] = IROUND64(matrix[7]);
+ params[14] = IROUND64(matrix[11]);
+ params[15] = IROUND64(matrix[15]);
+ }
+ break;
+ case GL_MAX_VERTEX_ATTRIBS_ARB:
+ CHECK_EXT1(ARB_vertex_program, "GetInteger64v");
+ params[0] = ctx->Const.VertexProgram.MaxAttribs;
+ break;
+ case GL_PROGRAM_ERROR_POSITION_ARB:
+ CHECK_EXT4(NV_vertex_program, ARB_vertex_program, NV_fragment_program, ARB_fragment_program, "GetInteger64v");
+ params[0] = ctx->Program.ErrorPos;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ CHECK_EXT1(ARB_fragment_program, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->FragmentProgram.Enabled);
+ break;
+ case GL_MAX_TEXTURE_COORDS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetInteger64v");
+ params[0] = ctx->Const.MaxTextureCoordUnits;
+ break;
+ case GL_MAX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT2(ARB_fragment_program, NV_fragment_program, "GetInteger64v");
+ params[0] = ctx->Const.MaxTextureImageUnits;
+ break;
+ case GL_DEPTH_BOUNDS_TEST_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Depth.BoundsTest);
+ break;
+ case GL_DEPTH_BOUNDS_EXT:
+ CHECK_EXT1(EXT_depth_bounds_test, "GetInteger64v");
+ params[0] = IROUND64(ctx->Depth.BoundsMin);
+ params[1] = IROUND64(ctx->Depth.BoundsMax);
+ break;
+ case GL_DEPTH_CLAMP:
+ CHECK_EXT1(ARB_depth_clamp, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Transform.DepthClamp);
+ break;
+ case GL_MAX_DRAW_BUFFERS_ARB:
+ params[0] = ctx->Const.MaxDrawBuffers;
+ break;
+ case GL_DRAW_BUFFER0_ARB:
+ params[0] = ENUM_TO_INT64(ctx->DrawBuffer->ColorDrawBuffer[0]);
+ break;
+ case GL_DRAW_BUFFER1_ARB:
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[1];
+ params[0] = ENUM_TO_INT64(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER2_ARB:
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[2];
+ params[0] = ENUM_TO_INT64(buffer);
+ }
+ break;
+ case GL_DRAW_BUFFER3_ARB:
+ {
+ GLenum buffer;
+ if (pname - GL_DRAW_BUFFER0_ARB >= ctx->Const.MaxDrawBuffers) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGet(GL_DRAW_BUFFERx_ARB)");
+ return;
+ }
+ buffer = ctx->DrawBuffer->ColorDrawBuffer[3];
+ params[0] = ENUM_TO_INT64(buffer);
+ }
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_TYPE_OES:
+ CHECK_EXT1(OES_read_format, "GetInteger64v");
+ params[0] = ctx->Const.ColorReadType;
+ break;
+ case GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES:
+ CHECK_EXT1(OES_read_format, "GetInteger64v");
+ params[0] = ctx->Const.ColorReadFormat;
+ break;
+ case GL_NUM_FRAGMENT_REGISTERS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 6;
+ break;
+ case GL_NUM_FRAGMENT_CONSTANTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 8;
+ break;
+ case GL_NUM_PASSES_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 2;
+ break;
+ case GL_NUM_INSTRUCTIONS_PER_PASS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 8;
+ break;
+ case GL_NUM_INSTRUCTIONS_TOTAL_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 16;
+ break;
+ case GL_COLOR_ALPHA_PAIRING_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(GL_TRUE);
+ break;
+ case GL_NUM_LOOPBACK_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 3;
+ break;
+ case GL_NUM_INPUT_INTERPOLATOR_COMPONENTS_ATI:
+ CHECK_EXT1(ATI_fragment_shader, "GetInteger64v");
+ params[0] = 3;
+ break;
+ case GL_STENCIL_BACK_FUNC:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.Function[1]);
+ break;
+ case GL_STENCIL_BACK_VALUE_MASK:
+ params[0] = ctx->Stencil.ValueMask[1];
+ break;
+ case GL_STENCIL_BACK_WRITEMASK:
+ params[0] = ctx->Stencil.WriteMask[1];
+ break;
+ case GL_STENCIL_BACK_REF:
+ params[0] = ctx->Stencil.Ref[1];
+ break;
+ case GL_STENCIL_BACK_FAIL:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.FailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.ZFailFunc[1]);
+ break;
+ case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+ params[0] = ENUM_TO_INT64(ctx->Stencil.ZPassFunc[1]);
+ break;
+ case GL_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetInteger64v");
+ params[0] = ctx->DrawBuffer->Name;
+ break;
+ case GL_RENDERBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetInteger64v");
+ params[0] = ctx->CurrentRenderbuffer ? ctx->CurrentRenderbuffer->Name : 0;
+ break;
+ case GL_MAX_COLOR_ATTACHMENTS_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetInteger64v");
+ params[0] = ctx->Const.MaxColorAttachments;
+ break;
+ case GL_MAX_RENDERBUFFER_SIZE_EXT:
+ CHECK_EXT1(EXT_framebuffer_object, "GetInteger64v");
+ params[0] = ctx->Const.MaxRenderbufferSize;
+ break;
+ case GL_READ_FRAMEBUFFER_BINDING_EXT:
+ CHECK_EXT1(EXT_framebuffer_blit, "GetInteger64v");
+ params[0] = ctx->ReadBuffer->Name;
+ break;
+ case GL_PROVOKING_VERTEX_EXT:
+ CHECK_EXT1(EXT_provoking_vertex, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Light.ProvokingVertex);
+ break;
+ case GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT:
+ CHECK_EXT1(EXT_provoking_vertex, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Const.QuadsFollowProvokingVertexConvention);
+ break;
+ case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetInteger64v");
+ params[0] = ctx->Const.FragmentProgram.MaxUniformComponents;
+ break;
+ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB:
+ CHECK_EXT1(ARB_fragment_shader, "GetInteger64v");
+ params[0] = ENUM_TO_INT64(ctx->Hint.FragmentShaderDerivative);
+ break;
+ case GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetInteger64v");
+ params[0] = ctx->Const.VertexProgram.MaxUniformComponents;
+ break;
+ case GL_MAX_VARYING_FLOATS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetInteger64v");
+ params[0] = ctx->Const.MaxVarying * 4;
+ break;
+ case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetInteger64v");
+ params[0] = ctx->Const.MaxVertexTextureImageUnits;
+ break;
+ case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB:
+ CHECK_EXT1(ARB_vertex_shader, "GetInteger64v");
+ params[0] = MAX_COMBINED_TEXTURE_IMAGE_UNITS;
+ break;
+ case GL_CURRENT_PROGRAM:
+ CHECK_EXT1(ARB_shader_objects, "GetInteger64v");
+ params[0] = ctx->Shader.CurrentProgram ? ctx->Shader.CurrentProgram->Name : 0;
+ break;
+ case GL_MAX_SAMPLES:
+ CHECK_EXT1(ARB_framebuffer_object, "GetInteger64v");
+ params[0] = ctx->Const.MaxSamples;
+ break;
+ case GL_VERTEX_ARRAY_BINDING_APPLE:
+ CHECK_EXT1(APPLE_vertex_array_object, "GetInteger64v");
+ params[0] = ctx->Array.ArrayObj->Name;
+ break;
+ case GL_TEXTURE_CUBE_MAP_SEAMLESS:
+ CHECK_EXT1(ARB_seamless_cube_map, "GetInteger64v");
+ params[0] = BOOLEAN_TO_INT64(ctx->Texture.CubeMapSeamless);
+ break;
+ case GL_MAX_SERVER_WAIT_TIMEOUT:
+ CHECK_EXT1(ARB_sync, "GetInteger64v");
+ params[0] = ctx->Const.MaxServerWaitTimeout;
+ break;
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetInteger64v(pname=0x%x)", pname);
+ }
+}
+#endif /* FEATURE_ARB_sync */
+
void GLAPIENTRY
_mesa_GetDoublev( GLenum pname, GLdouble *params )
diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h
index 9b47b230a9..77a9a7d04b 100644
--- a/src/mesa/main/get.h
+++ b/src/mesa/main/get.h
@@ -48,6 +48,9 @@ extern void GLAPIENTRY
_mesa_GetIntegerv( GLenum pname, GLint *params );
extern void GLAPIENTRY
+_mesa_GetInteger64v( GLenum pname, GLint64 *params );
+
+extern void GLAPIENTRY
_mesa_GetPointerv( GLenum pname, GLvoid **params );
extern const GLubyte * GLAPIENTRY
diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py
index 5666ad0e42..364d8c55c4 100644
--- a/src/mesa/main/get_gen.py
+++ b/src/mesa/main/get_gen.py
@@ -35,6 +35,7 @@ GLfloat = 3
GLdouble = 4
GLboolean = 5
GLfloatN = 6 # A normalized value, such as a color or depth range
+GLint64 = 7
TypeStrings = {
@@ -42,7 +43,8 @@ TypeStrings = {
GLenum : "GLenum",
GLfloat : "GLfloat",
GLdouble : "GLdouble",
- GLboolean : "GLboolean"
+ GLboolean : "GLboolean",
+ GLint64 : "GLint64"
}
@@ -176,7 +178,8 @@ StateVars = [
"ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][1]",
"ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][2]",
"ctx->Current.Attrib[VERT_ATTRIB_TEX0 + texUnit][3]"],
- "const GLuint texUnit = ctx->Texture.CurrentUnit;", None ),
+ """const GLuint texUnit = ctx->Texture.CurrentUnit;
+ FLUSH_CURRENT(ctx, 0);""", None ),
( "GL_DEPTH_BIAS", GLfloat, ["ctx->Pixel.DepthBias"], "", None ),
( "GL_DEPTH_BITS", GLint, ["ctx->DrawBuffer->Visual.depthBits"],
"", None ),
@@ -902,6 +905,10 @@ StateVars = [
["ctx->Depth.BoundsMin", "ctx->Depth.BoundsMax"],
"", ["EXT_depth_bounds_test"] ),
+ # GL_ARB_depth_clamp
+ ( "GL_DEPTH_CLAMP", GLboolean, ["ctx->Transform.DepthClamp"], "",
+ ["ARB_depth_clamp"] ),
+
# GL_ARB_draw_buffers
( "GL_MAX_DRAW_BUFFERS_ARB", GLint,
["ctx->Const.MaxDrawBuffers"], "", None ),
@@ -1015,6 +1022,14 @@ StateVars = [
# GL_APPLE_vertex_array_object
( "GL_VERTEX_ARRAY_BINDING_APPLE", GLint, ["ctx->Array.ArrayObj->Name"], "",
["APPLE_vertex_array_object"] ),
+
+ # GL_ARB_seamless_cube_map
+ ( "GL_TEXTURE_CUBE_MAP_SEAMLESS", GLboolean, ["ctx->Texture.CubeMapSeamless"], "",
+ ["ARB_seamless_cube_map"] ),
+
+ # GL_ARB_sync
+ ( "GL_MAX_SERVER_WAIT_TIMEOUT", GLint64, ["ctx->Const.MaxServerWaitTimeout"], "",
+ ["ARB_sync"] ),
]
@@ -1024,10 +1039,16 @@ def ConversionFunc(fromType, toType):
return ""
elif fromType == GLfloat and toType == GLint:
return "IROUND"
+ elif fromType == GLfloat and toType == GLint64:
+ return "IROUND64"
elif fromType == GLfloatN and toType == GLfloat:
return ""
elif fromType == GLint and toType == GLfloat: # but not GLfloatN!
return "(GLfloat)"
+ elif fromType == GLint and toType == GLint64:
+ return ""
+ elif fromType == GLint64 and toType == GLfloat: # but not GLfloatN!
+ return "(GLfloat)"
else:
if fromType == GLfloatN:
fromType = GLfloat
@@ -1042,6 +1063,7 @@ def EmitGetFunction(stateVars, returnType):
"""Emit the code to implement glGetBooleanv, glGetIntegerv or glGetFloatv."""
assert (returnType == GLboolean or
returnType == GLint or
+ returnType == GLint64 or
returnType == GLfloat)
strType = TypeStrings[returnType]
@@ -1052,9 +1074,14 @@ def EmitGetFunction(stateVars, returnType):
function = "GetBooleanv"
elif returnType == GLfloat:
function = "GetFloatv"
+ elif returnType == GLint64:
+ function = "GetInteger64v"
else:
abort()
+ if returnType == GLint64:
+ print "#if FEATURE_ARB_sync"
+
print "void GLAPIENTRY"
print "_mesa_%s( GLenum pname, %s *params )" % (function, strType)
print "{"
@@ -1108,6 +1135,8 @@ def EmitGetFunction(stateVars, returnType):
print ' _mesa_error(ctx, GL_INVALID_ENUM, "gl%s(pname=0x%%x)", pname);' % function
print " }"
print "}"
+ if returnType == GLint64:
+ print "#endif /* FEATURE_ARB_sync */"
print ""
return
@@ -1136,9 +1165,15 @@ def EmitHeader():
#define INT_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_BOOLEAN(I) ( (I) ? GL_TRUE : GL_FALSE )
+#define INT64_TO_INT(I) ( (GLint)((I > INT_MAX) ? INT_MAX : ((I < INT_MIN) ? INT_MIN : (I))) )
+
#define BOOLEAN_TO_INT(B) ( (GLint) (B) )
+#define BOOLEAN_TO_INT64(B) ( (GLint64) (B) )
#define BOOLEAN_TO_FLOAT(B) ( (B) ? 1.0F : 0.0F )
+#define ENUM_TO_INT64(E) ( (GLint64) (E) )
+
/*
* Check if named extension is enabled, if not generate error and return.
@@ -1216,5 +1251,6 @@ EmitHeader()
EmitGetFunction(StateVars, GLboolean)
EmitGetFunction(StateVars, GLfloat)
EmitGetFunction(StateVars, GLint)
+EmitGetFunction(StateVars, GLint64)
EmitGetDoublev()
diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c
index 41fd786d7d..6599ed9698 100644
--- a/src/mesa/main/getstring.c
+++ b/src/mesa/main/getstring.c
@@ -266,5 +266,6 @@ _mesa_GetError( void )
_mesa_debug(ctx, "glGetError <-- %s\n", _mesa_lookup_enum_by_nr(e));
ctx->ErrorValue = (GLenum) GL_NO_ERROR;
+ ctx->ErrorDebugCount = 0;
return e;
}
diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c
index 5fee4fd0e3..ceb0d5a6a8 100644
--- a/src/mesa/main/histogram.c
+++ b/src/mesa/main/histogram.c
@@ -649,29 +649,11 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
return;
}
- if (ctx->Pack.BufferObj->Name) {
- /* pack min/max values into a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Pack, 2, 1, 1,
- format, type, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetMinMax(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx, GL_INVALID_OPERATION,"glGetMinMax(PBO is mapped)");
- return;
- }
- values = ADD_POINTERS(buf, values);
- }
- else if (!values) {
- /* not an error */
+
+ values = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack, 2, 1, 1,
+ format, type, values, "glGetMinmax");
+ if (!values)
return;
- }
{
GLfloat minmax[2][4];
@@ -687,10 +669,7 @@ _mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, GLvo
format, type, values, &ctx->Pack, 0x0);
}
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
if (reset) {
_mesa_ResetMinmax(GL_MINMAX);
@@ -733,38 +712,18 @@ _mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, G
return;
}
- if (ctx->Pack.BufferObj->Name) {
- /* pack min/max values into a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(1, &ctx->Pack, ctx->Histogram.Width, 1, 1,
- format, type, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetHistogram(invalid PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
- _mesa_error(ctx,GL_INVALID_OPERATION,"glGetHistogram(PBO is mapped)");
- return;
- }
- values = ADD_POINTERS(buf, values);
- }
- else if (!values) {
- /* not an error */
+ values = _mesa_map_validate_pbo_dest(ctx, 1, &ctx->Pack,
+ ctx->Histogram.Width, 1, 1,
+ format, type, values,
+ "glGetHistogram");
+ if (!values)
return;
- }
pack_histogram(ctx, ctx->Histogram.Width,
(CONST GLuint (*)[4]) ctx->Histogram.Count,
format, type, values, &ctx->Pack);
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
if (reset) {
GLuint i;
diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c
index 090e5eb330..baecbab0a3 100644
--- a/src/mesa/main/image.c
+++ b/src/mesa/main/image.c
@@ -531,6 +531,226 @@ _mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type )
/**
+ * Test if the given image format is a color/RGBA format (i.e., not color
+ * index, depth, stencil, etc).
+ * \param format the image format value (may by an internal texture format)
+ * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
+ */
+GLboolean
+_mesa_is_color_format(GLenum format)
+{
+ switch (format) {
+ case GL_RED:
+ case GL_GREEN:
+ case GL_BLUE:
+ case GL_ALPHA:
+ case GL_ALPHA4:
+ case GL_ALPHA8:
+ case GL_ALPHA12:
+ case GL_ALPHA16:
+ case 1:
+ case GL_LUMINANCE:
+ case GL_LUMINANCE4:
+ case GL_LUMINANCE8:
+ case GL_LUMINANCE12:
+ case GL_LUMINANCE16:
+ case 2:
+ case GL_LUMINANCE_ALPHA:
+ case GL_LUMINANCE4_ALPHA4:
+ case GL_LUMINANCE6_ALPHA2:
+ case GL_LUMINANCE8_ALPHA8:
+ case GL_LUMINANCE12_ALPHA4:
+ case GL_LUMINANCE12_ALPHA12:
+ case GL_LUMINANCE16_ALPHA16:
+ case GL_INTENSITY:
+ case GL_INTENSITY4:
+ case GL_INTENSITY8:
+ case GL_INTENSITY12:
+ case GL_INTENSITY16:
+ case 3:
+ case GL_RGB:
+ case GL_BGR:
+ case GL_R3_G3_B2:
+ case GL_RGB4:
+ case GL_RGB5:
+ case GL_RGB8:
+ case GL_RGB10:
+ case GL_RGB12:
+ case GL_RGB16:
+ case 4:
+ case GL_ABGR_EXT:
+ case GL_RGBA:
+ case GL_BGRA:
+ case GL_RGBA2:
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ case GL_RGBA8:
+ case GL_RGB10_A2:
+ case GL_RGBA12:
+ case GL_RGBA16:
+ /* float texture formats */
+ case GL_ALPHA16F_ARB:
+ case GL_ALPHA32F_ARB:
+ case GL_LUMINANCE16F_ARB:
+ case GL_LUMINANCE32F_ARB:
+ case GL_LUMINANCE_ALPHA16F_ARB:
+ case GL_LUMINANCE_ALPHA32F_ARB:
+ case GL_INTENSITY16F_ARB:
+ case GL_INTENSITY32F_ARB:
+ case GL_RGB16F_ARB:
+ case GL_RGB32F_ARB:
+ case GL_RGBA16F_ARB:
+ case GL_RGBA32F_ARB:
+ /* compressed formats */
+ case GL_COMPRESSED_ALPHA:
+ case GL_COMPRESSED_LUMINANCE:
+ case GL_COMPRESSED_LUMINANCE_ALPHA:
+ case GL_COMPRESSED_INTENSITY:
+ case GL_COMPRESSED_RGB:
+ case GL_COMPRESSED_RGBA:
+ case GL_RGB_S3TC:
+ case GL_RGB4_S3TC:
+ case GL_RGBA_S3TC:
+ case GL_RGBA4_S3TC:
+ case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_RGB_FXT1_3DFX:
+ case GL_COMPRESSED_RGBA_FXT1_3DFX:
+#if FEATURE_EXT_texture_sRGB
+ case GL_SRGB_EXT:
+ case GL_SRGB8_EXT:
+ case GL_SRGB_ALPHA_EXT:
+ case GL_SRGB8_ALPHA8_EXT:
+ case GL_SLUMINANCE_ALPHA_EXT:
+ case GL_SLUMINANCE8_ALPHA8_EXT:
+ case GL_SLUMINANCE_EXT:
+ case GL_SLUMINANCE8_EXT:
+ case GL_COMPRESSED_SRGB_EXT:
+ case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
+ case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
+ case GL_COMPRESSED_SLUMINANCE_EXT:
+ case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
+#endif /* FEATURE_EXT_texture_sRGB */
+ return GL_TRUE;
+ /* signed texture formats */
+ case GL_RGBA_SNORM:
+ case GL_RGBA8_SNORM:
+ return GL_TRUE;
+ case GL_YCBCR_MESA: /* not considered to be RGB */
+ /* fall-through */
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a color index format.
+ */
+GLboolean
+_mesa_is_index_format(GLenum format)
+{
+ switch (format) {
+ case GL_COLOR_INDEX:
+ case GL_COLOR_INDEX1_EXT:
+ case GL_COLOR_INDEX2_EXT:
+ case GL_COLOR_INDEX4_EXT:
+ case GL_COLOR_INDEX8_EXT:
+ case GL_COLOR_INDEX12_EXT:
+ case GL_COLOR_INDEX16_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth component format.
+ */
+GLboolean
+_mesa_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;
+ }
+}
+
+
+/**
+ * Test if the given image format is a stencil format.
+ */
+GLboolean
+_mesa_is_stencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_STENCIL_INDEX:
+ case GL_DEPTH_STENCIL:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a YCbCr format.
+ */
+GLboolean
+_mesa_is_ycbcr_format(GLenum format)
+{
+ switch (format) {
+ case GL_YCBCR_MESA:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
+ * Test if the given image format is a depth+stencil format.
+ */
+GLboolean
+_mesa_is_depthstencil_format(GLenum format)
+{
+ switch (format) {
+ case GL_DEPTH24_STENCIL8_EXT:
+ case GL_DEPTH_STENCIL_EXT:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+/**
+ * Test if the given image format is a dudv format.
+ */
+GLboolean
+_mesa_is_dudv_format(GLenum format)
+{
+ switch (format) {
+ case GL_DUDV_ATI:
+ case GL_DU8DV8_ATI:
+ return GL_TRUE;
+ default:
+ return GL_FALSE;
+ }
+}
+
+
+/**
* Return the address of a specific pixel in an image (1D, 2D or 3D).
*
* Pixel unpacking/packing parameters are observed according to \p packing.
@@ -1039,6 +1259,91 @@ _mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
}
+/**
+ * "Expand" a bitmap from 1-bit per pixel to 8-bits per pixel.
+ * This is typically used to convert a bitmap into a GLubyte/pixel texture.
+ * "On" bits will set texels to \p onValue.
+ * "Off" bits will not modify texels.
+ * \param width src bitmap width in pixels
+ * \param height src bitmap height in pixels
+ * \param unpack bitmap unpacking state
+ * \param bitmap the src bitmap data
+ * \param destBuffer start of dest buffer
+ * \param destStride row stride in dest buffer
+ * \param onValue if bit is 1, set destBuffer pixel to this value
+ */
+void
+_mesa_expand_bitmap(GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap,
+ GLubyte *destBuffer, GLint destStride,
+ GLubyte onValue)
+{
+ const GLubyte *srcRow = (const GLubyte *)
+ _mesa_image_address2d(unpack, bitmap, width, height,
+ GL_COLOR_INDEX, GL_BITMAP, 0, 0);
+ const GLint srcStride = _mesa_image_row_stride(unpack, width,
+ GL_COLOR_INDEX, GL_BITMAP);
+ GLint row, col;
+
+#define SET_PIXEL(COL, ROW) \
+ destBuffer[(ROW) * destStride + (COL)] = onValue;
+
+ for (row = 0; row < height; row++) {
+ const GLubyte *src = srcRow;
+
+ if (unpack->LsbFirst) {
+ /* Lsb first */
+ GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ if (*src & mask) {
+ SET_PIXEL(col, row);
+ }
+
+ if (mask == 128U) {
+ src++;
+ mask = 1U;
+ }
+ else {
+ mask = mask << 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 1)
+ src++;
+ }
+ else {
+ /* Msb first */
+ GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
+ for (col = 0; col < width; col++) {
+
+ if (*src & mask) {
+ SET_PIXEL(col, row);
+ }
+
+ if (mask == 1U) {
+ src++;
+ mask = 128U;
+ }
+ else {
+ mask = mask >> 1;
+ }
+ }
+
+ /* get ready for next row */
+ if (mask != 128)
+ src++;
+ }
+
+ srcRow += srcStride;
+ } /* row */
+
+#undef SET_PIXEL
+}
+
+
/**********************************************************************/
/***** Pixel processing functions ******/
/**********************************************************************/
@@ -5335,3 +5640,181 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
return GL_TRUE;
}
+
+
+/**
+ * Clip dst coords against Xmax (or Ymax).
+ */
+static INLINE void
+clip_right_or_top(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint maxValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX1 > maxValue) {
+ /* X1 outside right edge */
+ ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = maxValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX0 > maxValue) {
+ /* X0 outside right edge */
+ ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
+ t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [t, 1] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = maxValue;
+ bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
+ *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Clip dst coords against Xmin (or Ymin).
+ */
+static INLINE void
+clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
+ GLint *dstX0, GLint *dstX1,
+ GLint minValue)
+{
+ GLfloat t, bias;
+
+ if (*dstX0 < minValue) {
+ /* X0 outside left edge */
+ ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX0 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
+ *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
+ }
+ else if (*dstX1 < minValue) {
+ /* X1 outside left edge */
+ ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
+ t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
+ /* chop off [0, t] part */
+ ASSERT(t >= 0.0 && t <= 1.0);
+ *dstX1 = minValue;
+ bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
+ *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
+ }
+}
+
+
+/**
+ * Do clipping of blit src/dest rectangles.
+ * The dest rect is clipped against both the buffer bounds and scissor bounds.
+ * The src rect is just clipped against the buffer bounds.
+ *
+ * When either the src or dest rect is clipped, the other is also clipped
+ * proportionately!
+ *
+ * Note that X0 need not be less than X1 (same for Y) for either the source
+ * and dest rects. That makes the clipping a little trickier.
+ *
+ * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
+ */
+GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
+{
+ const GLint srcXmin = 0;
+ const GLint srcXmax = ctx->ReadBuffer->Width;
+ const GLint srcYmin = 0;
+ const GLint srcYmax = ctx->ReadBuffer->Height;
+
+ /* these include scissor bounds */
+ const GLint dstXmin = ctx->DrawBuffer->_Xmin;
+ const GLint dstXmax = ctx->DrawBuffer->_Xmax;
+ const GLint dstYmin = ctx->DrawBuffer->_Ymin;
+ const GLint dstYmax = ctx->DrawBuffer->_Ymax;
+
+ /*
+ printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ /* trivial rejection tests */
+ if (*dstX0 == *dstX1)
+ return GL_FALSE; /* no width */
+ if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
+ return GL_FALSE; /* totally out (left) of bounds */
+ if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
+ return GL_FALSE; /* totally out (right) of bounds */
+
+ if (*dstY0 == *dstY1)
+ return GL_FALSE;
+ if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
+ return GL_FALSE;
+ if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
+ return GL_FALSE;
+
+ if (*srcX0 == *srcX1)
+ return GL_FALSE;
+ if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
+ return GL_FALSE;
+ if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
+ return GL_FALSE;
+
+ if (*srcY0 == *srcY1)
+ return GL_FALSE;
+ if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
+ return GL_FALSE;
+ if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
+ return GL_FALSE;
+
+ /*
+ * dest clip
+ */
+ clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
+ clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
+ clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
+ clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
+
+ /*
+ * src clip (just swap src/dst values from above)
+ */
+ clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
+ clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
+ clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
+ clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
+
+ /*
+ printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
+ *srcX0, *srcX1, *dstX0, *dstX1);
+ printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
+ *srcY0, *srcY1, *dstY0, *dstY1);
+ */
+
+ ASSERT(*dstX0 >= dstXmin);
+ ASSERT(*dstX0 <= dstXmax);
+ ASSERT(*dstX1 >= dstXmin);
+ ASSERT(*dstX1 <= dstXmax);
+
+ ASSERT(*dstY0 >= dstYmin);
+ ASSERT(*dstY0 <= dstYmax);
+ ASSERT(*dstY1 >= dstYmin);
+ ASSERT(*dstY1 <= dstYmax);
+
+ ASSERT(*srcX0 >= srcXmin);
+ ASSERT(*srcX0 <= srcXmax);
+ ASSERT(*srcX1 >= srcXmin);
+ ASSERT(*srcX1 <= srcXmax);
+
+ ASSERT(*srcY0 >= srcYmin);
+ ASSERT(*srcY0 <= srcYmax);
+ ASSERT(*srcY1 >= srcYmin);
+ ASSERT(*srcY1 <= srcYmax);
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h
index b26c27e5a8..72717d6787 100644
--- a/src/mesa/main/image.h
+++ b/src/mesa/main/image.h
@@ -54,6 +54,27 @@ _mesa_bytes_per_pixel( GLenum format, GLenum type );
extern GLboolean
_mesa_is_legal_format_and_type( GLcontext *ctx, GLenum format, GLenum type );
+extern GLboolean
+_mesa_is_color_format(GLenum format);
+
+extern GLboolean
+_mesa_is_index_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depth_format(GLenum format);
+
+extern GLboolean
+_mesa_is_stencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_ycbcr_format(GLenum format);
+
+extern GLboolean
+_mesa_is_depthstencil_format(GLenum format);
+
+extern GLboolean
+_mesa_is_dudv_format(GLenum format);
+
extern GLvoid *
_mesa_image_address( GLuint dimensions,
@@ -113,6 +134,13 @@ extern void
_mesa_pack_bitmap( GLint width, GLint height, const GLubyte *source,
GLubyte *dest, const struct gl_pixelstore_attrib *packing );
+extern void
+_mesa_expand_bitmap(GLsizei width, GLsizei height,
+ const struct gl_pixelstore_attrib *unpack,
+ const GLubyte *bitmap,
+ GLubyte *destBuffer, GLint destStride,
+ GLubyte onValue);
+
/** \name Pixel processing functions */
/*@{*/
@@ -291,4 +319,10 @@ _mesa_clip_to_region(GLint xmin, GLint ymin,
GLint *x, GLint *y,
GLsizei *width, GLsizei *height );
+extern GLboolean
+_mesa_clip_blit(GLcontext *ctx,
+ GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
+ GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1);
+
+
#endif
diff --git a/src/mesa/main/imports.c b/src/mesa/main/imports.c
index 1722579e82..6ffaddcde9 100644
--- a/src/mesa/main/imports.c
+++ b/src/mesa/main/imports.c
@@ -911,6 +911,20 @@ _mesa_strtod( const char *s, char **end )
return strtod(s, end);
}
+/** Compute simple checksum/hash for a string */
+unsigned int
+_mesa_str_checksum(const char *str)
+{
+ /* This could probably be much better */
+ unsigned int sum, i;
+ const char *c;
+ sum = i = 1;
+ for (c = str; *c; c++)
+ sum += *c * (i % 100);
+ return sum;
+}
+
+
/*@}*/
@@ -1021,23 +1035,59 @@ output_if_debug(const char *prefixString, const char *outputString,
}
}
-static const char *error_string( GLenum error );
-static void flush_delayed_errors( GLcontext *ctx )
+/**
+ * Return string version of GL error code.
+ */
+static const char *
+error_string( GLenum error )
+{
+ switch (error) {
+ case GL_NO_ERROR:
+ return "GL_NO_ERROR";
+ case GL_INVALID_VALUE:
+ return "GL_INVALID_VALUE";
+ case GL_INVALID_ENUM:
+ return "GL_INVALID_ENUM";
+ case GL_INVALID_OPERATION:
+ return "GL_INVALID_OPERATION";
+ case GL_STACK_OVERFLOW:
+ return "GL_STACK_OVERFLOW";
+ case GL_STACK_UNDERFLOW:
+ return "GL_STACK_UNDERFLOW";
+ case GL_OUT_OF_MEMORY:
+ return "GL_OUT_OF_MEMORY";
+ case GL_TABLE_TOO_LARGE:
+ return "GL_TABLE_TOO_LARGE";
+ case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
+ return "GL_INVALID_FRAMEBUFFER_OPERATION";
+ default:
+ return "unknown";
+ }
+}
+
+
+/**
+ * When a new type of error is recorded, print a message describing
+ * previous errors which were accumulated.
+ */
+static void
+flush_delayed_errors( GLcontext *ctx )
{
- char s2[MAXSTRING];
+ char s[MAXSTRING];
if (ctx->ErrorDebugCount) {
- _mesa_snprintf(s2, MAXSTRING, "%d similar %s errors",
+ _mesa_snprintf(s, MAXSTRING, "%d similar %s errors",
ctx->ErrorDebugCount,
error_string(ctx->ErrorValue));
- output_if_debug("Mesa: ", s2, GL_TRUE);
+ output_if_debug("Mesa", s, GL_TRUE);
ctx->ErrorDebugCount = 0;
}
}
+
/**
* Report a warning (a recoverable error condition) to stderr if
* either DEBUG is defined or the MESA_DEBUG env var is set.
@@ -1083,31 +1133,6 @@ _mesa_problem( const GLcontext *ctx, const char *fmtString, ... )
fprintf(stderr, "Please report at bugzilla.freedesktop.org\n");
}
-static const char *error_string( GLenum error )
-{
- switch (error) {
- case GL_NO_ERROR:
- return "GL_NO_ERROR";
- case GL_INVALID_VALUE:
- return "GL_INVALID_VALUE";
- case GL_INVALID_ENUM:
- return "GL_INVALID_ENUM";
- case GL_INVALID_OPERATION:
- return "GL_INVALID_OPERATION";
- case GL_STACK_OVERFLOW:
- return "GL_STACK_OVERFLOW";
- case GL_STACK_UNDERFLOW:
- return "GL_STACK_UNDERFLOW";
- case GL_OUT_OF_MEMORY:
- return "GL_OUT_OF_MEMORY";
- case GL_TABLE_TOO_LARGE:
- return "GL_TABLE_TOO_LARGE";
- case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
- return "GL_INVALID_FRAMEBUFFER_OPERATION";
- default:
- return "unknown";
- }
-}
/**
* Record an OpenGL state error. These usually occur when the user
diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h
index 7b61e22e93..7d4012a856 100644
--- a/src/mesa/main/imports.h
+++ b/src/mesa/main/imports.h
@@ -291,6 +291,7 @@ long iround(float f);
#define IROUND(f) ((int) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
#endif
+#define IROUND64(f) ((GLint64) (((f) >= 0.0F) ? ((f) + 0.5F) : ((f) - 0.5F)))
/***
*** IROUND_POS: return (as an integer) positive float rounded to nearest int
@@ -586,6 +587,9 @@ _mesa_atoi( const char *s );
extern double
_mesa_strtod( const char *s, char **end );
+extern unsigned int
+_mesa_str_checksum(const char *str);
+
extern int
_mesa_sprintf( char *str, const char *fmt, ... );
diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c
index 0f0d831fee..10c89f4368 100644
--- a/src/mesa/main/light.c
+++ b/src/mesa/main/light.c
@@ -528,7 +528,7 @@ _mesa_LightModeliv( GLenum pname, const GLint *params )
break;
default:
/* Error will be caught later in gl_LightModelfv */
- ;
+ ASSIGN_4V(fparam, 0.0F, 0.0F, 0.0F, 0.0F);
}
_mesa_LightModelfv( pname, fparam );
}
@@ -1256,15 +1256,15 @@ _mesa_update_tnl_spaces( GLcontext *ctx, GLuint new_state )
ctx->Driver.LightingSpaceChange( ctx );
}
else {
- GLuint new_state = ctx->NewState;
+ GLuint new_state2 = ctx->NewState;
/* Recalculate that same state only if it has been invalidated
* by other statechanges.
*/
- if (new_state & _NEW_MODELVIEW)
+ if (new_state2 & _NEW_MODELVIEW)
update_modelview_scale(ctx);
- if (new_state & (_NEW_LIGHT|_NEW_MODELVIEW))
+ if (new_state2 & (_NEW_LIGHT|_NEW_MODELVIEW))
compute_light_positions( ctx );
}
}
diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h
index 4ca7957ffa..3d9a1aba98 100644
--- a/src/mesa/main/macros.h
+++ b/src/mesa/main/macros.h
@@ -99,6 +99,9 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256];
/* a close approximation: */
#define FLOAT_TO_INT(X) ( (GLint) (2147483647.0 * (X)) )
+/** Convert GLfloat in [-1.0,1.0] to GLint64 in [-(1<<63),(1 << 63) -1] */
+#define FLOAT_TO_INT64(X) ( (GLint64) (9223372036854775807.0 * (double)(X)) )
+
/** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0], texture/fb data */
#define INT_TO_FLOAT_TEX(I) ((I) == -2147483648 ? -1.0F : (I) * (1.0F/2147483647.0))
diff --git a/src/mesa/main/mfeatures.h b/src/mesa/main/mfeatures.h
index ef973314e3..e23cdb1f42 100644
--- a/src/mesa/main/mfeatures.h
+++ b/src/mesa/main/mfeatures.h
@@ -70,6 +70,7 @@
#define FEATURE_ARB_shader_objects (FEATURE_ARB_vertex_shader || FEATURE_ARB_fragment_shader)
#define FEATURE_ARB_shading_language_100 FEATURE_ARB_shader_objects
#define FEATURE_ARB_shading_language_120 FEATURE_ARB_shader_objects
+#define FEATURE_ARB_sync _HAVE_FULL_GL
#define FEATURE_EXT_framebuffer_blit _HAVE_FULL_GL
#define FEATURE_EXT_framebuffer_object _HAVE_FULL_GL
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index d0309f5e90..ae169fb9db 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -40,6 +40,7 @@
#include "main/mfeatures.h"
#include "glapi/glapi.h"
#include "math/m_matrix.h" /* GLmatrix */
+#include "main/simple_list.h" /* struct simple_node */
/**
@@ -83,6 +84,7 @@
/*@{*/
struct _mesa_HashTable;
struct gl_attrib_node;
+struct gl_meta_state;
struct gl_pixelstore_attrib;
struct gl_program_cache;
struct gl_texture_format;
@@ -227,7 +229,9 @@ typedef enum
FRAG_ATTRIB_TEX5 = 9,
FRAG_ATTRIB_TEX6 = 10,
FRAG_ATTRIB_TEX7 = 11,
- FRAG_ATTRIB_VAR0 = 12, /**< shader varying */
+ FRAG_ATTRIB_FACE = 12, /**< front/back face */
+ FRAG_ATTRIB_PNTC = 13, /**< sprite/point coord */
+ FRAG_ATTRIB_VAR0 = 14, /**< shader varying */
FRAG_ATTRIB_MAX = (FRAG_ATTRIB_VAR0 + MAX_VARYING)
} gl_frag_attrib;
@@ -239,6 +243,8 @@ typedef enum
#define FRAG_BIT_COL0 (1 << FRAG_ATTRIB_COL0)
#define FRAG_BIT_COL1 (1 << FRAG_ATTRIB_COL1)
#define FRAG_BIT_FOGC (1 << FRAG_ATTRIB_FOGC)
+#define FRAG_BIT_FACE (1 << FRAG_ATTRIB_FACE)
+#define FRAG_BIT_PNTC (1 << FRAG_ATTRIB_PNTC)
#define FRAG_BIT_TEX0 (1 << FRAG_ATTRIB_TEX0)
#define FRAG_BIT_TEX1 (1 << FRAG_ATTRIB_TEX1)
#define FRAG_BIT_TEX2 (1 << FRAG_ATTRIB_TEX2)
@@ -1440,6 +1446,9 @@ struct gl_texture_attrib
struct gl_texture_object *ProxyTex[NUM_TEXTURE_TARGETS];
+ /** GL_ARB_seamless_cubemap */
+ GLboolean CubeMapSeamless;
+
/** GL_EXT_shared_texture_palette */
GLboolean SharedPalette;
struct gl_color_table Palette;
@@ -1473,6 +1482,7 @@ struct gl_transform_attrib
GLboolean Normalize; /**< Normalize all normals? */
GLboolean RescaleNormals; /**< GL_EXT_rescale_normal */
GLboolean RasterPositionUnclipped; /**< GL_IBM_rasterpos_clip */
+ GLboolean DepthClamp; /**< GL_ARB_depth_clamp */
GLboolean CullVertexFlag; /**< True if GL_CULL_VERTEX_EXT is enabled */
GLfloat CullEyePos[4];
@@ -1791,7 +1801,7 @@ struct gl_program
/** Map from sampler unit to texture unit (set by glUniform1i()) */
GLubyte SamplerUnits[MAX_SAMPLERS];
/** Which texture target is being sampled (TEXTURE_1D/2D/3D/etc_INDEX) */
- GLubyte SamplerTargets[MAX_SAMPLERS];
+ gl_texture_index SamplerTargets[MAX_SAMPLERS];
/** Logical counts */
/*@{*/
@@ -1834,9 +1844,6 @@ struct gl_fragment_program
struct gl_program Base; /**< base class */
GLenum FogOption;
GLboolean UsesKill; /**< shader uses KIL instruction */
- GLboolean UsesPointCoord; /**< shader uses gl_PointCoord */
- GLboolean UsesFrontFacing; /**< shader used gl_FrontFacing */
- GLboolean UsesFogFragCoord; /**< shader used gl_FogFragCoord */
};
@@ -1981,6 +1988,21 @@ struct gl_query_state
};
+/** Sync object state */
+struct gl_sync_object {
+ struct simple_node link;
+ GLenum Type; /**< GL_SYNC_FENCE */
+ GLuint Name; /**< Fence name */
+ GLint RefCount; /**< Reference count */
+ GLboolean DeletePending; /**< Object was deleted while there were still
+ * live references (e.g., sync not yet finished)
+ */
+ GLenum SyncCondition;
+ GLbitfield Flags; /**< Flags passed to glFenceSync */
+ GLuint StatusFlag:1; /**< Has the sync object been signaled? */
+};
+
+
/** Set by #pragma directives */
struct gl_sl_pragmas
{
@@ -2004,6 +2026,7 @@ struct gl_shader
GLboolean Main; /**< shader defines main() */
GLboolean UnresolvedRefs;
const GLchar *Source; /**< Source code string */
+ GLuint SourceChecksum; /**< for debug/logging purposes */
struct gl_program *Program; /**< Post-compile assembly code */
GLchar *InfoLog;
struct gl_sl_pragmas Pragmas;
@@ -2034,6 +2057,7 @@ struct gl_shader_program
struct gl_program_parameter_list *Varying;
GLboolean LinkStatus; /**< GL_LINK_STATUS */
GLboolean Validated;
+ GLboolean _Used; /**< Ever used for drawing? */
GLchar *InfoLog;
};
@@ -2124,6 +2148,10 @@ struct gl_shared_state
struct _mesa_HashTable *FrameBuffers;
#endif
+#if FEATURE_ARB_sync
+ struct simple_node SyncObjects;
+#endif
+
void *DriverData; /**< Device driver shared state */
};
@@ -2428,6 +2456,12 @@ struct gl_constants
GLbitfield SupportedBumpUnits; /**> units supporting GL_ATI_envmap_bumpmap as targets */
+ /**
+ * Maximum amount of time, measured in nanseconds, that the server can wait.
+ */
+ GLuint64 MaxServerWaitTimeout;
+
+
/**< GL_EXT_provoking_vertex */
GLboolean QuadsFollowProvokingVertexConvention;
};
@@ -2442,7 +2476,9 @@ struct gl_extensions
GLboolean dummy; /* don't remove this! */
GLboolean ARB_copy_buffer;
GLboolean ARB_depth_texture;
+ GLboolean ARB_depth_clamp;
GLboolean ARB_draw_buffers;
+ GLboolean ARB_draw_elements_base_vertex;
GLboolean ARB_fragment_program;
GLboolean ARB_fragment_program_shadow;
GLboolean ARB_fragment_shader;
@@ -2454,11 +2490,13 @@ struct gl_extensions
GLboolean ARB_multitexture;
GLboolean ARB_occlusion_query;
GLboolean ARB_point_sprite;
+ GLboolean ARB_seamless_cube_map;
GLboolean ARB_shader_objects;
GLboolean ARB_shading_language_100;
GLboolean ARB_shading_language_120;
GLboolean ARB_shadow;
GLboolean ARB_shadow_ambient; /* or GL_ARB_shadow_ambient */
+ GLboolean ARB_sync;
GLboolean ARB_texture_border_clamp;
GLboolean ARB_texture_compression;
GLboolean ARB_texture_cube_map;
@@ -2981,6 +3019,8 @@ struct __GLcontextRec
struct gl_buffer_object *CopyWriteBuffer; /**< GL_ARB_copy_buffer */
/*@}*/
+ struct gl_meta_state *Meta; /**< for "meta" operations */
+
#if FEATURE_EXT_framebuffer_object
struct gl_renderbuffer *CurrentRenderbuffer;
#endif
diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c
index d9f3e476e8..fcef6dfd42 100644
--- a/src/mesa/main/pixel.c
+++ b/src/mesa/main/pixel.c
@@ -136,6 +136,33 @@ store_pixelmap(GLcontext *ctx, GLenum map, GLsizei mapsize,
}
+/**
+ * Convenience wrapper for _mesa_validate_pbo_access() for gl[Get]PixelMap().
+ */
+static GLboolean
+validate_pbo_access(GLcontext *ctx, struct gl_pixelstore_attrib *pack,
+ GLsizei mapsize, GLenum format, GLenum type,
+ const GLvoid *ptr)
+{
+ GLboolean ok;
+
+ /* Note, need to use DefaultPacking and Unpack's buffer object */
+ ctx->DefaultPacking.BufferObj = pack->BufferObj;
+
+ ok = _mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
+ format, type, ptr);
+
+ /* restore */
+ ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
+
+ if (!ok) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glPixelMap(invalid PBO access)");
+ }
+ return ok;
+}
+
+
void GLAPIENTRY
_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
{
@@ -158,40 +185,23 @@ _mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack pixelmap from PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Unpack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_FLOAT, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glPixelMapfv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
+ GL_INTENSITY, GL_FLOAT, values)) {
+ return;
+ }
+
+ values = (const GLfloat *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glPixelMapfv(PBO is mapped)");
- return;
}
- values = (const GLfloat *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
store_pixelmap(ctx, map, mapsize, values);
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
}
@@ -217,31 +227,17 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack pixelmap from PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Unpack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_UNSIGNED_INT, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glPixelMapuiv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
+ GL_INTENSITY, GL_UNSIGNED_INT, values)) {
+ return;
+ }
+
+ values = (const GLuint *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glPixelMapuiv(PBO is mapped)");
- return;
}
- values = (const GLuint *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
@@ -259,10 +255,7 @@ _mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
store_pixelmap(ctx, map, mapsize, fvalues);
}
@@ -290,32 +283,17 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
FLUSH_VERTICES(ctx, _NEW_PIXEL);
- if (ctx->Unpack.BufferObj->Name) {
- /* unpack pixelmap from PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Unpack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Unpack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_UNSIGNED_SHORT,
- values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glPixelMapusv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Unpack, mapsize,
+ GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
+ return;
+ }
+
+ values = (const GLushort *) _mesa_map_pbo_source(ctx, &ctx->Unpack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Unpack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glPixelMapusv(PBO is mapped)");
- return;
}
- values = (const GLushort *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
@@ -333,10 +311,7 @@ _mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values )
}
}
- if (ctx->Unpack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
store_pixelmap(ctx, map, mapsize, fvalues);
}
@@ -359,31 +334,17 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
- /* pack pixelmap into PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Pack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_FLOAT, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetPixelMapfv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
+ GL_INTENSITY, GL_FLOAT, values)) {
+ return;
+ }
+
+ values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetPixelMapfv(PBO is mapped)");
- return;
}
- values = (GLfloat *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
@@ -397,10 +358,7 @@ _mesa_GetPixelMapfv( GLenum map, GLfloat *values )
MEMCPY(values, pm->Map, mapsize * sizeof(GLfloat));
}
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
@@ -420,31 +378,17 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
mapsize = pm->Size;
- if (ctx->Pack.BufferObj->Name) {
- /* pack pixelmap into PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Pack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_UNSIGNED_INT, values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetPixelMapuiv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
+ GL_INTENSITY, GL_UNSIGNED_INT, values)) {
+ return;
+ }
+
+ values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetPixelMapuiv(PBO is mapped)");
- return;
}
- values = (GLuint *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
@@ -458,10 +402,7 @@ _mesa_GetPixelMapuiv( GLenum map, GLuint *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
@@ -481,32 +422,17 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
mapsize = pm ? pm->Size : 0;
- if (ctx->Pack.BufferObj->Name) {
- /* pack pixelmap into PBO */
- GLubyte *buf;
- /* Note, need to use DefaultPacking and Pack's buffer object */
- ctx->DefaultPacking.BufferObj = ctx->Pack.BufferObj;
- if (!_mesa_validate_pbo_access(1, &ctx->DefaultPacking, mapsize, 1, 1,
- GL_INTENSITY, GL_UNSIGNED_SHORT,
- values)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetPixelMapusv(invalid PBO access)");
- return;
- }
- /* restore */
- ctx->DefaultPacking.BufferObj = ctx->Shared->NullBufferObj;
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- /* buffer is already mapped - that's an error */
+ if (!validate_pbo_access(ctx, &ctx->Pack, mapsize,
+ GL_INTENSITY, GL_UNSIGNED_SHORT, values)) {
+ return;
+ }
+
+ values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values);
+ if (!values) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glGetPixelMapusv(PBO is mapped)");
- return;
}
- values = (GLushort *) ADD_POINTERS(buf, values);
- }
- else if (!values) {
return;
}
@@ -528,10 +454,7 @@ _mesa_GetPixelMapusv( GLenum map, GLushort *values )
}
}
- if (ctx->Pack.BufferObj->Name) {
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c
index 564250b881..376a87a396 100644
--- a/src/mesa/main/polygon.c
+++ b/src/mesa/main/polygon.c
@@ -193,32 +193,16 @@ _mesa_PolygonMode( GLenum face, GLenum mode )
void
_mesa_polygon_stipple(GLcontext *ctx, const GLubyte *pattern)
{
- if (ctx->Unpack.BufferObj->Name) {
- /* Get/unpack the stipple pattern from a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &ctx->Unpack, 32, 32, 1,
- GL_COLOR_INDEX, GL_BITMAP, pattern)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glPolygonStipple(bad PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- GL_READ_ONLY_ARB,
- ctx->Unpack.BufferObj);
- if (!buf) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glPolygonStipple(PBO mapped)");
- return;
- }
- buf = ADD_POINTERS(buf, pattern);
- _mesa_unpack_polygon_stipple(buf, ctx->PolygonStipple, &ctx->Unpack);
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
- ctx->Unpack.BufferObj);
- }
- else {
- /* Get/unpack the stipple pattern from user memory */
- _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
- }
+ pattern = _mesa_map_validate_pbo_source(ctx, 2,
+ &ctx->Unpack, 32, 32, 1,
+ GL_COLOR_INDEX, GL_BITMAP, pattern,
+ "glPolygonStipple");
+ if (!pattern)
+ return;
+
+ _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack);
+
+ _mesa_unmap_pbo_source(ctx, &ctx->Unpack);
}
@@ -255,35 +239,16 @@ _mesa_GetPolygonStipple( GLubyte *dest )
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glGetPolygonStipple\n");
- /* XXX someday we may put this code into a separate function and call
- * it with ctx->Driver.GetPolygonStipple().
- */
- if (ctx->Pack.BufferObj->Name) {
- /* Put/pack the stipple pattern into a PBO */
- GLubyte *buf;
- if (!_mesa_validate_pbo_access(2, &ctx->Pack, 32, 32, 1,
- GL_COLOR_INDEX, GL_BITMAP, dest)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetPolygonStipple(bad PBO access)");
- return;
- }
- buf = (GLubyte *) ctx->Driver.MapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- GL_WRITE_ONLY_ARB,
- ctx->Pack.BufferObj);
- if (!buf) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetPolygonStipple(PBO mapped)");
- return;
- }
- buf = ADD_POINTERS(buf, dest);
- _mesa_pack_polygon_stipple(ctx->PolygonStipple, buf, &ctx->Pack);
- ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
- ctx->Pack.BufferObj);
- }
- else {
- /* Put/pack the stipple pattern into user memory */
- _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
- }
+ dest = _mesa_map_validate_pbo_dest(ctx, 2,
+ &ctx->Pack, 32, 32, 1,
+ GL_COLOR_INDEX, GL_BITMAP, dest,
+ "glGetPolygonStipple");
+ if (!dest)
+ return;
+
+ _mesa_pack_polygon_stipple(ctx->PolygonStipple, dest, &ctx->Pack);
+
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
}
diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c
index 2326776ecb..feea1d375f 100644
--- a/src/mesa/main/readpix.c
+++ b/src/mesa/main/readpix.c
@@ -44,6 +44,10 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
GLboolean drawing)
{
const char *readDraw = drawing ? "Draw" : "Read";
+ const GLboolean reading = !drawing;
+
+ /* state validation should have already been done */
+ ASSERT(ctx->NewState == 0x0);
if (ctx->Extensions.EXT_packed_depth_stencil
&& type == GL_UNSIGNED_INT_24_8_EXT
@@ -73,32 +77,45 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
- if (drawing && !ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
+ if (drawing) {
+ if (!ctx->DrawBuffer->Visual.rgbMode) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
"glDrawPixels(drawing RGB pixels into color index buffer)");
- return GL_TRUE;
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_COLOR_INDEX:
- if (!drawing && ctx->Visual.rgbMode) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(reading color index format from RGB buffer)");
- return GL_TRUE;
+ if (drawing) {
+ if (ctx->DrawBuffer->Visual.rgbMode &&
+ (ctx->PixelMaps.ItoR.Size == 0 ||
+ ctx->PixelMaps.ItoG.Size == 0 ||
+ ctx->PixelMaps.ItoB.Size == 0)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glDrawPixels(drawing color index pixels into RGB buffer)");
+ return GL_TRUE;
+ }
}
- if (!drawing && !_mesa_dest_buffer_exists(ctx, GL_COLOR)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glReadPixels(no color buffer)");
- return GL_TRUE;
+ else {
+ /* reading */
+ if (!_mesa_source_buffer_exists(ctx, GL_COLOR)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glReadPixels(no color buffer)");
+ return GL_TRUE;
+ }
}
break;
case GL_STENCIL_INDEX:
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no stencil buffer)", readDraw);
return GL_TRUE;
@@ -118,7 +135,7 @@ _mesa_error_check_format_type(GLcontext *ctx, GLenum format, GLenum type,
return GL_TRUE;
}
if ((drawing && !_mesa_dest_buffer_exists(ctx, format)) ||
- (!drawing && !_mesa_source_buffer_exists(ctx, format))) {
+ (reading && !_mesa_source_buffer_exists(ctx, format))) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"gl%sPixels(no depth or stencil buffer)", readDraw);
return GL_TRUE;
@@ -173,7 +190,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
if (width == 0 || height == 0)
return; /* nothing to do */
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
if (!_mesa_validate_pbo_access(2, &ctx->Pack, width, height, 1,
format, type, pixels)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -181,7 +198,7 @@ _mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- if (ctx->Pack.BufferObj->Pointer) {
+ if (_mesa_bufferobj_mapped(ctx->Pack.BufferObj)) {
/* buffer is mapped - that's an error */
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(PBO is mapped)");
return;
diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c
index ad6e6ce7cd..643ad3354e 100644
--- a/src/mesa/main/shared.c
+++ b/src/mesa/main/shared.c
@@ -43,7 +43,9 @@
#if FEATURE_ATI_fragment_shader
#include "shader/atifragshader.h"
#endif
-
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+#endif
/**
* Allocate and initialize a shared context state structure.
@@ -127,6 +129,10 @@ _mesa_alloc_shared_state(GLcontext *ctx)
shared->RenderBuffers = _mesa_NewHashTable();
#endif
+#if FEATURE_ARB_sync
+ make_empty_list(& shared->SyncObjects);
+#endif
+
return shared;
}
@@ -196,7 +202,7 @@ delete_bufferobj_cb(GLuint id, void *data, void *userData)
{
struct gl_buffer_object *bufObj = (struct gl_buffer_object *) data;
GLcontext *ctx = (GLcontext *) userData;
- if (bufObj->Pointer) {
+ if (_mesa_bufferobj_mapped(bufObj)) {
ctx->Driver.UnmapBuffer(ctx, 0, bufObj);
bufObj->Pointer = NULL;
}
@@ -336,6 +342,17 @@ _mesa_free_shared_state(GLcontext *ctx, struct gl_shared_state *shared)
ctx->Driver.DeleteBuffer(ctx, shared->NullBufferObj);
#endif
+#if FEATURE_ARB_sync
+ {
+ struct simple_node *node;
+ struct simple_node *temp;
+
+ foreach_s(node, temp, & shared->SyncObjects) {
+ _mesa_unref_sync_object(ctx, (struct gl_sync_object *) node);
+ }
+ }
+#endif
+
/*
* Free texture objects (after FBOs since some textures might have
* been bound to FBOs).
diff --git a/src/mesa/main/simple_list.h b/src/mesa/main/simple_list.h
index 63475f6f74..ff7f888238 100644
--- a/src/mesa/main/simple_list.h
+++ b/src/mesa/main/simple_list.h
@@ -37,6 +37,11 @@
#ifndef _SIMPLE_LIST_H
#define _SIMPLE_LIST_H
+struct simple_node {
+ struct simple_node *next;
+ struct simple_node *prev;
+};
+
/**
* Remove an element from list.
*
diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c
index d8191ab518..140a998df2 100644
--- a/src/mesa/main/state.c
+++ b/src/mesa/main/state.c
@@ -547,7 +547,8 @@ _mesa_update_state_locked( GLcontext *ctx )
/* Determine which state flags effect vertex/fragment program state */
if (ctx->FragmentProgram._MaintainTexEnvProgram) {
prog_flags |= (_NEW_TEXTURE | _NEW_FOG |
- _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE);
+ _NEW_ARRAY | _NEW_LIGHT | _NEW_POINT | _NEW_RENDERMODE |
+ _NEW_PROGRAM);
}
if (ctx->VertexProgram._MaintainTnlProgram) {
prog_flags |= (_NEW_ARRAY | _NEW_TEXTURE | _NEW_TEXTURE_MATRIX |
@@ -712,6 +713,6 @@ _mesa_set_vp_override(GLcontext *ctx, GLboolean flag)
/* Set one of the bits which will trigger fragment program
* regeneration:
*/
- ctx->NewState |= _NEW_ARRAY;
+ ctx->NewState |= _NEW_PROGRAM;
}
}
diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c
new file mode 100644
index 0000000000..ac3f9eb175
--- /dev/null
+++ b/src/mesa/main/syncobj.c
@@ -0,0 +1,409 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file syncobj.c
+ * Sync object management.
+ *
+ * Unlike textures and other objects that are shared between contexts, sync
+ * objects are not bound to the context. As a result, the reference counting
+ * and delete behavior of sync objects is slightly different. References to
+ * sync objects are added:
+ *
+ * - By \c glFencSynce. This sets the initial reference count to 1.
+ * - At the start of \c glClientWaitSync. The reference is held for the
+ * duration of the wait call.
+ *
+ * References are removed:
+ *
+ * - By \c glDeleteSync.
+ * - At the end of \c glClientWaitSync.
+ *
+ * Additionally, drivers may call \c _mesa_ref_sync_object and
+ * \c _mesa_unref_sync_object as needed to implement \c ServerWaitSync.
+ *
+ * As with shader objects, sync object names become invalid as soon as
+ * \c glDeleteSync is called. For this reason \c glDeleteSync sets the
+ * \c DeletePending flag. All functions validate object handles by testing
+ * this flag.
+ *
+ * \note
+ * Only \c GL_ARB_sync objects are shared between contexts. If support is ever
+ * added for either \c GL_NV_fence or \c GL_APPLE_fence different semantics
+ * will need to be implemented.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "glheader.h"
+#include "imports.h"
+#include "context.h"
+#include "macros.h"
+
+#if FEATURE_ARB_sync
+#include "syncobj.h"
+
+static struct gl_sync_object *
+_mesa_new_sync_object(GLcontext *ctx, GLenum type)
+{
+ struct gl_sync_object *s = MALLOC_STRUCT(gl_sync_object);
+ (void) ctx;
+ (void) type;
+
+ return s;
+}
+
+
+static void
+_mesa_delete_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+ (void) ctx;
+ _mesa_free(syncObj);
+}
+
+
+static void
+_mesa_fence_sync(GLcontext *ctx, struct gl_sync_object *syncObj,
+ GLenum condition, GLbitfield flags)
+{
+ (void) ctx;
+ (void) condition;
+ (void) flags;
+
+ syncObj->StatusFlag = 1;
+}
+
+
+static void
+_mesa_check_sync(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+ (void) ctx;
+ (void) syncObj;
+
+ /* No-op for software rendering. Hardware drivers will need to determine
+ * whether the state of the sync object has changed.
+ */
+}
+
+
+static void
+_mesa_wait_sync(GLcontext *ctx, struct gl_sync_object *syncObj,
+ GLbitfield flags, GLuint64 timeout)
+{
+ (void) ctx;
+ (void) syncObj;
+ (void) flags;
+ (void) timeout;
+
+ /* No-op for software rendering. Hardware drivers will need to wait until
+ * the state of the sync object changes or the timeout expires.
+ */
+}
+
+
+void
+_mesa_init_sync_object_functions(struct dd_function_table *driver)
+{
+ driver->NewSyncObject = _mesa_new_sync_object;
+ driver->FenceSync = _mesa_fence_sync;
+ driver->DeleteSyncObject = _mesa_delete_sync_object;
+ driver->CheckSync = _mesa_check_sync;
+
+ /* Use the same no-op wait function for both.
+ */
+ driver->ClientWaitSync = _mesa_wait_sync;
+ driver->ServerWaitSync = _mesa_wait_sync;
+}
+
+
+/**
+ * Allocate/init the context state related to sync objects.
+ */
+void
+_mesa_init_sync(GLcontext *ctx)
+{
+ (void) ctx;
+}
+
+
+/**
+ * Free the context state related to sync objects.
+ */
+void
+_mesa_free_sync_data(GLcontext *ctx)
+{
+ (void) ctx;
+}
+
+
+static int
+_mesa_validate_sync(struct gl_sync_object *syncObj)
+{
+ return (syncObj != NULL)
+ && (syncObj->Type == GL_SYNC_FENCE)
+ && !syncObj->DeletePending;
+}
+
+
+void
+_mesa_ref_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ syncObj->RefCount++;
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+}
+
+
+void
+_mesa_unref_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj)
+{
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ syncObj->RefCount--;
+ if (syncObj->RefCount == 0) {
+ remove_from_list(& syncObj->link);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ ctx->Driver.DeleteSyncObject(ctx, syncObj);
+ } else {
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+ }
+}
+
+
+GLboolean GLAPIENTRY
+_mesa_IsSync(GLsync sync)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE);
+
+ return _mesa_validate_sync(syncObj) ? GL_TRUE : GL_FALSE;
+}
+
+
+void GLAPIENTRY
+_mesa_DeleteSync(GLsync sync)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ /* From the GL_ARB_sync spec:
+ *
+ * DeleteSync will silently ignore a <sync> value of zero. An
+ * INVALID_VALUE error is generated if <sync> is neither zero nor the
+ * name of a sync object.
+ */
+ if (sync == 0) {
+ return;
+ }
+
+ if (!_mesa_validate_sync(syncObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glDeleteSync");
+ return;
+ }
+
+ /* If there are no client-waits or server-waits pending on this sync, delete
+ * the underlying object.
+ */
+ syncObj->DeletePending = GL_TRUE;
+ _mesa_unref_sync_object(ctx, syncObj);
+}
+
+
+GLsync GLAPIENTRY
+_mesa_FenceSync(GLenum condition, GLbitfield flags)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *syncObj;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0);
+
+ if (condition != GL_SYNC_GPU_COMMANDS_COMPLETE) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glFenceSync(condition=0x%x)",
+ condition);
+ return 0;
+ }
+
+ if (flags != 0) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glFenceSync(flags=0x%x)",
+ condition);
+ return 0;
+ }
+
+ syncObj = ctx->Driver.NewSyncObject(ctx, GL_SYNC_FENCE);
+ if (syncObj != NULL) {
+ syncObj->Type = GL_SYNC_FENCE;
+ /* The name is not currently used, and it is never visible to
+ * applications. If sync support is extended to provide support for
+ * NV_fence, this field will be used. We'll also need to add an object
+ * ID hashtable.
+ */
+ syncObj->Name = 1;
+ syncObj->RefCount = 1;
+ syncObj->DeletePending = GL_FALSE;
+ syncObj->SyncCondition = condition;
+ syncObj->Flags = flags;
+ syncObj->StatusFlag = 0;
+
+ ctx->Driver.FenceSync(ctx, syncObj, condition, flags);
+
+ _glthread_LOCK_MUTEX(ctx->Shared->Mutex);
+ insert_at_tail(& ctx->Shared->SyncObjects, & syncObj->link);
+ _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex);
+
+ return (GLsync) syncObj;
+ }
+
+ return NULL;
+}
+
+
+GLenum GLAPIENTRY
+_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+ GLenum ret;
+ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED);
+
+ if (!_mesa_validate_sync(syncObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glClientWaitSync");
+ return GL_WAIT_FAILED;
+ }
+
+ if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glClientWaitSync(flags=0x%x)", flags);
+ return GL_WAIT_FAILED;
+ }
+
+ _mesa_ref_sync_object(ctx, syncObj);
+
+ /* From the GL_ARB_sync spec:
+ *
+ * ClientWaitSync returns one of four status values. A return value of
+ * ALREADY_SIGNALED indicates that <sync> was signaled at the time
+ * ClientWaitSync was called. ALREADY_SIGNALED will always be returned
+ * if <sync> was signaled, even if the value of <timeout> is zero.
+ */
+ ctx->Driver.CheckSync(ctx, syncObj);
+ if (syncObj->StatusFlag) {
+ ret = GL_ALREADY_SIGNALED;
+ } else {
+ ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout);
+
+ ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED;
+ }
+
+ _mesa_unref_sync_object(ctx, syncObj);
+ return ret;
+}
+
+
+void GLAPIENTRY
+_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!_mesa_validate_sync(syncObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glWaitSync");
+ return;
+ }
+
+ if (flags != 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glWaitSync(flags=0x%x)", flags);
+ return;
+ }
+
+ /* From the GL_ARB_sync spec:
+ *
+ * If the value of <timeout> is zero, then WaitSync does nothing.
+ */
+ if (timeout == 0) {
+ return;
+ }
+
+ ctx->Driver.ServerWaitSync(ctx, syncObj, flags, timeout);
+}
+
+
+void GLAPIENTRY
+_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
+ GLint *values)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync;
+ GLsizei size = 0;
+ GLint v[1];
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!_mesa_validate_sync(syncObj)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSynciv");
+ return;
+ }
+
+ switch (pname) {
+ case GL_OBJECT_TYPE:
+ v[0] = syncObj->Type;
+ size = 1;
+ break;
+
+ case GL_SYNC_CONDITION:
+ v[0] = syncObj->SyncCondition;
+ size = 1;
+ break;
+
+ case GL_SYNC_STATUS:
+ /* Update the state of the sync by dipping into the driver. Note that
+ * this call won't block. It just updates state in the common object
+ * data from the current driver state.
+ */
+ ctx->Driver.CheckSync(ctx, syncObj);
+
+ v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED;
+ size = 1;
+ break;
+
+ case GL_SYNC_FLAGS:
+ v[0] = syncObj->Flags;
+ size = 1;
+ break;
+
+ default:
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname);
+ return;
+ }
+
+ if (size > 0) {
+ const GLsizei copy_count = MIN2(size, bufSize);
+
+ _mesa_memcpy(values, v, sizeof(GLint) * copy_count);
+ }
+
+ if (length != NULL) {
+ *length = size;
+ }
+}
+
+#endif /* FEATURE_ARB_sync */
diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h
new file mode 100644
index 0000000000..f23fa281e2
--- /dev/null
+++ b/src/mesa/main/syncobj.h
@@ -0,0 +1,70 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file syncobj.h
+ * Sync object management.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef SYNCOBJ_H
+#define SYNCOBJ_H
+
+#include "context.h"
+
+extern void
+_mesa_init_sync_object_functions(struct dd_function_table *driver);
+
+extern void
+_mesa_init_sync(GLcontext *);
+
+extern void
+_mesa_free_sync_data(GLcontext *);
+
+extern void
+_mesa_ref_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj);
+
+extern void
+_mesa_unref_sync_object(GLcontext *ctx, struct gl_sync_object *syncObj);
+
+extern GLboolean GLAPIENTRY
+_mesa_IsSync(GLsync sync);
+
+extern void GLAPIENTRY
+_mesa_DeleteSync(GLsync sync);
+
+extern GLsync GLAPIENTRY
+_mesa_FenceSync(GLenum condition, GLbitfield flags);
+
+extern GLenum GLAPIENTRY
+_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+extern void GLAPIENTRY
+_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout);
+
+extern void GLAPIENTRY
+_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length,
+ GLint *values);
+
+#endif /* SYNCOBJ_H */
diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c
index 4c04a7ed37..6d86a4275c 100644
--- a/src/mesa/main/texenv.c
+++ b/src/mesa/main/texenv.c
@@ -35,6 +35,7 @@
#include "main/enums.h"
#include "main/macros.h"
#include "main/texenv.h"
+#include "main/texstate.h"
#define TE_ERROR(errCode, msg, value) \
@@ -466,7 +467,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
switch (pname) {
@@ -793,7 +794,7 @@ _mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -857,7 +858,7 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (target == GL_TEXTURE_ENV) {
if (pname == GL_TEXTURE_ENV_COLOR) {
@@ -908,12 +909,26 @@ _mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params )
}
}
-/* why does ATI_envmap_bumpmap require new entrypoints? Should just
- reuse TexEnv ones... */
+
+/**
+ * Why does ATI_envmap_bumpmap require new entrypoints? Should just
+ * reuse TexEnv ones...
+ */
void GLAPIENTRY
_mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
{
GLfloat p[4];
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END(ctx);
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ /* This isn't an "official" error case, but let's tell the user
+ * that something's wrong.
+ */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterivATI");
+ return;
+ }
+
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
/* hope that conversion is correct here */
p[0] = INT_TO_FLOAT( param[0] );
@@ -923,11 +938,12 @@ _mesa_TexBumpParameterivATI( GLenum pname, const GLint *param )
}
else {
p[0] = (GLfloat) param[0];
- p[1] = p[2] = p[3] = 0; /* init to zero, just to be safe */
+ p[1] = p[2] = p[3] = 0.0F; /* init to zero, just to be safe */
}
_mesa_TexBumpParameterfvATI( pname, p );
}
+
void GLAPIENTRY
_mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
{
@@ -935,8 +951,12 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_ATI) {
if (TEST_EQ_4V(param, texUnit->RotMatrix))
@@ -955,17 +975,21 @@ _mesa_TexBumpParameterfvATI( GLenum pname, const GLfloat *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterivATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
@@ -982,12 +1006,13 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
param[3] = FLOAT_TO_INT(texUnit->RotMatrix[3]);
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = temp;
+ *param = count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1002,23 +1027,27 @@ _mesa_GetTexBumpParameterivATI( GLenum pname, GLint *param )
}
}
+
void GLAPIENTRY
_mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
{
const struct gl_texture_unit *texUnit;
GLuint i;
- GLint temp = 0;
GET_CURRENT_CONTEXT(ctx);
ASSERT_OUTSIDE_BEGIN_END(ctx);
- /* should return error if extension not supported? */
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ if (!ctx->Extensions.ATI_envmap_bumpmap) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexBumpParameterfvATI");
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
if (pname == GL_BUMP_ROT_MATRIX_SIZE_ATI) {
/* spec leaves open to support larger matrices.
Don't think anyone would ever want to use it
(and apps might not understand it) so hardcode this. */
- *param = (GLfloat) 4;
+ *param = 4.0F;
}
else if (pname == GL_BUMP_ROT_MATRIX_ATI) {
param[0] = texUnit->RotMatrix[0];
@@ -1027,12 +1056,13 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
param[3] = texUnit->RotMatrix[3];
}
else if (pname == GL_BUMP_NUM_TEX_UNITS_ATI) {
+ GLint count = 0;
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
if (ctx->Const.SupportedBumpUnits & (1 << i)) {
- temp++;
+ count++;
}
}
- *param = (GLfloat) temp;
+ *param = (GLfloat) count;
}
else if (pname == GL_BUMP_TEX_UNITS_ATI) {
for (i = 0; i < ctx->Const.MaxTextureImageUnits; i++) {
@@ -1046,4 +1076,3 @@ _mesa_GetTexBumpParameterfvATI( GLenum pname, GLfloat *param )
return;
}
}
-
diff --git a/src/mesa/main/texenvprogram.c b/src/mesa/main/texenvprogram.c
index 6b090ff399..2f3e47e69e 100644
--- a/src/mesa/main/texenvprogram.c
+++ b/src/mesa/main/texenvprogram.c
@@ -27,8 +27,7 @@
**************************************************************************/
#include "glheader.h"
-#include "macros.h"
-#include "enums.h"
+#include "imports.h"
#include "shader/program.h"
#include "shader/prog_parameter.h"
#include "shader/prog_cache.h"
@@ -83,8 +82,13 @@ texenv_doing_secondary_color(GLcontext *ctx)
#define DISASSEM (MESA_VERBOSE & VERBOSE_DISASSEM)
struct mode_opt {
- GLuint Source:4;
- GLuint Operand:3;
+#ifdef __GNUC__
+ __extension__ GLubyte Source:4; /**< SRC_x */
+ __extension__ GLubyte Operand:3; /**< OPR_x */
+#else
+ GLubyte Source; /**< SRC_x */
+ GLubyte Operand; /**< OPR_x */
+#endif
};
struct state_key {
@@ -92,24 +96,26 @@ struct state_key {
GLuint enabled_units:8;
GLuint separate_specular:1;
GLuint fog_enabled:1;
- GLuint fog_mode:2;
+ GLuint fog_mode:2; /**< FOG_x */
GLuint inputs_available:12;
+ /* NOTE: This array of structs must be last! (see "keySize" below) */
struct {
GLuint enabled:1;
- GLuint source_index:3; /* one of TEXTURE_1D/2D/3D/CUBE/RECT_INDEX */
+ GLuint source_index:3; /**< TEXTURE_x_INDEX */
GLuint shadow:1;
GLuint ScaleShiftRGB:2;
GLuint ScaleShiftA:2;
- GLuint NumArgsRGB:3;
- GLuint ModeRGB:5;
- struct mode_opt OptRGB[MAX_COMBINER_TERMS];
+ GLuint NumArgsRGB:3; /**< up to MAX_COMBINER_TERMS */
+ GLuint ModeRGB:5; /**< MODE_x */
- GLuint NumArgsA:3;
- GLuint ModeA:5;
+ GLuint NumArgsA:3; /**< up to MAX_COMBINER_TERMS */
+ GLuint ModeA:5; /**< MODE_x */
+
+ struct mode_opt OptRGB[MAX_COMBINER_TERMS];
struct mode_opt OptA[MAX_COMBINER_TERMS];
- } unit[8];
+ } unit[MAX_TEXTURE_UNITS];
};
#define FOG_LINEAR 0
@@ -240,25 +246,51 @@ static GLuint translate_mode( GLenum envMode, GLenum mode )
}
}
-#define TEXTURE_UNKNOWN_INDEX 7
-static GLuint translate_tex_src_bit( GLbitfield bit )
+
+/**
+ * Do we need to clamp the results of the given texture env/combine mode?
+ * If the inputs to the mode are in [0,1] we don't always have to clamp
+ * the results.
+ */
+static GLboolean
+need_saturate( GLuint mode )
{
- /* make sure number of switch cases is correct */
- assert(NUM_TEXTURE_TARGETS == 7);
- switch (bit) {
- case TEXTURE_1D_BIT: return TEXTURE_1D_INDEX;
- case TEXTURE_2D_BIT: return TEXTURE_2D_INDEX;
- case TEXTURE_RECT_BIT: return TEXTURE_RECT_INDEX;
- case TEXTURE_3D_BIT: return TEXTURE_3D_INDEX;
- case TEXTURE_CUBE_BIT: return TEXTURE_CUBE_INDEX;
- case TEXTURE_1D_ARRAY_BIT: return TEXTURE_1D_ARRAY_INDEX;
- case TEXTURE_2D_ARRAY_BIT: return TEXTURE_2D_ARRAY_INDEX;
+ switch (mode) {
+ case MODE_REPLACE:
+ case MODE_MODULATE:
+ case MODE_INTERPOLATE:
+ return GL_FALSE;
+ case MODE_ADD:
+ case MODE_ADD_SIGNED:
+ case MODE_SUBTRACT:
+ case MODE_DOT3_RGB:
+ case MODE_DOT3_RGB_EXT:
+ case MODE_DOT3_RGBA:
+ case MODE_DOT3_RGBA_EXT:
+ case MODE_MODULATE_ADD_ATI:
+ case MODE_MODULATE_SIGNED_ADD_ATI:
+ case MODE_MODULATE_SUBTRACT_ATI:
+ case MODE_ADD_PRODUCTS:
+ case MODE_ADD_PRODUCTS_SIGNED:
+ case MODE_BUMP_ENVMAP_ATI:
+ return GL_TRUE;
default:
assert(0);
- return TEXTURE_UNKNOWN_INDEX;
}
}
+
+
+/**
+ * Translate TEXTURE_x_BIT to TEXTURE_x_INDEX.
+ */
+static GLuint translate_tex_src_bit( GLbitfield bit )
+{
+ ASSERT(bit);
+ return _mesa_ffs(bit) - 1;
+}
+
+
#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0)
#define VERT_RESULT_TEX_ANY (0xff << VERT_RESULT_TEX0)
@@ -275,6 +307,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
{
/* _NEW_PROGRAM */
const GLboolean vertexShader = (ctx->Shader.CurrentProgram &&
+ ctx->Shader.CurrentProgram->LinkStatus &&
ctx->Shader.CurrentProgram->VertexProgram);
const GLboolean vertexProgram = ctx->VertexProgram._Enabled;
GLbitfield fp_inputs = 0x0;
@@ -321,8 +354,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
/* Then look at what might be varying as a result of enabled
* arrays, etc:
*/
- if (varying_inputs & VERT_BIT_COLOR0) fp_inputs |= FRAG_BIT_COL0;
- if (varying_inputs & VERT_BIT_COLOR1) fp_inputs |= FRAG_BIT_COL1;
+ if (varying_inputs & VERT_BIT_COLOR0)
+ fp_inputs |= FRAG_BIT_COL0;
+ if (varying_inputs & VERT_BIT_COLOR1)
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0)
<< FRAG_ATTRIB_TEX0);
@@ -340,7 +375,7 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (vertexShader)
vprog = ctx->Shader.CurrentProgram->VertexProgram;
else
- vprog = ctx->VertexProgram._Current;
+ vprog = ctx->VertexProgram.Current;
vp_outputs = vprog->Base.OutputsWritten;
@@ -351,8 +386,10 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
if (ctx->Point.PointSprite)
vp_outputs |= FRAG_BITS_TEX_ANY;
- if (vp_outputs & (1 << VERT_RESULT_COL0)) fp_inputs |= FRAG_BIT_COL0;
- if (vp_outputs & (1 << VERT_RESULT_COL1)) fp_inputs |= FRAG_BIT_COL1;
+ if (vp_outputs & (1 << VERT_RESULT_COL0))
+ fp_inputs |= FRAG_BIT_COL0;
+ if (vp_outputs & (1 << VERT_RESULT_COL1))
+ fp_inputs |= FRAG_BIT_COL1;
fp_inputs |= (((vp_outputs & VERT_RESULT_TEX_ANY) >> VERT_RESULT_TEX0)
<< FRAG_ATTRIB_TEX0);
@@ -366,55 +403,55 @@ static GLbitfield get_fp_input_mask( GLcontext *ctx )
* Examine current texture environment state and generate a unique
* key to identify it.
*/
-static void make_state_key( GLcontext *ctx, struct state_key *key )
+static GLuint make_state_key( GLcontext *ctx, struct state_key *key )
{
GLuint i, j;
GLbitfield inputs_referenced = FRAG_BIT_COL0;
- GLbitfield inputs_available = get_fp_input_mask( ctx );
+ const GLbitfield inputs_available = get_fp_input_mask( ctx );
+ GLuint keySize;
memset(key, 0, sizeof(*key));
/* _NEW_TEXTURE */
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i];
+ const struct gl_texture_object *texObj = texUnit->_Current;
+ const struct gl_tex_env_combine_state *comb = texUnit->_CurrentCombine;
GLenum format;
if (!texUnit->_ReallyEnabled || !texUnit->Enabled)
continue;
- format = texUnit->_Current->Image[0][texUnit->_Current->BaseLevel]->_BaseFormat;
+ format = texObj->Image[0][texObj->BaseLevel]->_BaseFormat;
key->unit[i].enabled = 1;
key->enabled_units |= (1<<i);
- key->nr_enabled_units = i+1;
+ key->nr_enabled_units = i + 1;
inputs_referenced |= FRAG_BIT_TEX(i);
- key->unit[i].source_index =
- translate_tex_src_bit(texUnit->_ReallyEnabled);
- key->unit[i].shadow = ((texUnit->_Current->CompareMode == GL_COMPARE_R_TO_TEXTURE) &&
+ key->unit[i].source_index =
+ translate_tex_src_bit(texUnit->_ReallyEnabled);
+
+ key->unit[i].shadow = ((texObj->CompareMode == GL_COMPARE_R_TO_TEXTURE) &&
((format == GL_DEPTH_COMPONENT) ||
(format == GL_DEPTH_STENCIL_EXT)));
- key->unit[i].NumArgsRGB = texUnit->_CurrentCombine->_NumArgsRGB;
- key->unit[i].NumArgsA = texUnit->_CurrentCombine->_NumArgsA;
+ key->unit[i].NumArgsRGB = comb->_NumArgsRGB;
+ key->unit[i].NumArgsA = comb->_NumArgsA;
key->unit[i].ModeRGB =
- translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeRGB);
+ translate_mode(texUnit->EnvMode, comb->ModeRGB);
key->unit[i].ModeA =
- translate_mode(texUnit->EnvMode, texUnit->_CurrentCombine->ModeA);
+ translate_mode(texUnit->EnvMode, comb->ModeA);
- key->unit[i].ScaleShiftRGB = texUnit->_CurrentCombine->ScaleShiftRGB;
- key->unit[i].ScaleShiftA = texUnit->_CurrentCombine->ScaleShiftA;
+ key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB;
+ key->unit[i].ScaleShiftA = comb->ScaleShiftA;
for (j = 0; j < MAX_COMBINER_TERMS; j++) {
- key->unit[i].OptRGB[j].Operand =
- translate_operand(texUnit->_CurrentCombine->OperandRGB[j]);
- key->unit[i].OptA[j].Operand =
- translate_operand(texUnit->_CurrentCombine->OperandA[j]);
- key->unit[i].OptRGB[j].Source =
- translate_source(texUnit->_CurrentCombine->SourceRGB[j]);
- key->unit[i].OptA[j].Source =
- translate_source(texUnit->_CurrentCombine->SourceA[j]);
+ key->unit[i].OptRGB[j].Operand = translate_operand(comb->OperandRGB[j]);
+ key->unit[i].OptA[j].Operand = translate_operand(comb->OperandA[j]);
+ key->unit[i].OptRGB[j].Source = translate_source(comb->SourceRGB[j]);
+ key->unit[i].OptA[j].Source = translate_source(comb->SourceA[j]);
}
if (key->unit[i].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
@@ -442,8 +479,15 @@ static void make_state_key( GLcontext *ctx, struct state_key *key )
}
key->inputs_available = (inputs_available & inputs_referenced);
+
+ /* compute size of state key, ignoring unused texture units */
+ keySize = sizeof(*key) - sizeof(key->unit)
+ + key->nr_enabled_units * sizeof(key->unit[0]);
+
+ return keySize;
}
+
/**
* Use uregs to represent registers internally, translate to Mesa's
* expected formats on emit.
@@ -461,10 +505,8 @@ struct ureg {
GLuint file:4;
GLuint idx:8;
GLuint negatebase:1;
- GLuint abs:1;
- GLuint negateabs:1;
GLuint swz:12;
- GLuint pad:5;
+ GLuint pad:7;
};
static const struct ureg undef = {
@@ -472,8 +514,6 @@ static const struct ureg undef = {
~0,
0,
0,
- 0,
- 0,
0
};
@@ -482,7 +522,6 @@ static const struct ureg undef = {
*/
struct texenv_fragment_program {
struct gl_fragment_program *program;
- GLcontext *ctx;
struct state_key *state;
GLbitfield alu_temps; /**< Track texture indirections, see spec. */
@@ -519,8 +558,6 @@ static struct ureg make_ureg(GLuint file, GLuint idx)
reg.file = file;
reg.idx = idx;
reg.negatebase = 0;
- reg.abs = 0;
- reg.negateabs = 0;
reg.swz = SWIZZLE_NOOP;
reg.pad = 0;
return reg;
@@ -686,7 +723,7 @@ static void emit_arg( struct prog_src_register *reg,
reg->Index = ureg.idx;
reg->Swizzle = ureg.swz;
reg->Negate = ureg.negatebase ? NEGATE_XYZW : NEGATE_NONE;
- reg->Abs = ureg.abs;
+ reg->Abs = GL_FALSE;
}
static void emit_dst( struct prog_dst_register *dst,
@@ -709,7 +746,7 @@ emit_op(struct texenv_fragment_program *p,
struct ureg src1,
struct ureg src2 )
{
- GLuint nr = p->program->Base.NumInstructions++;
+ const GLuint nr = p->program->Base.NumInstructions++;
struct prog_instruction *inst = &p->program->Base.Instructions[nr];
assert(nr < MAX_INSTRUCTIONS);
@@ -947,17 +984,22 @@ static struct ureg emit_combine_source( struct texenv_fragment_program *p,
}
}
-static GLboolean args_match( struct state_key *key, GLuint unit )
+/**
+ * Check if the RGB and Alpha sources and operands match for the given
+ * texture unit's combinder state. When the RGB and A sources and
+ * operands match, we can emit fewer instructions.
+ */
+static GLboolean args_match( const struct state_key *key, GLuint unit )
{
- GLuint i, nr = key->unit[unit].NumArgsRGB;
+ GLuint i, numArgs = key->unit[unit].NumArgsRGB;
- for (i = 0 ; i < nr ; i++) {
+ for (i = 0; i < numArgs; i++) {
if (key->unit[unit].OptA[i].Source != key->unit[unit].OptRGB[i].Source)
return GL_FALSE;
- switch(key->unit[unit].OptA[i].Operand) {
+ switch (key->unit[unit].OptA[i].Operand) {
case OPR_SRC_ALPHA:
- switch(key->unit[unit].OptRGB[i].Operand) {
+ switch (key->unit[unit].OptRGB[i].Operand) {
case OPR_SRC_COLOR:
case OPR_SRC_ALPHA:
break;
@@ -966,7 +1008,7 @@ static GLboolean args_match( struct state_key *key, GLuint unit )
}
break;
case OPR_ONE_MINUS_SRC_ALPHA:
- switch(key->unit[unit].OptRGB[i].Operand) {
+ switch (key->unit[unit].OptRGB[i].Operand) {
case OPR_ONE_MINUS_SRC_COLOR:
case OPR_ONE_MINUS_SRC_ALPHA:
break;
@@ -1107,11 +1149,10 @@ static struct ureg emit_combine( struct texenv_fragment_program *p,
static struct ureg
emit_texenv(struct texenv_fragment_program *p, GLuint unit)
{
- struct state_key *key = p->state;
- GLboolean saturate = (unit < p->last_tex_stage);
+ const struct state_key *key = p->state;
+ GLboolean rgb_saturate, alpha_saturate;
GLuint rgb_shift, alpha_shift;
- struct ureg out, shift;
- struct ureg dest;
+ struct ureg out, dest;
if (!key->unit[unit].enabled) {
return get_source(p, SRC_PREVIOUS, 0);
@@ -1136,6 +1177,23 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
break;
}
+ /* If we'll do rgb/alpha shifting don't saturate in emit_combine().
+ * We don't want to clamp twice.
+ */
+ if (rgb_shift)
+ rgb_saturate = GL_FALSE; /* saturate after rgb shift */
+ else if (need_saturate(key->unit[unit].ModeRGB))
+ rgb_saturate = GL_TRUE;
+ else
+ rgb_saturate = GL_FALSE;
+
+ if (alpha_shift)
+ alpha_saturate = GL_FALSE; /* saturate after alpha shift */
+ else if (need_saturate(key->unit[unit].ModeA))
+ alpha_saturate = GL_TRUE;
+ else
+ alpha_saturate = GL_FALSE;
+
/* If this is the very last calculation, emit direct to output reg:
*/
if (key->separate_specular ||
@@ -1150,7 +1208,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
*/
if (key->unit[unit].ModeRGB == key->unit[unit].ModeA &&
args_match(key, unit)) {
- out = emit_combine( p, dest, WRITEMASK_XYZW, saturate,
+ out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate,
unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
@@ -1158,8 +1216,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
}
else if (key->unit[unit].ModeRGB == MODE_DOT3_RGBA_EXT ||
key->unit[unit].ModeRGB == MODE_DOT3_RGBA) {
-
- out = emit_combine( p, dest, WRITEMASK_XYZW, saturate,
+ out = emit_combine( p, dest, WRITEMASK_XYZW, rgb_saturate,
unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
@@ -1169,12 +1226,12 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
/* Need to do something to stop from re-emitting identical
* argument calculations here:
*/
- out = emit_combine( p, dest, WRITEMASK_XYZ, saturate,
+ out = emit_combine( p, dest, WRITEMASK_XYZ, rgb_saturate,
unit,
key->unit[unit].NumArgsRGB,
key->unit[unit].ModeRGB,
key->unit[unit].OptRGB);
- out = emit_combine( p, dest, WRITEMASK_W, saturate,
+ out = emit_combine( p, dest, WRITEMASK_W, alpha_saturate,
unit,
key->unit[unit].NumArgsA,
key->unit[unit].ModeA,
@@ -1184,6 +1241,9 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
/* Deal with the final shift:
*/
if (alpha_shift || rgb_shift) {
+ struct ureg shift;
+ GLboolean saturate = GL_TRUE; /* always saturate at this point */
+
if (rgb_shift == alpha_shift) {
shift = register_scalar_const(p, (GLfloat)(1<<rgb_shift));
}
@@ -1208,7 +1268,7 @@ emit_texenv(struct texenv_fragment_program *p, GLuint unit)
static void load_texture( struct texenv_fragment_program *p, GLuint unit )
{
if (is_undef(p->src_texture[unit])) {
- GLuint texTarget = p->state->unit[unit].source_index;
+ const GLuint texTarget = p->state->unit[unit].source_index;
struct ureg texcoord;
struct ureg tmp = get_tex_temp( p );
@@ -1220,9 +1280,6 @@ static void load_texture( struct texenv_fragment_program *p, GLuint unit )
texcoord = p->texcoord_tex[unit];
}
- if (texTarget == TEXTURE_UNKNOWN_INDEX)
- program_error(p, "TexSrcBit");
-
/* TODO: Use D0_MASK_XY where possible.
*/
if (p->state->unit[unit].enabled) {
@@ -1281,9 +1338,9 @@ static GLboolean load_texenv_source( struct texenv_fragment_program *p,
* Generate instructions for loading all texture source terms.
*/
static GLboolean
-load_texunit_sources( struct texenv_fragment_program *p, int unit )
+load_texunit_sources( struct texenv_fragment_program *p, GLuint unit )
{
- struct state_key *key = p->state;
+ const struct state_key *key = p->state;
GLuint i;
for (i = 0; i < key->unit[unit].NumArgsRGB; i++) {
@@ -1301,9 +1358,9 @@ load_texunit_sources( struct texenv_fragment_program *p, int unit )
* Generate instructions for loading bump map textures.
*/
static GLboolean
-load_texunit_bumpmap( struct texenv_fragment_program *p, int unit )
+load_texunit_bumpmap( struct texenv_fragment_program *p, GLuint unit )
{
- struct state_key *key = p->state;
+ const struct state_key *key = p->state;
GLuint bumpedUnitNr = key->unit[unit].OptRGB[1].Source - SRC_TEXTURE0;
struct ureg texcDst, bumpMapRes;
struct ureg constdudvcolor = register_const4f(p, 0.0, 0.0, 0.0, 1.0);
@@ -1317,17 +1374,20 @@ load_texunit_bumpmap( struct texenv_fragment_program *p, int unit )
texcDst = get_tex_temp( p );
p->texcoord_tex[bumpedUnitNr] = texcDst;
- /* apply rot matrix and add coords to be available in next phase */
- /* dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1) */
- /* note only 2 coords are affected the rest are left unchanged (mul by 0) */
+ /* Apply rot matrix and add coords to be available in next phase.
+ * dest = (Arg0.xxxx * rotMat0 + Arg1) + (Arg0.yyyy * rotMat1)
+ * note only 2 coords are affected the rest are left unchanged (mul by 0)
+ */
emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0,
swizzle1(bumpMapRes, SWIZZLE_X), rotMat0, texcSrc );
emit_arith( p, OPCODE_MAD, texcDst, WRITEMASK_XYZW, 0,
swizzle1(bumpMapRes, SWIZZLE_Y), rotMat1, texcDst );
- /* move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish
- enough to access this later, should optimize away */
- emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0, constdudvcolor, undef, undef );
+ /* Move 0,0,0,1 into bumpmap src if someone (crossbar) is foolish
+ * enough to access this later, should optimize away.
+ */
+ emit_arith( p, OPCODE_MOV, bumpMapRes, WRITEMASK_XYZW, 0,
+ constdudvcolor, undef, undef );
return GL_TRUE;
}
@@ -1346,7 +1406,6 @@ create_new_program(GLcontext *ctx, struct state_key *key,
struct ureg cf, out;
_mesa_memset(&p, 0, sizeof(p));
- p.ctx = ctx;
p.state = key;
p.program = program;
@@ -1355,17 +1414,17 @@ create_new_program(GLcontext *ctx, struct state_key *key,
*/
p.program->Base.Instructions = instBuffer;
p.program->Base.Target = GL_FRAGMENT_PROGRAM_ARB;
- p.program->Base.NumTexIndirections = 1;
+ p.program->Base.String = NULL;
+ p.program->Base.NumTexIndirections = 1; /* is this right? */
p.program->Base.NumTexInstructions = 0;
p.program->Base.NumAluInstructions = 0;
- p.program->Base.String = NULL;
- p.program->Base.NumInstructions =
- p.program->Base.NumTemporaries =
- p.program->Base.NumParameters =
- p.program->Base.NumAttributes = p.program->Base.NumAddressRegs = 0;
+ p.program->Base.NumInstructions = 0;
+ p.program->Base.NumTemporaries = 0;
+ p.program->Base.NumParameters = 0;
+ p.program->Base.NumAttributes = 0;
+ p.program->Base.NumAddressRegs = 0;
p.program->Base.Parameters = _mesa_new_parameter_list();
-
- p.program->Base.InputsRead = 0;
+ p.program->Base.InputsRead = 0x0;
p.program->Base.OutputsWritten = 1 << FRAG_RESULT_COLOR;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
@@ -1382,10 +1441,12 @@ create_new_program(GLcontext *ctx, struct state_key *key,
release_temps(ctx, &p);
if (key->enabled_units) {
- GLboolean needbumpstage = GL_FALSE;
+ GLboolean needbumpstage = GL_FALSE;
+
/* Zeroth pass - bump map textures first */
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
- if (key->unit[unit].enabled && key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
+ for (unit = 0; unit < key->nr_enabled_units; unit++)
+ if (key->unit[unit].enabled &&
+ key->unit[unit].ModeRGB == MODE_BUMP_ENVMAP_ATI) {
needbumpstage = GL_TRUE;
load_texunit_bumpmap( &p, unit );
}
@@ -1396,7 +1457,7 @@ create_new_program(GLcontext *ctx, struct state_key *key,
* all referenced texture sources and emit texld instructions
* for each:
*/
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits ; unit++)
+ for (unit = 0; unit < key->nr_enabled_units; unit++)
if (key->unit[unit].enabled) {
load_texunit_sources( &p, unit );
p.last_tex_stage = unit;
@@ -1404,8 +1465,8 @@ create_new_program(GLcontext *ctx, struct state_key *key,
/* Second pass - emit combine instructions to build final color:
*/
- for (unit = 0 ; unit < ctx->Const.MaxTextureUnits; unit++)
- if (key->enabled_units & (1<<unit)) {
+ for (unit = 0; unit < key->nr_enabled_units; unit++)
+ if (key->unit[unit].enabled) {
p.src_previous = emit_texenv( &p, unit );
reserve_temp(&p, p.src_previous); /* don't re-use this temp reg */
release_temps(ctx, &p); /* release all temps */
@@ -1438,9 +1499,11 @@ create_new_program(GLcontext *ctx, struct state_key *key,
* a reduced value and not what is expected in FogOption
*/
p.program->FogOption = ctx->Fog.Mode;
- p.program->Base.InputsRead |= FRAG_BIT_FOGC; /* XXX new */
- } else
+ p.program->Base.InputsRead |= FRAG_BIT_FOGC;
+ }
+ else {
p.program->FogOption = GL_NONE;
+ }
if (p.program->Base.NumTexIndirections > ctx->Const.FragmentProgram.MaxTexIndirections)
program_error(&p, "Exceeded max nr indirect texture lookups");
@@ -1493,12 +1556,13 @@ _mesa_get_fixed_func_fragment_program(GLcontext *ctx)
{
struct gl_fragment_program *prog;
struct state_key key;
+ GLuint keySize;
- make_state_key(ctx, &key);
+ keySize = make_state_key(ctx, &key);
prog = (struct gl_fragment_program *)
_mesa_search_program_cache(ctx->FragmentProgram.Cache,
- &key, sizeof(key));
+ &key, keySize);
if (!prog) {
prog = (struct gl_fragment_program *)
@@ -1507,7 +1571,7 @@ _mesa_get_fixed_func_fragment_program(GLcontext *ctx)
create_new_program(ctx, &key, prog);
_mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache,
- &key, sizeof(key), &prog->Base);
+ &key, keySize, &prog->Base);
}
return prog;
diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c
index e3feb024c3..b3ecfc784e 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/texgetimage.c b/src/mesa/main/texgetimage.c
index 02409d8009..14d6fc7659 100644
--- a/src/mesa/main/texgetimage.c
+++ b/src/mesa/main/texgetimage.c
@@ -30,11 +30,14 @@
#include "glheader.h"
+#include "bufferobj.h"
#include "context.h"
#include "image.h"
#include "texcompress.h"
#include "texformat.h"
#include "texgetimage.h"
+#include "teximage.h"
+#include "texstate.h"
@@ -116,7 +119,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
{
const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* Packing texture image into a PBO.
* Map the (potentially) VRAM-based buffer into our process space so
* we can write into it with the code below.
@@ -296,7 +299,7 @@ _mesa_get_teximage(GLcontext *ctx, GLenum target, GLint level,
} /* img */
}
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
@@ -316,7 +319,7 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
{
GLuint size;
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
/* pack texture image into a PBO */
GLubyte *buf;
if ((const GLubyte *) img + texImage->CompressedSize >
@@ -349,8 +352,230 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
/* just memcpy, no pixelstore or pixel transfer */
_mesa_memcpy(img, texImage->Data, size);
- if (ctx->Pack.BufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_PACK_BUFFER_EXT,
ctx->Pack.BufferObj);
}
}
+
+
+
+/**
+ * Do error checking for a glGetTexImage() call.
+ * \return GL_TRUE if any error, GL_FALSE if no errors.
+ */
+static GLboolean
+getteximage_error_check(GLcontext *ctx, GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ const GLuint maxLevels = _mesa_max_texture_levels(ctx, target);
+
+ if (maxLevels == 0) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target=0x%x)", target);
+ return GL_TRUE;
+ }
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_sizeof_packed_type(type) <= 0) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
+ return GL_TRUE;
+ }
+
+ if (_mesa_components_in_format(format) <= 0 ||
+ format == GL_STENCIL_INDEX) {
+ _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_paletted_texture && _mesa_is_index_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ARB_depth_texture && _mesa_is_depth_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.MESA_ycbcr_texture && _mesa_is_ycbcr_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.EXT_packed_depth_stencil
+ && _mesa_is_depthstencil_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ if (!ctx->Extensions.ATI_envmap_bumpmap
+ && _mesa_is_dudv_format(format)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
+ return GL_TRUE;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ if (!texObj || _mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
+ return GL_TRUE;
+ }
+
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (!texImage) {
+ /* out of memory */
+ return GL_TRUE;
+ }
+
+ /* Make sure the requested image format is compatible with the
+ * texture's format. Note that a color index texture can be converted
+ * to RGBA so that combo is allowed.
+ */
+ if (_mesa_is_color_format(format)
+ && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_index_format(format)
+ && !_mesa_is_index_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depth_format(format)
+ && !_mesa_is_depth_format(texImage->TexFormat->BaseFormat)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_ycbcr_format(format)
+ && !_mesa_is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_depthstencil_format(format)
+ && !_mesa_is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+ else if (_mesa_is_dudv_format(format)
+ && !_mesa_is_dudv_format(texImage->TexFormat->BaseFormat)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
+ return GL_TRUE;
+ }
+
+ if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) {
+ /* packing texture image into a PBO */
+ const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
+ if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
+ texImage->Height, texImage->Depth,
+ format, type, pixels)) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetTexImage(invalid PBO access)");
+ return GL_TRUE;
+ }
+ }
+
+ return GL_FALSE;
+}
+
+
+
+/**
+ * Get texture image. Called by glGetTexImage.
+ *
+ * \param target texture target.
+ * \param level image level.
+ * \param format pixel data format for returned image.
+ * \param type pixel data type for returned image.
+ * \param pixels returned pixel data.
+ */
+void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
+ GLenum type, GLvoid *pixels )
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ if (getteximage_error_check(ctx, target, level, format, type, pixels)) {
+ return;
+ }
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ struct gl_texture_image *texImage =
+ _mesa_select_tex_image(ctx, texObj, target, level);
+
+ /* typically, this will call _mesa_get_teximage() */
+ ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
+ texObj, texImage);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
+
+
+void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
+{
+ const struct gl_texture_unit *texUnit;
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ GLint maxLevels;
+ GET_CURRENT_CONTEXT(ctx);
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ texUnit = _mesa_get_current_tex_unit(ctx);
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ if (!texObj) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
+ return;
+ }
+
+ maxLevels = _mesa_max_texture_levels(ctx, target);
+ ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
+
+ if (level < 0 || level >= maxLevels) {
+ _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
+ return;
+ }
+
+ if (_mesa_is_proxy_texture(target)) {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
+ return;
+ }
+
+ _mesa_lock_texture(ctx, texObj);
+ {
+ texImage = _mesa_select_tex_image(ctx, texObj, target, level);
+ if (texImage) {
+ if (texImage->IsCompressed) {
+ /* this typically calls _mesa_get_compressed_teximage() */
+ ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
+ texObj, texImage);
+ }
+ else {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glGetCompressedTexImageARB");
+ }
+ }
+ else {
+ /* probably invalid mipmap level */
+ _mesa_error(ctx, GL_INVALID_VALUE,
+ "glGetCompressedTexImageARB(level)");
+ }
+ }
+ _mesa_unlock_texture(ctx, texObj);
+}
diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h
index 01f486e8f0..088d27c7e1 100644
--- a/src/mesa/main/texgetimage.h
+++ b/src/mesa/main/texgetimage.h
@@ -43,4 +43,13 @@ _mesa_get_compressed_teximage(GLcontext *ctx, GLenum target, GLint level,
+extern void GLAPIENTRY
+_mesa_GetTexImage( GLenum target, GLint level,
+ GLenum format, GLenum type, GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
+
+
#endif /* TEXGETIMAGE_H */
diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c
index 6e21066537..b555624d88 100644
--- a/src/mesa/main/teximage.c
+++ b/src/mesa/main/teximage.c
@@ -1,6 +1,6 @@
/*
* mesa 3-D graphics library
- * Version: 7.5
+ * Version: 7.6
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
@@ -36,6 +36,7 @@
#if FEATURE_convolve
#include "convolve.h"
#endif
+#include "enums.h"
#include "fbobject.h"
#include "framebuffer.h"
#include "hash.h"
@@ -182,6 +183,8 @@ logbase2( int n )
*
* This is the format which is used during texture application (i.e. the
* texture format and env mode determine the arithmetic used.
+ *
+ * XXX this could be static
*/
GLint
_mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
@@ -415,211 +418,6 @@ _mesa_base_tex_format( GLcontext *ctx, GLint internalFormat )
/**
- * Test if the given image format is a color/RGBA format (i.e., not color
- * index, depth, stencil, etc).
- * \param format the image format value (may by an internal texture format)
- * \return GL_TRUE if its a color/RGBA format, GL_FALSE otherwise.
- * XXX maybe move this func to image.c
- */
-GLboolean
-_mesa_is_color_format(GLenum format)
-{
- switch (format) {
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_ALPHA4:
- case GL_ALPHA8:
- case GL_ALPHA12:
- case GL_ALPHA16:
- case 1:
- case GL_LUMINANCE:
- case GL_LUMINANCE4:
- case GL_LUMINANCE8:
- case GL_LUMINANCE12:
- case GL_LUMINANCE16:
- case 2:
- case GL_LUMINANCE_ALPHA:
- case GL_LUMINANCE4_ALPHA4:
- case GL_LUMINANCE6_ALPHA2:
- case GL_LUMINANCE8_ALPHA8:
- case GL_LUMINANCE12_ALPHA4:
- case GL_LUMINANCE12_ALPHA12:
- case GL_LUMINANCE16_ALPHA16:
- case GL_INTENSITY:
- case GL_INTENSITY4:
- case GL_INTENSITY8:
- case GL_INTENSITY12:
- case GL_INTENSITY16:
- case 3:
- case GL_RGB:
- case GL_BGR:
- case GL_R3_G3_B2:
- case GL_RGB4:
- case GL_RGB5:
- case GL_RGB8:
- case GL_RGB10:
- case GL_RGB12:
- case GL_RGB16:
- case 4:
- case GL_ABGR_EXT:
- case GL_RGBA:
- case GL_BGRA:
- case GL_RGBA2:
- case GL_RGBA4:
- case GL_RGB5_A1:
- case GL_RGBA8:
- case GL_RGB10_A2:
- case GL_RGBA12:
- case GL_RGBA16:
- /* float texture formats */
- case GL_ALPHA16F_ARB:
- case GL_ALPHA32F_ARB:
- case GL_LUMINANCE16F_ARB:
- case GL_LUMINANCE32F_ARB:
- case GL_LUMINANCE_ALPHA16F_ARB:
- case GL_LUMINANCE_ALPHA32F_ARB:
- case GL_INTENSITY16F_ARB:
- case GL_INTENSITY32F_ARB:
- case GL_RGB16F_ARB:
- case GL_RGB32F_ARB:
- case GL_RGBA16F_ARB:
- case GL_RGBA32F_ARB:
- /* compressed formats */
- case GL_COMPRESSED_ALPHA:
- case GL_COMPRESSED_LUMINANCE:
- case GL_COMPRESSED_LUMINANCE_ALPHA:
- case GL_COMPRESSED_INTENSITY:
- case GL_COMPRESSED_RGB:
- case GL_COMPRESSED_RGBA:
- case GL_RGB_S3TC:
- case GL_RGB4_S3TC:
- case GL_RGBA_S3TC:
- case GL_RGBA4_S3TC:
- case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_RGB_FXT1_3DFX:
- case GL_COMPRESSED_RGBA_FXT1_3DFX:
-#if FEATURE_EXT_texture_sRGB
- case GL_SRGB_EXT:
- case GL_SRGB8_EXT:
- case GL_SRGB_ALPHA_EXT:
- case GL_SRGB8_ALPHA8_EXT:
- case GL_SLUMINANCE_ALPHA_EXT:
- case GL_SLUMINANCE8_ALPHA8_EXT:
- case GL_SLUMINANCE_EXT:
- case GL_SLUMINANCE8_EXT:
- case GL_COMPRESSED_SRGB_EXT:
- case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT:
- case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT:
- case GL_COMPRESSED_SLUMINANCE_EXT:
- case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT:
-#endif /* FEATURE_EXT_texture_sRGB */
- return GL_TRUE;
- /* signed texture formats */
- case GL_RGBA_SNORM:
- case GL_RGBA8_SNORM:
- return GL_TRUE;
- case GL_YCBCR_MESA: /* not considered to be RGB */
- /* fall-through */
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a color index format.
- */
-static GLboolean
-is_index_format(GLenum format)
-{
- switch (format) {
- case GL_COLOR_INDEX:
- case GL_COLOR_INDEX1_EXT:
- case GL_COLOR_INDEX2_EXT:
- case GL_COLOR_INDEX4_EXT:
- case GL_COLOR_INDEX8_EXT:
- case GL_COLOR_INDEX12_EXT:
- case GL_COLOR_INDEX16_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a depth component format.
- */
-static GLboolean
-is_depth_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH_COMPONENT16:
- case GL_DEPTH_COMPONENT24:
- case GL_DEPTH_COMPONENT32:
- case GL_DEPTH_COMPONENT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a YCbCr format.
- */
-static GLboolean
-is_ycbcr_format(GLenum format)
-{
- switch (format) {
- case GL_YCBCR_MESA:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
- * Test if the given image format is a Depth/Stencil format.
- */
-static GLboolean
-is_depthstencil_format(GLenum format)
-{
- switch (format) {
- case GL_DEPTH24_STENCIL8_EXT:
- case GL_DEPTH_STENCIL_EXT:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-/**
- * Test if the given image format is a dudv format.
- */
-static GLboolean
-is_dudv_format(GLenum format)
-{
- switch (format) {
- case GL_DUDV_ATI:
- case GL_DU8DV8_ATI:
- return GL_TRUE;
- default:
- return GL_FALSE;
- }
-}
-
-
-/**
* Test if it is a supported compressed format.
*
* \param internalFormat the internal format token provided by the user.
@@ -679,37 +477,14 @@ _mesa_set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
struct gl_texture_image *texImage)
{
+ const GLuint face = _mesa_tex_target_to_face(target);
+
ASSERT(tObj);
ASSERT(texImage);
- /* XXX simplify this with _mesa_tex_target_to_face() */
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- tObj->Image[0][level] = texImage;
- break;
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
- {
- GLuint face = ((GLuint) target -
- (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
- tObj->Image[face][level] = texImage;
- }
- break;
- case GL_TEXTURE_RECTANGLE_NV:
- ASSERT(level == 0);
- tObj->Image[0][level] = texImage;
- break;
- default:
- _mesa_problem(NULL, "bad target in _mesa_set_tex_image()");
- return;
- }
+ ASSERT(target != GL_TEXTURE_RECTANGLE_NV || level == 0);
+
+ tObj->Image[face][level] = texImage;
+
/* Set the 'back' pointer */
texImage->TexObject = tObj;
}
@@ -788,6 +563,9 @@ _mesa_delete_texture_image( GLcontext *ctx, struct gl_texture_image *texImage )
GLboolean
_mesa_is_proxy_texture(GLenum target)
{
+ /* NUM_TEXTURE_TARGETS should match number of terms below */
+ assert(NUM_TEXTURE_TARGETS == 7);
+
return (target == GL_PROXY_TEXTURE_1D ||
target == GL_PROXY_TEXTURE_2D ||
target == GL_PROXY_TEXTURE_3D ||
@@ -864,74 +642,28 @@ _mesa_select_tex_object(GLcontext *ctx, const struct gl_texture_unit *texUnit,
/**
- * Get the texture image struct which corresponds to target and level
- * of the given texture unit.
+ * Get a texture image pointer from a texture object, given a texture
+ * target and mipmap level. The target and level parameters should
+ * have already been error-checked.
*
* \param ctx GL context.
* \param texObj texture unit.
* \param target texture target.
* \param level image level.
*
- * \return pointer to the texture image structure on success, or NULL on failure.
- *
- * \sa gl_texture_unit.
+ * \return pointer to the texture image structure, or NULL on failure.
*/
struct gl_texture_image *
_mesa_select_tex_image(GLcontext *ctx, const struct gl_texture_object *texObj,
GLenum target, GLint level)
{
- ASSERT(texObj);
-
- if (level < 0 || level >= MAX_TEXTURE_LEVELS)
- return NULL;
-
- /* XXX simplify this with _mesa_tex_target_to_face() */
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_PROXY_TEXTURE_1D:
- case GL_TEXTURE_2D:
- case GL_PROXY_TEXTURE_2D:
- case GL_TEXTURE_3D:
- case GL_PROXY_TEXTURE_3D:
- return texObj->Image[0][level];
-
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
- if (ctx->Extensions.ARB_texture_cube_map) {
- GLuint face = ((GLuint) target -
- (GLuint) GL_TEXTURE_CUBE_MAP_POSITIVE_X);
- return texObj->Image[face][level];
- }
- else
- return NULL;
-
- case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- if (ctx->Extensions.ARB_texture_cube_map)
- return texObj->Image[0][level];
- else
- return NULL;
-
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_PROXY_TEXTURE_RECTANGLE_NV:
- if (ctx->Extensions.NV_texture_rectangle && level == 0)
- return texObj->Image[0][level];
- else
- return NULL;
+ const GLuint face = _mesa_tex_target_to_face(target);
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return (ctx->Extensions.MESA_texture_array)
- ? texObj->Image[0][level] : NULL;
+ ASSERT(texObj);
+ ASSERT(level >= 0);
+ ASSERT(level < MAX_TEXTURE_LEVELS);
- default:
- return NULL;
- }
+ return texObj->Image[face][level];
}
@@ -1053,10 +785,6 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_PROXY_TEXTURE_1D:
case GL_TEXTURE_2D:
case GL_PROXY_TEXTURE_2D:
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
return ctx->Const.MaxTextureLevels;
case GL_TEXTURE_3D:
case GL_PROXY_TEXTURE_3D:
@@ -1069,10 +797,17 @@ _mesa_max_texture_levels(GLcontext *ctx, GLenum target)
case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB:
case GL_TEXTURE_CUBE_MAP_ARB:
case GL_PROXY_TEXTURE_CUBE_MAP_ARB:
- return ctx->Const.MaxCubeTextureLevels;
+ return ctx->Extensions.ARB_texture_cube_map
+ ? ctx->Const.MaxCubeTextureLevels : 0;
case GL_TEXTURE_RECTANGLE_NV:
case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return 1;
+ return ctx->Extensions.NV_texture_rectangle ? 1 : 0;
+ case GL_TEXTURE_1D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
+ case GL_TEXTURE_2D_ARRAY_EXT:
+ case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
+ return ctx->Extensions.MESA_texture_array
+ ? ctx->Const.MaxTextureLevels : 0;
default:
return 0; /* bad target */
}
@@ -1273,6 +1008,23 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
/**
+ * Free and clear fields of the gl_texture_image struct.
+ *
+ * \param ctx GL context.
+ * \param texImage texture image structure to be cleared.
+ *
+ * After the call, \p texImage will have no data associated with it. Its
+ * fields are cleared so that its parent object will test incomplete.
+ */
+void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage)
+{
+ ctx->Driver.FreeTexImageData(ctx, texImage);
+ clear_teximage_fields(texImage);
+}
+
+
+/**
* This is the fallback for Driver.TestProxyTexImage(). Test the texture
* level, width, height and depth against the ctx->Const limits for textures.
*
@@ -1586,13 +1338,13 @@ texture_error_check( GLcontext *ctx, GLenum target,
/* make sure internal format and format basically agree */
colorFormat = _mesa_is_color_format(format);
- indexFormat = is_index_format(format);
+ indexFormat = _mesa_is_index_format(format);
if ((_mesa_is_color_format(internalFormat) && !colorFormat && !indexFormat) ||
- (is_index_format(internalFormat) && !indexFormat) ||
- (is_depth_format(internalFormat) != is_depth_format(format)) ||
- (is_ycbcr_format(internalFormat) != is_ycbcr_format(format)) ||
- (is_depthstencil_format(internalFormat) != is_depthstencil_format(format)) ||
- (is_dudv_format(internalFormat) != is_dudv_format(format))) {
+ (_mesa_is_index_format(internalFormat) && !indexFormat) ||
+ (_mesa_is_depth_format(internalFormat) != _mesa_is_depth_format(format)) ||
+ (_mesa_is_ycbcr_format(internalFormat) != _mesa_is_ycbcr_format(format)) ||
+ (_mesa_is_depthstencil_format(internalFormat) != _mesa_is_depthstencil_format(format)) ||
+ (_mesa_is_dudv_format(internalFormat) != _mesa_is_dudv_format(format))) {
if (!isProxy)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glTexImage%dD(incompatible internalFormat 0x%x, format 0x%x)",
@@ -1926,14 +1678,14 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
- /* NOTE: the format and type aren't really significant for
- * TestProxyTexImage(). Only the internalformat really matters.
if (!_mesa_source_buffer_exists(ctx, format)) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glCopyTexImage%dD(missing readbuffer)", dimensions);
return GL_TRUE;
}
+ /* NOTE: the format and type aren't really significant for
+ * TestProxyTexImage(). Only the internalformat really matters.
*/
type = GL_FLOAT;
@@ -2027,7 +1779,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depth_format(internalFormat)) {
+ else if (_mesa_is_depth_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2035,7 +1787,7 @@ copytexture_error_check( GLcontext *ctx, GLuint dimensions,
return GL_TRUE;
}
}
- else if (is_depthstencil_format(internalFormat)) {
+ else if (_mesa_is_depthstencil_format(internalFormat)) {
/* make sure we have depth/stencil buffers */
if (!ctx->ReadBuffer->_DepthBuffer || !ctx->ReadBuffer->_StencilBuffer) {
_mesa_error(ctx, GL_INVALID_OPERATION,
@@ -2260,147 +2012,6 @@ copytexsubimage_error_check2( GLcontext *ctx, GLuint dimensions,
}
-/**
- * Get texture image. Called by glGetTexImage.
- *
- * \param target texture target.
- * \param level image level.
- * \param format pixel data format for returned image.
- * \param type pixel data type for returned image.
- * \param pixels returned pixel data.
- */
-void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level, GLenum format,
- GLenum type, GLvoid *pixels )
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLint maxLevels = 0;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj || _mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(target)");
- return;
- }
-
- maxLevels = _mesa_max_texture_levels(ctx, target);
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error( ctx, GL_INVALID_VALUE, "glGetTexImage(level)" );
- return;
- }
-
- if (_mesa_sizeof_packed_type(type) <= 0) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(type)" );
- return;
- }
-
- if (_mesa_components_in_format(format) <= 0 ||
- format == GL_STENCIL_INDEX) {
- _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexImage(format)" );
- return;
- }
-
- if (!ctx->Extensions.EXT_paletted_texture && is_index_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return;
- }
-
- if (!ctx->Extensions.ARB_depth_texture && is_depth_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return;
- }
-
- if (!ctx->Extensions.MESA_ycbcr_texture && is_ycbcr_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return;
- }
-
- if (!ctx->Extensions.EXT_packed_depth_stencil
- && is_depthstencil_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return;
- }
-
- if (!ctx->Extensions.ATI_envmap_bumpmap
- && is_dudv_format(format)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexImage(format)");
- return;
- }
-
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (!texImage) {
- /* invalid mipmap level, not an error */
- goto out;
- }
-
-
- /* Make sure the requested image format is compatible with the
- * texture's format. Note that a color index texture can be converted
- * to RGBA so that combo is allowed.
- */
- if (_mesa_is_color_format(format)
- && !_mesa_is_color_format(texImage->TexFormat->BaseFormat)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
- else if (is_index_format(format)
- && !is_index_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
- else if (is_depth_format(format)
- && !is_depth_format(texImage->TexFormat->BaseFormat)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
- else if (is_ycbcr_format(format)
- && !is_ycbcr_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
- else if (is_depthstencil_format(format)
- && !is_depthstencil_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
- else if (is_dudv_format(format)
- && !is_dudv_format(texImage->TexFormat->BaseFormat)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glGetTexImage(format mismatch)");
- goto out;
- }
-
- if (ctx->Pack.BufferObj->Name) {
- /* packing texture image into a PBO */
- const GLuint dimensions = (target == GL_TEXTURE_3D) ? 3 : 2;
- if (!_mesa_validate_pbo_access(dimensions, &ctx->Pack, texImage->Width,
- texImage->Height, texImage->Depth,
- format, type, pixels)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetTexImage(invalid PBO access)");
- goto out;
- }
- }
-
- /* typically, this will call _mesa_get_teximage() */
- ctx->Driver.GetTexImage(ctx, target, level, format, type, pixels,
- texObj, texImage);
-
- }
- out:
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
/** Callback info for walking over FBO hash table */
struct cb_info
{
@@ -2465,6 +2076,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)
@@ -2521,6 +2149,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
@@ -2544,43 +2179,43 @@ _mesa_TexImage1D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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, "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);
- 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:
+ /* 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);
+
+ 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) {
@@ -2620,6 +2255,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
@@ -2652,42 +2294,42 @@ _mesa_TexImage2D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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, "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 ||
@@ -2736,6 +2378,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 ||
@@ -2755,42 +2404,42 @@ _mesa_TexImage3D( GLenum target, GLint level, GLint internalFormat,
if (ctx->NewState & _MESA_NEW_TRANSFER_STATE)
_mesa_update_state(ctx);
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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, "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 ||
@@ -2845,6 +2494,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);
@@ -2861,7 +2516,7 @@ _mesa_TexSubImage1D( GLenum target, GLint level,
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
assert(texObj);
@@ -2870,23 +2525,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);
}
@@ -2905,6 +2561,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);
@@ -2921,32 +2584,33 @@ _mesa_TexSubImage2D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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;
- if (width == 0 || height == 0)
- goto out; /* no-op, not an error */
+ ASSERT(ctx->Driver.TexSubImage2D);
+ ctx->Driver.TexSubImage2D(ctx, target, level, xoffset, yoffset,
+ width, height, 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;
-
- 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;
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -2965,6 +2629,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);
@@ -2973,35 +2644,37 @@ _mesa_TexSubImage3D( GLenum target, GLint level,
return; /* error was detected */
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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, 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);
}
@@ -3021,6 +2694,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);
@@ -3034,40 +2713,41 @@ _mesa_CopyTexImage1D( GLenum target, GLint level,
postConvWidth, 1, border))
return;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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);
}
@@ -3086,6 +2766,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);
@@ -3100,7 +2786,7 @@ _mesa_CopyTexImage2D( GLenum target, GLint level, GLenum internalFormat,
postConvWidth, postConvHeight, border))
return;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3109,33 +2795,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);
+
+ ASSERT(texImage->TexFormat);
- 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);
+ 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);
}
@@ -3154,13 +2841,18 @@ _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);
if (copytexsubimage_error_check1(ctx, 1, target, level))
return;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3175,23 +2867,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);
}
@@ -3209,13 +2903,18 @@ _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);
if (copytexsubimage_error_check1(ctx, 2, target, level))
return;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3229,24 +2928,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);
}
@@ -3264,13 +2968,18 @@ _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);
if (copytexsubimage_error_check1(ctx, 3, target, level))
return;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3286,25 +2995,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;
- ctx->NewState |= _NEW_TEXTURE;
+ 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);
+
+ check_gen_mipmap(ctx, target, texObj, level);
+
+ ctx->NewState |= _NEW_TEXTURE;
+ }
+ }
}
- out:
_mesa_unlock_texture(ctx, texObj);
}
@@ -3512,6 +3224,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;
@@ -3524,7 +3242,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3532,28 +3250,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);
+ check_gen_mipmap(ctx, target, texObj, 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_1D) {
@@ -3578,7 +3297,7 @@ _mesa_CompressedTexImage1DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3606,6 +3325,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 &&
@@ -3621,7 +3346,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3629,28 +3354,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 ||
@@ -3677,7 +3403,7 @@ _mesa_CompressedTexImage2DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
@@ -3705,6 +3431,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;
@@ -3717,36 +3449,38 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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, "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) {
@@ -3771,7 +3505,7 @@ _mesa_CompressedTexImage3DARB(GLenum target, GLint level,
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
texObj = _mesa_select_tex_object(ctx, texUnit, target);
_mesa_lock_texture(ctx, texObj);
{
@@ -3810,8 +3544,9 @@ _mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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);
@@ -3820,26 +3555,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);
}
@@ -3867,8 +3601,9 @@ _mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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);
@@ -3877,27 +3612,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);
}
@@ -3924,8 +3658,9 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ 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);
@@ -3934,82 +3669,30 @@ _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);
- }
- ctx->NewState |= _NEW_TEXTURE;
- }
- out:
- _mesa_unlock_texture(ctx, texObj);
-}
-
-
-void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint level, GLvoid *img)
-{
- const struct gl_texture_unit *texUnit;
- struct gl_texture_object *texObj;
- struct gl_texture_image *texImage;
- GLint maxLevels;
- GET_CURRENT_CONTEXT(ctx);
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
- texObj = _mesa_select_tex_object(ctx, texUnit, target);
- if (!texObj) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB");
- return;
- }
-
- maxLevels = _mesa_max_texture_levels(ctx, target);
- ASSERT(maxLevels > 0); /* 0 indicates bad target, caught above */
-
- if (level < 0 || level >= maxLevels) {
- _mesa_error(ctx, GL_INVALID_VALUE, "glGetCompressedTexImageARB(level)");
- return;
- }
+ }
- if (_mesa_is_proxy_texture(target)) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImageARB(target)");
- return;
- }
+ check_gen_mipmap(ctx, target, texObj, level);
- _mesa_lock_texture(ctx, texObj);
- {
- texImage = _mesa_select_tex_image(ctx, texObj, target, level);
- if (texImage) {
- if (texImage->IsCompressed) {
- /* this typically calls _mesa_get_compressed_teximage() */
- ctx->Driver.GetCompressedTexImage(ctx, target, level, img,
- texObj, texImage);
- }
- else {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glGetCompressedTexImageARB");
- }
- }
- else {
- /* probably invalid mipmap level */
- _mesa_error(ctx, GL_INVALID_VALUE,
- "glGetCompressedTexImageARB(level)");
+ ctx->NewState |= _NEW_TEXTURE;
}
}
_mesa_unlock_texture(ctx, texObj);
}
+
+
diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h
index eb60a1fa8f..094177da79 100644
--- a/src/mesa/main/teximage.h
+++ b/src/mesa/main/teximage.h
@@ -73,6 +73,10 @@ _mesa_init_teximage_fields(GLcontext *ctx, GLenum target,
extern void
+_mesa_clear_texture_image(GLcontext *ctx, struct gl_texture_image *texImage);
+
+
+extern void
_mesa_set_tex_image(struct gl_texture_object *tObj,
GLenum target, GLint level,
struct gl_texture_image *texImage);
@@ -111,10 +115,6 @@ extern GLuint
_mesa_tex_target_to_face(GLenum target);
-extern GLboolean
-_mesa_is_color_format(GLenum format);
-
-
/**
* Lock a texture for updating. See also _mesa_lock_context_textures().
*/
@@ -164,11 +164,6 @@ _mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
extern void GLAPIENTRY
-_mesa_GetTexImage( GLenum target, GLint level,
- GLenum format, GLenum type, GLvoid *pixels );
-
-
-extern void GLAPIENTRY
_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
GLsizei width,
GLenum format, GLenum type,
@@ -260,9 +255,6 @@ _mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
GLsizei height, GLsizei depth, GLenum format,
GLsizei imageSize, const GLvoid *data);
-extern void GLAPIENTRY
-_mesa_GetCompressedTexImageARB(GLenum target, GLint lod, GLvoid *img);
-
/*@}*/
#endif
diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c
index 2082f945f1..d09c439250 100644
--- a/src/mesa/main/texobj.c
+++ b/src/mesa/main/texobj.c
@@ -261,6 +261,32 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
/**
+ * Clear all texture images of the given texture object.
+ *
+ * \param ctx GL context.
+ * \param t texture object.
+ *
+ * \sa _mesa_clear_texture_image().
+ */
+void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *texObj)
+{
+ GLuint i, j;
+
+ if (texObj->Target == 0)
+ return;
+
+ for (i = 0; i < MAX_FACES; i++) {
+ for (j = 0; j < MAX_TEXTURE_LEVELS; j++) {
+ struct gl_texture_image *texImage = texObj->Image[i][j];
+ if (texImage)
+ _mesa_clear_texture_image(ctx, texImage);
+ }
+ }
+}
+
+
+/**
* Check if the given texture object is valid by examining its Target field.
* For debugging only.
*/
@@ -308,7 +334,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
GLboolean deleteFlag = GL_FALSE;
struct gl_texture_object *oldTex = *ptr;
- assert(valid_texture_object(oldTex));
+ ASSERT(valid_texture_object(oldTex));
_glthread_LOCK_MUTEX(oldTex->Mutex);
ASSERT(oldTex->RefCount > 0);
@@ -331,7 +357,7 @@ _mesa_reference_texobj(struct gl_texture_object **ptr,
if (tex) {
/* reference new texture */
- assert(valid_texture_object(tex));
+ ASSERT(valid_texture_object(tex));
_glthread_LOCK_MUTEX(tex->Mutex);
if (tex->RefCount == 0) {
/* this texture's being deleted (look just above) */
@@ -665,6 +691,24 @@ _mesa_test_texobj_completeness( const GLcontext *ctx,
/**
+ * Mark a texture object dirty. It forces the object to be incomplete
+ * and optionally forces the context to re-validate its state.
+ *
+ * \param ctx GL context.
+ * \param texObj texture object.
+ * \param invalidate_state also invalidate context state.
+ */
+void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state)
+{
+ texObj->_Complete = GL_FALSE;
+ if (invalidate_state)
+ ctx->NewState |= _NEW_TEXTURE;
+}
+
+
+/**
* Return pointer to a default/fallback texture.
* The texture is a 2D 8x8 RGBA texture with all texels = (0,0,0,1).
* That's the value a sampler should get when sampling from an
@@ -715,7 +759,6 @@ _mesa_get_fallback_texture(GLcontext *ctx)
}
-
/*@}*/
@@ -1160,10 +1203,9 @@ _mesa_IsTexture( GLuint texture )
/**
- * Simplest implementation of texture locking: Grab the a new mutex in
- * the shared context. Examine the shared context state timestamp and
- * if there has been a change, set the appropriate bits in
- * ctx->NewState.
+ * Simplest implementation of texture locking: grab the shared tex
+ * mutex. Examine the shared context state timestamp and if there has
+ * been a change, set the appropriate bits in ctx->NewState.
*
* This is used to deal with synchronizing things when a texture object
* is used/modified by different contexts (or threads) which are sharing
diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h
index 2599c0816a..9bfebd45c8 100644
--- a/src/mesa/main/texobj.h
+++ b/src/mesa/main/texobj.h
@@ -58,6 +58,9 @@ _mesa_copy_texture_object( struct gl_texture_object *dest,
const struct gl_texture_object *src );
extern void
+_mesa_clear_texture_object(GLcontext *ctx, struct gl_texture_object *obj);
+
+extern void
_mesa_reference_texobj(struct gl_texture_object **ptr,
struct gl_texture_object *tex);
@@ -65,6 +68,10 @@ extern void
_mesa_test_texobj_completeness( const GLcontext *ctx,
struct gl_texture_object *obj );
+extern void
+_mesa_dirty_texobj(GLcontext *ctx, struct gl_texture_object *texObj,
+ GLboolean invalidate_state);
+
extern struct gl_texture_object *
_mesa_get_fallback_texture(GLcontext *ctx);
@@ -76,7 +83,6 @@ _mesa_lock_context_textures( GLcontext *ctx );
/*@}*/
-
/**
* \name API functions
*/
diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c
index d27c59381c..b2fbe2205b 100644
--- a/src/mesa/main/texparam.c
+++ b/src/mesa/main/texparam.c
@@ -38,6 +38,7 @@
#include "main/texcompress.h"
#include "main/texparam.h"
#include "main/teximage.h"
+#include "main/texstate.h"
#include "shader/prog_instruction.h"
@@ -69,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;
}
@@ -88,7 +89,7 @@ get_texobj(GLcontext *ctx, GLenum target)
return NULL;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
switch (target) {
case GL_TEXTURE_1D:
@@ -209,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;
@@ -224,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;
@@ -716,44 +717,6 @@ _mesa_GetTexLevelParameterfv( GLenum target, GLint level,
}
-static GLuint
-tex_image_dimensions(GLcontext *ctx, GLenum target)
-{
- switch (target) {
- case GL_TEXTURE_1D:
- case GL_PROXY_TEXTURE_1D:
- return 1;
- case GL_TEXTURE_2D:
- case GL_PROXY_TEXTURE_2D:
- return 2;
- case GL_TEXTURE_3D:
- case GL_PROXY_TEXTURE_3D:
- return 3;
- case GL_TEXTURE_CUBE_MAP:
- case GL_PROXY_TEXTURE_CUBE_MAP:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- return ctx->Extensions.ARB_texture_cube_map ? 2 : 0;
- case GL_TEXTURE_RECTANGLE_NV:
- case GL_PROXY_TEXTURE_RECTANGLE_NV:
- return ctx->Extensions.NV_texture_rectangle ? 2 : 0;
- case GL_TEXTURE_1D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_1D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 2 : 0;
- case GL_TEXTURE_2D_ARRAY_EXT:
- case GL_PROXY_TEXTURE_2D_ARRAY_EXT:
- return ctx->Extensions.MESA_texture_array ? 3 : 0;
- default:
- _mesa_problem(ctx, "bad target in _mesa_tex_target_dimensions()");
- return 0;
- }
-}
-
-
void GLAPIENTRY
_mesa_GetTexLevelParameteriv( GLenum target, GLint level,
GLenum pname, GLint *params )
@@ -761,7 +724,6 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
const struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
const struct gl_texture_image *img = NULL;
- GLuint dimensions;
GLboolean isProxy;
GLint maxLevels;
GET_CURRENT_CONTEXT(ctx);
@@ -773,19 +735,13 @@ _mesa_GetTexLevelParameteriv( GLenum target, GLint level,
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
/* this will catch bad target values */
- dimensions = tex_image_dimensions(ctx, target); /* 1, 2 or 3 */
- if (dimensions == 0) {
- _mesa_error(ctx, GL_INVALID_ENUM, "glGetTexLevelParameter[if]v(target)");
- return;
- }
-
maxLevels = _mesa_max_texture_levels(ctx, target);
if (maxLevels == 0) {
- /* should not happen since <target> was just checked above */
- _mesa_problem(ctx, "maxLevels=0 in _mesa_GetTexLevelParameter");
+ _mesa_error(ctx, GL_INVALID_ENUM,
+ "glGetTexLevelParameter[if]v(target=0x%x)", target);
return;
}
@@ -1002,7 +958,7 @@ _mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
@@ -1169,7 +1125,7 @@ _mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params )
return;
}
- texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
+ texUnit = _mesa_get_current_tex_unit(ctx);
obj = _mesa_select_tex_object(ctx, texUnit, target);
if (!obj) {
diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c
index 6e0c0c688a..861c5f37c4 100644
--- a/src/mesa/main/texstate.c
+++ b/src/mesa/main/texstate.c
@@ -729,14 +729,7 @@ init_texture_unit( GLcontext *ctx, GLuint unit )
ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenS.ObjectPlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.ObjectPlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.ObjectPlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenS.EyePlane, 1.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenT.EyePlane, 0.0, 1.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenR.EyePlane, 0.0, 0.0, 0.0, 0.0 );
- ASSIGN_4V( texUnit->GenQ.EyePlane, 0.0, 0.0, 0.0, 0.0 );
+
/* no mention of this in spec, but maybe id matrix expected? */
ASSIGN_4V( texUnit->RotMatrix, 1.0, 0.0, 0.0, 1.0 );
diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h
index a7d7088c62..17ac68000c 100644
--- a/src/mesa/main/texstate.h
+++ b/src/mesa/main/texstate.h
@@ -35,6 +35,18 @@
#include "mtypes.h"
+/**
+ * Return pointer to current texture unit.
+ * This the texture unit set by glActiveTexture(), not glClientActiveTexture().
+ */
+static INLINE struct gl_texture_unit *
+_mesa_get_current_tex_unit(GLcontext *ctx)
+{
+ ASSERT(ctx->Texture.CurrentUnit < Elements(ctx->Texture.Unit));
+ return &(ctx->Texture.Unit[ctx->Texture.CurrentUnit]);
+}
+
+
extern void
_mesa_copy_texture_state( const GLcontext *src, GLcontext *dst );
@@ -48,16 +60,14 @@ _mesa_print_texunit_state( GLcontext *ctx, GLuint unit );
*/
/*@{*/
-
-/*
- * GL_ARB_multitexture
- */
extern void GLAPIENTRY
_mesa_ActiveTextureARB( GLenum target );
extern void GLAPIENTRY
_mesa_ClientActiveTextureARB( GLenum target );
+/*@}*/
+
/**
* \name Initialization, state maintenance
diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c
index bfced1b3f4..ab9973b810 100644
--- a/src/mesa/main/texstore.c
+++ b/src/mesa/main/texstore.c
@@ -3138,7 +3138,7 @@ _mesa_validate_pbo_teximage(GLcontext *ctx, GLuint dimensions,
{
GLubyte *buf;
- if (unpack->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(unpack->BufferObj)) {
/* no PBO */
return pixels;
}
@@ -3174,7 +3174,7 @@ _mesa_validate_pbo_compressed_teximage(GLcontext *ctx,
{
GLubyte *buf;
- if (packing->BufferObj->Name == 0) {
+ if (!_mesa_is_bufferobj(packing->BufferObj)) {
/* not using a PBO - return pointer unchanged */
return pixels;
}
@@ -3204,7 +3204,7 @@ void
_mesa_unmap_teximage_pbo(GLcontext *ctx,
const struct gl_pixelstore_attrib *unpack)
{
- if (unpack->BufferObj->Name) {
+ if (_mesa_is_bufferobj(unpack->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx, GL_PIXEL_UNPACK_BUFFER_EXT,
unpack->BufferObj);
}
@@ -3302,32 +3302,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 +3342,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 +3385,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 +3411,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 +3463,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 +3485,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 +3537,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 +3578,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 +3626,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 +3674,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 +3724,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 +3748,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 +3853,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/main/varray.c b/src/mesa/main/varray.c
index 3d5b8faecf..6cd2a2f4f6 100644
--- a/src/mesa/main/varray.c
+++ b/src/mesa/main/varray.c
@@ -135,7 +135,8 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -186,7 +187,8 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr )
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glNormalPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -265,7 +267,8 @@ _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr)
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -415,7 +418,8 @@ _mesa_SecondaryColorPointerEXT(GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glSecondaryColorPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -476,7 +480,8 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride,
break;
#endif
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glTexCoordPointer(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -610,7 +615,8 @@ _mesa_VertexAttribPointerNV(GLuint index, GLint size, GLenum type,
elementSize = size * sizeof(GLdouble);
break;
default:
- _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type)" );
+ _mesa_error( ctx, GL_INVALID_ENUM, "glVertexAttribPointerNV(type=%s)",
+ _mesa_lookup_enum_by_nr(type));
return;
}
@@ -1032,24 +1038,6 @@ _mesa_MultiDrawArraysEXT( GLenum mode, GLint *first,
}
-/* GL_EXT_multi_draw_arrays */
-void GLAPIENTRY
-_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
- const GLvoid **indices, GLsizei primcount )
-{
- GET_CURRENT_CONTEXT(ctx);
- GLint i;
-
- ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
-
- for (i = 0; i < primcount; i++) {
- if (count[i] > 0) {
- CALL_DrawElements(ctx->Exec, (mode, count[i], type, indices[i]));
- }
- }
-}
-
-
/* GL_IBM_multimode_draw_arrays */
void GLAPIENTRY
_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
@@ -1093,6 +1081,29 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count,
/**
+ * Copy one client vertex array to another.
+ */
+void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src)
+{
+ dst->Size = src->Size;
+ dst->Type = src->Type;
+ dst->Format = src->Format;
+ dst->Stride = src->Stride;
+ dst->StrideB = src->StrideB;
+ dst->Ptr = src->Ptr;
+ dst->Enabled = src->Enabled;
+ dst->Normalized = src->Normalized;
+ dst->_ElementSize = src->_ElementSize;
+ _mesa_reference_buffer_object(ctx, &dst->BufferObj, src->BufferObj);
+ dst->_MaxElement = src->_MaxElement;
+}
+
+
+
+/**
* Print vertex array's fields.
*/
static void
diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h
index d4d505ae04..ef790c504e 100644
--- a/src/mesa/main/varray.h
+++ b/src/mesa/main/varray.h
@@ -129,6 +129,11 @@ extern void GLAPIENTRY
_mesa_MultiDrawElementsEXT( GLenum mode, const GLsizei *count, GLenum type,
const GLvoid **indices, GLsizei primcount );
+extern void GLAPIENTRY
+_mesa_MultiDrawElementsBaseVertex( GLenum mode,
+ const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount,
+ const GLint *basevertex);
extern void GLAPIENTRY
_mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first,
@@ -159,6 +164,22 @@ extern void GLAPIENTRY
_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
GLenum type, const GLvoid *indices);
+extern void GLAPIENTRY
+_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex);
+
+extern void GLAPIENTRY
+_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices,
+ GLint basevertex);
+
+
+extern void
+_mesa_copy_client_array(GLcontext *ctx,
+ struct gl_client_array *dst,
+ struct gl_client_array *src);
+
extern void
_mesa_print_arrays(GLcontext *ctx);
diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h
index d4d3dd1a94..0cae1860a3 100644
--- a/src/mesa/main/version.h
+++ b/src/mesa/main/version.h
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 7.6
+ * Version: 7.7
*
* Copyright (C) 1999-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
@@ -30,9 +30,9 @@
/* Mesa version */
#define MESA_MAJOR 7
-#define MESA_MINOR 6
+#define MESA_MINOR 7
#define MESA_PATCH 0
-#define MESA_VERSION_STRING "7.6-devel"
+#define MESA_VERSION_STRING "7.7-devel"
/* To make version comparison easy */
#define MESA_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c
index 50e0402d27..309308c983 100644
--- a/src/mesa/main/viewport.c
+++ b/src/mesa/main/viewport.c
@@ -120,6 +120,10 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval)
if (MESA_VERBOSE&VERBOSE_API)
_mesa_debug(ctx, "glDepthRange %f %f\n", nearval, farval);
+ if (ctx->Viewport.Near == nearval &&
+ ctx->Viewport.Far == farval)
+ return;
+
ctx->Viewport.Near = (GLfloat) CLAMP(nearval, 0.0, 1.0);
ctx->Viewport.Far = (GLfloat) CLAMP(farval, 0.0, 1.0);
ctx->NewState |= _NEW_VIEWPORT;
diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c
index 1f807dc3dc..91412f138a 100644
--- a/src/mesa/main/vtxfmt.c
+++ b/src/mesa/main/vtxfmt.c
@@ -133,6 +133,10 @@ install_vtxfmt( struct _glapi_table *tab, const GLvertexformat *vfmt )
SET_DrawArrays(tab, vfmt->DrawArrays);
SET_DrawElements(tab, vfmt->DrawElements);
SET_DrawRangeElements(tab, vfmt->DrawRangeElements);
+ SET_MultiDrawElementsEXT(tab, vfmt->MultiDrawElementsEXT);
+ SET_DrawElementsBaseVertex(tab, vfmt->DrawElementsBaseVertex);
+ SET_DrawRangeElementsBaseVertex(tab, vfmt->DrawRangeElementsBaseVertex);
+ SET_MultiDrawElementsBaseVertex(tab, vfmt->MultiDrawElementsBaseVertex);
SET_EvalMesh1(tab, vfmt->EvalMesh1);
SET_EvalMesh2(tab, vfmt->EvalMesh2);
ASSERT(tab->EvalMesh2);
diff --git a/src/mesa/main/vtxfmt_tmp.h b/src/mesa/main/vtxfmt_tmp.h
index 6f5d01e40f..d56a2bb95e 100644
--- a/src/mesa/main/vtxfmt_tmp.h
+++ b/src/mesa/main/vtxfmt_tmp.h
@@ -335,6 +335,17 @@ static void GLAPIENTRY TAG(DrawElements)( GLenum mode, GLsizei count, GLenum typ
CALL_DrawElements(GET_DISPATCH(), ( mode, count, type, indices ));
}
+static void GLAPIENTRY TAG(MultiDrawElementsEXT)( GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount)
+{
+ PRE_LOOPBACK( MultiDrawElementsEXT );
+ CALL_MultiDrawElementsEXT(GET_DISPATCH(), ( mode, count, type, indices,
+ primcount ));
+}
+
static void GLAPIENTRY TAG(DrawRangeElements)( GLenum mode, GLuint start,
GLuint end, GLsizei count,
GLenum type, const GLvoid *indices )
@@ -343,6 +354,44 @@ static void GLAPIENTRY TAG(DrawRangeElements)( GLenum mode, GLuint start,
CALL_DrawRangeElements(GET_DISPATCH(), ( mode, start, end, count, type, indices ));
}
+static void GLAPIENTRY TAG(DrawElementsBaseVertex)( GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
+{
+ PRE_LOOPBACK( DrawElementsBaseVertex );
+ CALL_DrawElementsBaseVertex(GET_DISPATCH(), ( mode, count, type,
+ indices, basevertex ));
+}
+
+static void GLAPIENTRY TAG(DrawRangeElementsBaseVertex)( GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
+{
+ PRE_LOOPBACK( DrawRangeElementsBaseVertex );
+ CALL_DrawRangeElementsBaseVertex(GET_DISPATCH(), ( mode, start, end,
+ count, type, indices,
+ basevertex ));
+}
+
+static void GLAPIENTRY TAG(MultiDrawElementsBaseVertex)( GLenum mode,
+ const GLsizei *count,
+ GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount,
+ const GLint *basevertex)
+{
+ PRE_LOOPBACK( MultiDrawElementsBaseVertex );
+ CALL_MultiDrawElementsBaseVertex(GET_DISPATCH(), ( mode, count, type,
+ indices,
+ primcount, basevertex ));
+}
+
static void GLAPIENTRY TAG(EvalMesh1)( GLenum mode, GLint i1, GLint i2 )
{
PRE_LOOPBACK( EvalMesh1 );
@@ -522,6 +571,10 @@ static GLvertexformat TAG(vtxfmt) = {
TAG(DrawArrays),
TAG(DrawElements),
TAG(DrawRangeElements),
+ TAG(MultiDrawElementsEXT),
+ TAG(DrawElementsBaseVertex),
+ TAG(DrawRangeElementsBaseVertex),
+ TAG(MultiDrawElementsBaseVertex),
TAG(EvalMesh1),
TAG(EvalMesh2)
};
diff --git a/src/mesa/math/m_clip_tmp.h b/src/mesa/math/m_clip_tmp.h
index f3a589be05..2e30964057 100644
--- a/src/mesa/math/m_clip_tmp.h
+++ b/src/mesa/math/m_clip_tmp.h
@@ -44,7 +44,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLfloat *from = (GLfloat *)clip_vec->start;
@@ -66,16 +67,20 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points4)( GLvector4f *clip_vec,
mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
mask |= (((cw < cy) << CLIP_TOP_SHIFT));
mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
- mask |= (((cw < cz) << CLIP_FAR_SHIFT));
- mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+ if (viewport_z_clip) {
+ mask |= (((cw < cz) << CLIP_FAR_SHIFT));
+ mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+ }
#else /* !defined(macintosh)) */
GLubyte mask = 0;
if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
- if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
- if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+ if (viewport_z_clip) {
+ if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
+ if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+ }
#endif /* defined(macintosh) */
clipMask[i] = mask;
@@ -119,7 +124,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -141,16 +147,20 @@ static GLvector4f * _XFORMAPI TAG(cliptest_np_points4)( GLvector4f *clip_vec,
mask |= (((cw < -cx) << CLIP_LEFT_SHIFT));
mask |= (((cw < cy) << CLIP_TOP_SHIFT));
mask |= (((cw < -cy) << CLIP_BOTTOM_SHIFT));
- mask |= (((cw < cz) << CLIP_FAR_SHIFT));
- mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+ if (viewport_z_clip) {
+ mask |= (((cw < cz) << CLIP_FAR_SHIFT));
+ mask |= (((cw < -cz) << CLIP_NEAR_SHIFT));
+ }
#else /* !defined(macintosh)) */
GLubyte mask = 0;
if (-cx + cw < 0) mask |= CLIP_RIGHT_BIT;
if ( cx + cw < 0) mask |= CLIP_LEFT_BIT;
if (-cy + cw < 0) mask |= CLIP_TOP_BIT;
if ( cy + cw < 0) mask |= CLIP_BOTTOM_BIT;
- if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
- if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+ if (viewport_z_clip) {
+ if (-cz + cw < 0) mask |= CLIP_FAR_BIT;
+ if ( cz + cw < 0) mask |= CLIP_NEAR_BIT;
+ }
#endif /* defined(macintosh) */
clipMask[i] = mask;
@@ -171,7 +181,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -187,8 +198,10 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points3)( GLvector4f *clip_vec,
else if (cx < -1.0) mask |= CLIP_LEFT_BIT;
if (cy > 1.0) mask |= CLIP_TOP_BIT;
else if (cy < -1.0) mask |= CLIP_BOTTOM_BIT;
- if (cz > 1.0) mask |= CLIP_FAR_BIT;
- else if (cz < -1.0) mask |= CLIP_NEAR_BIT;
+ if (viewport_z_clip) {
+ if (cz > 1.0) mask |= CLIP_FAR_BIT;
+ else if (cz < -1.0) mask |= CLIP_NEAR_BIT;
+ }
clipMask[i] = mask;
tmpOrMask |= mask;
tmpAndMask &= mask;
@@ -204,7 +217,8 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -231,7 +245,7 @@ static GLvector4f * _XFORMAPI TAG(cliptest_points2)( GLvector4f *clip_vec,
}
-static void TAG(init_c_cliptest)( void )
+void TAG(init_c_cliptest)( void )
{
_mesa_clip_tab[4] = TAG(cliptest_points4);
_mesa_clip_tab[3] = TAG(cliptest_points3);
diff --git a/src/mesa/math/m_debug_clip.c b/src/mesa/math/m_debug_clip.c
index 460fed4a75..95ae5a347d 100644
--- a/src/mesa/math/m_debug_clip.c
+++ b/src/mesa/math/m_debug_clip.c
@@ -67,7 +67,8 @@ static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -87,8 +88,10 @@ static GLvector4f *ref_cliptest_points4( GLvector4f *clip_vec,
if ( cx + cw < 0 ) mask |= CLIP_LEFT_BIT;
if ( -cy + cw < 0 ) mask |= CLIP_TOP_BIT;
if ( cy + cw < 0 ) mask |= CLIP_BOTTOM_BIT;
- if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT;
- if ( cz + cw < 0 ) mask |= CLIP_NEAR_BIT;
+ if (viewport_z_clip) {
+ if ( -cz + cw < 0 ) mask |= CLIP_FAR_BIT;
+ if ( cz + cw < 0 ) mask |= CLIP_NEAR_BIT;
+ }
clipMask[i] = mask;
if ( mask ) {
c++;
@@ -122,7 +125,8 @@ static GLvector4f *ref_cliptest_points3( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -138,8 +142,10 @@ static GLvector4f *ref_cliptest_points3( GLvector4f *clip_vec,
else if ( cx < -1.0 ) mask |= CLIP_LEFT_BIT;
if ( cy > 1.0 ) mask |= CLIP_TOP_BIT;
else if ( cy < -1.0 ) mask |= CLIP_BOTTOM_BIT;
- if ( cz > 1.0 ) mask |= CLIP_FAR_BIT;
- else if ( cz < -1.0 ) mask |= CLIP_NEAR_BIT;
+ if (viewport_z_clip) {
+ if ( cz > 1.0 ) mask |= CLIP_FAR_BIT;
+ else if ( cz < -1.0 ) mask |= CLIP_NEAR_BIT;
+ }
clipMask[i] = mask;
tmpOrMask |= mask;
tmpAndMask &= mask;
@@ -154,7 +160,8 @@ static GLvector4f * ref_cliptest_points2( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask )
+ GLubyte *andMask,
+ GLboolean viewport_z_clip )
{
const GLuint stride = clip_vec->stride;
const GLuint count = clip_vec->count;
@@ -163,6 +170,9 @@ static GLvector4f * ref_cliptest_points2( GLvector4f *clip_vec,
GLubyte tmpOrMask = *orMask;
GLubyte tmpAndMask = *andMask;
GLuint i;
+
+ (void) viewport_z_clip;
+
for ( i = 0 ; i < count ; i++, STRIDE_F(from, stride) ) {
const GLfloat cx = from[0], cy = from[1];
GLubyte mask = 0;
@@ -208,6 +218,7 @@ static int test_cliptest_function( clip_func func, int np,
#ifdef RUN_DEBUG_BENCHMARK
int cycle_i; /* the counter for the benchmarks we run */
#endif
+ GLboolean viewport_z_clip = GL_TRUE;
(void) cycles;
@@ -247,15 +258,15 @@ static int test_cliptest_function( clip_func func, int np,
dco = rco = 0;
dca = rca = CLIP_FRUSTUM_BITS;
- ref_cliptest[psize]( source, ref, rm, &rco, &rca );
+ ref_cliptest[psize]( source, ref, rm, &rco, &rca, viewport_z_clip );
if ( mesa_profile ) {
BEGIN_RACE( *cycles );
- func( source, dest, dm, &dco, &dca );
+ func( source, dest, dm, &dco, &dca, viewport_z_clip );
END_RACE( *cycles );
}
else {
- func( source, dest, dm, &dco, &dca );
+ func( source, dest, dm, &dco, &dca, viewport_z_clip );
}
if ( dco != rco ) {
diff --git a/src/mesa/math/m_xform.h b/src/mesa/math/m_xform.h
index 7ef76e0b92..33421ad1c0 100644
--- a/src/mesa/math/m_xform.h
+++ b/src/mesa/math/m_xform.h
@@ -43,7 +43,8 @@
extern void
_math_init_transformation(void);
-
+extern void
+init_c_cliptest(void);
/* KW: Clip functions now do projective divide as well. The projected
* coordinates are very useful to us because they let us cull
@@ -102,7 +103,8 @@ typedef GLvector4f * (_XFORMAPIP clip_func)( GLvector4f *vClip,
GLvector4f *vProj,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask );
+ GLubyte *andMask,
+ GLboolean viewport_z_clip );
typedef void (*dotprod_func)( GLfloat *out,
GLuint out_stride,
diff --git a/src/mesa/shader/.gitignore b/src/mesa/shader/.gitignore
new file mode 100644
index 0000000000..086fd9a705
--- /dev/null
+++ b/src/mesa/shader/.gitignore
@@ -0,0 +1 @@
+program_parse.output
diff --git a/src/mesa/shader/Makefile b/src/mesa/shader/Makefile
new file mode 100644
index 0000000000..400a543bda
--- /dev/null
+++ b/src/mesa/shader/Makefile
@@ -0,0 +1,7 @@
+all: program_parse.tab.c lex.yy.c
+
+program_parse.tab.c program_parse.tab.h: program_parse.y
+ bison -v -d $<
+
+lex.yy.c: program_lexer.l
+ flex --never-interactive $<
diff --git a/src/mesa/shader/arbprogparse.c b/src/mesa/shader/arbprogparse.c
index bc65aba39a..05ee4f563e 100644
--- a/src/mesa/shader/arbprogparse.c
+++ b/src/mesa/shader/arbprogparse.c
@@ -63,3867 +63,7 @@ having three separate program parameter arrays.
#include "prog_parameter.h"
#include "prog_statevars.h"
#include "prog_instruction.h"
-
-/**
- * This is basically a union of the vertex_program and fragment_program
- * structs that we can use to parse the program into
- *
- * XXX we can probably get rid of this entirely someday.
- */
-struct arb_program
-{
- struct gl_program Base;
-
- GLuint Position; /* Just used for error reporting while parsing */
- GLuint MajorVersion;
- GLuint MinorVersion;
-
- /* ARB_vertex_progmra options */
- GLboolean HintPositionInvariant;
-
- /* ARB_fragment_progmra options */
- GLenum PrecisionOption; /* GL_DONT_CARE, GL_NICEST or GL_FASTEST */
- GLenum FogOption; /* GL_NONE, GL_LINEAR, GL_EXP or GL_EXP2 */
-
- /* ARB_fragment_program specifics */
- GLbitfield TexturesUsed[MAX_TEXTURE_IMAGE_UNITS];
- GLbitfield ShadowSamplers;
- GLuint NumAluInstructions;
- GLuint NumTexInstructions;
- GLuint NumTexIndirections;
-
- GLboolean UsesKill;
-};
-
-
-
-/* TODO:
- * Fragment Program Stuff:
- * -----------------------------------------------------
- *
- * - things from Michal's email
- * + overflow on atoi
- * + not-overflowing floats (don't use parse_integer..)
- * + can remove range checking in arbparse.c
- *
- * - check all limits of number of various variables
- * + parameters
- *
- * - test! test! test!
- *
- * Vertex Program Stuff:
- * -----------------------------------------------------
- * - Optimize param array usage and count limits correctly, see spec,
- * section 2.14.3.7
- * + Record if an array is reference absolutly or relatively (or both)
- * + For absolute arrays, store a bitmap of accesses
- * + For single parameters, store an access flag
- * + After parsing, make a parameter cleanup and merging pass, where
- * relative arrays are layed out first, followed by abs arrays, and
- * finally single state.
- * + Remap offsets for param src and dst registers
- * + Now we can properly count parameter usage
- *
- * - Multiple state binding errors in param arrays (see spec, just before
- * section 2.14.3.3)
- * - grep for XXX
- *
- * Mesa Stuff
- * -----------------------------------------------------
- * - User clipping planes vs. PositionInvariant
- * - Is it sufficient to just multiply by the mvp to transform in the
- * PositionInvariant case? Or do we need something more involved?
- *
- * - vp_src swizzle is GLubyte, fp_src swizzle is GLuint
- * - fetch state listed in program_parameters list
- * + WTF should this go???
- * + currently in nvvertexec.c and s_nvfragprog.c
- *
- * - allow for multiple address registers (and fetch address regs properly)
- *
- * Cosmetic Stuff
- * -----------------------------------------------------
- * - remove any leftover unused grammer.c stuff (dict_ ?)
- * - fix grammer.c error handling so its not static
- * - #ifdef around stuff pertaining to extentions
- *
- * Outstanding Questions:
- * -----------------------------------------------------
- * - ARB_matrix_palette / ARB_vertex_blend -- not supported
- * what gets hacked off because of this:
- * + VERTEX_ATTRIB_MATRIXINDEX
- * + VERTEX_ATTRIB_WEIGHT
- * + MATRIX_MODELVIEW
- * + MATRIX_PALETTE
- *
- * - When can we fetch env/local params from their own register files, and
- * when to we have to fetch them into the main state register file?
- * (think arrays)
- *
- * Grammar Changes:
- * -----------------------------------------------------
- */
-
-/* Changes since moving the file to shader directory
-
-2004-III-4 ------------------------------------------------------------
-- added #include "grammar_mesa.h"
-- removed grammar specific code part (it resides now in grammar.c)
-- added GL_ARB_fragment_program_shadow tokens
-- modified #include "arbparse_syn.h"
-- major changes inside _mesa_parse_arb_program()
-- check the program string for '\0' characters
-- copy the program string to a one-byte-longer location to have
- it null-terminated
-- position invariance test (not writing to result.position) moved
- to syntax part
-*/
-
-typedef GLubyte *production;
-
-
-/**
- * This is the text describing the rules to parse the grammar
- */
-LONGSTRING static char arb_grammar_text[] =
-#include "arbprogram_syn.h"
-;
-
-/**
- * These should match up with the values defined in arbprogram.syn
- */
-
-/*
- Changes:
- - changed and merged V_* and F_* opcode values to OP_*.
- - added GL_ARB_fragment_program_shadow specific tokens (michal)
-*/
-#define REVISION 0x0a
-
-/* program type */
-#define FRAGMENT_PROGRAM 0x01
-#define VERTEX_PROGRAM 0x02
-
-/* program section */
-#define OPTION 0x01
-#define INSTRUCTION 0x02
-#define DECLARATION 0x03
-#define END 0x04
-
-/* GL_ARB_fragment_program option */
-#define ARB_PRECISION_HINT_FASTEST 0x00
-#define ARB_PRECISION_HINT_NICEST 0x01
-#define ARB_FOG_EXP 0x02
-#define ARB_FOG_EXP2 0x03
-#define ARB_FOG_LINEAR 0x04
-
-/* GL_ARB_vertex_program option */
-#define ARB_POSITION_INVARIANT 0x05
-
-/* GL_ARB_fragment_program_shadow option */
-#define ARB_FRAGMENT_PROGRAM_SHADOW 0x06
-
-/* GL_ARB_draw_buffers option */
-#define ARB_DRAW_BUFFERS 0x07
-
-/* GL_MESA_texture_array option */
-#define MESA_TEXTURE_ARRAY 0x08
-
-/* GL_ARB_fragment_program instruction class */
-#define OP_ALU_INST 0x00
-#define OP_TEX_INST 0x01
-
-/* GL_ARB_vertex_program instruction class */
-/* OP_ALU_INST */
-
-/* GL_ARB_fragment_program instruction type */
-#define OP_ALU_VECTOR 0x00
-#define OP_ALU_SCALAR 0x01
-#define OP_ALU_BINSC 0x02
-#define OP_ALU_BIN 0x03
-#define OP_ALU_TRI 0x04
-#define OP_ALU_SWZ 0x05
-#define OP_TEX_SAMPLE 0x06
-#define OP_TEX_KIL 0x07
-
-/* GL_ARB_vertex_program instruction type */
-#define OP_ALU_ARL 0x08
-/* OP_ALU_VECTOR */
-/* OP_ALU_SCALAR */
-/* OP_ALU_BINSC */
-/* OP_ALU_BIN */
-/* OP_ALU_TRI */
-/* OP_ALU_SWZ */
-
-/* GL_ARB_fragment_program instruction code */
-#define OP_ABS 0x00
-#define OP_ABS_SAT 0x1B
-#define OP_FLR 0x09
-#define OP_FLR_SAT 0x26
-#define OP_FRC 0x0A
-#define OP_FRC_SAT 0x27
-#define OP_LIT 0x0C
-#define OP_LIT_SAT 0x2A
-#define OP_MOV 0x11
-#define OP_MOV_SAT 0x30
-#define OP_COS 0x1F
-#define OP_COS_SAT 0x20
-#define OP_EX2 0x07
-#define OP_EX2_SAT 0x25
-#define OP_LG2 0x0B
-#define OP_LG2_SAT 0x29
-#define OP_RCP 0x14
-#define OP_RCP_SAT 0x33
-#define OP_RSQ 0x15
-#define OP_RSQ_SAT 0x34
-#define OP_SIN 0x38
-#define OP_SIN_SAT 0x39
-#define OP_SCS 0x35
-#define OP_SCS_SAT 0x36
-#define OP_POW 0x13
-#define OP_POW_SAT 0x32
-#define OP_ADD 0x01
-#define OP_ADD_SAT 0x1C
-#define OP_DP3 0x03
-#define OP_DP3_SAT 0x21
-#define OP_DP4 0x04
-#define OP_DP4_SAT 0x22
-#define OP_DPH 0x05
-#define OP_DPH_SAT 0x23
-#define OP_DST 0x06
-#define OP_DST_SAT 0x24
-#define OP_MAX 0x0F
-#define OP_MAX_SAT 0x2E
-#define OP_MIN 0x10
-#define OP_MIN_SAT 0x2F
-#define OP_MUL 0x12
-#define OP_MUL_SAT 0x31
-#define OP_SGE 0x16
-#define OP_SGE_SAT 0x37
-#define OP_SLT 0x17
-#define OP_SLT_SAT 0x3A
-#define OP_SUB 0x18
-#define OP_SUB_SAT 0x3B
-#define OP_XPD 0x1A
-#define OP_XPD_SAT 0x43
-#define OP_CMP 0x1D
-#define OP_CMP_SAT 0x1E
-#define OP_LRP 0x2B
-#define OP_LRP_SAT 0x2C
-#define OP_MAD 0x0E
-#define OP_MAD_SAT 0x2D
-#define OP_SWZ 0x19
-#define OP_SWZ_SAT 0x3C
-#define OP_TEX 0x3D
-#define OP_TEX_SAT 0x3E
-#define OP_TXB 0x3F
-#define OP_TXB_SAT 0x40
-#define OP_TXP 0x41
-#define OP_TXP_SAT 0x42
-#define OP_KIL 0x28
-
-/* GL_ARB_vertex_program instruction code */
-#define OP_ARL 0x02
-/* OP_ABS */
-/* OP_FLR */
-/* OP_FRC */
-/* OP_LIT */
-/* OP_MOV */
-/* OP_EX2 */
-#define OP_EXP 0x08
-/* OP_LG2 */
-#define OP_LOG 0x0D
-/* OP_RCP */
-/* OP_RSQ */
-/* OP_POW */
-/* OP_ADD */
-/* OP_DP3 */
-/* OP_DP4 */
-/* OP_DPH */
-/* OP_DST */
-/* OP_MAX */
-/* OP_MIN */
-/* OP_MUL */
-/* OP_SGE */
-/* OP_SLT */
-/* OP_SUB */
-/* OP_XPD */
-/* OP_MAD */
-/* OP_SWZ */
-
-/* fragment attribute binding */
-#define FRAGMENT_ATTRIB_COLOR 0x01
-#define FRAGMENT_ATTRIB_TEXCOORD 0x02
-#define FRAGMENT_ATTRIB_FOGCOORD 0x03
-#define FRAGMENT_ATTRIB_POSITION 0x04
-
-/* vertex attribute binding */
-#define VERTEX_ATTRIB_POSITION 0x01
-#define VERTEX_ATTRIB_WEIGHT 0x02
-#define VERTEX_ATTRIB_NORMAL 0x03
-#define VERTEX_ATTRIB_COLOR 0x04
-#define VERTEX_ATTRIB_FOGCOORD 0x05
-#define VERTEX_ATTRIB_TEXCOORD 0x06
-#define VERTEX_ATTRIB_MATRIXINDEX 0x07
-#define VERTEX_ATTRIB_GENERIC 0x08
-
-/* fragment result binding */
-#define FRAGMENT_RESULT_COLOR 0x01
-#define FRAGMENT_RESULT_DEPTH 0x02
-
-/* vertex result binding */
-#define VERTEX_RESULT_POSITION 0x01
-#define VERTEX_RESULT_COLOR 0x02
-#define VERTEX_RESULT_FOGCOORD 0x03
-#define VERTEX_RESULT_POINTSIZE 0x04
-#define VERTEX_RESULT_TEXCOORD 0x05
-
-/* texture target */
-#define TEXTARGET_1D 0x01
-#define TEXTARGET_2D 0x02
-#define TEXTARGET_3D 0x03
-#define TEXTARGET_RECT 0x04
-#define TEXTARGET_CUBE 0x05
-/* GL_ARB_fragment_program_shadow */
-#define TEXTARGET_SHADOW1D 0x06
-#define TEXTARGET_SHADOW2D 0x07
-#define TEXTARGET_SHADOWRECT 0x08
-/* GL_MESA_texture_array */
-#define TEXTARGET_1D_ARRAY 0x09
-#define TEXTARGET_2D_ARRAY 0x0a
-#define TEXTARGET_SHADOW1D_ARRAY 0x0b
-#define TEXTARGET_SHADOW2D_ARRAY 0x0c
-
-/* face type */
-#define FACE_FRONT 0x00
-#define FACE_BACK 0x01
-
-/* color type */
-#define COLOR_PRIMARY 0x00
-#define COLOR_SECONDARY 0x01
-
-/* component */
-#define COMPONENT_X 0x00
-#define COMPONENT_Y 0x01
-#define COMPONENT_Z 0x02
-#define COMPONENT_W 0x03
-#define COMPONENT_0 0x04
-#define COMPONENT_1 0x05
-
-/* array index type */
-#define ARRAY_INDEX_ABSOLUTE 0x00
-#define ARRAY_INDEX_RELATIVE 0x01
-
-/* matrix name */
-#define MATRIX_MODELVIEW 0x01
-#define MATRIX_PROJECTION 0x02
-#define MATRIX_MVP 0x03
-#define MATRIX_TEXTURE 0x04
-#define MATRIX_PALETTE 0x05
-#define MATRIX_PROGRAM 0x06
-
-/* matrix modifier */
-#define MATRIX_MODIFIER_IDENTITY 0x00
-#define MATRIX_MODIFIER_INVERSE 0x01
-#define MATRIX_MODIFIER_TRANSPOSE 0x02
-#define MATRIX_MODIFIER_INVTRANS 0x03
-
-/* constant type */
-#define CONSTANT_SCALAR 0x01
-#define CONSTANT_VECTOR 0x02
-
-/* program param type */
-#define PROGRAM_PARAM_ENV 0x01
-#define PROGRAM_PARAM_LOCAL 0x02
-
-/* register type */
-#define REGISTER_ATTRIB 0x01
-#define REGISTER_PARAM 0x02
-#define REGISTER_RESULT 0x03
-#define REGISTER_ESTABLISHED_NAME 0x04
-
-/* param binding */
-#define PARAM_NULL 0x00
-#define PARAM_ARRAY_ELEMENT 0x01
-#define PARAM_STATE_ELEMENT 0x02
-#define PARAM_PROGRAM_ELEMENT 0x03
-#define PARAM_PROGRAM_ELEMENTS 0x04
-#define PARAM_CONSTANT 0x05
-
-/* param state property */
-#define STATE_MATERIAL_PARSER 0x01
-#define STATE_LIGHT_PARSER 0x02
-#define STATE_LIGHT_MODEL 0x03
-#define STATE_LIGHT_PROD 0x04
-#define STATE_FOG 0x05
-#define STATE_MATRIX_ROWS 0x06
-/* GL_ARB_fragment_program */
-#define STATE_TEX_ENV 0x07
-#define STATE_DEPTH 0x08
-/* GL_ARB_vertex_program */
-#define STATE_TEX_GEN 0x09
-#define STATE_CLIP_PLANE 0x0A
-#define STATE_POINT 0x0B
-
-/* state material property */
-#define MATERIAL_AMBIENT 0x01
-#define MATERIAL_DIFFUSE 0x02
-#define MATERIAL_SPECULAR 0x03
-#define MATERIAL_EMISSION 0x04
-#define MATERIAL_SHININESS 0x05
-
-/* state light property */
-#define LIGHT_AMBIENT 0x01
-#define LIGHT_DIFFUSE 0x02
-#define LIGHT_SPECULAR 0x03
-#define LIGHT_POSITION 0x04
-#define LIGHT_ATTENUATION 0x05
-#define LIGHT_HALF 0x06
-#define LIGHT_SPOT_DIRECTION 0x07
-
-/* state light model property */
-#define LIGHT_MODEL_AMBIENT 0x01
-#define LIGHT_MODEL_SCENECOLOR 0x02
-
-/* state light product property */
-#define LIGHT_PROD_AMBIENT 0x01
-#define LIGHT_PROD_DIFFUSE 0x02
-#define LIGHT_PROD_SPECULAR 0x03
-
-/* state texture environment property */
-#define TEX_ENV_COLOR 0x01
-
-/* state texture generation coord property */
-#define TEX_GEN_EYE 0x01
-#define TEX_GEN_OBJECT 0x02
-
-/* state fog property */
-#define FOG_COLOR 0x01
-#define FOG_PARAMS 0x02
-
-/* state depth property */
-#define DEPTH_RANGE 0x01
-
-/* state point parameters property */
-#define POINT_SIZE 0x01
-#define POINT_ATTENUATION 0x02
-
-/* declaration */
-#define ATTRIB 0x01
-#define PARAM 0x02
-#define TEMP 0x03
-#define OUTPUT 0x04
-#define ALIAS 0x05
-/* GL_ARB_vertex_program */
-#define ADDRESS 0x06
-
-/*-----------------------------------------------------------------------
- * From here on down is the semantic checking portion
- *
- */
-
-/**
- * Variable Table Handling functions
- */
-typedef enum
-{
- vt_none,
- vt_address,
- vt_attrib,
- vt_param,
- vt_temp,
- vt_output,
- vt_alias
-} var_type;
-
-
-/**
- * Setting an explicit field for each of the binding properties is a bit
- * wasteful of space, but it should be much more clear when reading later on..
- */
-struct var_cache
-{
- const GLubyte *name; /* don't free() - no need */
- var_type type;
- GLuint address_binding; /* The index of the address register we should
- * be using */
- GLuint attrib_binding; /* For type vt_attrib, see nvfragprog.h for values */
- GLuint attrib_is_generic; /* If the attrib was specified through a generic
- * vertex attrib */
- GLuint temp_binding; /* The index of the temp register we are to use */
- GLuint output_binding; /* Output/result register number */
- struct var_cache *alias_binding; /* For type vt_alias, points to the var_cache entry
- * that this is aliased to */
- GLuint param_binding_type; /* {PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM,
- * PROGRAM_ENV_PARAM} */
- GLuint param_binding_begin; /* This is the offset into the program_parameter_list where
- * the tokens representing our bound state (or constants)
- * start */
- GLuint param_binding_length; /* This is how many entries in the the program_parameter_list
- * we take up with our state tokens or constants. Note that
- * this is _not_ the same as the number of param registers
- * we eventually use */
- GLuint swizzle; /**< swizzle to access this variable */
- struct var_cache *next;
-};
-
-static GLvoid
-var_cache_create (struct var_cache **va)
-{
- *va = (struct var_cache *) _mesa_malloc (sizeof (struct var_cache));
- if (*va) {
- (**va).name = NULL;
- (**va).type = vt_none;
- (**va).attrib_binding = ~0;
- (**va).attrib_is_generic = 0;
- (**va).temp_binding = ~0;
- (**va).output_binding = ~0;
- (**va).param_binding_type = ~0;
- (**va).param_binding_begin = ~0;
- (**va).param_binding_length = ~0;
- (**va).alias_binding = NULL;
- (**va).swizzle = SWIZZLE_XYZW;
- (**va).next = NULL;
- }
-}
-
-static GLvoid
-var_cache_destroy (struct var_cache **va)
-{
- if (*va) {
- var_cache_destroy (&(**va).next);
- _mesa_free (*va);
- *va = NULL;
- }
-}
-
-static GLvoid
-var_cache_append (struct var_cache **va, struct var_cache *nv)
-{
- if (*va)
- var_cache_append (&(**va).next, nv);
- else
- *va = nv;
-}
-
-static struct var_cache *
-var_cache_find (struct var_cache *va, const GLubyte * name)
-{
- /*struct var_cache *first = va;*/
-
- while (va) {
- if (!_mesa_strcmp ( (const char*) name, (const char*) va->name)) {
- if (va->type == vt_alias)
- return va->alias_binding;
- return va;
- }
-
- va = va->next;
- }
-
- return NULL;
-}
-
-
-
-/**
- * Called when an error is detected while parsing/compiling a program.
- * Sets the ctx->Program.ErrorString field to descript and records a
- * GL_INVALID_OPERATION error.
- * \param position position of error in program string
- * \param descrip verbose error description
- */
-static void
-program_error(GLcontext *ctx, GLint position, const char *descrip)
-{
- if (descrip) {
- const char *prefix = "glProgramString(", *suffix = ")";
- char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
- _mesa_strlen(prefix) +
- _mesa_strlen(suffix) + 1);
- if (str) {
- _mesa_sprintf(str, "%s%s%s", prefix, descrip, suffix);
- _mesa_error(ctx, GL_INVALID_OPERATION, str);
- _mesa_free(str);
- }
- }
- _mesa_set_program_error(ctx, position, descrip);
-}
-
-
-/**
- * As above, but with an extra string parameter for more info.
- */
-static void
-program_error2(GLcontext *ctx, GLint position, const char *descrip,
- const char *var)
-{
- if (descrip) {
- const char *prefix = "glProgramString(", *suffix = ")";
- char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
- _mesa_strlen(": ") +
- _mesa_strlen(var) +
- _mesa_strlen(prefix) +
- _mesa_strlen(suffix) + 1);
- if (str) {
- _mesa_sprintf(str, "%s%s: %s%s", prefix, descrip, var, suffix);
- _mesa_error(ctx, GL_INVALID_OPERATION, str);
- _mesa_free(str);
- }
- }
- {
- char *str = (char *) _mesa_malloc(_mesa_strlen(descrip) +
- _mesa_strlen(": ") +
- _mesa_strlen(var) + 1);
- if (str) {
- _mesa_sprintf(str, "%s: %s", descrip, var);
- }
- _mesa_set_program_error(ctx, position, str);
- if (str) {
- _mesa_free(str);
- }
- }
-}
-
-
-
-/**
- * constructs an integer from 4 GLubytes in LE format
- */
-static GLuint
-parse_position (const GLubyte ** inst)
-{
- GLuint value;
-
- value = (GLuint) (*(*inst)++);
- value += (GLuint) (*(*inst)++) * 0x100;
- value += (GLuint) (*(*inst)++) * 0x10000;
- value += (GLuint) (*(*inst)++) * 0x1000000;
-
- return value;
-}
-
-/**
- * This will, given a string, lookup the string as a variable name in the
- * var cache. If the name is found, the var cache node corresponding to the
- * var name is returned. If it is not found, a new entry is allocated
- *
- * \param I Points into the binary array where the string identifier begins
- * \param found 1 if the string was found in the var_cache, 0 if it was allocated
- * \return The location on the var_cache corresponding the the string starting at I
- */
-static struct var_cache *
-parse_string (const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program, GLuint * found)
-{
- const GLubyte *i = *inst;
- struct var_cache *va = NULL;
- (void) Program;
-
- *inst += _mesa_strlen ((char *) i) + 1;
-
- va = var_cache_find (*vc_head, i);
-
- if (va) {
- *found = 1;
- return va;
- }
-
- *found = 0;
- var_cache_create (&va);
- va->name = (const GLubyte *) i;
-
- var_cache_append (vc_head, va);
-
- return va;
-}
-
-static char *
-parse_string_without_adding (const GLubyte ** inst, struct arb_program *Program)
-{
- const GLubyte *i = *inst;
- (void) Program;
-
- *inst += _mesa_strlen ((char *) i) + 1;
-
- return (char *) i;
-}
-
-/**
- * \return -1 if we parse '-', return 1 otherwise
- */
-static GLint
-parse_sign (const GLubyte ** inst)
-{
- /*return *(*inst)++ != '+'; */
-
- if (**inst == '-') {
- (*inst)++;
- return -1;
- }
- else if (**inst == '+') {
- (*inst)++;
- return 1;
- }
-
- return 1;
-}
-
-/**
- * parses and returns signed integer
- */
-static GLint
-parse_integer (const GLubyte ** inst, struct arb_program *Program)
-{
- GLint sign;
- GLint value;
-
- /* check if *inst points to '+' or '-'
- * if yes, grab the sign and increment *inst
- */
- sign = parse_sign (inst);
-
- /* now check if *inst points to 0
- * if yes, increment the *inst and return the default value
- */
- if (**inst == 0) {
- (*inst)++;
- return 0;
- }
-
- /* parse the integer as you normally would do it */
- value = _mesa_atoi (parse_string_without_adding (inst, Program));
-
- /* now, after terminating 0 there is a position
- * to parse it - parse_position()
- */
- Program->Position = parse_position (inst);
-
- return value * sign;
-}
-
-/**
- Accumulate this string of digits, and return them as
- a large integer represented in floating point (for range).
- If scale is not NULL, also accumulates a power-of-ten
- integer scale factor that represents the number of digits
- in the string.
-*/
-static GLdouble
-parse_float_string(const GLubyte ** inst, struct arb_program *Program, GLdouble *scale)
-{
- GLdouble value = 0.0;
- GLdouble oscale = 1.0;
-
- if (**inst == 0) { /* this string of digits is empty-- do nothing */
- (*inst)++;
- }
- else { /* nonempty string-- parse out the digits */
- while (**inst >= '0' && **inst <= '9') {
- GLubyte digit = *((*inst)++);
- value = value * 10.0 + (GLint) (digit - '0');
- oscale *= 10.0;
- }
- assert(**inst == 0); /* integer string should end with 0 */
- (*inst)++; /* skip over terminating 0 */
- Program->Position = parse_position(inst); /* skip position (from integer) */
- }
- if (scale)
- *scale = oscale;
- return value;
-}
-
-/**
- Parse an unsigned floating-point number from this stream of tokenized
- characters. Example floating-point formats supported:
- 12.34
- 12
- 0.34
- .34
- 12.34e-4
- */
-static GLfloat
-parse_float (const GLubyte ** inst, struct arb_program *Program)
-{
- GLint exponent;
- GLdouble whole, fraction, fracScale = 1.0;
-
- whole = parse_float_string(inst, Program, 0);
- fraction = parse_float_string(inst, Program, &fracScale);
-
- /* Parse signed exponent */
- exponent = parse_integer(inst, Program); /* This is the exponent */
-
- /* Assemble parts of floating-point number: */
- return (GLfloat) ((whole + fraction / fracScale) *
- _mesa_pow(10.0, (GLfloat) exponent));
-}
-
-
-/**
- */
-static GLfloat
-parse_signed_float (const GLubyte ** inst, struct arb_program *Program)
-{
- GLint sign = parse_sign (inst);
- GLfloat value = parse_float (inst, Program);
- return value * sign;
-}
-
-/**
- * This picks out a constant value from the parsed array. The constant vector is r
- * returned in the *values array, which should be of length 4.
- *
- * \param values - return the vector constant values.
- * \param size - returns the number elements in valuesOut [1..4]
- */
-static GLvoid
-parse_constant(const GLubyte ** inst, GLfloat *values, GLint *size,
- struct arb_program *Program,
- GLboolean use)
-{
- GLuint components, i;
-
- switch (*(*inst)++) {
- case CONSTANT_SCALAR:
- if (use == GL_TRUE) {
- values[0] =
- values[1] =
- values[2] = values[3] = parse_float (inst, Program);
- }
- else {
- values[0] =
- values[1] =
- values[2] = values[3] = parse_signed_float (inst, Program);
- }
- *size = 1;
- break;
- case CONSTANT_VECTOR:
- values[0] = values[1] = values[2] = 0;
- values[3] = 1;
- components = *(*inst)++;
- for (i = 0; i < components; i++) {
- values[i] = parse_signed_float (inst, Program);
- }
- *size = 4;
- break;
- default:
- _mesa_problem(NULL, "unexpected case in parse_constant()");
- values[0] = 0.0F;
- *size = 0;
- }
-}
-
-/**
- * \param offset The offset from the address register that we should
- * address
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_relative_offset(GLcontext *ctx, const GLubyte **inst,
- struct arb_program *Program, GLint *offset)
-{
- (void) ctx;
- *offset = parse_integer(inst, Program);
- return 0;
-}
-
-/**
- * \param color 0 if color type is primary, 1 if color type is secondary
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_color_type (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program,
- GLint * color)
-{
- (void) ctx; (void) Program;
- *color = *(*inst)++ != COLOR_PRIMARY;
- return 0;
-}
-
-/**
- * Get an integer corresponding to a generic vertex attribute.
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_generic_attrib_num(GLcontext *ctx, const GLubyte ** inst,
- struct arb_program *Program, GLuint *attrib)
-{
- GLint i = parse_integer(inst, Program);
-
- if ((i < 0) || (i >= MAX_VERTEX_GENERIC_ATTRIBS))
- {
- program_error(ctx, Program->Position,
- "Invalid generic vertex attribute index");
- return 1;
- }
-
- *attrib = (GLuint) i;
-
- return 0;
-}
-
-
-/**
- * \param color The index of the color buffer to write into
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_output_color_num (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program, GLuint * color)
-{
- GLint i = parse_integer (inst, Program);
-
- if ((i < 0) || (i >= (int)ctx->Const.MaxDrawBuffers)) {
- *color = 0;
- program_error(ctx, Program->Position, "Invalid draw buffer index");
- return 1;
- }
-
- *color = (GLuint) i;
- return 0;
-}
-
-
-/**
- * Validate the index of a texture coordinate
- *
- * \param coord The texture unit index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_texcoord_num (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program, GLuint * coord)
-{
- GLint i = parse_integer (inst, Program);
-
- if ((i < 0) || (i >= (int)ctx->Const.MaxTextureCoordUnits)) {
- program_error(ctx, Program->Position, "Invalid texture coordinate index");
- return 1;
- }
-
- *coord = (GLuint) i;
- return 0;
-}
-
-
-/**
- * Validate the index of a texture image unit
- *
- * \param coord The texture unit index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_teximage_num (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program, GLuint * coord)
-{
- GLint i = parse_integer (inst, Program);
-
- if ((i < 0) || (i >= (int)ctx->Const.MaxTextureImageUnits)) {
- char s[100];
- _mesa_snprintf(s, sizeof(s), "Invalid texture image index %d (%u is max)",
- i, ctx->Const.MaxTextureImageUnits);
- program_error(ctx, Program->Position, s);
- return 1;
- }
-
- *coord = (GLuint) i;
- return 0;
-}
-
-
-/**
- * \param coord The weight index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_weight_num (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program,
- GLint * coord)
-{
- *coord = parse_integer (inst, Program);
-
- if ((*coord < 0) || (*coord >= 1)) {
- program_error(ctx, Program->Position, "Invalid weight index");
- return 1;
- }
-
- return 0;
-}
-
-/**
- * \param coord The clip plane index
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_clipplane_num (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program, GLint * coord)
-{
- *coord = parse_integer (inst, Program);
-
- if ((*coord < 0) || (*coord >= (GLint) ctx->Const.MaxClipPlanes)) {
- program_error(ctx, Program->Position, "Invalid clip plane index");
- return 1;
- }
-
- return 0;
-}
-
-
-/**
- * \return 0 on front face, 1 on back face
- */
-static GLuint
-parse_face_type (const GLubyte ** inst)
-{
- switch (*(*inst)++) {
- case FACE_FRONT:
- return 0;
-
- case FACE_BACK:
- return 1;
- }
- return 0;
-}
-
-
-/**
- * Given a matrix and a modifier token on the binary array, return tokens
- * that _mesa_fetch_state() [program.c] can understand.
- *
- * \param matrix - the matrix we are talking about
- * \param matrix_idx - the index of the matrix we have (for texture & program matricies)
- * \param matrix_modifier - the matrix modifier (trans, inv, etc)
- * \return 0 on sucess, 1 on failure
- */
-static GLuint
-parse_matrix (GLcontext * ctx, const GLubyte ** inst, struct arb_program *Program,
- GLint * matrix, GLint * matrix_idx, GLint * matrix_modifier)
-{
- GLubyte mat = *(*inst)++;
-
- *matrix_idx = 0;
-
- switch (mat) {
- case MATRIX_MODELVIEW:
- *matrix = STATE_MODELVIEW_MATRIX;
- *matrix_idx = parse_integer (inst, Program);
- if (*matrix_idx > 0) {
- program_error(ctx, Program->Position,
- "ARB_vertex_blend not supported");
- return 1;
- }
- break;
-
- case MATRIX_PROJECTION:
- *matrix = STATE_PROJECTION_MATRIX;
- break;
-
- case MATRIX_MVP:
- *matrix = STATE_MVP_MATRIX;
- break;
-
- case MATRIX_TEXTURE:
- *matrix = STATE_TEXTURE_MATRIX;
- *matrix_idx = parse_integer (inst, Program);
- if (*matrix_idx >= (GLint) ctx->Const.MaxTextureUnits) {
- program_error(ctx, Program->Position, "Invalid Texture Unit");
- /* bad *matrix_id */
- return 1;
- }
- break;
-
- /* This is not currently supported (ARB_matrix_palette) */
- case MATRIX_PALETTE:
- *matrix_idx = parse_integer (inst, Program);
- program_error(ctx, Program->Position,
- "ARB_matrix_palette not supported");
- return 1;
- break;
-
- case MATRIX_PROGRAM:
- *matrix = STATE_PROGRAM_MATRIX;
- *matrix_idx = parse_integer (inst, Program);
- if (*matrix_idx >= (GLint) ctx->Const.MaxProgramMatrices) {
- program_error(ctx, Program->Position, "Invalid Program Matrix");
- /* bad *matrix_idx */
- return 1;
- }
- break;
- }
-
- switch (*(*inst)++) {
- case MATRIX_MODIFIER_IDENTITY:
- *matrix_modifier = 0;
- break;
- case MATRIX_MODIFIER_INVERSE:
- *matrix_modifier = STATE_MATRIX_INVERSE;
- break;
- case MATRIX_MODIFIER_TRANSPOSE:
- *matrix_modifier = STATE_MATRIX_TRANSPOSE;
- break;
- case MATRIX_MODIFIER_INVTRANS:
- *matrix_modifier = STATE_MATRIX_INVTRANS;
- break;
- }
-
- return 0;
-}
-
-
-/**
- * This parses a state string (rather, the binary version of it) into
- * a 6-token sequence as described in _mesa_fetch_state() [program.c]
- *
- * \param inst - the start in the binary arry to start working from
- * \param state_tokens - the storage for the 6-token state description
- * \return - 0 on sucess, 1 on error
- */
-static GLuint
-parse_state_single_item (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program,
- gl_state_index state_tokens[STATE_LENGTH])
-{
- GLubyte token = *(*inst)++;
-
- switch (token) {
- case STATE_MATERIAL_PARSER:
- state_tokens[0] = STATE_MATERIAL;
- state_tokens[1] = parse_face_type (inst);
- switch (*(*inst)++) {
- case MATERIAL_AMBIENT:
- state_tokens[2] = STATE_AMBIENT;
- break;
- case MATERIAL_DIFFUSE:
- state_tokens[2] = STATE_DIFFUSE;
- break;
- case MATERIAL_SPECULAR:
- state_tokens[2] = STATE_SPECULAR;
- break;
- case MATERIAL_EMISSION:
- state_tokens[2] = STATE_EMISSION;
- break;
- case MATERIAL_SHININESS:
- state_tokens[2] = STATE_SHININESS;
- break;
- }
- break;
-
- case STATE_LIGHT_PARSER:
- state_tokens[0] = STATE_LIGHT;
- state_tokens[1] = parse_integer (inst, Program);
-
- /* Check the value of state_tokens[1] against the # of lights */
- if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
- program_error(ctx, Program->Position, "Invalid Light Number");
- /* bad state_tokens[1] */
- return 1;
- }
-
- switch (*(*inst)++) {
- case LIGHT_AMBIENT:
- state_tokens[2] = STATE_AMBIENT;
- break;
- case LIGHT_DIFFUSE:
- state_tokens[2] = STATE_DIFFUSE;
- break;
- case LIGHT_SPECULAR:
- state_tokens[2] = STATE_SPECULAR;
- break;
- case LIGHT_POSITION:
- state_tokens[2] = STATE_POSITION;
- break;
- case LIGHT_ATTENUATION:
- state_tokens[2] = STATE_ATTENUATION;
- break;
- case LIGHT_HALF:
- state_tokens[2] = STATE_HALF_VECTOR;
- break;
- case LIGHT_SPOT_DIRECTION:
- state_tokens[2] = STATE_SPOT_DIRECTION;
- break;
- }
- break;
-
- case STATE_LIGHT_MODEL:
- switch (*(*inst)++) {
- case LIGHT_MODEL_AMBIENT:
- state_tokens[0] = STATE_LIGHTMODEL_AMBIENT;
- break;
- case LIGHT_MODEL_SCENECOLOR:
- state_tokens[0] = STATE_LIGHTMODEL_SCENECOLOR;
- state_tokens[1] = parse_face_type (inst);
- break;
- }
- break;
-
- case STATE_LIGHT_PROD:
- state_tokens[0] = STATE_LIGHTPROD;
- state_tokens[1] = parse_integer (inst, Program);
-
- /* Check the value of state_tokens[1] against the # of lights */
- if (state_tokens[1] >= (GLint) ctx->Const.MaxLights) {
- program_error(ctx, Program->Position, "Invalid Light Number");
- /* bad state_tokens[1] */
- return 1;
- }
-
- state_tokens[2] = parse_face_type (inst);
- switch (*(*inst)++) {
- case LIGHT_PROD_AMBIENT:
- state_tokens[3] = STATE_AMBIENT;
- break;
- case LIGHT_PROD_DIFFUSE:
- state_tokens[3] = STATE_DIFFUSE;
- break;
- case LIGHT_PROD_SPECULAR:
- state_tokens[3] = STATE_SPECULAR;
- break;
- }
- break;
-
-
- case STATE_FOG:
- switch (*(*inst)++) {
- case FOG_COLOR:
- state_tokens[0] = STATE_FOG_COLOR;
- break;
- case FOG_PARAMS:
- state_tokens[0] = STATE_FOG_PARAMS;
- break;
- }
- break;
-
- case STATE_TEX_ENV:
- state_tokens[1] = parse_integer (inst, Program);
- switch (*(*inst)++) {
- case TEX_ENV_COLOR:
- state_tokens[0] = STATE_TEXENV_COLOR;
- break;
- }
- break;
-
- case STATE_TEX_GEN:
- {
- GLuint type, coord;
-
- state_tokens[0] = STATE_TEXGEN;
- /*state_tokens[1] = parse_integer (inst, Program);*/ /* Texture Unit */
-
- if (parse_texcoord_num (ctx, inst, Program, &coord))
- return 1;
- state_tokens[1] = coord;
-
- /* EYE or OBJECT */
- type = *(*inst)++;
-
- /* 0 - s, 1 - t, 2 - r, 3 - q */
- coord = *(*inst)++;
-
- if (type == TEX_GEN_EYE) {
- switch (coord) {
- case COMPONENT_X:
- state_tokens[2] = STATE_TEXGEN_EYE_S;
- break;
- case COMPONENT_Y:
- state_tokens[2] = STATE_TEXGEN_EYE_T;
- break;
- case COMPONENT_Z:
- state_tokens[2] = STATE_TEXGEN_EYE_R;
- break;
- case COMPONENT_W:
- state_tokens[2] = STATE_TEXGEN_EYE_Q;
- break;
- default:
- _mesa_problem(ctx, "bad texgen component in "
- "parse_state_single_item()");
- }
- }
- else {
- switch (coord) {
- case COMPONENT_X:
- state_tokens[2] = STATE_TEXGEN_OBJECT_S;
- break;
- case COMPONENT_Y:
- state_tokens[2] = STATE_TEXGEN_OBJECT_T;
- break;
- case COMPONENT_Z:
- state_tokens[2] = STATE_TEXGEN_OBJECT_R;
- break;
- case COMPONENT_W:
- state_tokens[2] = STATE_TEXGEN_OBJECT_Q;
- break;
- default:
- _mesa_problem(ctx, "bad texgen component in "
- "parse_state_single_item()");
- }
- }
- }
- break;
-
- case STATE_DEPTH:
- switch (*(*inst)++) {
- case DEPTH_RANGE:
- state_tokens[0] = STATE_DEPTH_RANGE;
- break;
- }
- break;
-
- case STATE_CLIP_PLANE:
- state_tokens[0] = STATE_CLIPPLANE;
- if (parse_clipplane_num (ctx, inst, Program,
- (GLint *) &state_tokens[1]))
- return 1;
- break;
-
- case STATE_POINT:
- switch (*(*inst)++) {
- case POINT_SIZE:
- state_tokens[0] = STATE_POINT_SIZE;
- break;
-
- case POINT_ATTENUATION:
- state_tokens[0] = STATE_POINT_ATTENUATION;
- break;
- }
- break;
-
- /* XXX: I think this is the correct format for a matrix row */
- case STATE_MATRIX_ROWS:
- if (parse_matrix(ctx, inst, Program,
- (GLint *) &state_tokens[0],
- (GLint *) &state_tokens[1],
- (GLint *) &state_tokens[4]))
- return 1;
-
- state_tokens[2] = parse_integer (inst, Program); /* The first row to grab */
-
- if ((**inst) != 0) { /* Either the last row, 0 */
- state_tokens[3] = parse_integer (inst, Program);
- if (state_tokens[3] < state_tokens[2]) {
- program_error(ctx, Program->Position,
- "Second matrix index less than the first");
- /* state_tokens[4] vs. state_tokens[3] */
- return 1;
- }
- }
- else {
- state_tokens[3] = state_tokens[2];
- (*inst)++;
- }
- break;
- }
-
- return 0;
-}
-
-/**
- * This parses a state string (rather, the binary version of it) into
- * a 6-token similar for the state fetching code in program.c
- *
- * One might ask, why fetch these parameters into just like you fetch
- * state when they are already stored in other places?
- *
- * Because of array offsets -> We can stick env/local parameters in the
- * middle of a parameter array and then index someplace into the array
- * when we execute.
- *
- * One optimization might be to only do this for the cases where the
- * env/local parameters end up inside of an array, and leave the
- * single parameters (or arrays of pure env/local pareameters) in their
- * respective register files.
- *
- * For ENV parameters, the format is:
- * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
- * state_tokens[1] = STATE_ENV
- * state_tokens[2] = the parameter index
- *
- * for LOCAL parameters, the format is:
- * state_tokens[0] = STATE_FRAGMENT_PROGRAM / STATE_VERTEX_PROGRAM
- * state_tokens[1] = STATE_LOCAL
- * state_tokens[2] = the parameter index
- *
- * \param inst - the start in the binary arry to start working from
- * \param state_tokens - the storage for the 6-token state description
- * \return - 0 on sucess, 1 on failure
- */
-static GLuint
-parse_program_single_item (GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program,
- gl_state_index state_tokens[STATE_LENGTH])
-{
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
- state_tokens[0] = STATE_FRAGMENT_PROGRAM;
- else
- state_tokens[0] = STATE_VERTEX_PROGRAM;
-
-
- switch (*(*inst)++) {
- case PROGRAM_PARAM_ENV:
- state_tokens[1] = STATE_ENV;
- state_tokens[2] = parse_integer (inst, Program);
-
- /* Check state_tokens[2] against the number of ENV parameters available */
- if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
- (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxEnvParams))
- ||
- ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
- (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxEnvParams))) {
- program_error(ctx, Program->Position,
- "Invalid Program Env Parameter");
- /* bad state_tokens[2] */
- return 1;
- }
-
- break;
-
- case PROGRAM_PARAM_LOCAL:
- state_tokens[1] = STATE_LOCAL;
- state_tokens[2] = parse_integer (inst, Program);
-
- /* Check state_tokens[2] against the number of LOCAL parameters available */
- if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
- (state_tokens[2] >= (GLint) ctx->Const.FragmentProgram.MaxLocalParams))
- ||
- ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
- (state_tokens[2] >= (GLint) ctx->Const.VertexProgram.MaxLocalParams))) {
- program_error(ctx, Program->Position,
- "Invalid Program Local Parameter");
- /* bad state_tokens[2] */
- return 1;
- }
- break;
- }
-
- return 0;
-}
-
-/**
- * For ARB_vertex_program, programs are not allowed to use both an explicit
- * vertex attribute and a generic vertex attribute corresponding to the same
- * state. See section 2.14.3.1 of the GL_ARB_vertex_program spec.
- *
- * This will walk our var_cache and make sure that nobody does anything fishy.
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-generic_attrib_check(struct var_cache *vc_head)
-{
- int a;
- struct var_cache *curr;
- GLboolean explicitAttrib[MAX_VERTEX_GENERIC_ATTRIBS],
- genericAttrib[MAX_VERTEX_GENERIC_ATTRIBS];
-
- for (a=0; a<MAX_VERTEX_GENERIC_ATTRIBS; a++) {
- explicitAttrib[a] = GL_FALSE;
- genericAttrib[a] = GL_FALSE;
- }
-
- curr = vc_head;
- while (curr) {
- if (curr->type == vt_attrib) {
- if (curr->attrib_is_generic) {
- GLuint attr = (curr->attrib_binding == 0)
- ? 0 : (curr->attrib_binding - VERT_ATTRIB_GENERIC0);
- assert(attr < MAX_VERTEX_GENERIC_ATTRIBS);
- genericAttrib[attr] = GL_TRUE;
- }
- else {
- assert(curr->attrib_binding < MAX_VERTEX_GENERIC_ATTRIBS);
- explicitAttrib[ curr->attrib_binding ] = GL_TRUE;
- }
- }
-
- curr = curr->next;
- }
-
- for (a=0; a<MAX_VERTEX_GENERIC_ATTRIBS; a++) {
- if ((explicitAttrib[a]) && (genericAttrib[a]))
- return 1;
- }
-
- return 0;
-}
-
-/**
- * This will handle the binding side of an ATTRIB var declaration
- *
- * \param inputReg returns the input register index, one of the
- * VERT_ATTRIB_* or FRAG_ATTRIB_* values.
- * \return returns 0 on success, 1 on error
- */
-static GLuint
-parse_attrib_binding(GLcontext * ctx, const GLubyte ** inst,
- struct arb_program *Program,
- GLuint *inputReg, GLuint *is_generic)
-{
- GLint err = 0;
-
- *is_generic = 0;
-
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- switch (*(*inst)++) {
- case FRAGMENT_ATTRIB_COLOR:
- {
- GLint coord;
- err = parse_color_type (ctx, inst, Program, &coord);
- *inputReg = FRAG_ATTRIB_COL0 + coord;
- }
- break;
- case FRAGMENT_ATTRIB_TEXCOORD:
- {
- GLuint texcoord = 0;
- err = parse_texcoord_num (ctx, inst, Program, &texcoord);
- *inputReg = FRAG_ATTRIB_TEX0 + texcoord;
- }
- break;
- case FRAGMENT_ATTRIB_FOGCOORD:
- *inputReg = FRAG_ATTRIB_FOGC;
- break;
- case FRAGMENT_ATTRIB_POSITION:
- *inputReg = FRAG_ATTRIB_WPOS;
- break;
- default:
- err = 1;
- break;
- }
- }
- else {
- switch (*(*inst)++) {
- case VERTEX_ATTRIB_POSITION:
- *inputReg = VERT_ATTRIB_POS;
- break;
-
- case VERTEX_ATTRIB_WEIGHT:
- {
- GLint weight;
- err = parse_weight_num (ctx, inst, Program, &weight);
- *inputReg = VERT_ATTRIB_WEIGHT;
-#if 1
- /* hack for Warcraft (see bug 8060) */
- _mesa_warning(ctx, "Application error: vertex program uses 'vertex.weight' but GL_ARB_vertex_blend not supported.");
- break;
-#else
- program_error(ctx, Program->Position,
- "ARB_vertex_blend not supported");
- return 1;
-#endif
- }
-
- case VERTEX_ATTRIB_NORMAL:
- *inputReg = VERT_ATTRIB_NORMAL;
- break;
-
- case VERTEX_ATTRIB_COLOR:
- {
- GLint color;
- err = parse_color_type (ctx, inst, Program, &color);
- if (color) {
- *inputReg = VERT_ATTRIB_COLOR1;
- }
- else {
- *inputReg = VERT_ATTRIB_COLOR0;
- }
- }
- break;
-
- case VERTEX_ATTRIB_FOGCOORD:
- *inputReg = VERT_ATTRIB_FOG;
- break;
-
- case VERTEX_ATTRIB_TEXCOORD:
- {
- GLuint unit = 0;
- err = parse_texcoord_num (ctx, inst, Program, &unit);
- *inputReg = VERT_ATTRIB_TEX0 + unit;
- }
- break;
-
- case VERTEX_ATTRIB_MATRIXINDEX:
- /* Not supported at this time */
- {
- const char *msg = "ARB_palette_matrix not supported";
- parse_integer (inst, Program);
- program_error(ctx, Program->Position, msg);
- }
- return 1;
-
- case VERTEX_ATTRIB_GENERIC:
- {
- GLuint attrib;
- err = parse_generic_attrib_num(ctx, inst, Program, &attrib);
- if (!err) {
- *is_generic = 1;
- /* Add VERT_ATTRIB_GENERIC0 here because ARB_vertex_program's
- * attributes do not alias the conventional vertex
- * attributes.
- */
- if (attrib > 0)
- *inputReg = attrib + VERT_ATTRIB_GENERIC0;
- else
- *inputReg = 0;
- }
- }
- break;
-
- default:
- err = 1;
- break;
- }
- }
-
- if (err) {
- program_error(ctx, Program->Position, "Bad attribute binding");
- }
-
- return err;
-}
-
-
-/**
- * This translates between a binary token for an output variable type
- * and the mesa token for the same thing.
- *
- * \param inst The parsed tokens
- * \param outputReg Returned index/number of the output register,
- * one of the VERT_RESULT_* or FRAG_RESULT_* values.
- */
-static GLuint
-parse_result_binding(GLcontext *ctx, const GLubyte **inst,
- GLuint *outputReg, struct arb_program *Program)
-{
- const GLubyte token = *(*inst)++;
-
- switch (token) {
- case FRAGMENT_RESULT_COLOR:
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- GLuint out_color;
-
- /* This gets result of the color buffer we're supposed to
- * draw into. This pertains to GL_ARB_draw_buffers.
- */
- parse_output_color_num(ctx, inst, Program, &out_color);
- ASSERT(out_color < MAX_DRAW_BUFFERS);
- *outputReg = FRAG_RESULT_COLOR;
- }
- else {
- /* for vtx programs, this is VERTEX_RESULT_POSITION */
- *outputReg = VERT_RESULT_HPOS;
- }
- break;
-
- case FRAGMENT_RESULT_DEPTH:
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- /* for frag programs, this is FRAGMENT_RESULT_DEPTH */
- *outputReg = FRAG_RESULT_DEPTH;
- }
- else {
- /* for vtx programs, this is VERTEX_RESULT_COLOR */
- GLint color_type;
- GLuint face_type = parse_face_type(inst);
- GLint err = parse_color_type(ctx, inst, Program, &color_type);
- if (err)
- return 1;
-
- if (face_type) {
- /* back face */
- if (color_type) {
- *outputReg = VERT_RESULT_BFC1; /* secondary color */
- }
- else {
- *outputReg = VERT_RESULT_BFC0; /* primary color */
- }
- }
- else {
- /* front face */
- if (color_type) {
- *outputReg = VERT_RESULT_COL1; /* secondary color */
- }
- /* primary color */
- else {
- *outputReg = VERT_RESULT_COL0; /* primary color */
- }
- }
- }
- break;
-
- case VERTEX_RESULT_FOGCOORD:
- *outputReg = VERT_RESULT_FOGC;
- break;
-
- case VERTEX_RESULT_POINTSIZE:
- *outputReg = VERT_RESULT_PSIZ;
- break;
-
- case VERTEX_RESULT_TEXCOORD:
- {
- GLuint unit;
- if (parse_texcoord_num (ctx, inst, Program, &unit))
- return 1;
- *outputReg = VERT_RESULT_TEX0 + unit;
- }
- break;
- }
-
- Program->Base.OutputsWritten |= (1 << *outputReg);
-
- return 0;
-}
-
-
-/**
- * This handles the declaration of ATTRIB variables
- *
- * XXX: Still needs
- * parse_vert_attrib_binding(), or something like that
- *
- * \return 0 on sucess, 1 on error
- */
-static GLint
-parse_attrib (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found;
- struct var_cache *attrib_var;
-
- attrib_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) attrib_var->name);
- return 1;
- }
-
- attrib_var->type = vt_attrib;
-
- if (parse_attrib_binding(ctx, inst, Program, &attrib_var->attrib_binding,
- &attrib_var->attrib_is_generic))
- return 1;
-
- if (generic_attrib_check(*vc_head)) {
- program_error(ctx, Program->Position,
- "Cannot use both a generic vertex attribute "
- "and a specific attribute of the same type");
- return 1;
- }
-
- Program->Base.NumAttributes++;
- return 0;
-}
-
-/**
- * \param use -- TRUE if we're called when declaring implicit parameters,
- * FALSE if we're declaraing variables. This has to do with
- * if we get a signed or unsigned float for scalar constants
- */
-static GLuint
-parse_param_elements (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache *param_var,
- struct arb_program *Program, GLboolean use)
-{
- GLint idx;
- GLuint err = 0;
- gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
-
- GLubyte token = *(*inst)++;
-
- switch (token) {
- case PARAM_STATE_ELEMENT:
- if (parse_state_single_item (ctx, inst, Program, state_tokens))
- return 1;
-
- /* If we adding STATE_MATRIX that has multiple rows, we need to
- * unroll it and call _mesa_add_state_reference() for each row
- */
- if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
- state_tokens[0] == STATE_PROJECTION_MATRIX ||
- state_tokens[0] == STATE_MVP_MATRIX ||
- state_tokens[0] == STATE_TEXTURE_MATRIX ||
- state_tokens[0] == STATE_PROGRAM_MATRIX)
- && (state_tokens[2] != state_tokens[3])) {
- GLint row;
- const GLint first_row = state_tokens[2];
- const GLint last_row = state_tokens[3];
-
- for (row = first_row; row <= last_row; row++) {
- state_tokens[2] = state_tokens[3] = row;
-
- idx = _mesa_add_state_reference(Program->Base.Parameters,
- state_tokens);
- if (param_var->param_binding_begin == ~0U)
- param_var->param_binding_begin = idx;
- param_var->param_binding_length++;
- }
- }
- else {
- idx = _mesa_add_state_reference(Program->Base.Parameters,
- state_tokens);
- if (param_var->param_binding_begin == ~0U)
- param_var->param_binding_begin = idx;
- param_var->param_binding_length++;
- }
- break;
-
- case PARAM_PROGRAM_ELEMENT:
- if (parse_program_single_item (ctx, inst, Program, state_tokens))
- return 1;
- idx = _mesa_add_state_reference (Program->Base.Parameters, state_tokens);
- if (param_var->param_binding_begin == ~0U)
- param_var->param_binding_begin = idx;
- param_var->param_binding_length++;
-
- /* Check if there is more: 0 -> we're done, else its an integer */
- if (**inst) {
- GLuint out_of_range, new_idx;
- GLuint start_idx = state_tokens[2] + 1;
- GLuint end_idx = parse_integer (inst, Program);
-
- out_of_range = 0;
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- if (((state_tokens[1] == STATE_ENV)
- && (end_idx >= ctx->Const.FragmentProgram.MaxEnvParams))
- || ((state_tokens[1] == STATE_LOCAL)
- && (end_idx >=
- ctx->Const.FragmentProgram.MaxLocalParams)))
- out_of_range = 1;
- }
- else {
- if (((state_tokens[1] == STATE_ENV)
- && (end_idx >= ctx->Const.VertexProgram.MaxEnvParams))
- || ((state_tokens[1] == STATE_LOCAL)
- && (end_idx >=
- ctx->Const.VertexProgram.MaxLocalParams)))
- out_of_range = 1;
- }
- if (out_of_range) {
- program_error(ctx, Program->Position,
- "Invalid Program Parameter"); /*end_idx*/
- return 1;
- }
-
- for (new_idx = start_idx; new_idx <= end_idx; new_idx++) {
- state_tokens[2] = new_idx;
- idx = _mesa_add_state_reference(Program->Base.Parameters,
- state_tokens);
- param_var->param_binding_length++;
- }
- }
- else {
- (*inst)++;
- }
- break;
-
- case PARAM_CONSTANT:
- /* parsing something like {1.0, 2.0, 3.0, 4.0} */
- {
- GLfloat const_values[4];
- GLint size;
- parse_constant(inst, const_values, &size, Program, use);
- if (param_var->name[0] == ' ') {
- /* this is an unnamed constant */
- idx = _mesa_add_unnamed_constant(Program->Base.Parameters,
- const_values, size,
- &param_var->swizzle);
- }
- else {
- /* named parameter/constant */
- idx = _mesa_add_named_constant(Program->Base.Parameters,
- (char *) param_var->name,
- const_values, size);
- }
- if (param_var->param_binding_begin == ~0U)
- param_var->param_binding_begin = idx;
- param_var->param_binding_type = PROGRAM_STATE_VAR;
- /* Note: when we reference this parameter in an instruction later,
- * we'll check if it's really a constant/immediate and set the
- * instruction register type appropriately.
- */
- param_var->param_binding_length++;
- }
- break;
-
- default:
- program_error(ctx, Program->Position,
- "Unexpected token (in parse_param_elements())");
- return 1;
- }
-
- Program->Base.NumParameters = Program->Base.Parameters->NumParameters;
-
- /* Make sure we haven't blown past our parameter limits */
- if (((Program->Base.Target == GL_VERTEX_PROGRAM_ARB) &&
- (Program->Base.NumParameters >
- ctx->Const.VertexProgram.MaxLocalParams))
- || ((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
- && (Program->Base.NumParameters >
- ctx->Const.FragmentProgram.MaxLocalParams))) {
- program_error(ctx, Program->Position, "Too many parameter variables");
- return 1;
- }
-
- return err;
-}
-
-
-/**
- * This picks out PARAM program parameter bindings.
- *
- * XXX: This needs to be stressed & tested
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_param (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found, err;
- GLint specified_length;
- struct var_cache *param_var;
-
- err = 0;
- param_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
-
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) param_var->name);
- return 1;
- }
-
- specified_length = parse_integer (inst, Program);
-
- if (specified_length < 0) {
- program_error(ctx, Program->Position, "Negative parameter array length");
- return 1;
- }
-
- param_var->type = vt_param;
- param_var->param_binding_length = 0;
-
- /* Right now, everything is shoved into the main state register file.
- *
- * In the future, it would be nice to leave things ENV/LOCAL params
- * in their respective register files, if possible
- */
- param_var->param_binding_type = PROGRAM_STATE_VAR;
-
- /* Remember to:
- * * - add each guy to the parameter list
- * * - increment the param_var->param_binding_len
- * * - store the param_var->param_binding_begin for the first one
- * * - compare the actual len to the specified len at the end
- */
- while (**inst != PARAM_NULL) {
- if (parse_param_elements (ctx, inst, param_var, Program, GL_FALSE))
- return 1;
- }
-
- /* Test array length here! */
- if (specified_length) {
- if (specified_length != (int)param_var->param_binding_length) {
- program_error(ctx, Program->Position,
- "Declared parameter array length does not match parameter list");
- }
- }
-
- (*inst)++;
-
- return 0;
-}
-
-/**
- *
- */
-static GLuint
-parse_param_use (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program, struct var_cache **new_var)
-{
- struct var_cache *param_var;
-
- /* First, insert a dummy entry into the var_cache */
- var_cache_create (&param_var);
- param_var->name = (const GLubyte *) " ";
- param_var->type = vt_param;
-
- param_var->param_binding_length = 0;
- /* Don't fill in binding_begin; We use the default value of -1
- * to tell if its already initialized, elsewhere.
- *
- * param_var->param_binding_begin = 0;
- */
- param_var->param_binding_type = PROGRAM_STATE_VAR;
-
- var_cache_append (vc_head, param_var);
-
- /* Then fill it with juicy parameter goodness */
- if (parse_param_elements (ctx, inst, param_var, Program, GL_TRUE))
- return 1;
-
- *new_var = param_var;
-
- return 0;
-}
-
-
-/**
- * This handles the declaration of TEMP variables
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_temp (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found;
- struct var_cache *temp_var;
-
- while (**inst != 0) {
- temp_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) temp_var->name);
- return 1;
- }
-
- temp_var->type = vt_temp;
-
- if (((Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) &&
- (Program->Base.NumTemporaries >=
- ctx->Const.FragmentProgram.MaxTemps))
- || ((Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
- && (Program->Base.NumTemporaries >=
- ctx->Const.VertexProgram.MaxTemps))) {
- program_error(ctx, Program->Position,
- "Too many TEMP variables declared");
- return 1;
- }
-
- temp_var->temp_binding = Program->Base.NumTemporaries;
- Program->Base.NumTemporaries++;
- }
- (*inst)++;
-
- return 0;
-}
-
-/**
- * This handles variables of the OUTPUT variety
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_output (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found;
- struct var_cache *output_var;
- GLuint err;
-
- output_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) output_var->name);
- return 1;
- }
-
- output_var->type = vt_output;
-
- err = parse_result_binding(ctx, inst, &output_var->output_binding, Program);
- return err;
-}
-
-/**
- * This handles variables of the ALIAS kind
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_alias (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found;
- struct var_cache *temp_var;
-
- temp_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
-
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) temp_var->name);
- return 1;
- }
-
- temp_var->type = vt_alias;
- temp_var->alias_binding = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
-
- if (!found)
- {
- program_error2(ctx, Program->Position,
- "Undefined alias value",
- (char *) temp_var->alias_binding->name);
- return 1;
- }
-
- return 0;
-}
-
-/**
- * This handles variables of the ADDRESS kind
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_address (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLuint found;
- struct var_cache *temp_var;
-
- while (**inst != 0) {
- temp_var = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
- if (found) {
- program_error2(ctx, Program->Position,
- "Duplicate variable declaration",
- (char *) temp_var->name);
- return 1;
- }
-
- temp_var->type = vt_address;
-
- if (Program->Base.NumAddressRegs >=
- ctx->Const.VertexProgram.MaxAddressRegs) {
- const char *msg = "Too many ADDRESS variables declared";
- program_error(ctx, Program->Position, msg);
- return 1;
- }
-
- temp_var->address_binding = Program->Base.NumAddressRegs;
- Program->Base.NumAddressRegs++;
- }
- (*inst)++;
-
- return 0;
-}
-
-/**
- * Parse a program declaration
- *
- * \return 0 on sucess, 1 on error
- */
-static GLint
-parse_declaration (GLcontext * ctx, const GLubyte ** inst, struct var_cache **vc_head,
- struct arb_program *Program)
-{
- GLint err = 0;
-
- switch (*(*inst)++) {
- case ADDRESS:
- err = parse_address (ctx, inst, vc_head, Program);
- break;
-
- case ALIAS:
- err = parse_alias (ctx, inst, vc_head, Program);
- break;
-
- case ATTRIB:
- err = parse_attrib (ctx, inst, vc_head, Program);
- break;
-
- case OUTPUT:
- err = parse_output (ctx, inst, vc_head, Program);
- break;
-
- case PARAM:
- err = parse_param (ctx, inst, vc_head, Program);
- break;
-
- case TEMP:
- err = parse_temp (ctx, inst, vc_head, Program);
- break;
- }
-
- return err;
-}
-
-/**
- * Handle the parsing out of a masked destination register, either for a
- * vertex or fragment program.
- *
- * If we are a vertex program, make sure we don't write to
- * result.position if we have specified that the program is
- * position invariant
- *
- * \param File - The register file we write to
- * \param Index - The register index we write to
- * \param WriteMask - The mask controlling which components we write (1->write)
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_masked_dst_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- gl_register_file *File, GLuint *Index, GLint *WriteMask)
-{
- GLuint tmp, result;
- struct var_cache *dst;
-
- /* We either have a result register specified, or a
- * variable that may or may not be writable
- */
- switch (*(*inst)++) {
- case REGISTER_RESULT:
- if (parse_result_binding(ctx, inst, Index, Program))
- return 1;
- *File = PROGRAM_OUTPUT;
- break;
-
- case REGISTER_ESTABLISHED_NAME:
- dst = parse_string (inst, vc_head, Program, &result);
- Program->Position = parse_position (inst);
-
- /* If the name has never been added to our symbol table, we're hosed */
- if (!result) {
- program_error(ctx, Program->Position, "0: Undefined variable");
- return 1;
- }
-
- switch (dst->type) {
- case vt_output:
- *File = PROGRAM_OUTPUT;
- *Index = dst->output_binding;
- break;
-
- case vt_temp:
- *File = PROGRAM_TEMPORARY;
- *Index = dst->temp_binding;
- break;
-
- /* If the var type is not vt_output or vt_temp, no go */
- default:
- program_error(ctx, Program->Position,
- "Destination register is read only");
- return 1;
- }
- break;
-
- default:
- program_error(ctx, Program->Position,
- "Unexpected opcode in parse_masked_dst_reg()");
- return 1;
- }
-
-
- /* Position invariance test */
- /* This test is done now in syntax portion - when position invariance OPTION
- is specified, "result.position" rule is disabled so there is no way
- to write the position
- */
- /*if ((Program->HintPositionInvariant) && (*File == PROGRAM_OUTPUT) &&
- (*Index == 0)) {
- program_error(ctx, Program->Position,
- "Vertex program specified position invariance and wrote vertex position");
- }*/
-
- /* And then the mask.
- * w,a -> bit 0
- * z,b -> bit 1
- * y,g -> bit 2
- * x,r -> bit 3
- *
- * ==> Need to reverse the order of bits for this!
- */
- tmp = (GLint) *(*inst)++;
- *WriteMask = (((tmp>>3) & 0x1) |
- ((tmp>>1) & 0x2) |
- ((tmp<<1) & 0x4) |
- ((tmp<<3) & 0x8));
-
- return 0;
-}
-
-
-/**
- * Handle the parsing of a address register
- *
- * \param Index - The register index we write to
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_address_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program, GLint * Index)
-{
- struct var_cache *dst;
- GLuint result;
-
- *Index = 0; /* XXX */
-
- dst = parse_string (inst, vc_head, Program, &result);
- Program->Position = parse_position (inst);
-
- /* If the name has never been added to our symbol table, we're hosed */
- if (!result) {
- program_error(ctx, Program->Position, "Undefined variable");
- return 1;
- }
-
- if (dst->type != vt_address) {
- program_error(ctx, Program->Position, "Variable is not of type ADDRESS");
- return 1;
- }
-
- return 0;
-}
-
-#if 0 /* unused */
-/**
- * Handle the parsing out of a masked address register
- *
- * \param Index - The register index we write to
- * \param WriteMask - The mask controlling which components we write (1->write)
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_masked_address_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program, GLint * Index,
- GLboolean * WriteMask)
-{
- if (parse_address_reg (ctx, inst, vc_head, Program, Index))
- return 1;
-
- /* This should be 0x8 */
- (*inst)++;
-
- /* Writemask of .x is implied */
- WriteMask[0] = 1;
- WriteMask[1] = WriteMask[2] = WriteMask[3] = 0;
-
- return 0;
-}
-#endif
-
-/**
- * Parse out a swizzle mask.
- *
- * Basically convert COMPONENT_X/Y/Z/W to SWIZZLE_X/Y/Z/W
- *
- * The len parameter allows us to grab 4 components for a vector
- * swizzle, or just 1 component for a scalar src register selection
- */
-static void
-parse_swizzle_mask(const GLubyte ** inst, GLubyte *swizzle, GLint len)
-{
- GLint i;
-
- for (i = 0; i < 4; i++)
- swizzle[i] = i;
-
- for (i = 0; i < len; i++) {
- switch (*(*inst)++) {
- case COMPONENT_X:
- swizzle[i] = SWIZZLE_X;
- break;
- case COMPONENT_Y:
- swizzle[i] = SWIZZLE_Y;
- break;
- case COMPONENT_Z:
- swizzle[i] = SWIZZLE_Z;
- break;
- case COMPONENT_W:
- swizzle[i] = SWIZZLE_W;
- break;
- default:
- _mesa_problem(NULL, "bad component in parse_swizzle_mask()");
- return;
- }
- }
-
- if (len == 1)
- swizzle[1] = swizzle[2] = swizzle[3] = swizzle[0];
-}
-
-
-/**
- * Parse an extended swizzle mask which is a sequence of
- * four x/y/z/w/0/1 tokens.
- * \return swizzle four swizzle values
- * \return negateMask four element bitfield
- */
-static void
-parse_extended_swizzle_mask(const GLubyte **inst, GLubyte swizzle[4],
- GLubyte *negateMask)
-{
- GLint i;
-
- *negateMask = 0x0;
- for (i = 0; i < 4; i++) {
- GLubyte swz;
- if (parse_sign(inst) == -1)
- *negateMask |= (1 << i);
-
- swz = *(*inst)++;
-
- switch (swz) {
- case COMPONENT_0:
- swizzle[i] = SWIZZLE_ZERO;
- break;
- case COMPONENT_1:
- swizzle[i] = SWIZZLE_ONE;
- break;
- case COMPONENT_X:
- swizzle[i] = SWIZZLE_X;
- break;
- case COMPONENT_Y:
- swizzle[i] = SWIZZLE_Y;
- break;
- case COMPONENT_Z:
- swizzle[i] = SWIZZLE_Z;
- break;
- case COMPONENT_W:
- swizzle[i] = SWIZZLE_W;
- break;
- default:
- _mesa_problem(NULL, "bad case in parse_extended_swizzle_mask()");
- return;
- }
- }
-}
-
-
-static GLuint
-parse_src_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- gl_register_file * File, GLint * Index, GLuint *swizzle,
- GLboolean *IsRelOffset )
-{
- struct var_cache *src;
- GLuint binding, is_generic, found;
- GLint offset;
-
- *IsRelOffset = 0;
-
- *swizzle = SWIZZLE_XYZW; /* default */
-
- /* And the binding for the src */
- switch (*(*inst)++) {
- case REGISTER_ATTRIB:
- if (parse_attrib_binding
- (ctx, inst, Program, &binding, &is_generic))
- return 1;
- *File = PROGRAM_INPUT;
- *Index = binding;
-
- /* We need to insert a dummy variable into the var_cache so we can
- * catch generic vertex attrib aliasing errors
- */
- var_cache_create(&src);
- src->type = vt_attrib;
- src->name = (const GLubyte *) "Dummy Attrib Variable";
- src->attrib_binding = binding;
- src->attrib_is_generic = is_generic;
- var_cache_append(vc_head, src);
- if (generic_attrib_check(*vc_head)) {
- program_error(ctx, Program->Position,
- "Cannot use both a generic vertex attribute "
- "and a specific attribute of the same type");
- return 1;
- }
- break;
-
- case REGISTER_PARAM:
- switch (**inst) {
- case PARAM_ARRAY_ELEMENT:
- (*inst)++;
- src = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
-
- if (!found) {
- program_error2(ctx, Program->Position,
- "Undefined variable",
- (char *) src->name);
- return 1;
- }
-
- *File = (gl_register_file) src->param_binding_type;
-
- switch (*(*inst)++) {
- case ARRAY_INDEX_ABSOLUTE:
- offset = parse_integer (inst, Program);
-
- if ((offset < 0)
- || (offset >= (int)src->param_binding_length)) {
- program_error(ctx, Program->Position,
- "Index out of range");
- /* offset, src->name */
- return 1;
- }
-
- *Index = src->param_binding_begin + offset;
- *swizzle = src->swizzle;
- break;
-
- case ARRAY_INDEX_RELATIVE:
- {
- GLint addr_reg_idx, rel_off;
-
- /* First, grab the address regiseter */
- if (parse_address_reg (ctx, inst, vc_head, Program, &addr_reg_idx))
- return 1;
-
- /* And the .x */
- ((*inst)++);
- ((*inst)++);
- ((*inst)++);
- ((*inst)++);
-
- /* Then the relative offset */
- if (parse_relative_offset(ctx, inst, Program, &rel_off)) return 1;
-
- /* And store it properly */
- *Index = src->param_binding_begin + rel_off;
- *IsRelOffset = 1;
- *swizzle = src->swizzle;
- }
- break;
- }
- break;
-
- default:
- if (parse_param_use (ctx, inst, vc_head, Program, &src))
- return 1;
-
- *File = (gl_register_file) src->param_binding_type;
- *Index = src->param_binding_begin;
- *swizzle = src->swizzle;
- break;
- }
- break;
-
- case REGISTER_ESTABLISHED_NAME:
- src = parse_string (inst, vc_head, Program, &found);
- Program->Position = parse_position (inst);
-
- /* If the name has never been added to our symbol table, we're hosed */
- if (!found) {
- program_error(ctx, Program->Position,
- "3: Undefined variable"); /* src->name */
- return 1;
- }
-
- switch (src->type) {
- case vt_attrib:
- *File = PROGRAM_INPUT;
- *Index = src->attrib_binding;
- break;
-
- /* XXX: We have to handle offsets someplace in here! -- or are those above? */
- case vt_param:
- *File = (gl_register_file) src->param_binding_type;
- *Index = src->param_binding_begin;
- break;
-
- case vt_temp:
- *File = PROGRAM_TEMPORARY;
- *Index = src->temp_binding;
- break;
-
- /* If the var type is vt_output no go */
- default:
- program_error(ctx, Program->Position,
- "destination register is read only");
- /* bad src->name */
- return 1;
- }
- break;
-
- default:
- program_error(ctx, Program->Position,
- "Unknown token in parse_src_reg");
- return 1;
- }
-
- if (*File == PROGRAM_STATE_VAR) {
- gl_register_file file;
-
- /* If we're referencing the Program->Parameters[] array, check if the
- * parameter is really a constant/literal. If so, set File to CONSTANT.
- */
- assert(*Index < (GLint) Program->Base.Parameters->NumParameters);
- file = Program->Base.Parameters->Parameters[*Index].Type;
- if (file == PROGRAM_CONSTANT)
- *File = PROGRAM_CONSTANT;
- }
-
- /* Add attributes to InputsRead only if they are used the program.
- * This avoids the handling of unused ATTRIB declarations in the drivers. */
- if (*File == PROGRAM_INPUT)
- Program->Base.InputsRead |= (1 << *Index);
-
- return 0;
-}
-
-
-static GLuint
-swizzle_swizzle(GLuint baseSwizzle, const GLubyte swizzle[4])
-{
- GLuint i, swz, s[4];
- for (i = 0; i < 4; i++) {
- GLuint c = swizzle[i];
- if (c <= SWIZZLE_W)
- s[i] = GET_SWZ(baseSwizzle, c);
- else
- s[i] = c;
- }
- swz = MAKE_SWIZZLE4(s[0], s[1], s[2], s[3]);
- return swz;
-}
-
-/**
- * Parse vertex/fragment program vector source register.
- */
-static GLuint
-parse_vector_src_reg(GLcontext *ctx, const GLubyte **inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg)
-{
- gl_register_file file;
- GLint index;
- GLubyte negateMask;
- GLubyte swizzle[4];
- GLboolean isRelOffset;
- GLuint baseSwizzle;
-
- /* Grab the sign */
- negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
-
- /* And the src reg */
- if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
- &isRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, swizzle, 4);
-
- reg->File = file;
- reg->Index = index;
- reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
- reg->Negate = negateMask;
- reg->RelAddr = isRelOffset;
- return 0;
-}
-
-
-/**
- * Parse vertex/fragment program scalar source register.
- */
-static GLuint
-parse_scalar_src_reg(GLcontext *ctx, const GLubyte **inst,
- struct var_cache **vc_head,
- struct arb_program *program,
- struct prog_src_register *reg)
-{
- gl_register_file file;
- GLint index;
- GLubyte negateMask;
- GLubyte swizzle[4];
- GLboolean isRelOffset;
- GLuint baseSwizzle;
-
- /* Grab the sign */
- negateMask = (parse_sign (inst) == -1) ? NEGATE_XYZW : NEGATE_NONE;
-
- /* And the src reg */
- if (parse_src_reg(ctx, inst, vc_head, program, &file, &index, &baseSwizzle,
- &isRelOffset))
- return 1;
-
- /* finally, the swizzle */
- parse_swizzle_mask(inst, swizzle, 1);
-
- reg->File = file;
- reg->Index = index;
- reg->Swizzle = swizzle_swizzle(baseSwizzle, swizzle);
- reg->Negate = negateMask;
- reg->RelAddr = isRelOffset;
- return 0;
-}
-
-
-/**
- * Parse vertex/fragment program destination register.
- * \return 1 if error, 0 if no error.
- */
-static GLuint
-parse_dst_reg(GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *program,
- struct prog_dst_register *reg )
-{
- GLint mask;
- GLuint idx;
- gl_register_file file;
-
- if (parse_masked_dst_reg (ctx, inst, vc_head, program, &file, &idx, &mask))
- return 1;
-
- reg->File = file;
- reg->Index = idx;
- reg->WriteMask = mask;
- return 0;
-}
-
-
-/**
- * This is a big mother that handles getting opcodes into the instruction
- * and handling the src & dst registers for fragment program instructions
- * \return 1 if error, 0 if no error
- */
-static GLuint
-parse_fp_instruction (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_instruction *fp)
-{
- GLint a;
- GLuint texcoord;
- GLubyte instClass, type, code;
- GLboolean rel;
- GLuint shadow_tex = 0;
-
- _mesa_init_instructions(fp, 1);
-
- /* OP_ALU_INST or OP_TEX_INST */
- instClass = *(*inst)++;
-
- /* OP_ALU_{VECTOR, SCALAR, BINSC, BIN, TRI, SWZ},
- * OP_TEX_{SAMPLE, KIL}
- */
- type = *(*inst)++;
-
- /* The actual opcode name */
- code = *(*inst)++;
-
- /* Increment the correct count */
- switch (instClass) {
- case OP_ALU_INST:
- Program->NumAluInstructions++;
- break;
- case OP_TEX_INST:
- Program->NumTexInstructions++;
- break;
- }
-
- switch (type) {
- case OP_ALU_VECTOR:
- switch (code) {
- case OP_ABS_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_ABS:
- fp->Opcode = OPCODE_ABS;
- break;
-
- case OP_FLR_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_FLR:
- fp->Opcode = OPCODE_FLR;
- break;
-
- case OP_FRC_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_FRC:
- fp->Opcode = OPCODE_FRC;
- break;
-
- case OP_LIT_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_LIT:
- fp->Opcode = OPCODE_LIT;
- break;
-
- case OP_MOV_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_MOV:
- fp->Opcode = OPCODE_MOV;
- break;
- }
-
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
- return 1;
- break;
-
- case OP_ALU_SCALAR:
- switch (code) {
- case OP_COS_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_COS:
- fp->Opcode = OPCODE_COS;
- break;
-
- case OP_EX2_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_EX2:
- fp->Opcode = OPCODE_EX2;
- break;
-
- case OP_LG2_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_LG2:
- fp->Opcode = OPCODE_LG2;
- break;
-
- case OP_RCP_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_RCP:
- fp->Opcode = OPCODE_RCP;
- break;
-
- case OP_RSQ_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_RSQ:
- fp->Opcode = OPCODE_RSQ;
- break;
-
- case OP_SIN_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SIN:
- fp->Opcode = OPCODE_SIN;
- break;
-
- case OP_SCS_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SCS:
-
- fp->Opcode = OPCODE_SCS;
- break;
- }
-
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
- return 1;
- break;
-
- case OP_ALU_BINSC:
- switch (code) {
- case OP_POW_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_POW:
- fp->Opcode = OPCODE_POW;
- break;
- }
-
- if (parse_dst_reg(ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- for (a = 0; a < 2; a++) {
- if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
- return 1;
- }
- break;
-
-
- case OP_ALU_BIN:
- switch (code) {
- case OP_ADD_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_ADD:
- fp->Opcode = OPCODE_ADD;
- break;
-
- case OP_DP3_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_DP3:
- fp->Opcode = OPCODE_DP3;
- break;
-
- case OP_DP4_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_DP4:
- fp->Opcode = OPCODE_DP4;
- break;
-
- case OP_DPH_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_DPH:
- fp->Opcode = OPCODE_DPH;
- break;
-
- case OP_DST_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_DST:
- fp->Opcode = OPCODE_DST;
- break;
-
- case OP_MAX_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_MAX:
- fp->Opcode = OPCODE_MAX;
- break;
-
- case OP_MIN_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_MIN:
- fp->Opcode = OPCODE_MIN;
- break;
-
- case OP_MUL_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_MUL:
- fp->Opcode = OPCODE_MUL;
- break;
-
- case OP_SGE_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SGE:
- fp->Opcode = OPCODE_SGE;
- break;
-
- case OP_SLT_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SLT:
- fp->Opcode = OPCODE_SLT;
- break;
-
- case OP_SUB_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SUB:
- fp->Opcode = OPCODE_SUB;
- break;
-
- case OP_XPD_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_XPD:
- fp->Opcode = OPCODE_XPD;
- break;
- }
-
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
- for (a = 0; a < 2; a++) {
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
- return 1;
- }
- break;
-
- case OP_ALU_TRI:
- switch (code) {
- case OP_CMP_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_CMP:
- fp->Opcode = OPCODE_CMP;
- break;
-
- case OP_LRP_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_LRP:
- fp->Opcode = OPCODE_LRP;
- break;
-
- case OP_MAD_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_MAD:
- fp->Opcode = OPCODE_MAD;
- break;
- }
-
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- for (a = 0; a < 3; a++) {
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[a]))
- return 1;
- }
- break;
-
- case OP_ALU_SWZ:
- switch (code) {
- case OP_SWZ_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_SWZ:
- fp->Opcode = OPCODE_SWZ;
- break;
- }
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- {
- GLubyte swizzle[4];
- GLubyte negateMask;
- gl_register_file file;
- GLint index;
- GLuint baseSwizzle;
-
- if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
- &baseSwizzle, &rel))
- return 1;
- parse_extended_swizzle_mask(inst, swizzle, &negateMask);
- fp->SrcReg[0].File = file;
- fp->SrcReg[0].Index = index;
- fp->SrcReg[0].Negate = negateMask;
- fp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0],
- swizzle[1],
- swizzle[2],
- swizzle[3]);
- }
- break;
-
- case OP_TEX_SAMPLE:
- switch (code) {
- case OP_TEX_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_TEX:
- fp->Opcode = OPCODE_TEX;
- break;
-
- case OP_TXP_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_TXP:
- fp->Opcode = OPCODE_TXP;
- break;
-
- case OP_TXB_SAT:
- fp->SaturateMode = SATURATE_ZERO_ONE;
- case OP_TXB:
- fp->Opcode = OPCODE_TXB;
- break;
- }
-
- if (parse_dst_reg (ctx, inst, vc_head, Program, &fp->DstReg))
- return 1;
-
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
- return 1;
-
- /* texImageUnit */
- if (parse_teximage_num (ctx, inst, Program, &texcoord))
- return 1;
- fp->TexSrcUnit = texcoord;
-
- /* texTarget */
- switch (*(*inst)++) {
- case TEXTARGET_SHADOW1D:
- shadow_tex = 1 << texcoord;
- /* FALLTHROUGH */
- case TEXTARGET_1D:
- fp->TexSrcTarget = TEXTURE_1D_INDEX;
- break;
- case TEXTARGET_SHADOW2D:
- shadow_tex = 1 << texcoord;
- /* FALLTHROUGH */
- case TEXTARGET_2D:
- fp->TexSrcTarget = TEXTURE_2D_INDEX;
- break;
- case TEXTARGET_3D:
- fp->TexSrcTarget = TEXTURE_3D_INDEX;
- break;
- case TEXTARGET_SHADOWRECT:
- shadow_tex = 1 << texcoord;
- /* FALLTHROUGH */
- case TEXTARGET_RECT:
- fp->TexSrcTarget = TEXTURE_RECT_INDEX;
- break;
- case TEXTARGET_CUBE:
- fp->TexSrcTarget = TEXTURE_CUBE_INDEX;
- break;
- case TEXTARGET_SHADOW1D_ARRAY:
- shadow_tex = 1 << texcoord;
- /* FALLTHROUGH */
- case TEXTARGET_1D_ARRAY:
- fp->TexSrcTarget = TEXTURE_1D_ARRAY_INDEX;
- break;
- case TEXTARGET_SHADOW2D_ARRAY:
- shadow_tex = 1 << texcoord;
- /* FALLTHROUGH */
- case TEXTARGET_2D_ARRAY:
- fp->TexSrcTarget = TEXTURE_2D_ARRAY_INDEX;
- break;
- }
-
- if (shadow_tex)
- fp->TexShadow = 1;
-
- /* Don't test the first time a particular sampler is seen. Each time
- * after that, make sure the shadow state is the same.
- */
- if ((_mesa_bitcount(Program->TexturesUsed[texcoord]) > 0)
- && ((Program->ShadowSamplers & (1 << texcoord)) != shadow_tex)) {
- program_error(ctx, Program->Position,
- "texture image unit used for shadow sampling and non-shadow sampling");
- return 1;
- }
-
- Program->TexturesUsed[texcoord] |= (1 << fp->TexSrcTarget);
- /* Check that both "2D" and "CUBE" (for example) aren't both used */
- if (_mesa_bitcount(Program->TexturesUsed[texcoord]) > 1) {
- program_error(ctx, Program->Position,
- "multiple targets used on one texture image unit");
- return 1;
- }
-
-
- Program->ShadowSamplers |= shadow_tex;
- break;
-
- case OP_TEX_KIL:
- Program->UsesKill = 1;
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &fp->SrcReg[0]))
- return 1;
- fp->Opcode = OPCODE_KIL;
- break;
- default:
- _mesa_problem(ctx, "bad type 0x%x in parse_fp_instruction()", type);
- return 1;
- }
-
- return 0;
-}
-
-
-/**
- * Handle the parsing out of a masked address register
- *
- * \param Index - The register index we write to
- * \param WriteMask - The mask controlling which components we write (1->write)
- *
- * \return 0 on sucess, 1 on error
- */
-static GLuint
-parse_vp_address_reg (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head,
- struct arb_program *Program,
- struct prog_dst_register *reg)
-{
- GLint idx;
-
- if (parse_address_reg (ctx, inst, vc_head, Program, &idx))
- return 1;
-
- /* This should be 0x8 */
- (*inst)++;
-
- reg->File = PROGRAM_ADDRESS;
- reg->Index = idx;
-
- /* Writemask of .x is implied */
- reg->WriteMask = 0x1;
- return 0;
-}
-
-
-/**
- * This is a big mother that handles getting opcodes into the instruction
- * and handling the src & dst registers for vertex program instructions
- */
-static GLuint
-parse_vp_instruction (GLcontext * ctx, const GLubyte ** inst,
- struct var_cache **vc_head, struct arb_program *Program,
- struct prog_instruction *vp)
-{
- GLint a;
- GLubyte type, code;
-
- /* OP_ALU_{ARL, VECTOR, SCALAR, BINSC, BIN, TRI, SWZ} */
- type = *(*inst)++;
-
- /* The actual opcode name */
- code = *(*inst)++;
-
- _mesa_init_instructions(vp, 1);
-
- switch (type) {
- /* XXX: */
- case OP_ALU_ARL:
- vp->Opcode = OPCODE_ARL;
-
- /* Remember to set SrcReg.RelAddr; */
-
- /* Get the masked address register [dst] */
- if (parse_vp_address_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- vp->DstReg.File = PROGRAM_ADDRESS;
-
- /* Get a scalar src register */
- if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
- return 1;
-
- break;
-
- case OP_ALU_VECTOR:
- switch (code) {
- case OP_ABS:
- vp->Opcode = OPCODE_ABS;
- break;
- case OP_FLR:
- vp->Opcode = OPCODE_FLR;
- break;
- case OP_FRC:
- vp->Opcode = OPCODE_FRC;
- break;
- case OP_LIT:
- vp->Opcode = OPCODE_LIT;
- break;
- case OP_MOV:
- vp->Opcode = OPCODE_MOV;
- break;
- }
-
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
- return 1;
- break;
-
- case OP_ALU_SCALAR:
- switch (code) {
- case OP_EX2:
- vp->Opcode = OPCODE_EX2;
- break;
- case OP_EXP:
- vp->Opcode = OPCODE_EXP;
- break;
- case OP_LG2:
- vp->Opcode = OPCODE_LG2;
- break;
- case OP_LOG:
- vp->Opcode = OPCODE_LOG;
- break;
- case OP_RCP:
- vp->Opcode = OPCODE_RCP;
- break;
- case OP_RSQ:
- vp->Opcode = OPCODE_RSQ;
- break;
- }
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[0]))
- return 1;
- break;
-
- case OP_ALU_BINSC:
- switch (code) {
- case OP_POW:
- vp->Opcode = OPCODE_POW;
- break;
- }
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- for (a = 0; a < 2; a++) {
- if (parse_scalar_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
- return 1;
- }
- break;
-
- case OP_ALU_BIN:
- switch (code) {
- case OP_ADD:
- vp->Opcode = OPCODE_ADD;
- break;
- case OP_DP3:
- vp->Opcode = OPCODE_DP3;
- break;
- case OP_DP4:
- vp->Opcode = OPCODE_DP4;
- break;
- case OP_DPH:
- vp->Opcode = OPCODE_DPH;
- break;
- case OP_DST:
- vp->Opcode = OPCODE_DST;
- break;
- case OP_MAX:
- vp->Opcode = OPCODE_MAX;
- break;
- case OP_MIN:
- vp->Opcode = OPCODE_MIN;
- break;
- case OP_MUL:
- vp->Opcode = OPCODE_MUL;
- break;
- case OP_SGE:
- vp->Opcode = OPCODE_SGE;
- break;
- case OP_SLT:
- vp->Opcode = OPCODE_SLT;
- break;
- case OP_SUB:
- vp->Opcode = OPCODE_SUB;
- break;
- case OP_XPD:
- vp->Opcode = OPCODE_XPD;
- break;
- }
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- for (a = 0; a < 2; a++) {
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
- return 1;
- }
- break;
-
- case OP_ALU_TRI:
- switch (code) {
- case OP_MAD:
- vp->Opcode = OPCODE_MAD;
- break;
- }
-
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- for (a = 0; a < 3; a++) {
- if (parse_vector_src_reg(ctx, inst, vc_head, Program, &vp->SrcReg[a]))
- return 1;
- }
- break;
-
- case OP_ALU_SWZ:
- switch (code) {
- case OP_SWZ:
- vp->Opcode = OPCODE_SWZ;
- break;
- }
- {
- GLubyte swizzle[4];
- GLubyte negateMask;
- GLboolean relAddr;
- gl_register_file file;
- GLint index;
- GLuint baseSwizzle;
-
- if (parse_dst_reg(ctx, inst, vc_head, Program, &vp->DstReg))
- return 1;
-
- if (parse_src_reg(ctx, inst, vc_head, Program, &file, &index,
- &baseSwizzle, &relAddr))
- return 1;
- parse_extended_swizzle_mask (inst, swizzle, &negateMask);
- vp->SrcReg[0].File = file;
- vp->SrcReg[0].Index = index;
- vp->SrcReg[0].Negate = negateMask;
- vp->SrcReg[0].Swizzle = MAKE_SWIZZLE4(swizzle[0],
- swizzle[1],
- swizzle[2],
- swizzle[3]);
- vp->SrcReg[0].RelAddr = relAddr;
- }
- break;
- }
- return 0;
-}
-
-#if DEBUG_PARSING
-
-static GLvoid
-debug_variables (GLcontext * ctx, struct var_cache *vc_head,
- struct arb_program *Program)
-{
- struct var_cache *vc;
- GLint a, b;
-
- fprintf (stderr, "debug_variables, vc_head: %p\n", (void*) vc_head);
-
- /* First of all, print out the contents of the var_cache */
- vc = vc_head;
- while (vc) {
- fprintf (stderr, "[%p]\n", (void*) vc);
- switch (vc->type) {
- case vt_none:
- fprintf (stderr, "UNDEFINED %s\n", vc->name);
- break;
- case vt_attrib:
- fprintf (stderr, "ATTRIB %s\n", vc->name);
- fprintf (stderr, " binding: 0x%x\n", vc->attrib_binding);
- break;
- case vt_param:
- fprintf (stderr, "PARAM %s begin: %d len: %d\n", vc->name,
- vc->param_binding_begin, vc->param_binding_length);
- b = vc->param_binding_begin;
- for (a = 0; a < vc->param_binding_length; a++) {
- fprintf (stderr, "%s\n",
- Program->Base.Parameters->Parameters[a + b].Name);
- if (Program->Base.Parameters->Parameters[a + b].Type == PROGRAM_STATE_VAR) {
- char *s;
- s = _mesa_program_state_string(Program->Base.Parameters->Parameters
- [a + b].StateIndexes);
- fprintf(stderr, "%s\n", s);
- _mesa_free(s);
- }
- else
- fprintf (stderr, "%f %f %f %f\n",
- Program->Base.Parameters->ParameterValues[a + b][0],
- Program->Base.Parameters->ParameterValues[a + b][1],
- Program->Base.Parameters->ParameterValues[a + b][2],
- Program->Base.Parameters->ParameterValues[a + b][3]);
- }
- break;
- case vt_temp:
- fprintf (stderr, "TEMP %s\n", vc->name);
- fprintf (stderr, " binding: 0x%x\n", vc->temp_binding);
- break;
- case vt_output:
- fprintf (stderr, "OUTPUT %s\n", vc->name);
- fprintf (stderr, " binding: 0x%x\n", vc->output_binding);
- break;
- case vt_alias:
- fprintf (stderr, "ALIAS %s\n", vc->name);
- fprintf (stderr, " binding: 0x%p (%s)\n",
- (void*) vc->alias_binding, vc->alias_binding->name);
- break;
- default:
- /* nothing */
- ;
- }
- vc = vc->next;
- }
-}
-
-#endif /* DEBUG_PARSING */
-
-
-/**
- * The main loop for parsing a fragment or vertex program
- *
- * \return 1 on error, 0 on success
- */
-static GLint
-parse_instructions(GLcontext * ctx, const GLubyte * inst,
- struct var_cache **vc_head, struct arb_program *Program)
-{
- const GLuint maxInst = (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB)
- ? ctx->Const.FragmentProgram.MaxInstructions
- : ctx->Const.VertexProgram.MaxInstructions;
- GLint err = 0;
-
- ASSERT(MAX_PROGRAM_INSTRUCTIONS >= maxInst);
-
- Program->MajorVersion = (GLuint) * inst++;
- Program->MinorVersion = (GLuint) * inst++;
-
- while (*inst != END) {
- switch (*inst++) {
-
- case OPTION:
- switch (*inst++) {
- case ARB_PRECISION_HINT_FASTEST:
- Program->PrecisionOption = GL_FASTEST;
- break;
-
- case ARB_PRECISION_HINT_NICEST:
- Program->PrecisionOption = GL_NICEST;
- break;
-
- case ARB_FOG_EXP:
- Program->FogOption = GL_EXP;
- break;
-
- case ARB_FOG_EXP2:
- Program->FogOption = GL_EXP2;
- break;
-
- case ARB_FOG_LINEAR:
- Program->FogOption = GL_LINEAR;
- break;
-
- case ARB_POSITION_INVARIANT:
- if (Program->Base.Target == GL_VERTEX_PROGRAM_ARB)
- Program->HintPositionInvariant = GL_TRUE;
- break;
-
- case ARB_FRAGMENT_PROGRAM_SHADOW:
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- /* TODO ARB_fragment_program_shadow code */
- }
- break;
-
- case ARB_DRAW_BUFFERS:
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- /* do nothing for now */
- }
- break;
-
- case MESA_TEXTURE_ARRAY:
- /* do nothing for now */
- break;
- }
- break;
-
- case INSTRUCTION:
- /* check length */
- if (Program->Base.NumInstructions + 1 >= maxInst) {
- program_error(ctx, Program->Position,
- "Max instruction count exceeded");
- return 1;
- }
- Program->Position = parse_position (&inst);
- /* parse the current instruction */
- if (Program->Base.Target == GL_FRAGMENT_PROGRAM_ARB) {
- err = parse_fp_instruction (ctx, &inst, vc_head, Program,
- &Program->Base.Instructions[Program->Base.NumInstructions]);
- }
- else {
- err = parse_vp_instruction (ctx, &inst, vc_head, Program,
- &Program->Base.Instructions[Program->Base.NumInstructions]);
- }
-
- /* increment instuction count */
- Program->Base.NumInstructions++;
- break;
-
- case DECLARATION:
- err = parse_declaration (ctx, &inst, vc_head, Program);
- break;
-
- default:
- break;
- }
-
- if (err)
- break;
- }
-
- /* Finally, tag on an OPCODE_END instruction */
- {
- const GLuint numInst = Program->Base.NumInstructions;
- _mesa_init_instructions(Program->Base.Instructions + numInst, 1);
- Program->Base.Instructions[numInst].Opcode = OPCODE_END;
- }
- Program->Base.NumInstructions++;
-
- /*
- * Initialize native counts to logical counts. The device driver may
- * change them if program is translated into a hardware program.
- */
- Program->Base.NumNativeInstructions = Program->Base.NumInstructions;
- Program->Base.NumNativeTemporaries = Program->Base.NumTemporaries;
- Program->Base.NumNativeParameters = Program->Base.NumParameters;
- Program->Base.NumNativeAttributes = Program->Base.NumAttributes;
- Program->Base.NumNativeAddressRegs = Program->Base.NumAddressRegs;
-
- return err;
-}
-
-
-/* XXX temporary */
-LONGSTRING static char core_grammar_text[] =
-#include "shader/grammar/grammar_syn.h"
-;
-
-
-/**
- * Set a grammar parameter.
- * \param name the grammar parameter
- * \param value the new parameter value
- * \return 0 if OK, 1 if error
- */
-static int
-set_reg8 (GLcontext *ctx, grammar id, const char *name, GLubyte value)
-{
- char error_msg[300];
- GLint error_pos;
-
- if (grammar_set_reg8 (id, (const byte *) name, value))
- return 0;
-
- grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
- _mesa_set_program_error (ctx, error_pos, error_msg);
- _mesa_error (ctx, GL_INVALID_OPERATION, "Grammar Register Error");
- return 1;
-}
-
-
-/**
- * Enable support for the given language option in the parser.
- * \return 1 if OK, 0 if error
- */
-static int
-enable_ext(GLcontext *ctx, grammar id, const char *name)
-{
- return !set_reg8(ctx, id, name, 1);
-}
-
-
-/**
- * Enable parser extensions based on which OpenGL extensions are supported
- * by this rendering context.
- *
- * \return GL_TRUE if OK, GL_FALSE if error.
- */
-static GLboolean
-enable_parser_extensions(GLcontext *ctx, grammar id)
-{
-#if 0
- /* These are not supported at this time */
- if ((ctx->Extensions.ARB_vertex_blend ||
- ctx->Extensions.EXT_vertex_weighting)
- && !enable_ext(ctx, id, "vertex_blend"))
- return GL_FALSE;
- if (ctx->Extensions.ARB_matrix_palette
- && !enable_ext(ctx, id, "matrix_palette"))
- return GL_FALSE;
-#endif
- if (ctx->Extensions.ARB_fragment_program_shadow
- && !enable_ext(ctx, id, "fragment_program_shadow"))
- return GL_FALSE;
- if (ctx->Extensions.EXT_point_parameters
- && !enable_ext(ctx, id, "point_parameters"))
- return GL_FALSE;
- if (ctx->Extensions.EXT_secondary_color
- && !enable_ext(ctx, id, "secondary_color"))
- return GL_FALSE;
- if (ctx->Extensions.EXT_fog_coord
- && !enable_ext(ctx, id, "fog_coord"))
- return GL_FALSE;
- if (ctx->Extensions.NV_texture_rectangle
- && !enable_ext(ctx, id, "texture_rectangle"))
- return GL_FALSE;
- if (!enable_ext(ctx, id, "draw_buffers"))
- return GL_FALSE;
- if (ctx->Extensions.MESA_texture_array
- && !enable_ext(ctx, id, "texture_array"))
- return GL_FALSE;
-#if 1
- /* hack for Warcraft (see bug 8060) */
- enable_ext(ctx, id, "vertex_blend");
-#endif
-
- return GL_TRUE;
-}
-
-
-/**
- * This kicks everything off.
- *
- * \param ctx - The GL Context
- * \param str - The program string
- * \param len - The program string length
- * \param program - The arb_program struct to return all the parsed info in
- * \return GL_TRUE on sucess, GL_FALSE on error
- */
-static GLboolean
-_mesa_parse_arb_program(GLcontext *ctx, GLenum target,
- const GLubyte *str, GLsizei len,
- struct arb_program *program)
-{
- GLint a, err, error_pos;
- char error_msg[300];
- GLuint parsed_len;
- struct var_cache *vc_head;
- grammar arbprogram_syn_id;
- GLubyte *parsed, *inst;
- GLubyte *strz = NULL;
- static int arbprogram_syn_is_ok = 0; /* XXX temporary */
-
- /* set the program target before parsing */
- program->Base.Target = target;
-
- /* Reset error state */
- _mesa_set_program_error(ctx, -1, NULL);
-
- /* check if arb_grammar_text (arbprogram.syn) is syntactically correct */
- if (!arbprogram_syn_is_ok) {
- /* One-time initialization of parsing system */
- grammar grammar_syn_id;
- GLuint parsed_len;
-
- grammar_syn_id = grammar_load_from_text ((byte *) core_grammar_text);
- if (grammar_syn_id == 0) {
- grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
- /* XXX this is not a GL error - it's an implementation bug! - FIX */
- _mesa_set_program_error (ctx, error_pos, error_msg);
- _mesa_error (ctx, GL_INVALID_OPERATION,
- "glProgramStringARB(Error loading grammar rule set)");
- return GL_FALSE;
- }
-
- err = !grammar_check(grammar_syn_id, (byte *) arb_grammar_text,
- &parsed, &parsed_len);
-
- /* 'parsed' is unused here */
- _mesa_free (parsed);
- parsed = NULL;
-
- /* NOTE: we can't destroy grammar_syn_id right here because
- * grammar_destroy() can reset the last error
- */
- if (err) {
- /* XXX this is not a GL error - it's an implementation bug! - FIX */
- grammar_get_last_error ((byte *) error_msg, 300, &error_pos);
- _mesa_set_program_error (ctx, error_pos, error_msg);
- _mesa_error (ctx, GL_INVALID_OPERATION,
- "glProgramString(Error loading grammar rule set");
- grammar_destroy (grammar_syn_id);
- return GL_FALSE;
- }
-
- grammar_destroy (grammar_syn_id);
-
- arbprogram_syn_is_ok = 1;
- }
-
- /* create the grammar object */
- arbprogram_syn_id = grammar_load_from_text ((byte *) arb_grammar_text);
- if (arbprogram_syn_id == 0) {
- /* XXX this is not a GL error - it's an implementation bug! - FIX */
- grammar_get_last_error ((GLubyte *) error_msg, 300, &error_pos);
- _mesa_set_program_error (ctx, error_pos, error_msg);
- _mesa_error (ctx, GL_INVALID_OPERATION,
- "glProgramString(Error loading grammer rule set)");
- return GL_FALSE;
- }
-
- /* Set program_target register value */
- if (set_reg8 (ctx, arbprogram_syn_id, "program_target",
- program->Base.Target == GL_FRAGMENT_PROGRAM_ARB ? 0x10 : 0x20)) {
- grammar_destroy (arbprogram_syn_id);
- return GL_FALSE;
- }
-
- if (!enable_parser_extensions(ctx, arbprogram_syn_id)) {
- grammar_destroy(arbprogram_syn_id);
- return GL_FALSE;
- }
-
- /* check for NULL character occurences */
- {
- GLint i;
- for (i = 0; i < len; i++) {
- if (str[i] == '\0') {
- program_error(ctx, i, "illegal character");
- grammar_destroy (arbprogram_syn_id);
- return GL_FALSE;
- }
- }
- }
-
- /* copy the program string to a null-terminated string */
- strz = (GLubyte *) _mesa_malloc (len + 1);
- if (!strz) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
- grammar_destroy (arbprogram_syn_id);
- return GL_FALSE;
- }
- _mesa_memcpy (strz, str, len);
- strz[len] = '\0';
-
- /* do a fast check on program string - initial production buffer is 4K */
- err = !grammar_fast_check(arbprogram_syn_id, strz,
- &parsed, &parsed_len, 0x1000);
-
- /* Syntax parse error */
- if (err) {
- grammar_get_last_error((GLubyte *) error_msg, 300, &error_pos);
- program_error(ctx, error_pos, error_msg);
-
-#if DEBUG_PARSING
- /* useful for debugging */
- do {
- int line, col;
- char *s;
- fprintf(stderr, "program: %s\n", (char *) strz);
- fprintf(stderr, "Error Pos: %d\n", ctx->Program.ErrorPos);
- s = (char *) _mesa_find_line_column(strz, strz+ctx->Program.ErrorPos,
- &line, &col);
- fprintf(stderr, "line %d col %d: %s\n", line, col, s);
- } while (0);
-#endif
-
- _mesa_free(strz);
- _mesa_free(parsed);
-
- grammar_destroy (arbprogram_syn_id);
- return GL_FALSE;
- }
-
- grammar_destroy (arbprogram_syn_id);
-
- /*
- * Program string is syntactically correct at this point
- * Parse the tokenized version of the program now, generating
- * vertex/fragment program instructions.
- */
-
- /* Initialize the arb_program struct */
- program->Base.String = strz;
- program->Base.Instructions = _mesa_alloc_instructions(MAX_PROGRAM_INSTRUCTIONS);
- program->Base.NumInstructions =
- program->Base.NumTemporaries =
- program->Base.NumParameters =
- program->Base.NumAttributes = program->Base.NumAddressRegs = 0;
- program->Base.Parameters = _mesa_new_parameter_list ();
- program->Base.InputsRead = 0x0;
- program->Base.OutputsWritten = 0x0;
- program->Position = 0;
- program->MajorVersion = program->MinorVersion = 0;
- program->PrecisionOption = GL_DONT_CARE;
- program->FogOption = GL_NONE;
- program->HintPositionInvariant = GL_FALSE;
- for (a = 0; a < MAX_TEXTURE_IMAGE_UNITS; a++)
- program->TexturesUsed[a] = 0x0;
- program->ShadowSamplers = 0x0;
- program->NumAluInstructions =
- program->NumTexInstructions =
- program->NumTexIndirections = 0;
- program->UsesKill = 0;
-
- vc_head = NULL;
- err = GL_FALSE;
-
- /* Start examining the tokens in the array */
- inst = parsed;
-
- /* Check the grammer rev */
- if (*inst++ != REVISION) {
- program_error (ctx, 0, "Grammar version mismatch");
- err = GL_TRUE;
- }
- else {
- /* ignore program target */
- inst++;
- err = parse_instructions(ctx, inst, &vc_head, program);
- }
-
- /*debug_variables(ctx, vc_head, program); */
-
- /* We're done with the parsed binary array */
- var_cache_destroy (&vc_head);
-
- _mesa_free (parsed);
-
- /* Reallocate the instruction array from size [MAX_PROGRAM_INSTRUCTIONS]
- * to size [ap.Base.NumInstructions].
- */
- program->Base.Instructions
- = _mesa_realloc_instructions(program->Base.Instructions,
- MAX_PROGRAM_INSTRUCTIONS,
- program->Base.NumInstructions);
-
- return !err;
-}
-
+#include "program_parser.h"
void
@@ -3931,11 +71,18 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
const GLvoid *str, GLsizei len,
struct gl_fragment_program *program)
{
- struct arb_program ap;
+ struct gl_program prog;
+ struct asm_parser_state state;
GLuint i;
ASSERT(target == GL_FRAGMENT_PROGRAM_ARB);
- if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) {
+
+ memset(&prog, 0, sizeof(prog));
+ memset(&state, 0, sizeof(state));
+ state.prog = &prog;
+
+ if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+ &state)) {
/* Error in the program. Just return. */
return;
}
@@ -3943,51 +90,50 @@ _mesa_parse_arb_fragment_program(GLcontext* ctx, GLenum target,
/* Copy the relevant contents of the arb_program struct into the
* fragment_program struct.
*/
- program->Base.String = ap.Base.String;
- program->Base.NumInstructions = ap.Base.NumInstructions;
- program->Base.NumTemporaries = ap.Base.NumTemporaries;
- program->Base.NumParameters = ap.Base.NumParameters;
- program->Base.NumAttributes = ap.Base.NumAttributes;
- program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
- program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions;
- program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries;
- program->Base.NumNativeParameters = ap.Base.NumNativeParameters;
- program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes;
- program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs;
- program->Base.NumAluInstructions = ap.Base.NumAluInstructions;
- program->Base.NumTexInstructions = ap.Base.NumTexInstructions;
- program->Base.NumTexIndirections = ap.Base.NumTexIndirections;
- program->Base.NumNativeAluInstructions = ap.Base.NumAluInstructions;
- program->Base.NumNativeTexInstructions = ap.Base.NumTexInstructions;
- program->Base.NumNativeTexIndirections = ap.Base.NumTexIndirections;
- program->Base.InputsRead = ap.Base.InputsRead;
- program->Base.OutputsWritten = ap.Base.OutputsWritten;
+ program->Base.String = prog.String;
+ program->Base.NumInstructions = prog.NumInstructions;
+ program->Base.NumTemporaries = prog.NumTemporaries;
+ program->Base.NumParameters = prog.NumParameters;
+ program->Base.NumAttributes = prog.NumAttributes;
+ program->Base.NumAddressRegs = prog.NumAddressRegs;
+ program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+ program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+ program->Base.NumNativeParameters = prog.NumNativeParameters;
+ program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+ program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+ program->Base.NumAluInstructions = prog.NumAluInstructions;
+ program->Base.NumTexInstructions = prog.NumTexInstructions;
+ program->Base.NumTexIndirections = prog.NumTexIndirections;
+ program->Base.NumNativeAluInstructions = prog.NumAluInstructions;
+ program->Base.NumNativeTexInstructions = prog.NumTexInstructions;
+ program->Base.NumNativeTexIndirections = prog.NumTexIndirections;
+ program->Base.InputsRead = prog.InputsRead;
+ program->Base.OutputsWritten = prog.OutputsWritten;
for (i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) {
- program->Base.TexturesUsed[i] = ap.TexturesUsed[i];
- if (ap.TexturesUsed[i])
+ program->Base.TexturesUsed[i] = prog.TexturesUsed[i];
+ if (prog.TexturesUsed[i])
program->Base.SamplersUsed |= (1 << i);
}
- program->Base.ShadowSamplers = ap.ShadowSamplers;
- program->FogOption = ap.FogOption;
- program->UsesKill = ap.UsesKill;
+ program->Base.ShadowSamplers = prog.ShadowSamplers;
+ switch (state.option.Fog) {
+ case OPTION_FOG_EXP: program->FogOption = GL_EXP; break;
+ case OPTION_FOG_EXP2: program->FogOption = GL_EXP2; break;
+ case OPTION_FOG_LINEAR: program->FogOption = GL_LINEAR; break;
+ default: program->FogOption = GL_NONE; break;
+ }
+
+ program->UsesKill = state.fragment.UsesKill;
if (program->FogOption)
program->Base.InputsRead |= FRAG_BIT_FOGC;
- /* XXX: assume that ARB fragment programs don't have access to the
- * FrontFacing and PointCoord values stuffed into the fog
- * coordinate in GLSL shaders.
- */
- if (program->Base.InputsRead & FRAG_BIT_FOGC)
- program->UsesFogFragCoord = GL_TRUE;
-
if (program->Base.Instructions)
_mesa_free(program->Base.Instructions);
- program->Base.Instructions = ap.Base.Instructions;
+ program->Base.Instructions = prog.Instructions;
if (program->Base.Parameters)
_mesa_free_parameter_list(program->Base.Parameters);
- program->Base.Parameters = ap.Base.Parameters;
+ program->Base.Parameters = prog.Parameters;
/* Append fog instructions now if the program has "OPTION ARB_fog_exp"
* or similar. We used to leave this up to drivers, but it appears
@@ -4017,11 +163,17 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
const GLvoid *str, GLsizei len,
struct gl_vertex_program *program)
{
- struct arb_program ap;
+ struct gl_program prog;
+ struct asm_parser_state state;
ASSERT(target == GL_VERTEX_PROGRAM_ARB);
- if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len, &ap)) {
+ memset(&prog, 0, sizeof(prog));
+ memset(&state, 0, sizeof(state));
+ state.prog = &prog;
+
+ if (!_mesa_parse_arb_program(ctx, target, (const GLubyte*) str, len,
+ &state)) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glProgramString(bad program)");
return;
}
@@ -4029,28 +181,29 @@ _mesa_parse_arb_vertex_program(GLcontext *ctx, GLenum target,
/* Copy the relevant contents of the arb_program struct into the
* vertex_program struct.
*/
- program->Base.String = ap.Base.String;
- program->Base.NumInstructions = ap.Base.NumInstructions;
- program->Base.NumTemporaries = ap.Base.NumTemporaries;
- program->Base.NumParameters = ap.Base.NumParameters;
- program->Base.NumAttributes = ap.Base.NumAttributes;
- program->Base.NumAddressRegs = ap.Base.NumAddressRegs;
- program->Base.NumNativeInstructions = ap.Base.NumNativeInstructions;
- program->Base.NumNativeTemporaries = ap.Base.NumNativeTemporaries;
- program->Base.NumNativeParameters = ap.Base.NumNativeParameters;
- program->Base.NumNativeAttributes = ap.Base.NumNativeAttributes;
- program->Base.NumNativeAddressRegs = ap.Base.NumNativeAddressRegs;
- program->Base.InputsRead = ap.Base.InputsRead;
- program->Base.OutputsWritten = ap.Base.OutputsWritten;
- program->IsPositionInvariant = ap.HintPositionInvariant;
+ program->Base.String = prog.String;
+ program->Base.NumInstructions = prog.NumInstructions;
+ program->Base.NumTemporaries = prog.NumTemporaries;
+ program->Base.NumParameters = prog.NumParameters;
+ program->Base.NumAttributes = prog.NumAttributes;
+ program->Base.NumAddressRegs = prog.NumAddressRegs;
+ program->Base.NumNativeInstructions = prog.NumNativeInstructions;
+ program->Base.NumNativeTemporaries = prog.NumNativeTemporaries;
+ program->Base.NumNativeParameters = prog.NumNativeParameters;
+ program->Base.NumNativeAttributes = prog.NumNativeAttributes;
+ program->Base.NumNativeAddressRegs = prog.NumNativeAddressRegs;
+ program->Base.InputsRead = prog.InputsRead;
+ program->Base.OutputsWritten = prog.OutputsWritten;
+ program->IsPositionInvariant = (state.option.PositionInvariant)
+ ? GL_TRUE : GL_FALSE;
if (program->Base.Instructions)
_mesa_free(program->Base.Instructions);
- program->Base.Instructions = ap.Base.Instructions;
+ program->Base.Instructions = prog.Instructions;
if (program->Base.Parameters)
_mesa_free_parameter_list(program->Base.Parameters);
- program->Base.Parameters = ap.Base.Parameters;
+ program->Base.Parameters = prog.Parameters;
#if DEBUG_VP
_mesa_printf("____________Vertex program %u __________\n", program->Base.Id);
diff --git a/src/mesa/shader/arbprogram.c b/src/mesa/shader/arbprogram.c
index 39136efada..4d8cff0700 100644
--- a/src/mesa/shader/arbprogram.c
+++ b/src/mesa/shader/arbprogram.c
@@ -1001,6 +1001,9 @@ _mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params)
_mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
return;
}
+ } else {
+ _mesa_error(ctx, GL_INVALID_ENUM, "glGetProgramivARB(pname)");
+ return;
}
}
diff --git a/src/mesa/shader/arbprogram.syn b/src/mesa/shader/arbprogram.syn
deleted file mode 100644
index b12c6a0eda..0000000000
--- a/src/mesa/shader/arbprogram.syn
+++ /dev/null
@@ -1,2824 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.2
- *
- * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
- /**
- * \file arbprogram.syn
- * ARB_fragment/vertex_program syntax
- * \author Michal Krol
- */
-
-.syntax program;
-
-/*
- This value must be incremented every time emit code values or structure of the production
- array changes. This value is placed at the beginning of the production array. The loader
- compares the value with its REVISION value. If they do not match, the loader is not up
- to date.
-*/
-.emtcode REVISION 0x0a
-
-/* program type */
-.emtcode FRAGMENT_PROGRAM 0x01
-.emtcode VERTEX_PROGRAM 0x02
-
-/* program section */
-.emtcode OPTION 0x01
-.emtcode INSTRUCTION 0x02
-.emtcode DECLARATION 0x03
-.emtcode END 0x04
-
-/* GL_ARB_fragment_program option */
-.emtcode ARB_PRECISION_HINT_FASTEST 0x00
-.emtcode ARB_PRECISION_HINT_NICEST 0x01
-.emtcode ARB_FOG_EXP 0x02
-.emtcode ARB_FOG_EXP2 0x03
-.emtcode ARB_FOG_LINEAR 0x04
-
-/* GL_ARB_vertex_program option */
-.emtcode ARB_POSITION_INVARIANT 0x05
-
-/* GL_ARB_fragment_program_shadow option */
-.emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x06
-
-/* GL_ARB_draw_buffers option */
-.emtcode ARB_DRAW_BUFFERS 0x07
-
-/* GL_MESA_texture_array option */
-.emtcode MESA_TEXTURE_ARRAY 0x08
-
-/* GL_ARB_fragment_program instruction class */
-.emtcode OP_ALU_INST 0x00
-.emtcode OP_TEX_INST 0x01
-
-/* GL_ARB_vertex_program instruction class */
-/* OP_ALU_INST */
-
-/* GL_ARB_fragment_program instruction type */
-.emtcode OP_ALU_VECTOR 0x00
-.emtcode OP_ALU_SCALAR 0x01
-.emtcode OP_ALU_BINSC 0x02
-.emtcode OP_ALU_BIN 0x03
-.emtcode OP_ALU_TRI 0x04
-.emtcode OP_ALU_SWZ 0x05
-.emtcode OP_TEX_SAMPLE 0x06
-.emtcode OP_TEX_KIL 0x07
-
-/* GL_ARB_vertex_program instruction type */
-.emtcode OP_ALU_ARL 0x08
-/* OP_ALU_VECTOR */
-/* OP_ALU_SCALAR */
-/* OP_ALU_BINSC */
-/* OP_ALU_BIN */
-/* OP_ALU_TRI */
-/* OP_ALU_SWZ */
-
-/* GL_ARB_fragment_program instruction code */
-.emtcode OP_ABS 0x00
-.emtcode OP_ABS_SAT 0x1B
-.emtcode OP_FLR 0x09
-.emtcode OP_FLR_SAT 0x26
-.emtcode OP_FRC 0x0A
-.emtcode OP_FRC_SAT 0x27
-.emtcode OP_LIT 0x0C
-.emtcode OP_LIT_SAT 0x2A
-.emtcode OP_MOV 0x11
-.emtcode OP_MOV_SAT 0x30
-.emtcode OP_COS 0x1F
-.emtcode OP_COS_SAT 0x20
-.emtcode OP_EX2 0x07
-.emtcode OP_EX2_SAT 0x25
-.emtcode OP_LG2 0x0B
-.emtcode OP_LG2_SAT 0x29
-.emtcode OP_RCP 0x14
-.emtcode OP_RCP_SAT 0x33
-.emtcode OP_RSQ 0x15
-.emtcode OP_RSQ_SAT 0x34
-.emtcode OP_SIN 0x38
-.emtcode OP_SIN_SAT 0x39
-.emtcode OP_SCS 0x35
-.emtcode OP_SCS_SAT 0x36
-.emtcode OP_POW 0x13
-.emtcode OP_POW_SAT 0x32
-.emtcode OP_ADD 0x01
-.emtcode OP_ADD_SAT 0x1C
-.emtcode OP_DP3 0x03
-.emtcode OP_DP3_SAT 0x21
-.emtcode OP_DP4 0x04
-.emtcode OP_DP4_SAT 0x22
-.emtcode OP_DPH 0x05
-.emtcode OP_DPH_SAT 0x23
-.emtcode OP_DST 0x06
-.emtcode OP_DST_SAT 0x24
-.emtcode OP_MAX 0x0F
-.emtcode OP_MAX_SAT 0x2E
-.emtcode OP_MIN 0x10
-.emtcode OP_MIN_SAT 0x2F
-.emtcode OP_MUL 0x12
-.emtcode OP_MUL_SAT 0x31
-.emtcode OP_SGE 0x16
-.emtcode OP_SGE_SAT 0x37
-.emtcode OP_SLT 0x17
-.emtcode OP_SLT_SAT 0x3A
-.emtcode OP_SUB 0x18
-.emtcode OP_SUB_SAT 0x3B
-.emtcode OP_XPD 0x1A
-.emtcode OP_XPD_SAT 0x43
-.emtcode OP_CMP 0x1D
-.emtcode OP_CMP_SAT 0x1E
-.emtcode OP_LRP 0x2B
-.emtcode OP_LRP_SAT 0x2C
-.emtcode OP_MAD 0x0E
-.emtcode OP_MAD_SAT 0x2D
-.emtcode OP_SWZ 0x19
-.emtcode OP_SWZ_SAT 0x3C
-.emtcode OP_TEX 0x3D
-.emtcode OP_TEX_SAT 0x3E
-.emtcode OP_TXB 0x3F
-.emtcode OP_TXB_SAT 0x40
-.emtcode OP_TXP 0x41
-.emtcode OP_TXP_SAT 0x42
-.emtcode OP_KIL 0x28
-
-/* GL_ARB_vertex_program instruction code */
-.emtcode OP_ARL 0x02
-/* OP_ABS */
-/* OP_FLR */
-/* OP_FRC */
-/* OP_LIT */
-/* OP_MOV */
-/* OP_EX2 */
-.emtcode OP_EXP 0x08
-/* OP_LG2 */
-.emtcode OP_LOG 0x0D
-/* OP_RCP */
-/* OP_RSQ */
-/* OP_POW */
-/* OP_ADD */
-/* OP_DP3 */
-/* OP_DP4 */
-/* OP_DPH */
-/* OP_DST */
-/* OP_MAX */
-/* OP_MIN */
-/* OP_MUL */
-/* OP_SGE */
-/* OP_SLT */
-/* OP_SUB */
-/* OP_XPD */
-/* OP_MAD */
-/* OP_SWZ */
-
-/* fragment attribute binding */
-.emtcode FRAGMENT_ATTRIB_COLOR 0x01
-.emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02
-.emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03
-.emtcode FRAGMENT_ATTRIB_POSITION 0x04
-
-/* vertex attribute binding */
-.emtcode VERTEX_ATTRIB_POSITION 0x01
-.emtcode VERTEX_ATTRIB_WEIGHT 0x02
-.emtcode VERTEX_ATTRIB_NORMAL 0x03
-.emtcode VERTEX_ATTRIB_COLOR 0x04
-.emtcode VERTEX_ATTRIB_FOGCOORD 0x05
-.emtcode VERTEX_ATTRIB_TEXCOORD 0x06
-.emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07
-.emtcode VERTEX_ATTRIB_GENERIC 0x08
-
-/* fragment result binding */
-.emtcode FRAGMENT_RESULT_COLOR 0x01
-.emtcode FRAGMENT_RESULT_DEPTH 0x02
-
-/* vertex result binding */
-.emtcode VERTEX_RESULT_POSITION 0x01
-.emtcode VERTEX_RESULT_COLOR 0x02
-.emtcode VERTEX_RESULT_FOGCOORD 0x03
-.emtcode VERTEX_RESULT_POINTSIZE 0x04
-.emtcode VERTEX_RESULT_TEXCOORD 0x05
-
-/* texture target */
-.emtcode TEXTARGET_1D 0x01
-.emtcode TEXTARGET_2D 0x02
-.emtcode TEXTARGET_3D 0x03
-.emtcode TEXTARGET_RECT 0x04
-.emtcode TEXTARGET_CUBE 0x05
-/* GL_ARB_fragment_program_shadow */
-.emtcode TEXTARGET_SHADOW1D 0x06
-.emtcode TEXTARGET_SHADOW2D 0x07
-.emtcode TEXTARGET_SHADOWRECT 0x08
-/* GL_MESA_texture_array */
-.emtcode TEXTARGET_1D_ARRAY 0x09
-.emtcode TEXTARGET_2D_ARRAY 0x0a
-.emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b
-.emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c
-
-/* face type */
-.emtcode FACE_FRONT 0x00
-.emtcode FACE_BACK 0x01
-
-/* color type */
-.emtcode COLOR_PRIMARY 0x00
-.emtcode COLOR_SECONDARY 0x01
-
-/* component */
-.emtcode COMPONENT_X 0x00
-.emtcode COMPONENT_Y 0x01
-.emtcode COMPONENT_Z 0x02
-.emtcode COMPONENT_W 0x03
-.emtcode COMPONENT_0 0x04
-.emtcode COMPONENT_1 0x05
-
-/* array index type */
-.emtcode ARRAY_INDEX_ABSOLUTE 0x00
-.emtcode ARRAY_INDEX_RELATIVE 0x01
-
-/* matrix name */
-.emtcode MATRIX_MODELVIEW 0x01
-.emtcode MATRIX_PROJECTION 0x02
-.emtcode MATRIX_MVP 0x03
-.emtcode MATRIX_TEXTURE 0x04
-.emtcode MATRIX_PALETTE 0x05
-.emtcode MATRIX_PROGRAM 0x06
-
-/* matrix modifier */
-.emtcode MATRIX_MODIFIER_IDENTITY 0x00
-.emtcode MATRIX_MODIFIER_INVERSE 0x01
-.emtcode MATRIX_MODIFIER_TRANSPOSE 0x02
-.emtcode MATRIX_MODIFIER_INVTRANS 0x03
-
-/* constant type */
-.emtcode CONSTANT_SCALAR 0x01
-.emtcode CONSTANT_VECTOR 0x02
-
-/* program param type */
-.emtcode PROGRAM_PARAM_ENV 0x01
-.emtcode PROGRAM_PARAM_LOCAL 0x02
-
-/* register type */
-.emtcode REGISTER_ATTRIB 0x01
-.emtcode REGISTER_PARAM 0x02
-.emtcode REGISTER_RESULT 0x03
-.emtcode REGISTER_ESTABLISHED_NAME 0x04
-
-/* param binding */
-.emtcode PARAM_NULL 0x00
-.emtcode PARAM_ARRAY_ELEMENT 0x01
-.emtcode PARAM_STATE_ELEMENT 0x02
-.emtcode PARAM_PROGRAM_ELEMENT 0x03
-.emtcode PARAM_PROGRAM_ELEMENTS 0x04
-.emtcode PARAM_CONSTANT 0x05
-
-/* param state property */
-.emtcode STATE_MATERIAL 0x01
-.emtcode STATE_LIGHT 0x02
-.emtcode STATE_LIGHT_MODEL 0x03
-.emtcode STATE_LIGHT_PROD 0x04
-.emtcode STATE_FOG 0x05
-.emtcode STATE_MATRIX_ROWS 0x06
-/* GL_ARB_fragment_program */
-.emtcode STATE_TEX_ENV 0x07
-.emtcode STATE_DEPTH 0x08
-/* GL_ARB_vertex_program */
-.emtcode STATE_TEX_GEN 0x09
-.emtcode STATE_CLIP_PLANE 0x0A
-.emtcode STATE_POINT 0x0B
-
-/* state material property */
-.emtcode MATERIAL_AMBIENT 0x01
-.emtcode MATERIAL_DIFFUSE 0x02
-.emtcode MATERIAL_SPECULAR 0x03
-.emtcode MATERIAL_EMISSION 0x04
-.emtcode MATERIAL_SHININESS 0x05
-
-/* state light property */
-.emtcode LIGHT_AMBIENT 0x01
-.emtcode LIGHT_DIFFUSE 0x02
-.emtcode LIGHT_SPECULAR 0x03
-.emtcode LIGHT_POSITION 0x04
-.emtcode LIGHT_ATTENUATION 0x05
-.emtcode LIGHT_HALF 0x06
-.emtcode LIGHT_SPOT_DIRECTION 0x07
-
-/* state light model property */
-.emtcode LIGHT_MODEL_AMBIENT 0x01
-.emtcode LIGHT_MODEL_SCENECOLOR 0x02
-
-/* state light product property */
-.emtcode LIGHT_PROD_AMBIENT 0x01
-.emtcode LIGHT_PROD_DIFFUSE 0x02
-.emtcode LIGHT_PROD_SPECULAR 0x03
-
-/* state texture environment property */
-.emtcode TEX_ENV_COLOR 0x01
-
-/* state texture generation coord property */
-.emtcode TEX_GEN_EYE 0x01
-.emtcode TEX_GEN_OBJECT 0x02
-
-/* state fog property */
-.emtcode FOG_COLOR 0x01
-.emtcode FOG_PARAMS 0x02
-
-/* state depth property */
-.emtcode DEPTH_RANGE 0x01
-
-/* state point parameters property */
-.emtcode POINT_SIZE 0x01
-.emtcode POINT_ATTENUATION 0x02
-
-/* declaration */
-.emtcode ATTRIB 0x01
-.emtcode PARAM 0x02
-.emtcode TEMP 0x03
-.emtcode OUTPUT 0x04
-.emtcode ALIAS 0x05
-/* GL_ARB_vertex_program */
-.emtcode ADDRESS 0x06
-
-/* error messages */
-.errtext UNKNOWN_PROGRAM_SIGNATURE "1001: '$e_signature$': unknown program signature"
-.errtext MISSING_END_OR_INVALID_STATEMENT "1002: '$e_statement$': invalid statement"
-.errtext CODE_AFTER_END "1003: '$e_statement$': code after 'END' keyword"
-.errtext INVALID_PROGRAM_OPTION "1004: '$e_identifier$': invalid program option"
-.errtext EXT_SWIZ_COMP_EXPECTED "1005: extended swizzle component expected but '$e_token$' found"
-.errtext TEX_TARGET_EXPECTED "1006: texture target expected but '$e_token$' found"
-.errtext TEXTURE_EXPECTED "1007: 'texture' expected but '$e_identifier$' found"
-.errtext SOURCE_REGISTER_EXPECTED "1008: source register expected but '$e_token$' found"
-.errtext DESTINATION_REGISTER_EXPECTED "1009: destination register expected but '$e_token$' found"
-.errtext INVALID_ADDRESS_COMPONENT "1010: '$e_identifier$': invalid address component"
-.errtext INVALID_ADDRESS_WRITEMASK "1011: '$e_identifier$': invalid address writemask"
-.errtext INVALID_COMPONENT "1012: '$e_charordigit$': invalid component"
-.errtext INVALID_SUFFIX "1013: '$e_identifier$': invalid suffix"
-.errtext INVALID_WRITEMASK "1014: '$e_identifier$': invalid writemask"
-.errtext FRAGMENT_EXPECTED "1015: 'fragment' expected but '$e_identifier$' found"
-.errtext VERTEX_EXPECTED "1016: 'vertex' expected but '$e_identifier$' found"
-.errtext INVALID_FRAGMENT_PROPERTY "1017: '$e_identifier$': invalid fragment property"
-.errtext INVALID_VERTEX_PROPERTY "1018: '$e_identifier$': invalid vertex property"
-.errtext INVALID_STATE_PROPERTY "1019: '$e_identifier$': invalid state property"
-.errtext INVALID_MATERIAL_PROPERTY "1020: '$e_identifier$': invalid material property"
-.errtext INVALID_LIGHT_PROPERTY "1021: '$e_identifier$': invalid light property"
-.errtext INVALID_SPOT_PROPERTY "1022: '$e_identifier$': invalid spot property"
-.errtext INVALID_LIGHTMODEL_PROPERTY "1023: '$e_identifier$': invalid light model property"
-.errtext INVALID_LIGHTPROD_PROPERTY "1024: '$e_identifier$': invalid light product property"
-.errtext INVALID_TEXENV_PROPERTY "1025: '$e_identifier$': invalid texture environment property"
-.errtext INVALID_TEXGEN_PROPERTY "1026: '$e_identifier$': invalid texture generating property"
-.errtext INVALID_TEXGEN_COORD "1027: '$e_identifier$': invalid texture generating coord"
-.errtext INVALID_FOG_PROPERTY "1028: '$e_identifier$': invalid fog property"
-.errtext INVALID_DEPTH_PROPERTY "1029: '$e_identifier$': invalid depth property"
-.errtext INVALID_CLIPPLANE_PROPERTY "1030: '$e_identifier$': invalid clip plane property"
-.errtext INVALID_POINT_PROPERTY "1031: '$e_identifier$': invalid point property"
-.errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED "1032: matrix row selector or modifier expected but '$e_token$' found"
-.errtext INVALID_MATRIX_NAME "1033: '$e_identifier$': invalid matrix name"
-.errtext INVALID_PROGRAM_PROPERTY "1034: '$e_identifier$': invalid program property"
-.errtext RESULT_EXPECTED "1035: 'result' expected but '$e_token$' found"
-.errtext INVALID_RESULT_PROPERTY "1036: '$e_identifier$': invalid result property"
-.errtext INVALID_FACE_PROPERTY "1037: '$e_identifier$': invalid face property"
-.errtext INVALID_COLOR_PROPERTY "1038: '$e_identifier$': invalid color property"
-.errtext IDENTIFIER_EXPECTED "1039: identifier expected but '$e_token$' found"
-.errtext RESERVED_KEYWORD "1040: use of reserved keyword as an identifier"
-.errtext INTEGER_EXPECTED "1041: integer value expected but '$e_token$' found"
-.errtext MISSING_SEMICOLON "1042: ';' expected but '$e_token$' found"
-.errtext MISSING_COMMA "1043: ',' expected but '$e_token$' found"
-.errtext MISSING_LBRACKET "1044: '[' expected but '$e_token$' found"
-.errtext MISSING_RBRACKET "1045: ']' expected but '$e_token$' found"
-.errtext MISSING_DOT "1046: '.' expected but '$e_token$' found"
-.errtext MISSING_EQUAL "1047: '=' expected but '$e_token$' found"
-.errtext MISSING_LBRACE "1048: '{' expected but '$e_token$' found"
-.errtext MISSING_RBRACE "1049: '}' expected but '$e_token$' found"
-.errtext MISSING_DOTDOT "1050: '..' expected but '$e_token$' found"
-.errtext MISSING_FRACTION_OR_EXPONENT "1051: missing fraction part or exponent"
-.errtext MISSING_DOT_OR_EXPONENT "1052: missing '.' or exponent"
-.errtext EXPONENT_VALUE_EXPECTED "1053: exponent value expected"
-.errtext INTEGER_OUT_OF_RANGE "1054: integer value out of range"
-.errtext OPERATION_NEEDS_DESTINATION_VARIABLE "1055: operation needs destination variable"
-.errtext OPERATION_NEEDS_SOURCE_VARIABLE "1056: operation needs source variable"
-.errtext ADDRESS_REGISTER_EXPECTED "1057: address register expected but '$e_token$' found"
-.errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED "1058: address register or integer literal expected but '$e_token$' found"
-
-/* extension presence condition registers */
-
-/* GL_ARB_vertex_blend */
-/* GL_EXT_vertex_weighting */
-.regbyte vertex_blend 0x00
-
-/* GL_ARB_matrix_palette */
-.regbyte matrix_palette 0x00
-
-/* GL_ARB_point_parameters */
-/* GL_EXT_point_parameters */
-.regbyte point_parameters 0x00
-
-/* GL_EXT_secondary_color */
-.regbyte secondary_color 0x00
-
-/* GL_EXT_fog_coord */
-.regbyte fog_coord 0x00
-
-/* GL_EXT_texture_rectangle */
-/* GL_NV_texture_rectangle */
-.regbyte texture_rectangle 0x00
-
-/* GL_ARB_fragment_program_shadow */
-.regbyte fragment_program_shadow 0x00
-
-/* GL_ARB_draw_buffers */
-.regbyte draw_buffers 0x00
-
-/* GL_MESA_texture_array */
-.regbyte texture_array 0x00
-
-/* option presence condition registers */
-/* they are all initially set to zero - when a particular OPTION is encountered, the appropriate */
-/* register is set to 1 to indicate that the OPTION was specified. */
-
-/* GL_ARB_fragment_program */
-.regbyte ARB_precision_hint_fastest 0x00
-.regbyte ARB_precision_hint_nicest 0x00
-.regbyte ARB_fog_exp 0x00
-.regbyte ARB_fog_exp2 0x00
-.regbyte ARB_fog_linear 0x00
-
-/* GL_ARB_vertex_program */
-.regbyte ARB_position_invariant 0x00
-
-/* GL_ARB_fragment_program_shadow */
-.regbyte ARB_fragment_program_shadow 0x00
-
-/* GL_ARB_draw_buffers */
-.regbyte ARB_draw_buffers 0x00
-
-/* GL_MESA_texture_array */
-.regbyte MESA_texture_array 0x00
-
-/* program target condition register */
-/* this syntax script deals with two program targets - VERTEX_PROGRAM and FRAGMENT_PROGRAM. */
-/* to distinguish between them we need a register that will store for us the current target. */
-/* the client will typically set the register to apropriate value before parsing a particular */
-/* program. the mapping between program targets and their values is listed below. */
-/* */
-/* program target register value */
-/* ---------------------------------------------- */
-/* FRAGMENT_PROGRAM 0x10 */
-/* VERTEX_PROGRAM 0x20 */
-/* */
-/* the initial value of the register is 0 to catch potential errors with not setting the register */
-/* with the proper value. */
-.regbyte program_target 0x00
-
-/*
- <program> ::= <optionSequence> <statementSequence> "END"
-*/
-program
- programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;
-programs
- .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or
- .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;
-frag_program_1_0
- '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and
- optional_space .and fp_optionSequence .and fp_statementSequence .and
- "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and
- '\0' .error CODE_AFTER_END;
-vert_program_1_0
- '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and
- optional_space .and vp_optionSequence .and vp_statementSequence .and
- "END" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and
- '\0' .error CODE_AFTER_END;
-
-/*
- <optionSequence> ::= <optionSequence> <option>
- | ""
-*/
-fp_optionSequence
- .loop fp_option;
-vp_optionSequence
- .loop vp_option;
-
-/*
- <option> ::= "OPTION" <identifier> ";"
-
-NOTE: options ARB_precision_hint_nicest and ARB_precision_hint_fastest are exclusive. When one of
- these options is encountered, the other one is automatically disabled.
- the same applies to options ARB_fog_exp, ARB_fog_exp2 and ARB_fog_linear.
-*/
-fp_option
- "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and
- fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;
-vp_option
- "OPTION" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and
- vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;
-fp_optionString
- .if (ARB_precision_hint_nicest == 0x00) "ARB_precision_hint_fastest"
- .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or
- .if (ARB_precision_hint_fastest == 0x00) "ARB_precision_hint_nicest"
- .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or
- fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or
- fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or
- fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or
- .if (fragment_program_shadow != 0x00) "ARB_fragment_program_shadow"
- .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01 .or
- .if (draw_buffers != 0x00) "ARB_draw_buffers" .emit ARB_DRAW_BUFFERS
- .load ARB_draw_buffers 0x01 .or
- .if (texture_array != 0x00) "MESA_texture_array" .emit MESA_TEXTURE_ARRAY
- .load MESA_texture_array 0x01;
-vp_optionString
- "ARB_position_invariant" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;
-fp_ARB_fog_exp
- .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp";
-fp_ARB_fog_exp2
- .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) "ARB_fog_exp2";
-fp_ARB_fog_linear
- .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) "ARB_fog_linear";
-
-/*
- <statementSequence> ::= <statementSequence> <statement>
- | ""
-*/
-fp_statementSequence
- .loop fp_statement;
-vp_statementSequence
- .loop vp_statement;
-
-/*
- <statement> ::= <instruction> ";"
- | <namingStatement> ";"
-
-NOTE: ".emit $" in the definitions below means that we output instruction position (offset of
- the first character of instruction) for program debugging purposes.
-*/
-fp_statement
- fp_statement_1 .or fp_statement_2;
-vp_statement
- vp_statement_1 .or vp_statement_2;
-fp_statement_1
- fp_instruction .emit INSTRUCTION .emit $ .and semicolon;
-fp_statement_2
- fp_namingStatement .emit DECLARATION .and semicolon;
-vp_statement_1
- vp_instruction .emit INSTRUCTION .emit $ .and semicolon;
-vp_statement_2
- vp_namingStatement .emit DECLARATION .and semicolon;
-
-/*
-fragment program
- <instruction> ::= <ALUInstruction>
- | <TexInstruction>
-
-vertex program
- <instruction> ::= <ARL_instruction>
- | <VECTORop_instruction>
- | <SCALARop_instruction>
- | <BINSCop_instruction>
- | <BINop_instruction>
- | <TRIop_instruction>
- | <SWZ_instruction>
-*/
-fp_instruction
- ALUInstruction .emit OP_ALU_INST .or
- TexInstruction .emit OP_TEX_INST;
-vp_instruction
- ARL_instruction .emit OP_ALU_ARL .or
- vp_VECTORop_instruction .emit OP_ALU_VECTOR .or
- vp_SCALARop_instruction .emit OP_ALU_SCALAR .or
- vp_BINSCop_instruction .emit OP_ALU_BINSC .or
- vp_BINop_instruction .emit OP_ALU_BIN .or
- vp_TRIop_instruction .emit OP_ALU_TRI .or
- vp_SWZ_instruction .emit OP_ALU_SWZ;
-
-/*
-fragment program
- <ALUInstruction> ::= <VECTORop_instruction>
- | <SCALARop_instruction>
- | <BINSCop_instruction>
- | <BINop_instruction>
- | <TRIop_instruction>
- | <SWZ_instruction>
-*/
-ALUInstruction
- fp_VECTORop_instruction .emit OP_ALU_VECTOR .or
- fp_SCALARop_instruction .emit OP_ALU_SCALAR .or
- fp_BINSCop_instruction .emit OP_ALU_BINSC .or
- fp_BINop_instruction .emit OP_ALU_BIN .or
- fp_TRIop_instruction .emit OP_ALU_TRI .or
- fp_SWZ_instruction .emit OP_ALU_SWZ;
-
-/*
-fragment program
- <TexInstruction> ::= <SAMPLE_instruction>
- | <KIL_instruction>
-*/
-TexInstruction
- SAMPLE_instruction .emit OP_TEX_SAMPLE .or
- KIL_instruction .emit OP_TEX_KIL;
-
-/*
-vertex program
- <ARL_instruction> ::= "ARL" <maskedAddrReg> "," <scalarSrcReg>
-*/
-ARL_instruction
- "ARL" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;
-
-/*
-fragment program
- <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> ","
- <vectorSrcReg>
-
-vertex program
- <VECTORop_instruction> ::= <VECTORop> <maskedDstReg> "," <swizzleSrcReg>
-*/
-fp_VECTORop_instruction
- fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;
-vp_VECTORop_instruction
- vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;
-
-/*
-fragment program
- <VECTORop> ::= "ABS" | "ABS_SAT"
- | "FLR" | "FLR_SAT"
- | "FRC" | "FRC_SAT"
- | "LIT" | "LIT_SAT"
- | "MOV" | "MOV_SAT"
-
-vertex program
- <VECTORop> ::= "ABS"
- | "FLR"
- | "FRC"
- | "LIT"
- | "MOV"
-*/
-fp_VECTORop
- "ABS" .emit OP_ABS .or "ABS_SAT" .emit OP_ABS_SAT .or
- "FLR" .emit OP_FLR .or "FLR_SAT" .emit OP_FLR_SAT .or
- "FRC" .emit OP_FRC .or "FRC_SAT" .emit OP_FRC_SAT .or
- "LIT" .emit OP_LIT .or "LIT_SAT" .emit OP_LIT_SAT .or
- "MOV" .emit OP_MOV .or "MOV_SAT" .emit OP_MOV_SAT;
-vp_VECTORop
- "ABS" .emit OP_ABS .or
- "FLR" .emit OP_FLR .or
- "FRC" .emit OP_FRC .or
- "LIT" .emit OP_LIT .or
- "MOV" .emit OP_MOV;
-
-/*
- <SCALARop_instruction> ::= <SCALARop> <maskedDstReg> "," <scalarSrcReg>
-*/
-fp_SCALARop_instruction
- fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;
-vp_SCALARop_instruction
- vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;
-
-/*
-fragment program
- <SCALARop> ::= "COS" | "COS_SAT"
- | "EX2" | "EX2_SAT"
- | "LG2" | "LG2_SAT"
- | "RCP" | "RCP_SAT"
- | "RSQ" | "RSQ_SAT"
- | "SIN" | "SIN_SAT"
- | "SCS" | "SCS_SAT"
-
-vertex program
- <SCALARop> ::= "EX2"
- | "EXP"
- | "LG2"
- | "LOG"
- | "RCP"
- | "RSQ"
-*/
-fp_SCALARop
- "COS" .emit OP_COS .or "COS_SAT" .emit OP_COS_SAT .or
- "EX2" .emit OP_EX2 .or "EX2_SAT" .emit OP_EX2_SAT .or
- "LG2" .emit OP_LG2 .or "LG2_SAT" .emit OP_LG2_SAT .or
- "RCP" .emit OP_RCP .or "RCP_SAT" .emit OP_RCP_SAT .or
- "RSQ" .emit OP_RSQ .or "RSQ_SAT" .emit OP_RSQ_SAT .or
- "SIN" .emit OP_SIN .or "SIN_SAT" .emit OP_SIN_SAT .or
- "SCS" .emit OP_SCS .or "SCS_SAT" .emit OP_SCS_SAT;
-vp_SCALARop
- "EX2" .emit OP_EX2 .or
- "EXP" .emit OP_EXP .or
- "LG2" .emit OP_LG2 .or
- "LOG" .emit OP_LOG .or
- "RCP" .emit OP_RCP .or
- "RSQ" .emit OP_RSQ;
-
-/*
- <BINSCop_instruction> ::= <BINSCop> <maskedDstReg> "," <scalarSrcReg> ","
- <scalarSrcReg>
-*/
-fp_BINSCop_instruction
- fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and
- fp_scalarSrcReg;
-vp_BINSCop_instruction
- vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and
- vp_scalarSrcReg;
-
-/*
-fragment program
- <BINSCop> ::= "POW" | "POW_SAT"
-
-vertex program
- <BINSCop> ::= "POW"
-*/
-fp_BINSCop
- "POW" .emit OP_POW .or "POW_SAT" .emit OP_POW_SAT;
-vp_BINSCop
- "POW" .emit OP_POW;
-
-/*
-fragment program
- <BINop_instruction> ::= <BINop> <maskedDstReg> ","
- <vectorSrcReg> "," <vectorSrcReg>
-
-vertex program
- <BINop_instruction> ::= <BINop> <maskedDstReg> ","
- <swizzleSrcReg> "," <swizzleSrcReg>
-*/
-fp_BINop_instruction
- fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
- vectorSrcReg;
-vp_BINop_instruction
- vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and
- swizzleSrcReg;
-
-/*
-fragment program
- <BINop> ::= "ADD" | "ADD_SAT"
- | "DP3" | "DP3_SAT"
- | "DP4" | "DP4_SAT"
- | "DPH" | "DPH_SAT"
- | "DST" | "DST_SAT"
- | "MAX" | "MAX_SAT"
- | "MIN" | "MIN_SAT"
- | "MUL" | "MUL_SAT"
- | "SGE" | "SGE_SAT"
- | "SLT" | "SLT_SAT"
- | "SUB" | "SUB_SAT"
- | "XPD" | "XPD_SAT"
-
-vertex program
- <BINop> ::= "ADD"
- | "DP3"
- | "DP4"
- | "DPH"
- | "DST"
- | "MAX"
- | "MIN"
- | "MUL"
- | "SGE"
- | "SLT"
- | "SUB"
- | "XPD"
-*/
-fp_BINop
- "ADD" .emit OP_ADD .or "ADD_SAT" .emit OP_ADD_SAT .or
- "DP3" .emit OP_DP3 .or "DP3_SAT" .emit OP_DP3_SAT .or
- "DP4" .emit OP_DP4 .or "DP4_SAT" .emit OP_DP4_SAT .or
- "DPH" .emit OP_DPH .or "DPH_SAT" .emit OP_DPH_SAT .or
- "DST" .emit OP_DST .or "DST_SAT" .emit OP_DST_SAT .or
- "MAX" .emit OP_MAX .or "MAX_SAT" .emit OP_MAX_SAT .or
- "MIN" .emit OP_MIN .or "MIN_SAT" .emit OP_MIN_SAT .or
- "MUL" .emit OP_MUL .or "MUL_SAT" .emit OP_MUL_SAT .or
- "SGE" .emit OP_SGE .or "SGE_SAT" .emit OP_SGE_SAT .or
- "SLT" .emit OP_SLT .or "SLT_SAT" .emit OP_SLT_SAT .or
- "SUB" .emit OP_SUB .or "SUB_SAT" .emit OP_SUB_SAT .or
- "XPD" .emit OP_XPD .or "XPD_SAT" .emit OP_XPD_SAT;
-vp_BINop
- "ADD" .emit OP_ADD .or
- "DP3" .emit OP_DP3 .or
- "DP4" .emit OP_DP4 .or
- "DPH" .emit OP_DPH .or
- "DST" .emit OP_DST .or
- "MAX" .emit OP_MAX .or
- "MIN" .emit OP_MIN .or
- "MUL" .emit OP_MUL .or
- "SGE" .emit OP_SGE .or
- "SLT" .emit OP_SLT .or
- "SUB" .emit OP_SUB .or
- "XPD" .emit OP_XPD;
-
-/*
-fragment program
- <TRIop_instruction> ::= <TRIop> <maskedDstReg> ","
- <vectorSrcReg> "," <vectorSrcReg> ","
- <vectorSrcReg>
-
-vertex program
- <TRIop_instruction> ::= <TRIop> <maskedDstReg> ","
- <swizzleSrcReg> "," <swizzleSrcReg> ","
- <swizzleSrcReg>
-*/
-fp_TRIop_instruction
- fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
- vectorSrcReg .and comma .and vectorSrcReg;
-vp_TRIop_instruction
- vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and
- swizzleSrcReg .and comma .and swizzleSrcReg;
-
-/*
-fragment program
- <TRIop> ::= "CMP" | "CMP_SAT"
- | "LRP" | "LRP_SAT"
- | "MAD" | "MAD_SAT"
-
-vertex program
- <TRIop> ::= "MAD"
-*/
-fp_TRIop
- "CMP" .emit OP_CMP .or "CMP_SAT" .emit OP_CMP_SAT .or
- "LRP" .emit OP_LRP .or "LRP_SAT" .emit OP_LRP_SAT .or
- "MAD" .emit OP_MAD .or "MAD_SAT" .emit OP_MAD_SAT;
-vp_TRIop
- "MAD" .emit OP_MAD;
-
-/*
-fragment program
- <SWZ_instruction> ::= <SWZop> <maskedDstReg> ","
- <srcReg> "," <extendedSwizzle>
-
-vertex program
- <SWZ_instruction> ::= "SWZ" <maskedDstReg> "," <srcReg> ","
- <extendedSwizzle>
-*/
-fp_SWZ_instruction
- SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and
- fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;
-vp_SWZ_instruction
- "SWZ" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and
- vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;
-
-/*
-fragment program
- <SWZop> ::= "SWZ" | "SWZ_SAT"
-*/
-SWZop
- "SWZ" .emit OP_SWZ .or "SWZ_SAT" .emit OP_SWZ_SAT;
-
-/*
-fragment program
- <SAMPLE_instruction> ::= <SAMPLEop> <maskedDstReg> ","
- <vectorSrcReg> "," <texImageUnit> ","
- <texTarget>
-*/
-SAMPLE_instruction
- SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and
- texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;
-
-/*
-fragment program
- <SAMPLEop> ::= "TEX" | "TEX_SAT"
- | "TXP" | "TXP_SAT"
- | "TXB" | "TXB_SAT"
-*/
-SAMPLEop
- "TEX" .emit OP_TEX .or "TEX_SAT" .emit OP_TEX_SAT .or
- "TXB" .emit OP_TXB .or "TXB_SAT" .emit OP_TXB_SAT .or
- "TXP" .emit OP_TXP .or "TXP_SAT" .emit OP_TXP_SAT;
-
-/*
-fragment program
- <KIL_instruction> ::= "KIL" <vectorSrcReg>
-*/
-KIL_instruction
- "KIL" .emit OP_KIL .and space_src .and vectorSrcReg;
-
-/*
-fragment program
- <texImageUnit> ::= "texture" <optTexImageUnitNum>
-*/
-texImageUnit
- "texture" .error TEXTURE_EXPECTED .and optTexImageUnitNum;
-
-/*
-fragment program
- <texTarget> ::= "1D"
- | "2D"
- | "3D"
- | "CUBE"
- | "RECT"
- | <shadowTarget> (if option ARB_fragment_program_shadow present)
- | <arrayTarget> (if option MESA_texture_array present)
-*/
-texTarget
- "1D" .emit TEXTARGET_1D .or
- "2D" .emit TEXTARGET_2D .or
- "3D" .emit TEXTARGET_3D .or
- .if (texture_rectangle != 0x00) "RECT" .emit TEXTARGET_RECT .or
- "CUBE" .emit TEXTARGET_CUBE .or
- .if (ARB_fragment_program_shadow != 0x00) shadowTarget .or
- .if (MESA_texture_array != 0x00) arrayTarget;
-
-/*
-GL_ARB_fragment_program_shadow
- <shadowTarget> ::= "SHADOW1D"
- | "SHADOW2D"
- | "SHADOWRECT"
- | <shadowArrayTarget> (if option MESA_texture_array present)
-*/
-shadowTarget
- "SHADOW1D" .emit TEXTARGET_SHADOW1D .or
- "SHADOW2D" .emit TEXTARGET_SHADOW2D .or
- .if (texture_rectangle != 0x00) "SHADOWRECT" .emit TEXTARGET_SHADOWRECT .or
- .if (MESA_texture_array != 0x00) shadowArrayTarget;
-
-/*
-GL_MESA_texture_array
-
- <arrayTarget> ::= "ARRAY1D"
- | "ARRAY2D"
-
- <shadowArrayTarget> ::= "SHADOWARRAY1D"
- | "SHADOWARRAY2D"
-*/
-
-arrayTarget
- "ARRAY1D" .emit TEXTARGET_1D_ARRAY .or
- "ARRAY2D" .emit TEXTARGET_2D_ARRAY;
-
-shadowArrayTarget
- "SHADOWARRAY1D" .emit TEXTARGET_SHADOW1D_ARRAY .or
- "SHADOWARRAY2D" .emit TEXTARGET_SHADOW2D_ARRAY;
-
-/*
-fragment program
- <optTexImageUnitNum> ::= ""
- | "[" <texImageUnitNum> "]"
-*/
-optTexImageUnitNum
- optTexImageUnitNum_1 .or .true .emit 0x00;
-optTexImageUnitNum_1
- lbracket_ne .and texImageUnitNum .and rbracket;
-
-/*
-fragment program
- <texImageUnitNum> ::= <integer> from 0 to
- MAX_TEXTURE_IMAGE_UNITS_ARB-1
-*/
-texImageUnitNum
- integer;
-
-/*
- <scalarSrcReg> ::= <optionalSign> <srcReg> <scalarSuffix>
-*/
-fp_scalarSrcReg
- optionalSign .and fp_srcReg .and fp_scalarSuffix;
-vp_scalarSrcReg
- optionalSign .and vp_srcReg .and vp_scalarSuffix;
-
-/*
-vertex program
- <swizzleSrcReg> ::= <optionalSign> <srcReg> <swizzleSuffix>
-*/
-swizzleSrcReg
- optionalSign .and vp_srcReg .and swizzleSuffix;
-
-/*
-fragment program
- <vectorSrcReg> ::= <optionalSign> <srcReg> <optionalSuffix>
-*/
-vectorSrcReg
- optionalSign .and fp_srcReg .and optionalSuffix;
-
-/*
- <maskedDstReg> ::= <dstReg> <optionalMask>
-*/
-fp_maskedDstReg
- fp_dstReg .and fp_optionalMask;
-vp_maskedDstReg
- vp_dstReg .and vp_optionalMask;
-
-/*
-vertex program
- <maskedAddrReg> ::= <addrReg> <addrWriteMask>
-*/
-maskedAddrReg
- addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;
-
-/*
-fragment program
- <extendedSwizzle> ::= <xyzwExtendedSwizzle>
- | <rgbaExtendedSwizzle>
-
-vertex program
- <extendedSwizzle> ::= <extSwizComp> "," <extSwizComp> ","
- <extSwizComp> "," <extSwizComp>
-
-NOTE: do NOT change the order of <rgbaExtendedSwizzle> and <xyzwExtendedSwizzle> rulez
-*/
-fp_extendedSwizzle
- rgbaExtendedSwizzle .or xyzwExtendedSwizzle;
-vp_extendedSwizzle
- extSwizComp .and comma .and
- extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- extSwizComp .error EXT_SWIZ_COMP_EXPECTED;
-
-/*
-fragment program
- <xyzwExtendedSwizzle> ::= <xyzwExtSwizComp> "," <xyzwExtSwizComp> ","
- <xyzwExtSwizComp> "," <xyzwExtSwizComp>
-*/
-xyzwExtendedSwizzle
- xyzwExtSwizComp .and comma .and
- xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
-
-/*
-fragment program
- <rgbaExtendedSwizzle> ::= <rgbaExtSwizComp> "," <rgbaExtSwizComp> ","
- <rgbaExtSwizComp> "," <rgbaExtSwizComp>
-*/
-rgbaExtendedSwizzle
- rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or
- rgbaExtendedSwizzle_4;
-rgbaExtendedSwizzle_1
- rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and
- rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;
-rgbaExtendedSwizzle_2
- rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and
- rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
-rgbaExtendedSwizzle_3
- rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and
- rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
-rgbaExtendedSwizzle_4
- rgbaExtSwizComp_alpha .and comma .and
- rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and
- rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;
-
-/*
-fragment program
- <xyzwExtSwizComp> ::= <optionalSign> <xyzwExtSwizSel>
-*/
-xyzwExtSwizComp
- optionalSign .and xyzwExtSwizSel;
-
-/*
-fragment program
- <rgbaExtSwizComp> ::= <optionalSign> <rgbaExtSwizSel>
-*/
-rgbaExtSwizComp
- optionalSign .and rgbaExtSwizSel;
-rgbaExtSwizComp_digit
- optionalSign .and rgbaExtSwizSel_digit;
-rgbaExtSwizComp_alpha
- optionalSign .and rgbaExtSwizSel_alpha;
-
-/*
-vertex program
- <extSwizComp> ::= <optionalSign> <extSwizSel>
-*/
-extSwizComp
- optionalSign .and extSwizSel;
-
-/*
-fragment program
- <xyzwExtSwizSel> ::= "0"
- | "1"
- | <xyzwComponent>
-*/
-xyzwExtSwizSel
- "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or xyzwComponent_single;
-
-/*
-fragment program
- <rgbaExtSwizSel> ::= "0"
- | "1"
- | <rgbaComponent>
-*/
-rgbaExtSwizSel
- rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;
-rgbaExtSwizSel_digit
- "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1;
-rgbaExtSwizSel_alpha
- rgbaComponent_single;
-
-/*
-vertex program
- <extSwizSel> ::= "0"
- | "1"
- | <component>
-*/
-extSwizSel
- "0" .emit COMPONENT_0 .or "1" .emit COMPONENT_1 .or vp_component_single;
-
-/*
-fragment program
- <srcReg> ::= <fragmentAttribReg>
- | <temporaryReg>
- | <progParamReg>
-
-vertex program
- <srcReg> ::= <vertexAttribReg>
- | <temporaryReg>
- | <progParamReg>
-*/
-fp_srcReg
- fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;
-vp_srcReg
- vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;
-fp_srcReg_1
- fragmentAttribReg .emit REGISTER_ATTRIB .or
- fp_progParamReg .emit REGISTER_PARAM .or
- fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
-vp_srcReg_1
- vertexAttribReg .emit REGISTER_ATTRIB .or
- vp_progParamReg .emit REGISTER_PARAM .or
- vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
-
-/*
-fragment program
- <dstReg> ::= <temporaryReg>
- | <fragmentResultReg>
-
-vertex program
- <dstReg> ::= <temporaryReg>
- | <vertexResultReg>
-*/
-fp_dstReg
- fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;
-vp_dstReg
- vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;
-fp_dstReg_1
- fragmentResultReg .emit REGISTER_RESULT .or
- fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
-vp_dstReg_1
- vertexResultReg .emit REGISTER_RESULT .or
- vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;
-
-/*
-fragment program
- <fragmentAttribReg> ::= <establishedName>
- | <fragAttribBinding>
-
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
-*/
-fragmentAttribReg
- /*fp_establishedName .or */fragAttribBinding;
-
-/*
-vertex program
- <vertexAttribReg> ::= <establishedName>
- | <vtxAttribBinding>
-
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
-*/
-vertexAttribReg
- vtxAttribBinding;
-
-/*
- <temporaryReg> ::= <establishedName>
-*/
-fp_temporaryReg
- fp_establishedName_no_error_on_identifier;
-vp_temporaryReg
- vp_establishedName_no_error_on_identifier;
-
-/*
-fragment program
- <progParamReg> ::= <progParamSingle>
- | <progParamArray> "[" <progParamArrayAbs> "]"
- | <paramSingleItemUse>
-
-vertex program
- <progParamReg> ::= <progParamSingle>
- | <progParamArray> "[" <progParamArrayMem> "]"
- | <paramSingleItemUse>
-*/
-fp_progParamReg
- fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;
-vp_progParamReg
- vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;
-fp_progParamReg_1
- fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and
- rbracket;
-vp_progParamReg_1
- vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and
- rbracket;
-
-/*
- <progParamSingle> ::= <establishedName>
-
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <srcReg>
-*/
-fp_progParamSingle
- .false;
-vp_progParamSingle
- .false;
-
-/*
- <progParamArray> ::= <establishedName>
-*/
-fp_progParamArray
- fp_establishedName_no_error_on_identifier;
-vp_progParamArray
- vp_establishedName_no_error_on_identifier;
-
-/*
-vertex program
- <progParamArrayMem> ::= <progParamArrayAbs>
- | <progParamArrayRel>
-*/
-progParamArrayMem
- progParamArrayAbs .or progParamArrayRel;
-
-/*
- <progParamArrayAbs> ::= <integer>
-*/
-progParamArrayAbs
- integer_ne .emit ARRAY_INDEX_ABSOLUTE;
-
-/*
-vertex program
- <progParamArrayRel> ::= <addrReg> <addrComponent> <addrRegRelOffset>
-*/
-progParamArrayRel
- addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and
- addrComponent .and addrRegRelOffset;
-
-/*
-vertex program
- <addrRegRelOffset> ::= ""
- | "+" <addrRegPosOffset>
- | "-" <addrRegNegOffset>
-*/
-addrRegRelOffset
- addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;
-addrRegRelOffset_1
- plus_ne .and addrRegPosOffset;
-addrRegRelOffset_2
- minus_ne .and addrRegNegOffset;
-
-/*
-vertex program
- <addrRegPosOffset> ::= <integer> from 0 to 63
-*/
-addrRegPosOffset
- integer_0_63;
-
-/*
-vertex program
- <addrRegNegOffset> ::= <integer> from 0 to 64
-*/
-addrRegNegOffset
- integer_0_64;
-
-/*
-fragment program
- <fragmentResultReg> ::= <establishedName>
- | <resultBinding>
-
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>
-*/
-fragmentResultReg
- fp_resultBinding;
-
-/*
-vertex program
- <vertexResultReg> ::= <establishedName>
- | <resultBinding>
-
-NOTE: <establishedName> is driven by <temporaryReg> rule at the end of <dstReg>
-*/
-vertexResultReg
- vp_resultBinding;
-
-/*
-vertex program
- <addrReg> ::= <establishedName>
-*/
-addrReg
- vp_establishedName_no_error_on_identifier;
-
-/*
-vertex program
- <addrComponent> ::= "." "x"
-*/
-addrComponent
- dot .and "x" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X
- .emit COMPONENT_X .emit COMPONENT_X;
-
-/*
-vertex program
- <addrWriteMask> ::= "." "x"
-*/
-addrWriteMask
- dot .and "x" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;
-
-/*
- <scalarSuffix> ::= "." <component>
-*/
-fp_scalarSuffix
- dot .and fp_component_single .error INVALID_COMPONENT;
-vp_scalarSuffix
- dot .and vp_component_single .error INVALID_COMPONENT;
-
-/*
-vertex program
- <swizzleSuffix> ::= ""
- | "." <component>
- | "." <component> <component>
- <component> <component>
-*/
-swizzleSuffix
- swizzleSuffix_1 .or
- .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;
-swizzleSuffix_1
- dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;
-swizzleSuffix_2
- swizzleSuffix_3 .or swizzleSuffix_4;
-swizzleSuffix_3
- vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and
- vp_component_multi .error INVALID_COMPONENT;
-swizzleSuffix_4
- "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
- "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
- "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
- "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;
-
-/*
-fragment program
- <optionalSuffix> ::= ""
- | "." <component>
- | "." <xyzwComponent> <xyzwComponent>
- <xyzwComponent> <xyzwComponent>
- | "." <rgbaComponent> <rgbaComponent>
- <rgbaComponent> <rgbaComponent>
-*/
-optionalSuffix
- optionalSuffix_1 .or
- .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;
-optionalSuffix_1
- dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;
-optionalSuffix_2
- optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;
-optionalSuffix_3
- xyzwComponent_multi .and xyzwComponent_multi .and
- xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;
-optionalSuffix_4
- rgbaComponent_multi .and rgbaComponent_multi .and
- rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;
-optionalSuffix_5
- "x" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
- "y" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
- "z" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
- "w" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or
- "r" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or
- "g" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or
- "b" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or
- "a" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;
-
-/*
-fragment program
- <component> ::= <xyzwComponent>
- | <rgbaComponent>
-
-vertex program
- <component> ::= "x"
- | "y"
- | "z"
- | "w"
-*/
-fp_component_single
- xyzwComponent_single .or rgbaComponent_single;
-vp_component_multi
- 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or
- 'w' .emit COMPONENT_W;
-vp_component_single
- "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or
- "w" .emit COMPONENT_W;
-
-/*
-fragment program
- <xyzwComponent> ::= "x" | "y" | "z" | "w"
-*/
-xyzwComponent_multi
- 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or
- 'w' .emit COMPONENT_W;
-xyzwComponent_single
- "x" .emit COMPONENT_X .or "y" .emit COMPONENT_Y .or "z" .emit COMPONENT_Z .or
- "w" .emit COMPONENT_W;
-
-/*
-fragment program
- <rgbaComponent> ::= "r" | "g" | "b" | "a"
-*/
-rgbaComponent_multi
- 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or
- 'a' .emit COMPONENT_W;
-rgbaComponent_single
- "r" .emit COMPONENT_X .or "g" .emit COMPONENT_Y .or "b" .emit COMPONENT_Z .or
- "a" .emit COMPONENT_W;
-
-/*
-fragment program
- <optionalMask> ::= ""
- | <xyzwMask>
- | <rgbaMask>
-
-vertex program
- <optionalMask> ::= ""
- | "." "x"
- | "." "y"
- | "." "xy"
- | "." "z"
- | "." "xz"
- | "." "yz"
- | "." "xyz"
- | "." "w"
- | "." "xw"
- | "." "yw"
- | "." "xyw"
- | "." "zw"
- | "." "xzw"
- | "." "yzw"
- | "." "xyzw"
-
-NOTE: do NOT change the order of <rgbaMask> and <xyzwMask> rulez
-*/
-fp_optionalMask
- rgbaMask .or xyzwMask .or .true .emit 0x0F;
-vp_optionalMask
- xyzwMask .or .true .emit 0x0F;
-
-/*
-fragment program
- <xyzwMask> ::= "." "x"
- | "." "y"
- | "." "xy"
- | "." "z"
- | "." "xz"
- | "." "yz"
- | "." "xyz"
- | "." "w"
- | "." "xw"
- | "." "yw"
- | "." "xyw"
- | "." "zw"
- | "." "xzw"
- | "." "yzw"
- | "." "xyzw"
-
-NOTE: <xyzwMask> is also referenced by the vertex program symbol <optionalMask>.
-*/
-xyzwMask
- dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;
-xyzwMask_1
- "xyzw" .emit 0x0F .or "xyz" .emit 0x0E .or "xyw" .emit 0x0D .or "xy" .emit 0x0C .or
- "xzw" .emit 0x0B .or "xz" .emit 0x0A .or "xw" .emit 0x09 .or "x" .emit 0x08 .or
- "yzw" .emit 0x07 .or "yz" .emit 0x06 .or "yw" .emit 0x05 .or "y" .emit 0x04 .or
- "zw" .emit 0x03 .or "z" .emit 0x02 .or "w" .emit 0x01;
-
-/*
-fragment program
- <rgbaMask> ::= "." "r"
- | "." "g"
- | "." "rg"
- | "." "b"
- | "." "rb"
- | "." "gb"
- | "." "rgb"
- | "." "a"
- | "." "ra"
- | "." "ga"
- | "." "rga"
- | "." "ba"
- | "." "rba"
- | "." "gba"
- | "." "rgba"
-*/
-rgbaMask
- dot_ne .and rgbaMask_1;
-rgbaMask_1
- "rgba" .emit 0x0F .or "rgb" .emit 0x0E .or "rga" .emit 0x0D .or "rg" .emit 0x0C .or
- "rba" .emit 0x0B .or "rb" .emit 0x0A .or "ra" .emit 0x09 .or "r" .emit 0x08 .or
- "gba" .emit 0x07 .or "gb" .emit 0x06 .or "ga" .emit 0x05 .or "g" .emit 0x04 .or
- "ba" .emit 0x03 .or "b" .emit 0x02 .or "a" .emit 0x01;
-
-/*
-fragment program
- <namingStatement> ::= <ATTRIB_statement>
- | <PARAM_statement>
- | <TEMP_statement>
- | <OUTPUT_statement>
- | <ALIAS_statement>
-
-vertex program
- <namingStatement> ::= <ATTRIB_statement>
- | <PARAM_statement>
- | <TEMP_statement>
- | <ADDRESS_statement>
- | <OUTPUT_statement>
- | <ALIAS_statement>
-*/
-fp_namingStatement
- fp_ATTRIB_statement .emit ATTRIB .or
- fp_PARAM_statement .emit PARAM .or
- fp_TEMP_statement .emit TEMP .or
- fp_OUTPUT_statement .emit OUTPUT .or
- fp_ALIAS_statement .emit ALIAS;
-vp_namingStatement
- vp_ATTRIB_statement .emit ATTRIB .or
- vp_PARAM_statement .emit PARAM .or
- vp_TEMP_statement .emit TEMP .or
- ADDRESS_statement .emit ADDRESS .or
- vp_OUTPUT_statement .emit OUTPUT .or
- vp_ALIAS_statement .emit ALIAS;
-
-/*
-fragment program
- <ATTRIB_statement> ::= "ATTRIB" <establishName> "="
- <fragAttribBinding>
-
-vertex program
- <ATTRIB_statement> ::= "ATTRIB" <establishName> "="
- <vtxAttribBinding>
-*/
-fp_ATTRIB_statement
- "ATTRIB" .and space .and fp_establishName .and equal .and
- fragAttribBinding .error FRAGMENT_EXPECTED;
-vp_ATTRIB_statement
- "ATTRIB" .and space .and vp_establishName .and equal .and
- vtxAttribBinding .error VERTEX_EXPECTED;
-
-/*
-fragment program
- <fragAttribBinding> ::= "fragment" "." <fragAttribItem>
-*/
-fragAttribBinding
- "fragment" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;
-
-/*
-vertex program
- <vtxAttribBinding> ::= "vertex" "." <vtxAttribItem>
-*/
-vtxAttribBinding
- "vertex" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;
-
-/*
-fragment program
- <fragAttribItem> ::= "color" <optColorType>
- | "texcoord" <optTexCoordNum>
- | "fogcoord"
- | "position"
-*/
-fragAttribItem
- fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or
- fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or
- .if (fog_coord != 0x00) "fogcoord" .emit FRAGMENT_ATTRIB_FOGCOORD .or
- "position" .emit FRAGMENT_ATTRIB_POSITION;
-fragAttribItem_1
- "color" .and optColorType;
-fragAttribItem_2
- "texcoord" .and optTexCoordNum;
-
-/*
-vertex program
- <vtxAttribItem> ::= "position"
- | "weight" <vtxOptWeightNum>
- | "normal"
- | "color" <optColorType>
- | "fogcoord"
- | "texcoord" <optTexCoordNum>
- | "matrixindex" "[" <vtxWeightNum> "]"
- | "attrib" "[" <vtxAttribNum> "]"
-*/
-vtxAttribItem
- "position" .emit VERTEX_ATTRIB_POSITION .or
- .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or
- "normal" .emit VERTEX_ATTRIB_NORMAL .or
- vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or
- "fogcoord" .emit VERTEX_ATTRIB_FOGCOORD .or
- vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or
- .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or
- vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;
-vtxAttribItem_1
- "weight" .and vtxOptWeightNum;
-vtxAttribItem_2
- "color" .and optColorType;
-vtxAttribItem_3
- "texcoord" .and optTexCoordNum;
-vtxAttribItem_4
- "matrixindex" .and lbracket .and vtxWeightNum .and rbracket;
-vtxAttribItem_5
- "attrib" .and lbracket .and vtxAttribNum .and rbracket;
-
-/*
-vertex program
- <vtxAttribNum> ::= <integer> from 0 to MAX_VERTEX_ATTRIBS_ARB-1
-*/
-vtxAttribNum
- integer;
-
-/*
-vertex program
- <vtxOptWeightNum> ::= ""
- | "[" <vtxWeightNum> "]"
-*/
-vtxOptWeightNum
- vtxOptWeightNum_1 .or .true .emit 0x00;
-vtxOptWeightNum_1
- lbracket_ne .and vtxWeightNum .and rbracket;
-
-/*
-vertex program
- <vtxWeightNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1,
- must be divisible by four
-*/
-vtxWeightNum
- integer;
-
-/*
- <PARAM_statement> ::= <PARAM_singleStmt>
- | <PARAM_multipleStmt>
-*/
-fp_PARAM_statement
- fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;
-vp_PARAM_statement
- vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;
-
-/*
- <PARAM_singleStmt> ::= "PARAM" <establishName> <paramSingleInit>
-*/
-fp_PARAM_singleStmt
- "PARAM" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and
- .true .emit PARAM_NULL;
-vp_PARAM_singleStmt
- "PARAM" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and
- .true .emit PARAM_NULL;
-
-/*
- <PARAM_multipleStmt> ::= "PARAM" <establishName> "[" <optArraySize> "]"
- <paramMultipleInit>
-*/
-fp_PARAM_multipleStmt
- "PARAM" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and
- fp_paramMultipleInit .and .true .emit PARAM_NULL;
-vp_PARAM_multipleStmt
- "PARAM" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and
- vp_paramMultipleInit .and .true .emit PARAM_NULL;
-
-/*
- <optArraySize> ::= ""
- | <integer> from 1 to MAX_PROGRAM_PARAMETERS_ARB
- (maximum number of allowed program
- parameter bindings)
-*/
-optArraySize
- optional_integer;
-
-/*
- <paramSingleInit> ::= "=" <paramSingleItemDecl>
-*/
-fp_paramSingleInit
- equal .and fp_paramSingleItemDecl;
-vp_paramSingleInit
- equal .and vp_paramSingleItemDecl;
-
-/*
- <paramMultipleInit> ::= "=" "{" <paramMultInitList> "}"
-*/
-fp_paramMultipleInit
- equal .and lbrace .and fp_paramMultInitList .and rbrace;
-vp_paramMultipleInit
- equal .and lbrace .and vp_paramMultInitList .and rbrace;
-
-/*
- <paramMultInitList> ::= <paramMultipleItem>
- | <paramMultipleItem> "," <paramMultiInitList>
-*/
-fp_paramMultInitList
- fp_paramMultInitList_1 .or fp_paramMultipleItem;
-vp_paramMultInitList
- vp_paramMultInitList_1 .or vp_paramMultipleItem;
-fp_paramMultInitList_1
- fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;
-vp_paramMultInitList_1
- vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;
-
-/*
- <paramSingleItemDecl> ::= <stateSingleItem>
- | <programSingleItem>
- | <paramConstDecl>
-*/
-fp_paramSingleItemDecl
- fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
- programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstDecl .emit PARAM_CONSTANT;
-vp_paramSingleItemDecl
- vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
- programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstDecl .emit PARAM_CONSTANT;
-
-/*
- <paramSingleItemUse> ::= <stateSingleItem>
- | <programSingleItem>
- | <paramConstUse>
-*/
-fp_paramSingleItemUse
- fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
- programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstUse .emit PARAM_CONSTANT;
-vp_paramSingleItemUse
- vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or
- programSingleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstUse .emit PARAM_CONSTANT;
-
-/*
- <paramMultipleItem> ::= <stateMultipleItem>
- | <programMultipleItem>
- | <paramConstDecl>
-*/
-fp_paramMultipleItem
- fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or
- programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstDecl .emit PARAM_CONSTANT;
-vp_paramMultipleItem
- vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or
- programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or
- paramConstDecl .emit PARAM_CONSTANT;
-
-/*
- <stateMultipleItem> ::= <stateSingleItem>
- | "state" "." <stateMatrixRows>
-*/
-fp_stateMultipleItem
- stateMultipleItem_1 .or fp_stateSingleItem;
-vp_stateMultipleItem
- stateMultipleItem_1 .or vp_stateSingleItem;
-stateMultipleItem_1
- "state" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;
-
-/*
-fragment program
- <stateSingleItem> ::= "state" "." <stateMaterialItem>
- | "state" "." <stateLightItem>
- | "state" "." <stateLightModelItem>
- | "state" "." <stateLightProdItem>
- | "state" "." <stateTexEnvItem>
- | "state" "." <stateFogItem>
- | "state" "." <stateDepthItem>
- | "state" "." <stateMatrixRow>
-
-vertex program
- <stateSingleItem> ::= "state" "." <stateMaterialItem>
- | "state" "." <stateLightItem>
- | "state" "." <stateLightModelItem>
- | "state" "." <stateLightProdItem>
- | "state" "." <stateTexGenItem>
- | "state" "." <stateFogItem>
- | "state" "." <stateClipPlaneItem>
- | "state" "." <statePointItem>
- | "state" "." <stateMatrixRow>
-*/
-fp_stateSingleItem
- "state" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;
-vp_stateSingleItem
- "state" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;
-fp_stateSingleItem_1
- stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or
- stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;
-vp_stateSingleItem_1
- stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or
- stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or
- stateSingleItem_11;
-stateSingleItem_1
- stateMaterialItem .emit STATE_MATERIAL;
-stateSingleItem_2
- stateLightItem .emit STATE_LIGHT;
-stateSingleItem_3
- stateLightModelItem .emit STATE_LIGHT_MODEL;
-stateSingleItem_4
- stateLightProdItem .emit STATE_LIGHT_PROD;
-stateSingleItem_5
- stateTexEnvItem .emit STATE_TEX_ENV;
-stateSingleItem_6
- stateTexGenItem .emit STATE_TEX_GEN;
-stateSingleItem_7
- stateFogItem .emit STATE_FOG;
-stateSingleItem_8
- stateDepthItem .emit STATE_DEPTH;
-stateSingleItem_9
- stateClipPlaneItem .emit STATE_CLIP_PLANE;
-stateSingleItem_10
- statePointItem .emit STATE_POINT;
-stateSingleItem_11
- stateMatrixRow .emit STATE_MATRIX_ROWS;
-
-/*
- <stateMaterialItem> ::= "material" <optFaceType> "." <stateMatProperty>
-*/
-stateMaterialItem
- "material" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;
-
-/*
- <stateMatProperty> ::= "ambient"
- | "diffuse"
- | "specular"
- | "emission"
- | "shininess"
-*/
-stateMatProperty
- "ambient" .emit MATERIAL_AMBIENT .or
- "diffuse" .emit MATERIAL_DIFFUSE .or
- "specular" .emit MATERIAL_SPECULAR .or
- "emission" .emit MATERIAL_EMISSION .or
- "shininess" .emit MATERIAL_SHININESS;
-
-/*
- <stateLightItem> ::= "light" "[" <stateLightNumber> "]" "."
- <stateLightProperty>
-*/
-stateLightItem
- "light" .and lbracket .and stateLightNumber .and rbracket .and dot .and
- stateLightProperty .error INVALID_LIGHT_PROPERTY;
-
-/*
- <stateLightProperty> ::= "ambient"
- | "diffuse"
- | "specular"
- | "position"
- | "attenuation"
- | "spot" "." <stateSpotProperty>
- | "half"
-*/
-stateLightProperty
- "ambient" .emit LIGHT_AMBIENT .or
- "diffuse" .emit LIGHT_DIFFUSE .or
- "specular" .emit LIGHT_SPECULAR .or
- "position" .emit LIGHT_POSITION .or
- "attenuation" .emit LIGHT_ATTENUATION .or
- stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or
- "half" .emit LIGHT_HALF;
-stateLightProperty_1
- "spot" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;
-
-/*
- <stateSpotProperty> ::= "direction"
-*/
-stateSpotProperty
- "direction";
-
-/*
- <stateLightModelItem> ::= "lightmodel" <stateLModProperty>
-*/
-stateLightModelItem
- "lightmodel" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;
-
-/*
- <stateLModProperty> ::= "." "ambient"
- | <optFaceType> "." "scenecolor"
-*/
-stateLModProperty
- stateLModProperty_1 .or stateLModProperty_2;
-stateLModProperty_1
- dot .and "ambient" .emit LIGHT_MODEL_AMBIENT;
-stateLModProperty_2
- stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;
-stateLModProperty_3
- optFaceType .and dot .and "scenecolor";
-
-/*
- <stateLightProdItem> ::= "lightprod" "[" <stateLightNumber> "]"
- <optFaceType> "." <stateLProdProperty>
-*/
-stateLightProdItem
- "lightprod" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and
- stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;
-
-/*
- <stateLProdProperty> ::= "ambient"
- | "diffuse"
- | "specular"
-*/
-stateLProdProperty
- "ambient" .emit LIGHT_PROD_AMBIENT .or
- "diffuse" .emit LIGHT_PROD_DIFFUSE .or
- "specular" .emit LIGHT_PROD_SPECULAR;
-
-/*
- <stateLightNumber> ::= <integer> from 0 to MAX_LIGHTS-1
-*/
-stateLightNumber
- integer;
-
-/*
-fragment program
- <stateTexEnvItem> ::= "texenv" <optLegacyTexUnitNum> "."
- <stateTexEnvProperty>
-*/
-stateTexEnvItem
- "texenv" .and optLegacyTexUnitNum .and dot .and
- stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;
-
-/*
-fragment program
- <stateTexEnvProperty> ::= "color"
-*/
-stateTexEnvProperty
- "color" .emit TEX_ENV_COLOR;
-
-/*
-fragment program
- <optLegacyTexUnitNum> ::= ""
- | "[" <legacyTexUnitNum> "]"
-*/
-optLegacyTexUnitNum
- optLegacyTexUnitNum_1 .or .true .emit 0x00;
-optLegacyTexUnitNum_1
- lbracket_ne .and legacyTexUnitNum .and rbracket;
-
-/*
-fragment program
- <legacyTexUnitNum> ::= <integer> from 0 to MAX_TEXTURE_UNITS-1
-*/
-legacyTexUnitNum
- integer;
-
-/*
-vertex program
- <stateTexGenItem> ::= "texgen" <optTexCoordNum> "."
- <stateTexGenType> "." <stateTexGenCoord>
-*/
-stateTexGenItem
- "texgen" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and
- dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;
-
-/*
-vertex program
- <stateTexGenType> ::= "eye"
- | "object"
-*/
-stateTexGenType
- "eye" .emit TEX_GEN_EYE .or
- "object" .emit TEX_GEN_OBJECT;
-
-/*
-vertex program
- <stateTexGenCoord> ::= "s"
- | "t"
- | "r"
- | "q"
-*/
-stateTexGenCoord
- "s" .emit COMPONENT_X .or
- "t" .emit COMPONENT_Y .or
- "r" .emit COMPONENT_Z .or
- "q" .emit COMPONENT_W;
-
-/*
- <stateFogItem> ::= "fog" "." <stateFogProperty>
-*/
-stateFogItem
- "fog" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;
-
-/*
- <stateFogProperty> ::= "color"
- | "params"
-*/
-stateFogProperty
- "color" .emit FOG_COLOR .or
- "params" .emit FOG_PARAMS;
-
-/*
-fragment program
- <stateDepthItem> ::= "depth" "." <stateDepthProperty>
-*/
-stateDepthItem
- "depth" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;
-
-/*
-fragment program
- <stateDepthProperty> ::= "range"
-*/
-stateDepthProperty
- "range" .emit DEPTH_RANGE;
-
-/*
-vertex program
- <stateClipPlaneItem> ::= "clip" "[" <stateClipPlaneNum> "]" "." "plane"
-*/
-stateClipPlaneItem
- "clip" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and
- "plane" .error INVALID_CLIPPLANE_PROPERTY;
-
-/*
-vertex program
- <stateClipPlaneNum> ::= <integer> from 0 to MAX_CLIP_PLANES-1
-*/
-stateClipPlaneNum
- integer;
-
-/*
-vertex program
- <statePointItem> ::= "point" "." <statePointProperty>
-*/
-statePointItem
- "point" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;
-
-/*
-vertex program
- <statePointProperty> ::= "size"
- | "attenuation"
-*/
-statePointProperty
- "size" .emit POINT_SIZE .or
- .if (point_parameters != 0x00) "attenuation" .emit POINT_ATTENUATION;
-
-/*
- <stateMatrixRow> ::= <stateMatrixItem> "." "row" "["
- <stateMatrixRowNum> "]"
-*/
-stateMatrixRow
- stateMatrixItem .and dot .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and
- lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;
-
-/*
- <stateMatrixRows> ::= <stateMatrixItem> <optMatrixRows>
-*/
-stateMatrixRows
- stateMatrixItem .and optMatrixRows;
-
-/*
- <optMatrixRows> ::= ""
- | "." "row" "[" <stateMatrixRowNum> ".."
- <stateMatrixRowNum> "]"
-*/
-optMatrixRows
- optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;
-optMatrixRows_1
- dot_ne .and "row" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and
- stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;
-
-/*
- <stateMatrixItem> ::= "matrix" "." <stateMatrixName>
- <stateOptMatModifier>
-*/
-stateMatrixItem
- "matrix" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;
-
-/*
- <stateOptMatModifier> ::= ""
- | "." <stateMatModifier>
-*/
-stateOptMatModifier
- stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;
-stateOptMatModifier_1
- dot_ne .and stateMatModifier;
-
-/*
- <stateMatModifier> ::= "inverse"
- | "transpose"
- | "invtrans"
-*/
-stateMatModifier
- "inverse" .emit MATRIX_MODIFIER_INVERSE .or
- "transpose" .emit MATRIX_MODIFIER_TRANSPOSE .or
- "invtrans" .emit MATRIX_MODIFIER_INVTRANS;
-
-/*
- <stateMatrixRowNum> ::= <integer> from 0 to 3
-*/
-stateMatrixRowNum
- integer_0_3;
-
-/*
- <stateMatrixName> ::= "modelview" <stateOptModMatNum>
- | "projection"
- | "mvp"
- | "texture" <optTexCoordNum>
- | "palette" "[" <statePaletteMatNum> "]"
- | "program" "[" <stateProgramMatNum> "]"
-*/
-stateMatrixName
- stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or
- "projection" .emit MATRIX_PROJECTION .or
- "mvp" .emit MATRIX_MVP .or
- stateMatrixName_1_2 .emit MATRIX_TEXTURE .or
- .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or
- stateMatrixName_1_4 .emit MATRIX_PROGRAM;
-stateMatrixName_1_1
- "modelview" .and stateOptModMatNum;
-stateMatrixName_1_2
- "texture" .and optTexCoordNum;
-stateMatrixName_1_3
- "palette" .and lbracket .and statePaletteMatNum .and rbracket;
-stateMatrixName_1_4
- "program" .and lbracket .and stateProgramMatNum .and rbracket;
-
-/*
- <stateOptModMatNum> ::= ""
- | "[" <stateModMatNum> "]"
-*/
-stateOptModMatNum
- .if (vertex_blend != 0x00) stateOptModMatNum_1 .or
- .true .emit 0x00;
-stateOptModMatNum_1
- lbracket_ne .and stateModMatNum .and rbracket;
-
-/*
- <stateModMatNum> ::= <integer> from 0 to MAX_VERTEX_UNITS_ARB-1
-*/
-stateModMatNum
- integer;
-
-/*
- <optTexCoordNum> ::= ""
- | "[" <texCoordNum> "]"
-*/
-optTexCoordNum
- optTexCoordNum_1 .or .true .emit 0x00;
-optTexCoordNum_1
- lbracket_ne .and texCoordNum .and rbracket;
-
-/*
- <texCoordNum> ::= <integer> from 0 to MAX_TEXTURE_COORDS_ARB-1
-*/
-texCoordNum
- integer;
-
-/*
- <statePaletteMatNum> ::= <integer> from 0 to MAX_PALETTE_MATRICES_ARB-1
-*/
-statePaletteMatNum
- integer;
-
-/*
- <stateProgramMatNum> ::= <integer> from 0 to MAX_PROGRAM_MATRICES_ARB-1
-*/
-stateProgramMatNum
- integer;
-
-/*
- <programSingleItem> ::= <progEnvParam>
- | <progLocalParam>
-
-NOTE: <programSingleItem> has been modified for correct error handling. If program property
- is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.
-*/
-programSingleItem
- "program" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;
-programSingleItem_1
- progEnvParam .or progLocalParam;
-
-/*
- <programMultipleItem> ::= <progEnvParams>
- | <progLocalParams>
-
-NOTE: <programMultipleItem> has been modified for correct error handling. If program property
- is neither "env" nor "local" INVALID_PROGRAM_PROPERTY is generated.
-*/
-programMultipleItem
- "program" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;
-programMultipleItem_1
- progEnvParams .or progLocalParams;
-
-/*
- <progEnvParams> ::= "program" "." "env"
- "[" <progEnvParamNums> "]"
-
-NOTE: "program" "." has been moved to <programMultipleItem>.
-*/
-progEnvParams
- "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;
-
-/*
- <progEnvParamNums> ::= <progEnvParamNum>
- | <progEnvParamNum> ".." <progEnvParamNum>
-*/
-progEnvParamNums
- progEnvParamNums_1 .or progEnvParamNums_2;
-progEnvParamNums_1
- progEnvParamNum .and dotdot_ne .and progEnvParamNum;
-progEnvParamNums_2
- progEnvParamNum .and .true .emit 0x00;
-
-/*
- <progEnvParam> ::= "program" "." "env"
- "[" <progEnvParamNum> "]"
-
-NOTE: "program" "." has been moved to <programSingleItem>.
-*/
-progEnvParam
- "env" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;
-
-/*
- <progLocalParams> ::= "program" "." "local"
- "[" <progLocalParamNums> "]"
-
-NOTE: "program" "." has been moved to <programMultipleItem>.
-*/
-progLocalParams
- "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;
-
-/*
- <progLocalParamNums> ::= <progLocalParamNum>
- | <progLocalParamNum> ".." <progLocalParamNum>
-*/
-progLocalParamNums
- progLocalParamNums_1 .or progLocalParamNums_2;
-progLocalParamNums_1
- progLocalParamNum .and dotdot_ne .and progLocalParamNum;
-progLocalParamNums_2
- progLocalParamNum .and .true .emit 0x00;
-
-/*
- <progLocalParam> ::= "program" "." "local"
- "[" <progLocalParamNum> "]"
-
-NOTE: "program" "." has been moved to <programSingleItem>.
-*/
-progLocalParam
- "local" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;
-
-/*
- <progEnvParamNum> ::= <integer> from 0 to
- MAX_PROGRAM_ENV_PARAMETERS_ARB - 1
-*/
-progEnvParamNum
- integer;
-
-/*
- <progLocalParamNum> ::= <integer> from 0 to
- MAX_PROGRAM_LOCAL_PARAMETERS_ARB - 1
-*/
-progLocalParamNum
- integer;
-
-/*
- <paramConstDecl> ::= <paramConstScalarDecl>
- | <paramConstVector>
-*/
-paramConstDecl
- paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;
-
-/*
- <paramConstUse> ::= <paramConstScalarUse>
- | <paramConstVector>
-*/
-paramConstUse
- paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;
-
-/*
- <paramConstScalarDecl> ::= <signedFloatConstant>
-*/
-paramConstScalarDecl
- signedFloatConstant;
-
-/*
- <paramConstScalarUse> ::= <floatConstant>
-*/
-paramConstScalarUse
- floatConstant;
-
-/*
- <paramConstVector> ::= "{" <signedFloatConstant> "}"
- | "{" <signedFloatConstant> ","
- <signedFloatConstant> "}"
- | "{" <signedFloatConstant> ","
- <signedFloatConstant> ","
- <signedFloatConstant> "}"
- | "{" <signedFloatConstant> ","
- <signedFloatConstant> ","
- <signedFloatConstant> ","
- <signedFloatConstant> "}"
-*/
-paramConstVector
- paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or
- paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;
-paramConstVector_1
- lbrace_ne .and signedFloatConstant .and rbrace;
-paramConstVector_2
- lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;
-paramConstVector_3
- lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and
- signedFloatConstant .and rbrace;
-paramConstVector_4
- lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and
- signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;
-
-/*
- <signedFloatConstant> ::= <optionalSign> <floatConstant>
-*/
-signedFloatConstant
- optionalSign .and floatConstant;
-
-/*
- <floatConstant> ::= see text
- The <floatConstant> rule matches a floating-point constant consisting
- of an integer part, a decimal point, a fraction part, an "e" or
- "E", and an optionally signed integer exponent. The integer and
- fraction parts both consist of a sequence of one or more digits ("0"
- through "9"). Either the integer part or the fraction parts (not
- both) may be missing; either the decimal point or the "e" (or "E")
- and the exponent (not both) may be missing.
-*/
-floatConstant
- float;
-
-/*
- <optionalSign> ::= ""
- | "-"
- | "+"
-*/
-optionalSign
- optional_sign_ne;
-
-/*
- <TEMP_statement> ::= "TEMP" <varNameList>
-*/
-fp_TEMP_statement
- "TEMP" .and space .and fp_varNameList .and .true .emit 0x00;
-vp_TEMP_statement
- "TEMP" .and space .and vp_varNameList .and .true .emit 0x00;
-
-/*
-vertex program
- <ADDRESS_statement> ::= "ADDRESS" <varNameList>
-*/
-ADDRESS_statement
- "ADDRESS" .and space .and vp_varNameList .and .true .emit 0x00;
-
-/*
- <varNameList> ::= <establishName>
- | <establishName> "," <varNameList>
-*/
-fp_varNameList
- fp_varNameList_1 .or fp_establishName;
-vp_varNameList
- vp_varNameList_1 .or vp_establishName;
-fp_varNameList_1
- fp_establishName .and comma_ne .and fp_varNameList;
-vp_varNameList_1
- vp_establishName .and comma_ne .and vp_varNameList;
-
-/*
- <OUTPUT_statement> ::= "OUTPUT" <establishName> "="
- <resultBinding>
-*/
-fp_OUTPUT_statement
- "OUTPUT" .and space .and fp_establishName .and equal .and
- fp_resultBinding .error RESULT_EXPECTED;
-vp_OUTPUT_statement
- "OUTPUT" .and space .and vp_establishName .and equal .and
- vp_resultBinding .error RESULT_EXPECTED;
-
-/*
-fragment program
- <resultBinding> ::= "result" "." "color"
- | "result" "." "color" <optOutputColorNum> (if option ARB_draw_buffers present)
- | "result" "." "depth"
-
-vertex program
- <resultBinding> ::= "result" "." "position"
- | "result" "." <resultColBinding>
- | "result" "." "fogcoord"
- | "result" "." "pointsize"
- | "result" "." "texcoord" <optTexCoordNum>
-*/
-fp_resultBinding
- "result" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;
-vp_resultBinding
- "result" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;
-fp_resultBinding_1
- fp_resultBinding_2 .emit FRAGMENT_RESULT_COLOR .or
- "depth" .emit FRAGMENT_RESULT_DEPTH;
-fp_resultBinding_2
- "color" .and optOutputColorNum;
-vp_resultBinding_1
- .if (ARB_position_invariant == 0x00) "position" .emit VERTEX_RESULT_POSITION .or
- resultColBinding .emit VERTEX_RESULT_COLOR .or
- "fogcoord" .emit VERTEX_RESULT_FOGCOORD .or
- "pointsize" .emit VERTEX_RESULT_POINTSIZE .or
- vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;
-vp_resultBinding_2
- "texcoord" .and optTexCoordNum;
-
-/*
-GL_ARB_draw_buffers
- <optOutputColorNum> ::= ""
- | "[" <outputColorNum> "]"
-*/
-optOutputColorNum
- .if (ARB_draw_buffers != 0x00) optOutputColorNum_1 .or .true .emit 0x00;
-optOutputColorNum_1
- lbracket_ne .and outputColorNum .and rbracket;
-
-/*
-GL_ARB_draw_buffers
- <outputColorNum> ::= <integer> from 0 to MAX_DRAW_BUFFERS_ARB-1
-*/
-outputColorNum
- integer;
-
-/*
-vertex program
- <resultColBinding> ::= "color" <optFaceType> <optColorType>
-*/
-resultColBinding
- "color" .and optFaceType .and optColorType;
-
-/*
- <optFaceType> ::= ""
- | "." "front"
- | "." "back"
-*/
-optFaceType
- FaceType .or .true .emit FACE_FRONT;
-FaceType
- dot_ne .and FaceProperty;
-FaceProperty
- "front" .emit FACE_FRONT .or "back" .emit FACE_BACK;
-
-/*
- <optColorType> ::= ""
- | "." "primary"
- | "." "secondary"
-*/
-optColorType
- ColorType .or .true .emit COLOR_PRIMARY;
-ColorType
- dot_ne .and ColorProperty;
-ColorProperty
- "primary" .emit COLOR_PRIMARY .or
- .if (secondary_color != 0x00) "secondary" .emit COLOR_SECONDARY;
-
-/*
- <ALIAS_statement> ::= "ALIAS" <establishName> "="
- <establishedName>
-*/
-fp_ALIAS_statement
- "ALIAS" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;
-vp_ALIAS_statement
- "ALIAS" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;
-fp_ALIAS_statement_1
- space .and fp_establishName;
-vp_ALIAS_statement_1
- space .and vp_establishName;
-
-/*
- <establishName> ::= <identifier>
-*/
-fp_establishName
- fp_identifier;
-vp_establishName
- vp_identifier;
-
-/*
- <establishedName> ::= <identifier>
-*/
-fp_establishedName
- fp_identifier;
-vp_establishedName
- vp_identifier;
-fp_establishedName_no_error_on_identifier
- fp_identifier_ne;
-vp_establishedName_no_error_on_identifier
- vp_identifier_ne;
-
-/*
-fragment program
- <identifier> ::= see text
- The <identifier> rule matches a sequence of one or more letters ("A"
- through "Z", "a" through "z"), digits ("0" through "9), underscores
- ("_"), or dollar signs ("$"); the first character must not be a
- number. Upper and lower case letters are considered different
- (names are case-sensitive). The following strings are reserved
- keywords and may not be used as identifiers:
-
- ABS, ABS_SAT, ADD, ADD_SAT, ALIAS, ATTRIB, CMP, CMP_SAT, COS,
- COS_SAT, DP3, DP3_SAT, DP4, DP4_SAT, DPH, DPH_SAT, DST, DST_SAT,
- END, EX2, EX2_SAT, FLR, FLR_SAT, FRC, FRC_SAT, KIL, LG2,
- LG2_SAT, LIT, LIT_SAT, LRP, LRP_SAT, MAD, MAD_SAT, MAX, MAX_SAT,
- MIN, MIN_SAT, MOV, MOV_SAT, MUL, MUL_SAT, OPTION, OUTPUT, PARAM,
- POW, POW_SAT, RCP, RCP_SAT, RSQ, RSQ_SAT, SIN, SIN_SAT, SCS,
- SCS_SAT, SGE, SGE_SAT, SLT, SLT_SAT, SUB, SUB_SAT, SWZ, SWZ_SAT,
- TEMP, TEX, TEX_SAT, TXB, TXB_SAT, TXP, TXP_SAT, XPD, XPD_SAT,
- fragment, program, result, state, and texture.
-
-vertex program
- <identifier> ::= see text
- The <identifier> rule matches a sequence of one or more letters ("A"
- through "Z", "a" through "z"), digits ("0" through "9), underscores ("_"),
- or dollar signs ("$"); the first character must not be a number. Upper
- and lower case letters are considered different (names are
- case-sensitive). The following strings are reserved keywords and may not
- be used as identifiers:
-
- ABS, ADD, ADDRESS, ALIAS, ARL, ATTRIB, DP3, DP4, DPH, DST, END, EX2,
- EXP, FLR, FRC, LG2, LIT, LOG, MAD, MAX, MIN, MOV, MUL, OPTION, OUTPUT,
- PARAM, POW, RCP, RSQ, SGE, SLT, SUB, SWZ, TEMP, XPD, program, result,
- state, and vertex.
-*/
-fp_identifier
- fp_identifier_ne .error IDENTIFIER_EXPECTED;
-vp_identifier
- vp_identifier_ne .error IDENTIFIER_EXPECTED;
-fp_identifier_ne
- fp_not_reserved_identifier .and identifier_ne;
-vp_identifier_ne
- vp_not_reserved_identifier .and identifier_ne;
-
-fp_not_reserved_identifier
- fp_not_reserved_identifier_1 .or .true;
-fp_not_reserved_identifier_1
- fp_reserved_identifier .and .false .error RESERVED_KEYWORD;
-vp_not_reserved_identifier
- vp_not_reserved_identifier_1 .or .true;
-vp_not_reserved_identifier_1
- vp_reserved_identifier .and .false .error RESERVED_KEYWORD;
-
-fp_reserved_identifier
- "ABS" .or "ABS_SAT" .or "ADD" .or "ADD_SAT" .or "ALIAS" .or "ATTRIB" .or "CMP" .or "CMP_SAT" .or
- "COS" .or "COS_SAT" .or "DP3" .or "DP3_SAT" .or "DP4" .or "DP4_SAT" .or "DPH" .or "DPH_SAT" .or
- "DST" .or "DST_SAT" .or "END" .or "EX2" .or "EX2_SAT" .or "FLR" .or "FLR_SAT" .or "FRC" .or
- "FRC_SAT" .or "KIL" .or "LG2" .or "LG2_SAT" .or "LIT" .or "LIT_SAT" .or "LRP" .or "LRP_SAT" .or
- "MAD" .or "MAD_SAT" .or "MAX" .or "MAX_SAT" .or "MIN" .or "MIN_SAT" .or "MOV" .or "MOV_SAT" .or
- "MUL" .or "MUL_SAT" .or "OPTION" .or "OUTPUT" .or "PARAM" .or "POW" .or "POW_SAT" .or "RCP" .or
- "RCP_SAT" .or "RSQ" .or "RSQ_SAT" .or "SIN" .or "SIN_SAT" .or "SCS" .or "SCS_SAT" .or "SGE" .or
- "SGE_SAT" .or "SLT" .or "SLT_SAT" .or "SUB" .or "SUB_SAT" .or "SWZ" .or "SWZ_SAT" .or "TEMP" .or
- "TEX" .or "TEX_SAT" .or "TXB" .or "TXB_SAT" .or "TXP" .or "TXP_SAT" .or "XPD" .or "XPD_SAT" .or
- "fragment" .or "program" .or "result" .or "state" .or "texture";
-vp_reserved_identifier
- "ABS" .or "ADD" .or "ADDRESS" .or "ALIAS" .or "ARL" .or "ATTRIB" .or "DP3" .or "DP4" .or
- "DPH" .or "DST" .or "END" .or "EX2" .or "EXP" .or "FLR" .or "FRC" .or "LG2" .or "LIT" .or
- "LOG" .or "MAD" .or "MAX" .or "MIN" .or "MOV" .or "MUL" .or "OPTION" .or "OUTPUT" .or
- "PARAM" .or "POW" .or "RCP" .or "RSQ" .or "SGE" .or "SLT" .or "SUB" .or "SWZ" .or "TEMP" .or
- "XPD" .or "program" .or "result" .or "state" .or "vertex";
-
-/*
- The <integer> rule matches an integer constant. The integer consists
- of a sequence of one or more digits ("0" through "9").
-*/
-integer
- integer_ne .error INTEGER_EXPECTED;
-
-zero
- '0';
-
-leading_zeroes
- .loop zero;
-
-no_digit
- no_digit_1 .or .true;
-no_digit_1
- digit10 .and .false .error INTEGER_OUT_OF_RANGE;
-
-all_zeroes
- all_zeroes_1 .or no_digit_1;
-all_zeroes_1
- '0' .and .loop zero .and no_digit;
-
-integer_0_3
- integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
-integer_0_3_1
- integer_0_3_2 .or all_zeroes .emit '0';
-integer_0_3_2 /* [1, 3] */
- leading_zeroes .and '1'-'3' .emit * .and no_digit;
-
-integer_0_63
- integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
-integer_0_63_1
- integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or
- all_zeroes .emit '0';
-integer_0_63_2 /* [7, 9] */
- leading_zeroes .and '7'-'9' .emit * .and no_digit;
-integer_0_63_3 /* [10, 59] */
- leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;
-integer_0_63_4 /* [60, 63] */
- leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;
-integer_0_63_5 /* [1, 6] */
- leading_zeroes .and '1'-'6' .emit * .and no_digit;
-
-integer_0_64
- integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;
-integer_0_64_1
- integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or
- all_zeroes .emit '0';
-integer_0_64_2 /* [7, 9] */
- leading_zeroes .and '7'-'9' .emit * .and no_digit;
-integer_0_64_3 /* [10, 59] */
- leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;
-integer_0_64_4 /* [60, 64] */
- leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;
-integer_0_64_5 /* [1, 6] */
- leading_zeroes .and '1'-'6' .emit * .and no_digit;
-
-optional_space
- space .or .true;
-
-space_dst
- space .error OPERATION_NEEDS_DESTINATION_VARIABLE;
-
-space_src
- space .error OPERATION_NEEDS_SOURCE_VARIABLE;
-
-space
- single_space .and .loop single_space;
-
-single_space
- white_char .or comment_block;
-
-white_char
- ' ' .or '\t' .or '\n' .or '\r';
-
-comment_block
- '#' .and .loop comment_char .and optional_new_line;
-
-/* All ASCII characters except '\r', '\n' and '\0' */
-comment_char
- '\x0E'-'\xFF' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-optional_new_line
- '\n' .or crlf .or .true;
-
-crlf
- '\r' .and '\n';
-
-semicolon
- optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;
-
-comma
- optional_space .and ',' .error MISSING_COMMA .and optional_space;
-
-comma_ne
- optional_space .and ',' .and optional_space;
-
-lbracket
- optional_space .and '[' .error MISSING_LBRACKET .and optional_space;
-
-lbracket_ne
- optional_space .and '[' .and optional_space;
-
-rbracket
- optional_space .and ']' .error MISSING_RBRACKET .and optional_space;
-
-dot
- optional_space .and '.' .error MISSING_DOT .and optional_space;
-
-dot_ne
- optional_space .and '.' .and optional_space;
-
-equal
- optional_space .and '=' .error MISSING_EQUAL .and optional_space;
-
-lbrace
- optional_space .and '{' .error MISSING_LBRACE .and optional_space;
-
-lbrace_ne
- optional_space .and '{' .and optional_space;
-
-rbrace
- optional_space .and '}' .error MISSING_RBRACE .and optional_space;
-
-dotdot
- optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;
-
-dotdot_ne
- optional_space .and '.' .and '.' .and optional_space;
-
-/*
- The definition below accepts the following floating point number formats:
- .99 .99e99 99. 99.99 99.99e99 99.e99 99e99
- Also 99 format was considered and accepted because of a large number of existing program
- strings with such a format.
-*/
-float
- float_1 .or float_2 .or float_legacy;
-float_1
- '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;
-float_2
- integer_ne .and float_3;
-float_3
- float_4 .or float_5;
-float_4
- '.' .and optional_integer .and optional_exponent;
-float_5
- exponent .emit 0x00;
-float_legacy
- integer_ne .and .true .emit 0x00 .emit 0x00;
-
-/*
- Below is a correct version of <float> definiton.
-*/
-/*
-float
- float_1 .or float_2;
-float_1
- '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;
-float_2
- integer_ne .and float_3 .error MISSING_DOT_OR_EXPONENT;
-float_3
- float_4 .or float_5;
-float_4
- '.' .and optional_integer .and optional_exponent;
-float_5
- exponent .emit 0x00;
-*/
-
-integer_ne
- integer_ne_1 .and .true .emit 0x00 .emit $;
-integer_ne_1
- digit10 .emit * .and .loop digit10 .emit *;
-
-optional_integer
- integer_ne .or .true .emit 0x00;
-
-/*
-NOTE: If exponent part is omited we treat it as if it was "E+1".
-*/
-optional_exponent
- exponent .or .true .emit 0x00;
-
-exponent
- exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;
-exponent_1
- 'e' .or 'E';
-
-optional_sign_ne
- minus_ne .or plus_ne .or .true;
-
-plus_ne
- optional_space .and '+' .and optional_space;
-
-minus_ne
- optional_space .and '-' .emit '-' .and optional_space;
-
-identifier_ne
- first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;
-
-follow_idchar
- first_idchar .or digit10;
-
-first_idchar
- 'a'-'z' .or 'A'-'Z' .or '_' .or '$';
-
-digit10
- '0'-'9';
-
-/*
- string filtering - if a string is encountered in grammar ("blabla"), the symbol below is
- executed to create the string. The symbol must not throw any errors and emit bytes - it should
- stop if it encounters invalid character. After this the resulting string (from starting
- position up to the invalid character (but without it) is compared with the grammar string.
-*/
-.string __string_filter;
-
-__string_filter
- .loop __identifier_char;
-
-__identifier_char
- 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';
-
-/*
- error token filtering
-*/
-e_signature
- e_signature_char .and .loop e_signature_char;
-e_signature_char
- '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';
-
-e_statement
- .loop e_statement_not_term;
-/* All ASCII characters to one of '\r', '\n', '\0' and ';' */
-e_statement_not_term
- '\x3C'-'\xFF' .or '\x0E'-'\x3A' .or '\x01'-'\x09' .or '\x0B'-'\x0C';
-
-e_identifier
- e_identifier_first .and .loop e_identifier_next;
-e_identifier_first
- 'a'-'z' .or 'A'-'Z' .or '_' .or '$';
-e_identifier_next
- e_identifier_first .or '0'-'9';
-
-e_token
- e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or
- '-' .or ',' .or ';';
-e_token_number
- e_token_digit .and .loop e_token_digit;
-e_token_digit
- '0'-'9';
-
-e_charordigit
- 'A'-'Z' .or 'a'-'z' .or '0'-'9';
-
diff --git a/src/mesa/shader/arbprogram_syn.h b/src/mesa/shader/arbprogram_syn.h
deleted file mode 100644
index d95a5dede4..0000000000
--- a/src/mesa/shader/arbprogram_syn.h
+++ /dev/null
@@ -1,1350 +0,0 @@
-
-/* DO NOT EDIT - THIS FILE IS AUTOMATICALLY GENERATED FROM THE .syn FILE */
-
-" \n"
-".syntax program;\n"
-".emtcode REVISION 0x0a\n"
-".emtcode FRAGMENT_PROGRAM 0x01\n"
-".emtcode VERTEX_PROGRAM 0x02\n"
-".emtcode OPTION 0x01\n"
-".emtcode INSTRUCTION 0x02\n"
-".emtcode DECLARATION 0x03\n"
-".emtcode END 0x04\n"
-".emtcode ARB_PRECISION_HINT_FASTEST 0x00\n"
-".emtcode ARB_PRECISION_HINT_NICEST 0x01\n"
-".emtcode ARB_FOG_EXP 0x02\n"
-".emtcode ARB_FOG_EXP2 0x03\n"
-".emtcode ARB_FOG_LINEAR 0x04\n"
-".emtcode ARB_POSITION_INVARIANT 0x05\n"
-".emtcode ARB_FRAGMENT_PROGRAM_SHADOW 0x06\n"
-".emtcode ARB_DRAW_BUFFERS 0x07\n"
-".emtcode MESA_TEXTURE_ARRAY 0x08\n"
-".emtcode OP_ALU_INST 0x00\n"
-".emtcode OP_TEX_INST 0x01\n"
-".emtcode OP_ALU_VECTOR 0x00\n"
-".emtcode OP_ALU_SCALAR 0x01\n"
-".emtcode OP_ALU_BINSC 0x02\n"
-".emtcode OP_ALU_BIN 0x03\n"
-".emtcode OP_ALU_TRI 0x04\n"
-".emtcode OP_ALU_SWZ 0x05\n"
-".emtcode OP_TEX_SAMPLE 0x06\n"
-".emtcode OP_TEX_KIL 0x07\n"
-".emtcode OP_ALU_ARL 0x08\n"
-".emtcode OP_ABS 0x00\n"
-".emtcode OP_ABS_SAT 0x1B\n"
-".emtcode OP_FLR 0x09\n"
-".emtcode OP_FLR_SAT 0x26\n"
-".emtcode OP_FRC 0x0A\n"
-".emtcode OP_FRC_SAT 0x27\n"
-".emtcode OP_LIT 0x0C\n"
-".emtcode OP_LIT_SAT 0x2A\n"
-".emtcode OP_MOV 0x11\n"
-".emtcode OP_MOV_SAT 0x30\n"
-".emtcode OP_COS 0x1F\n"
-".emtcode OP_COS_SAT 0x20\n"
-".emtcode OP_EX2 0x07\n"
-".emtcode OP_EX2_SAT 0x25\n"
-".emtcode OP_LG2 0x0B\n"
-".emtcode OP_LG2_SAT 0x29\n"
-".emtcode OP_RCP 0x14\n"
-".emtcode OP_RCP_SAT 0x33\n"
-".emtcode OP_RSQ 0x15\n"
-".emtcode OP_RSQ_SAT 0x34\n"
-".emtcode OP_SIN 0x38\n"
-".emtcode OP_SIN_SAT 0x39\n"
-".emtcode OP_SCS 0x35\n"
-".emtcode OP_SCS_SAT 0x36\n"
-".emtcode OP_POW 0x13\n"
-".emtcode OP_POW_SAT 0x32\n"
-".emtcode OP_ADD 0x01\n"
-".emtcode OP_ADD_SAT 0x1C\n"
-".emtcode OP_DP3 0x03\n"
-".emtcode OP_DP3_SAT 0x21\n"
-".emtcode OP_DP4 0x04\n"
-".emtcode OP_DP4_SAT 0x22\n"
-".emtcode OP_DPH 0x05\n"
-".emtcode OP_DPH_SAT 0x23\n"
-".emtcode OP_DST 0x06\n"
-".emtcode OP_DST_SAT 0x24\n"
-".emtcode OP_MAX 0x0F\n"
-".emtcode OP_MAX_SAT 0x2E\n"
-".emtcode OP_MIN 0x10\n"
-".emtcode OP_MIN_SAT 0x2F\n"
-".emtcode OP_MUL 0x12\n"
-".emtcode OP_MUL_SAT 0x31\n"
-".emtcode OP_SGE 0x16\n"
-".emtcode OP_SGE_SAT 0x37\n"
-".emtcode OP_SLT 0x17\n"
-".emtcode OP_SLT_SAT 0x3A\n"
-".emtcode OP_SUB 0x18\n"
-".emtcode OP_SUB_SAT 0x3B\n"
-".emtcode OP_XPD 0x1A\n"
-".emtcode OP_XPD_SAT 0x43\n"
-".emtcode OP_CMP 0x1D\n"
-".emtcode OP_CMP_SAT 0x1E\n"
-".emtcode OP_LRP 0x2B\n"
-".emtcode OP_LRP_SAT 0x2C\n"
-".emtcode OP_MAD 0x0E\n"
-".emtcode OP_MAD_SAT 0x2D\n"
-".emtcode OP_SWZ 0x19\n"
-".emtcode OP_SWZ_SAT 0x3C\n"
-".emtcode OP_TEX 0x3D\n"
-".emtcode OP_TEX_SAT 0x3E\n"
-".emtcode OP_TXB 0x3F\n"
-".emtcode OP_TXB_SAT 0x40\n"
-".emtcode OP_TXP 0x41\n"
-".emtcode OP_TXP_SAT 0x42\n"
-".emtcode OP_KIL 0x28\n"
-".emtcode OP_ARL 0x02\n"
-".emtcode OP_EXP 0x08\n"
-".emtcode OP_LOG 0x0D\n"
-".emtcode FRAGMENT_ATTRIB_COLOR 0x01\n"
-".emtcode FRAGMENT_ATTRIB_TEXCOORD 0x02\n"
-".emtcode FRAGMENT_ATTRIB_FOGCOORD 0x03\n"
-".emtcode FRAGMENT_ATTRIB_POSITION 0x04\n"
-".emtcode VERTEX_ATTRIB_POSITION 0x01\n"
-".emtcode VERTEX_ATTRIB_WEIGHT 0x02\n"
-".emtcode VERTEX_ATTRIB_NORMAL 0x03\n"
-".emtcode VERTEX_ATTRIB_COLOR 0x04\n"
-".emtcode VERTEX_ATTRIB_FOGCOORD 0x05\n"
-".emtcode VERTEX_ATTRIB_TEXCOORD 0x06\n"
-".emtcode VERTEX_ATTRIB_MATRIXINDEX 0x07\n"
-".emtcode VERTEX_ATTRIB_GENERIC 0x08\n"
-".emtcode FRAGMENT_RESULT_COLOR 0x01\n"
-".emtcode FRAGMENT_RESULT_DEPTH 0x02\n"
-".emtcode VERTEX_RESULT_POSITION 0x01\n"
-".emtcode VERTEX_RESULT_COLOR 0x02\n"
-".emtcode VERTEX_RESULT_FOGCOORD 0x03\n"
-".emtcode VERTEX_RESULT_POINTSIZE 0x04\n"
-".emtcode VERTEX_RESULT_TEXCOORD 0x05\n"
-".emtcode TEXTARGET_1D 0x01\n"
-".emtcode TEXTARGET_2D 0x02\n"
-".emtcode TEXTARGET_3D 0x03\n"
-".emtcode TEXTARGET_RECT 0x04\n"
-".emtcode TEXTARGET_CUBE 0x05\n"
-".emtcode TEXTARGET_SHADOW1D 0x06\n"
-".emtcode TEXTARGET_SHADOW2D 0x07\n"
-".emtcode TEXTARGET_SHADOWRECT 0x08\n"
-".emtcode TEXTARGET_1D_ARRAY 0x09\n"
-".emtcode TEXTARGET_2D_ARRAY 0x0a\n"
-".emtcode TEXTARGET_SHADOW1D_ARRAY 0x0b\n"
-".emtcode TEXTARGET_SHADOW2D_ARRAY 0x0c\n"
-".emtcode FACE_FRONT 0x00\n"
-".emtcode FACE_BACK 0x01\n"
-".emtcode COLOR_PRIMARY 0x00\n"
-".emtcode COLOR_SECONDARY 0x01\n"
-".emtcode COMPONENT_X 0x00\n"
-".emtcode COMPONENT_Y 0x01\n"
-".emtcode COMPONENT_Z 0x02\n"
-".emtcode COMPONENT_W 0x03\n"
-".emtcode COMPONENT_0 0x04\n"
-".emtcode COMPONENT_1 0x05\n"
-".emtcode ARRAY_INDEX_ABSOLUTE 0x00\n"
-".emtcode ARRAY_INDEX_RELATIVE 0x01\n"
-".emtcode MATRIX_MODELVIEW 0x01\n"
-".emtcode MATRIX_PROJECTION 0x02\n"
-".emtcode MATRIX_MVP 0x03\n"
-".emtcode MATRIX_TEXTURE 0x04\n"
-".emtcode MATRIX_PALETTE 0x05\n"
-".emtcode MATRIX_PROGRAM 0x06\n"
-".emtcode MATRIX_MODIFIER_IDENTITY 0x00\n"
-".emtcode MATRIX_MODIFIER_INVERSE 0x01\n"
-".emtcode MATRIX_MODIFIER_TRANSPOSE 0x02\n"
-".emtcode MATRIX_MODIFIER_INVTRANS 0x03\n"
-".emtcode CONSTANT_SCALAR 0x01\n"
-".emtcode CONSTANT_VECTOR 0x02\n"
-".emtcode PROGRAM_PARAM_ENV 0x01\n"
-".emtcode PROGRAM_PARAM_LOCAL 0x02\n"
-".emtcode REGISTER_ATTRIB 0x01\n"
-".emtcode REGISTER_PARAM 0x02\n"
-".emtcode REGISTER_RESULT 0x03\n"
-".emtcode REGISTER_ESTABLISHED_NAME 0x04\n"
-".emtcode PARAM_NULL 0x00\n"
-".emtcode PARAM_ARRAY_ELEMENT 0x01\n"
-".emtcode PARAM_STATE_ELEMENT 0x02\n"
-".emtcode PARAM_PROGRAM_ELEMENT 0x03\n"
-".emtcode PARAM_PROGRAM_ELEMENTS 0x04\n"
-".emtcode PARAM_CONSTANT 0x05\n"
-".emtcode STATE_MATERIAL 0x01\n"
-".emtcode STATE_LIGHT 0x02\n"
-".emtcode STATE_LIGHT_MODEL 0x03\n"
-".emtcode STATE_LIGHT_PROD 0x04\n"
-".emtcode STATE_FOG 0x05\n"
-".emtcode STATE_MATRIX_ROWS 0x06\n"
-".emtcode STATE_TEX_ENV 0x07\n"
-".emtcode STATE_DEPTH 0x08\n"
-".emtcode STATE_TEX_GEN 0x09\n"
-".emtcode STATE_CLIP_PLANE 0x0A\n"
-".emtcode STATE_POINT 0x0B\n"
-".emtcode MATERIAL_AMBIENT 0x01\n"
-".emtcode MATERIAL_DIFFUSE 0x02\n"
-".emtcode MATERIAL_SPECULAR 0x03\n"
-".emtcode MATERIAL_EMISSION 0x04\n"
-".emtcode MATERIAL_SHININESS 0x05\n"
-".emtcode LIGHT_AMBIENT 0x01\n"
-".emtcode LIGHT_DIFFUSE 0x02\n"
-".emtcode LIGHT_SPECULAR 0x03\n"
-".emtcode LIGHT_POSITION 0x04\n"
-".emtcode LIGHT_ATTENUATION 0x05\n"
-".emtcode LIGHT_HALF 0x06\n"
-".emtcode LIGHT_SPOT_DIRECTION 0x07\n"
-".emtcode LIGHT_MODEL_AMBIENT 0x01\n"
-".emtcode LIGHT_MODEL_SCENECOLOR 0x02\n"
-".emtcode LIGHT_PROD_AMBIENT 0x01\n"
-".emtcode LIGHT_PROD_DIFFUSE 0x02\n"
-".emtcode LIGHT_PROD_SPECULAR 0x03\n"
-".emtcode TEX_ENV_COLOR 0x01\n"
-".emtcode TEX_GEN_EYE 0x01\n"
-".emtcode TEX_GEN_OBJECT 0x02\n"
-".emtcode FOG_COLOR 0x01\n"
-".emtcode FOG_PARAMS 0x02\n"
-".emtcode DEPTH_RANGE 0x01\n"
-".emtcode POINT_SIZE 0x01\n"
-".emtcode POINT_ATTENUATION 0x02\n"
-".emtcode ATTRIB 0x01\n"
-".emtcode PARAM 0x02\n"
-".emtcode TEMP 0x03\n"
-".emtcode OUTPUT 0x04\n"
-".emtcode ALIAS 0x05\n"
-".emtcode ADDRESS 0x06\n"
-".errtext UNKNOWN_PROGRAM_SIGNATURE \"1001: '$e_signature$': unknown program signature\"\n"
-".errtext MISSING_END_OR_INVALID_STATEMENT \"1002: '$e_statement$': invalid statement\"\n"
-".errtext CODE_AFTER_END \"1003: '$e_statement$': code after 'END' keyword\"\n"
-".errtext INVALID_PROGRAM_OPTION \"1004: '$e_identifier$': invalid program option\"\n"
-".errtext EXT_SWIZ_COMP_EXPECTED \"1005: extended swizzle component expected but '$e_token$' found\"\n"
-".errtext TEX_TARGET_EXPECTED \"1006: texture target expected but '$e_token$' found\"\n"
-".errtext TEXTURE_EXPECTED \"1007: 'texture' expected but '$e_identifier$' found\"\n"
-".errtext SOURCE_REGISTER_EXPECTED \"1008: source register expected but '$e_token$' found\"\n"
-".errtext DESTINATION_REGISTER_EXPECTED \"1009: destination register expected but '$e_token$' found\"\n"
-".errtext INVALID_ADDRESS_COMPONENT \"1010: '$e_identifier$': invalid address component\"\n"
-".errtext INVALID_ADDRESS_WRITEMASK \"1011: '$e_identifier$': invalid address writemask\"\n"
-".errtext INVALID_COMPONENT \"1012: '$e_charordigit$': invalid component\"\n"
-".errtext INVALID_SUFFIX \"1013: '$e_identifier$': invalid suffix\"\n"
-".errtext INVALID_WRITEMASK \"1014: '$e_identifier$': invalid writemask\"\n"
-".errtext FRAGMENT_EXPECTED \"1015: 'fragment' expected but '$e_identifier$' found\"\n"
-".errtext VERTEX_EXPECTED \"1016: 'vertex' expected but '$e_identifier$' found\"\n"
-".errtext INVALID_FRAGMENT_PROPERTY \"1017: '$e_identifier$': invalid fragment property\"\n"
-".errtext INVALID_VERTEX_PROPERTY \"1018: '$e_identifier$': invalid vertex property\"\n"
-".errtext INVALID_STATE_PROPERTY \"1019: '$e_identifier$': invalid state property\"\n"
-".errtext INVALID_MATERIAL_PROPERTY \"1020: '$e_identifier$': invalid material property\"\n"
-".errtext INVALID_LIGHT_PROPERTY \"1021: '$e_identifier$': invalid light property\"\n"
-".errtext INVALID_SPOT_PROPERTY \"1022: '$e_identifier$': invalid spot property\"\n"
-".errtext INVALID_LIGHTMODEL_PROPERTY \"1023: '$e_identifier$': invalid light model property\"\n"
-".errtext INVALID_LIGHTPROD_PROPERTY \"1024: '$e_identifier$': invalid light product property\"\n"
-".errtext INVALID_TEXENV_PROPERTY \"1025: '$e_identifier$': invalid texture environment property\"\n"
-".errtext INVALID_TEXGEN_PROPERTY \"1026: '$e_identifier$': invalid texture generating property\"\n"
-".errtext INVALID_TEXGEN_COORD \"1027: '$e_identifier$': invalid texture generating coord\"\n"
-".errtext INVALID_FOG_PROPERTY \"1028: '$e_identifier$': invalid fog property\"\n"
-".errtext INVALID_DEPTH_PROPERTY \"1029: '$e_identifier$': invalid depth property\"\n"
-".errtext INVALID_CLIPPLANE_PROPERTY \"1030: '$e_identifier$': invalid clip plane property\"\n"
-".errtext INVALID_POINT_PROPERTY \"1031: '$e_identifier$': invalid point property\"\n"
-".errtext MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED \"1032: matrix row selector or modifier expected but '$e_token$' found\"\n"
-".errtext INVALID_MATRIX_NAME \"1033: '$e_identifier$': invalid matrix name\"\n"
-".errtext INVALID_PROGRAM_PROPERTY \"1034: '$e_identifier$': invalid program property\"\n"
-".errtext RESULT_EXPECTED \"1035: 'result' expected but '$e_token$' found\"\n"
-".errtext INVALID_RESULT_PROPERTY \"1036: '$e_identifier$': invalid result property\"\n"
-".errtext INVALID_FACE_PROPERTY \"1037: '$e_identifier$': invalid face property\"\n"
-".errtext INVALID_COLOR_PROPERTY \"1038: '$e_identifier$': invalid color property\"\n"
-".errtext IDENTIFIER_EXPECTED \"1039: identifier expected but '$e_token$' found\"\n"
-".errtext RESERVED_KEYWORD \"1040: use of reserved keyword as an identifier\"\n"
-".errtext INTEGER_EXPECTED \"1041: integer value expected but '$e_token$' found\"\n"
-".errtext MISSING_SEMICOLON \"1042: ';' expected but '$e_token$' found\"\n"
-".errtext MISSING_COMMA \"1043: ',' expected but '$e_token$' found\"\n"
-".errtext MISSING_LBRACKET \"1044: '[' expected but '$e_token$' found\"\n"
-".errtext MISSING_RBRACKET \"1045: ']' expected but '$e_token$' found\"\n"
-".errtext MISSING_DOT \"1046: '.' expected but '$e_token$' found\"\n"
-".errtext MISSING_EQUAL \"1047: '=' expected but '$e_token$' found\"\n"
-".errtext MISSING_LBRACE \"1048: '{' expected but '$e_token$' found\"\n"
-".errtext MISSING_RBRACE \"1049: '}' expected but '$e_token$' found\"\n"
-".errtext MISSING_DOTDOT \"1050: '..' expected but '$e_token$' found\"\n"
-".errtext MISSING_FRACTION_OR_EXPONENT \"1051: missing fraction part or exponent\"\n"
-".errtext MISSING_DOT_OR_EXPONENT \"1052: missing '.' or exponent\"\n"
-".errtext EXPONENT_VALUE_EXPECTED \"1053: exponent value expected\"\n"
-".errtext INTEGER_OUT_OF_RANGE \"1054: integer value out of range\"\n"
-".errtext OPERATION_NEEDS_DESTINATION_VARIABLE \"1055: operation needs destination variable\"\n"
-".errtext OPERATION_NEEDS_SOURCE_VARIABLE \"1056: operation needs source variable\"\n"
-".errtext ADDRESS_REGISTER_EXPECTED \"1057: address register expected but '$e_token$' found\"\n"
-".errtext ADDRESS_REGISTER_OR_INTEGER_EXPECTED \"1058: address register or integer literal expected but '$e_token$' found\"\n"
-".regbyte vertex_blend 0x00\n"
-".regbyte matrix_palette 0x00\n"
-".regbyte point_parameters 0x00\n"
-".regbyte secondary_color 0x00\n"
-".regbyte fog_coord 0x00\n"
-".regbyte texture_rectangle 0x00\n"
-".regbyte fragment_program_shadow 0x00\n"
-".regbyte draw_buffers 0x00\n"
-".regbyte texture_array 0x00\n"
-".regbyte ARB_precision_hint_fastest 0x00\n"
-".regbyte ARB_precision_hint_nicest 0x00\n"
-".regbyte ARB_fog_exp 0x00\n"
-".regbyte ARB_fog_exp2 0x00\n"
-".regbyte ARB_fog_linear 0x00\n"
-".regbyte ARB_position_invariant 0x00\n"
-".regbyte ARB_fragment_program_shadow 0x00\n"
-".regbyte ARB_draw_buffers 0x00\n"
-".regbyte MESA_texture_array 0x00\n"
-".regbyte program_target 0x00\n"
-"program\n"
-" programs .error UNKNOWN_PROGRAM_SIGNATURE .emit REVISION;\n"
-"programs\n"
-" .if (program_target == 0x10) frag_program_1_0 .emit FRAGMENT_PROGRAM .emit 0x01 .emit 0x00 .or\n"
-" .if (program_target == 0x20) vert_program_1_0 .emit VERTEX_PROGRAM .emit 0x01 .emit 0x00;\n"
-"frag_program_1_0\n"
-" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'f' .and 'p' .and '1' .and '.' .and '0' .and\n"
-" optional_space .and fp_optionSequence .and fp_statementSequence .and\n"
-" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"
-" '\\0' .error CODE_AFTER_END;\n"
-"vert_program_1_0\n"
-" '!' .and '!' .and 'A' .and 'R' .and 'B' .and 'v' .and 'p' .and '1' .and '.' .and '0' .and\n"
-" optional_space .and vp_optionSequence .and vp_statementSequence .and\n"
-" \"END\" .error MISSING_END_OR_INVALID_STATEMENT .emit END .and optional_space .and\n"
-" '\\0' .error CODE_AFTER_END;\n"
-"fp_optionSequence\n"
-" .loop fp_option;\n"
-"vp_optionSequence\n"
-" .loop vp_option;\n"
-"fp_option\n"
-" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"
-" fp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"
-"vp_option\n"
-" \"OPTION\" .emit OPTION .and space .error IDENTIFIER_EXPECTED .and\n"
-" vp_optionString .error INVALID_PROGRAM_OPTION .and semicolon;\n"
-"fp_optionString\n"
-" .if (ARB_precision_hint_nicest == 0x00) \"ARB_precision_hint_fastest\"\n"
-" .emit ARB_PRECISION_HINT_FASTEST .load ARB_precision_hint_fastest 0x01 .or\n"
-" .if (ARB_precision_hint_fastest == 0x00) \"ARB_precision_hint_nicest\"\n"
-" .emit ARB_PRECISION_HINT_NICEST .load ARB_precision_hint_nicest 0x01 .or\n"
-" fp_ARB_fog_exp .emit ARB_FOG_EXP .load ARB_fog_exp 0x01 .or\n"
-" fp_ARB_fog_exp2 .emit ARB_FOG_EXP2 .load ARB_fog_exp2 0x01 .or\n"
-" fp_ARB_fog_linear .emit ARB_FOG_LINEAR .load ARB_fog_linear 0x01 .or\n"
-" .if (fragment_program_shadow != 0x00) \"ARB_fragment_program_shadow\"\n"
-" .emit ARB_FRAGMENT_PROGRAM_SHADOW .load ARB_fragment_program_shadow 0x01 .or\n"
-" .if (draw_buffers != 0x00) \"ARB_draw_buffers\" .emit ARB_DRAW_BUFFERS\n"
-" .load ARB_draw_buffers 0x01 .or\n"
-" .if (texture_array != 0x00) \"MESA_texture_array\" .emit MESA_TEXTURE_ARRAY\n"
-" .load MESA_texture_array 0x01;\n"
-"vp_optionString\n"
-" \"ARB_position_invariant\" .emit ARB_POSITION_INVARIANT .load ARB_position_invariant 0x01;\n"
-"fp_ARB_fog_exp\n"
-" .if (ARB_fog_exp2 == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp\";\n"
-"fp_ARB_fog_exp2\n"
-" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_linear == 0x00) \"ARB_fog_exp2\";\n"
-"fp_ARB_fog_linear\n"
-" .if (ARB_fog_exp == 0x00) .true .and .if (ARB_fog_exp2 == 0x00) \"ARB_fog_linear\";\n"
-"fp_statementSequence\n"
-" .loop fp_statement;\n"
-"vp_statementSequence\n"
-" .loop vp_statement;\n"
-"fp_statement\n"
-" fp_statement_1 .or fp_statement_2;\n"
-"vp_statement\n"
-" vp_statement_1 .or vp_statement_2;\n"
-"fp_statement_1\n"
-" fp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"
-"fp_statement_2\n"
-" fp_namingStatement .emit DECLARATION .and semicolon;\n"
-"vp_statement_1\n"
-" vp_instruction .emit INSTRUCTION .emit $ .and semicolon;\n"
-"vp_statement_2\n"
-" vp_namingStatement .emit DECLARATION .and semicolon;\n"
-"fp_instruction\n"
-" ALUInstruction .emit OP_ALU_INST .or\n"
-" TexInstruction .emit OP_TEX_INST;\n"
-"vp_instruction\n"
-" ARL_instruction .emit OP_ALU_ARL .or\n"
-" vp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"
-" vp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"
-" vp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"
-" vp_BINop_instruction .emit OP_ALU_BIN .or\n"
-" vp_TRIop_instruction .emit OP_ALU_TRI .or\n"
-" vp_SWZ_instruction .emit OP_ALU_SWZ;\n"
-"ALUInstruction\n"
-" fp_VECTORop_instruction .emit OP_ALU_VECTOR .or\n"
-" fp_SCALARop_instruction .emit OP_ALU_SCALAR .or\n"
-" fp_BINSCop_instruction .emit OP_ALU_BINSC .or\n"
-" fp_BINop_instruction .emit OP_ALU_BIN .or\n"
-" fp_TRIop_instruction .emit OP_ALU_TRI .or\n"
-" fp_SWZ_instruction .emit OP_ALU_SWZ;\n"
-"TexInstruction\n"
-" SAMPLE_instruction .emit OP_TEX_SAMPLE .or\n"
-" KIL_instruction .emit OP_TEX_KIL;\n"
-"ARL_instruction\n"
-" \"ARL\" .emit OP_ARL .and space_dst .and maskedAddrReg .and comma .and vp_scalarSrcReg;\n"
-"fp_VECTORop_instruction\n"
-" fp_VECTORop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg;\n"
-"vp_VECTORop_instruction\n"
-" vp_VECTORop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg;\n"
-"fp_VECTORop\n"
-" \"ABS\" .emit OP_ABS .or \"ABS_SAT\" .emit OP_ABS_SAT .or\n"
-" \"FLR\" .emit OP_FLR .or \"FLR_SAT\" .emit OP_FLR_SAT .or\n"
-" \"FRC\" .emit OP_FRC .or \"FRC_SAT\" .emit OP_FRC_SAT .or\n"
-" \"LIT\" .emit OP_LIT .or \"LIT_SAT\" .emit OP_LIT_SAT .or\n"
-" \"MOV\" .emit OP_MOV .or \"MOV_SAT\" .emit OP_MOV_SAT;\n"
-"vp_VECTORop\n"
-" \"ABS\" .emit OP_ABS .or\n"
-" \"FLR\" .emit OP_FLR .or\n"
-" \"FRC\" .emit OP_FRC .or\n"
-" \"LIT\" .emit OP_LIT .or\n"
-" \"MOV\" .emit OP_MOV;\n"
-"fp_SCALARop_instruction\n"
-" fp_SCALARop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg;\n"
-"vp_SCALARop_instruction\n"
-" vp_SCALARop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg;\n"
-"fp_SCALARop\n"
-" \"COS\" .emit OP_COS .or \"COS_SAT\" .emit OP_COS_SAT .or\n"
-" \"EX2\" .emit OP_EX2 .or \"EX2_SAT\" .emit OP_EX2_SAT .or\n"
-" \"LG2\" .emit OP_LG2 .or \"LG2_SAT\" .emit OP_LG2_SAT .or\n"
-" \"RCP\" .emit OP_RCP .or \"RCP_SAT\" .emit OP_RCP_SAT .or\n"
-" \"RSQ\" .emit OP_RSQ .or \"RSQ_SAT\" .emit OP_RSQ_SAT .or\n"
-" \"SIN\" .emit OP_SIN .or \"SIN_SAT\" .emit OP_SIN_SAT .or\n"
-" \"SCS\" .emit OP_SCS .or \"SCS_SAT\" .emit OP_SCS_SAT;\n"
-"vp_SCALARop\n"
-" \"EX2\" .emit OP_EX2 .or\n"
-" \"EXP\" .emit OP_EXP .or\n"
-" \"LG2\" .emit OP_LG2 .or\n"
-" \"LOG\" .emit OP_LOG .or\n"
-" \"RCP\" .emit OP_RCP .or\n"
-" \"RSQ\" .emit OP_RSQ;\n"
-"fp_BINSCop_instruction\n"
-" fp_BINSCop .and space_dst .and fp_maskedDstReg .and comma .and fp_scalarSrcReg .and comma .and\n"
-" fp_scalarSrcReg;\n"
-"vp_BINSCop_instruction\n"
-" vp_BINSCop .and space_dst .and vp_maskedDstReg .and comma .and vp_scalarSrcReg .and comma .and\n"
-" vp_scalarSrcReg;\n"
-"fp_BINSCop\n"
-" \"POW\" .emit OP_POW .or \"POW_SAT\" .emit OP_POW_SAT;\n"
-"vp_BINSCop\n"
-" \"POW\" .emit OP_POW;\n"
-"fp_BINop_instruction\n"
-" fp_BINop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
-" vectorSrcReg;\n"
-"vp_BINop_instruction\n"
-" vp_BINop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"
-" swizzleSrcReg;\n"
-"fp_BINop\n"
-" \"ADD\" .emit OP_ADD .or \"ADD_SAT\" .emit OP_ADD_SAT .or\n"
-" \"DP3\" .emit OP_DP3 .or \"DP3_SAT\" .emit OP_DP3_SAT .or\n"
-" \"DP4\" .emit OP_DP4 .or \"DP4_SAT\" .emit OP_DP4_SAT .or\n"
-" \"DPH\" .emit OP_DPH .or \"DPH_SAT\" .emit OP_DPH_SAT .or\n"
-" \"DST\" .emit OP_DST .or \"DST_SAT\" .emit OP_DST_SAT .or\n"
-" \"MAX\" .emit OP_MAX .or \"MAX_SAT\" .emit OP_MAX_SAT .or\n"
-" \"MIN\" .emit OP_MIN .or \"MIN_SAT\" .emit OP_MIN_SAT .or\n"
-" \"MUL\" .emit OP_MUL .or \"MUL_SAT\" .emit OP_MUL_SAT .or\n"
-" \"SGE\" .emit OP_SGE .or \"SGE_SAT\" .emit OP_SGE_SAT .or\n"
-" \"SLT\" .emit OP_SLT .or \"SLT_SAT\" .emit OP_SLT_SAT .or\n"
-" \"SUB\" .emit OP_SUB .or \"SUB_SAT\" .emit OP_SUB_SAT .or\n"
-" \"XPD\" .emit OP_XPD .or \"XPD_SAT\" .emit OP_XPD_SAT;\n"
-"vp_BINop\n"
-" \"ADD\" .emit OP_ADD .or\n"
-" \"DP3\" .emit OP_DP3 .or\n"
-" \"DP4\" .emit OP_DP4 .or\n"
-" \"DPH\" .emit OP_DPH .or\n"
-" \"DST\" .emit OP_DST .or\n"
-" \"MAX\" .emit OP_MAX .or\n"
-" \"MIN\" .emit OP_MIN .or\n"
-" \"MUL\" .emit OP_MUL .or\n"
-" \"SGE\" .emit OP_SGE .or\n"
-" \"SLT\" .emit OP_SLT .or\n"
-" \"SUB\" .emit OP_SUB .or\n"
-" \"XPD\" .emit OP_XPD;\n"
-"fp_TRIop_instruction\n"
-" fp_TRIop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
-" vectorSrcReg .and comma .and vectorSrcReg;\n"
-"vp_TRIop_instruction\n"
-" vp_TRIop .and space_dst .and vp_maskedDstReg .and comma .and swizzleSrcReg .and comma .and\n"
-" swizzleSrcReg .and comma .and swizzleSrcReg;\n"
-"fp_TRIop\n"
-" \"CMP\" .emit OP_CMP .or \"CMP_SAT\" .emit OP_CMP_SAT .or\n"
-" \"LRP\" .emit OP_LRP .or \"LRP_SAT\" .emit OP_LRP_SAT .or\n"
-" \"MAD\" .emit OP_MAD .or \"MAD_SAT\" .emit OP_MAD_SAT;\n"
-"vp_TRIop\n"
-" \"MAD\" .emit OP_MAD;\n"
-"fp_SWZ_instruction\n"
-" SWZop .and space_dst .and fp_maskedDstReg .and comma .and fp_srcReg .and comma .and\n"
-" fp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"
-"vp_SWZ_instruction\n"
-" \"SWZ\" .emit OP_SWZ .and space_dst .and vp_maskedDstReg .and comma .and vp_srcReg .and comma .and\n"
-" vp_extendedSwizzle .error EXT_SWIZ_COMP_EXPECTED;\n"
-"SWZop\n"
-" \"SWZ\" .emit OP_SWZ .or \"SWZ_SAT\" .emit OP_SWZ_SAT;\n"
-"SAMPLE_instruction\n"
-" SAMPLEop .and space_dst .and fp_maskedDstReg .and comma .and vectorSrcReg .and comma .and\n"
-" texImageUnit .and comma .and texTarget .error TEX_TARGET_EXPECTED;\n"
-"SAMPLEop\n"
-" \"TEX\" .emit OP_TEX .or \"TEX_SAT\" .emit OP_TEX_SAT .or\n"
-" \"TXB\" .emit OP_TXB .or \"TXB_SAT\" .emit OP_TXB_SAT .or\n"
-" \"TXP\" .emit OP_TXP .or \"TXP_SAT\" .emit OP_TXP_SAT;\n"
-"KIL_instruction\n"
-" \"KIL\" .emit OP_KIL .and space_src .and vectorSrcReg;\n"
-"texImageUnit\n"
-" \"texture\" .error TEXTURE_EXPECTED .and optTexImageUnitNum;\n"
-"texTarget\n"
-" \"1D\" .emit TEXTARGET_1D .or\n"
-" \"2D\" .emit TEXTARGET_2D .or\n"
-" \"3D\" .emit TEXTARGET_3D .or\n"
-" .if (texture_rectangle != 0x00) \"RECT\" .emit TEXTARGET_RECT .or\n"
-" \"CUBE\" .emit TEXTARGET_CUBE .or\n"
-" .if (ARB_fragment_program_shadow != 0x00) shadowTarget .or\n"
-" .if (MESA_texture_array != 0x00) arrayTarget;\n"
-"shadowTarget\n"
-" \"SHADOW1D\" .emit TEXTARGET_SHADOW1D .or\n"
-" \"SHADOW2D\" .emit TEXTARGET_SHADOW2D .or\n"
-" .if (texture_rectangle != 0x00) \"SHADOWRECT\" .emit TEXTARGET_SHADOWRECT .or\n"
-" .if (MESA_texture_array != 0x00) shadowArrayTarget;\n"
-"arrayTarget\n"
-" \"ARRAY1D\" .emit TEXTARGET_1D_ARRAY .or\n"
-" \"ARRAY2D\" .emit TEXTARGET_2D_ARRAY;\n"
-"shadowArrayTarget\n"
-" \"SHADOWARRAY1D\" .emit TEXTARGET_SHADOW1D_ARRAY .or\n"
-" \"SHADOWARRAY2D\" .emit TEXTARGET_SHADOW2D_ARRAY;\n"
-"optTexImageUnitNum\n"
-" optTexImageUnitNum_1 .or .true .emit 0x00;\n"
-"optTexImageUnitNum_1\n"
-" lbracket_ne .and texImageUnitNum .and rbracket;\n"
-"texImageUnitNum\n"
-" integer;\n"
-"fp_scalarSrcReg\n"
-" optionalSign .and fp_srcReg .and fp_scalarSuffix;\n"
-"vp_scalarSrcReg\n"
-" optionalSign .and vp_srcReg .and vp_scalarSuffix;\n"
-"swizzleSrcReg\n"
-" optionalSign .and vp_srcReg .and swizzleSuffix;\n"
-"vectorSrcReg\n"
-" optionalSign .and fp_srcReg .and optionalSuffix;\n"
-"fp_maskedDstReg\n"
-" fp_dstReg .and fp_optionalMask;\n"
-"vp_maskedDstReg\n"
-" vp_dstReg .and vp_optionalMask;\n"
-"maskedAddrReg\n"
-" addrReg .error ADDRESS_REGISTER_EXPECTED .and addrWriteMask;\n"
-"fp_extendedSwizzle\n"
-" rgbaExtendedSwizzle .or xyzwExtendedSwizzle;\n"
-"vp_extendedSwizzle\n"
-" extSwizComp .and comma .and\n"
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" extSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
-"xyzwExtendedSwizzle\n"
-" xyzwExtSwizComp .and comma .and\n"
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" xyzwExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
-"rgbaExtendedSwizzle\n"
-" rgbaExtendedSwizzle_1 .or rgbaExtendedSwizzle_2 .or rgbaExtendedSwizzle_3 .or\n"
-" rgbaExtendedSwizzle_4;\n"
-"rgbaExtendedSwizzle_1\n"
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp;\n"
-"rgbaExtendedSwizzle_2\n"
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_digit .and comma .and\n"
-" rgbaExtSwizComp_alpha .and comma .and rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
-"rgbaExtendedSwizzle_3\n"
-" rgbaExtSwizComp_digit .and comma .and rgbaExtSwizComp_alpha .and comma .and\n"
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
-"rgbaExtendedSwizzle_4\n"
-" rgbaExtSwizComp_alpha .and comma .and \n"
-"rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED .and comma .and\n"
-" rgbaExtSwizComp .error EXT_SWIZ_COMP_EXPECTED;\n"
-"xyzwExtSwizComp\n"
-" optionalSign .and xyzwExtSwizSel;\n"
-"rgbaExtSwizComp\n"
-" optionalSign .and rgbaExtSwizSel;\n"
-"rgbaExtSwizComp_digit\n"
-" optionalSign .and rgbaExtSwizSel_digit;\n"
-"rgbaExtSwizComp_alpha\n"
-" optionalSign .and rgbaExtSwizSel_alpha;\n"
-"extSwizComp\n"
-" optionalSign .and extSwizSel;\n"
-"xyzwExtSwizSel\n"
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or xyzwComponent_single;\n"
-"rgbaExtSwizSel\n"
-" rgbaExtSwizSel_digit .or rgbaExtSwizSel_alpha;\n"
-"rgbaExtSwizSel_digit\n"
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1;\n"
-"rgbaExtSwizSel_alpha\n"
-" rgbaComponent_single;\n"
-"extSwizSel\n"
-" \"0\" .emit COMPONENT_0 .or \"1\" .emit COMPONENT_1 .or vp_component_single;\n"
-"fp_srcReg\n"
-" fp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"
-"vp_srcReg\n"
-" vp_srcReg_1 .error SOURCE_REGISTER_EXPECTED;\n"
-"fp_srcReg_1\n"
-" fragmentAttribReg .emit REGISTER_ATTRIB .or\n"
-" fp_progParamReg .emit REGISTER_PARAM .or\n"
-" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
-"vp_srcReg_1\n"
-" vertexAttribReg .emit REGISTER_ATTRIB .or\n"
-" vp_progParamReg .emit REGISTER_PARAM .or\n"
-" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
-"fp_dstReg\n"
-" fp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"
-"vp_dstReg\n"
-" vp_dstReg_1 .error DESTINATION_REGISTER_EXPECTED;\n"
-"fp_dstReg_1\n"
-" fragmentResultReg .emit REGISTER_RESULT .or\n"
-" fp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
-"vp_dstReg_1\n"
-" vertexResultReg .emit REGISTER_RESULT .or\n"
-" vp_temporaryReg .emit REGISTER_ESTABLISHED_NAME;\n"
-"fragmentAttribReg\n"
-" fragAttribBinding;\n"
-"vertexAttribReg\n"
-" vtxAttribBinding;\n"
-"fp_temporaryReg\n"
-" fp_establishedName_no_error_on_identifier;\n"
-"vp_temporaryReg\n"
-" vp_establishedName_no_error_on_identifier;\n"
-"fp_progParamReg\n"
-" fp_paramSingleItemUse .or fp_progParamReg_1 .or fp_progParamSingle;\n"
-"vp_progParamReg\n"
-" vp_paramSingleItemUse .or vp_progParamReg_1 .or vp_progParamSingle;\n"
-"fp_progParamReg_1\n"
-" fp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayAbs .and\n"
-" rbracket;\n"
-"vp_progParamReg_1\n"
-" vp_progParamArray .emit PARAM_ARRAY_ELEMENT .and lbracket_ne .and progParamArrayMem .and\n"
-" rbracket;\n"
-"fp_progParamSingle\n"
-" .false;\n"
-"vp_progParamSingle\n"
-" .false;\n"
-"fp_progParamArray\n"
-" fp_establishedName_no_error_on_identifier;\n"
-"vp_progParamArray\n"
-" vp_establishedName_no_error_on_identifier;\n"
-"progParamArrayMem\n"
-" progParamArrayAbs .or progParamArrayRel;\n"
-"progParamArrayAbs\n"
-" integer_ne .emit ARRAY_INDEX_ABSOLUTE;\n"
-"progParamArrayRel\n"
-" addrReg .error ADDRESS_REGISTER_OR_INTEGER_EXPECTED .emit ARRAY_INDEX_RELATIVE .and\n"
-" addrComponent .and addrRegRelOffset;\n"
-"addrRegRelOffset\n"
-" addrRegRelOffset_1 .or addrRegRelOffset_2 .or .true .emit 0x00;\n"
-"addrRegRelOffset_1\n"
-" plus_ne .and addrRegPosOffset;\n"
-"addrRegRelOffset_2\n"
-" minus_ne .and addrRegNegOffset;\n"
-"addrRegPosOffset\n"
-" integer_0_63;\n"
-"addrRegNegOffset\n"
-" integer_0_64;\n"
-"fragmentResultReg\n"
-" fp_resultBinding;\n"
-"vertexResultReg\n"
-" vp_resultBinding;\n"
-"addrReg\n"
-" vp_establishedName_no_error_on_identifier;\n"
-"addrComponent\n"
-" dot .and \"x\" .error INVALID_ADDRESS_COMPONENT .emit COMPONENT_X .emit COMPONENT_X\n"
-" .emit COMPONENT_X .emit COMPONENT_X;\n"
-"addrWriteMask\n"
-" dot .and \"x\" .error INVALID_ADDRESS_WRITEMASK .emit 0x08;\n"
-"fp_scalarSuffix\n"
-" dot .and fp_component_single .error INVALID_COMPONENT;\n"
-"vp_scalarSuffix\n"
-" dot .and vp_component_single .error INVALID_COMPONENT;\n"
-"swizzleSuffix\n"
-" swizzleSuffix_1 .or\n"
-" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"
-"swizzleSuffix_1\n"
-" dot_ne .and swizzleSuffix_2 .error INVALID_SUFFIX;\n"
-"swizzleSuffix_2\n"
-" swizzleSuffix_3 .or swizzleSuffix_4;\n"
-"swizzleSuffix_3\n"
-" vp_component_multi .and vp_component_multi .and vp_component_multi .error INVALID_COMPONENT .and\n"
-" vp_component_multi .error INVALID_COMPONENT;\n"
-"swizzleSuffix_4\n"
-" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
-" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
-" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
-" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"
-"optionalSuffix\n"
-" optionalSuffix_1 .or\n"
-" .true .emit COMPONENT_X .emit COMPONENT_Y .emit COMPONENT_Z .emit COMPONENT_W;\n"
-"optionalSuffix_1\n"
-" dot_ne .and optionalSuffix_2 .error INVALID_SUFFIX;\n"
-"optionalSuffix_2\n"
-" optionalSuffix_3 .or optionalSuffix_4 .or optionalSuffix_5;\n"
-"optionalSuffix_3\n"
-" xyzwComponent_multi .and xyzwComponent_multi .and\n"
-" xyzwComponent_multi .error INVALID_COMPONENT .and xyzwComponent_multi .error INVALID_COMPONENT;\n"
-"optionalSuffix_4\n"
-" rgbaComponent_multi .and rgbaComponent_multi .and\n"
-" rgbaComponent_multi .error INVALID_COMPONENT .and rgbaComponent_multi .error INVALID_COMPONENT;\n"
-"optionalSuffix_5\n"
-" \"x\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
-" \"y\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
-" \"z\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
-" \"w\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .or\n"
-" \"r\" .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .emit COMPONENT_X .or\n"
-" \"g\" .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .emit COMPONENT_Y .or\n"
-" \"b\" .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .emit COMPONENT_Z .or\n"
-" \"a\" .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W .emit COMPONENT_W;\n"
-"fp_component_single\n"
-" xyzwComponent_single .or rgbaComponent_single;\n"
-"vp_component_multi\n"
-" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"
-" 'w' .emit COMPONENT_W;\n"
-"vp_component_single\n"
-" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"
-" \"w\" .emit COMPONENT_W;\n"
-"xyzwComponent_multi\n"
-" 'x' .emit COMPONENT_X .or 'y' .emit COMPONENT_Y .or 'z' .emit COMPONENT_Z .or\n"
-" 'w' .emit COMPONENT_W;\n"
-"xyzwComponent_single\n"
-" \"x\" .emit COMPONENT_X .or \"y\" .emit COMPONENT_Y .or \"z\" .emit COMPONENT_Z .or\n"
-" \"w\" .emit COMPONENT_W;\n"
-"rgbaComponent_multi\n"
-" 'r' .emit COMPONENT_X .or 'g' .emit COMPONENT_Y .or 'b' .emit COMPONENT_Z .or\n"
-" 'a' .emit COMPONENT_W;\n"
-"rgbaComponent_single\n"
-" \"r\" .emit COMPONENT_X .or \"g\" .emit COMPONENT_Y .or \"b\" .emit COMPONENT_Z .or\n"
-" \"a\" .emit COMPONENT_W;\n"
-"fp_optionalMask\n"
-" rgbaMask .or xyzwMask .or .true .emit 0x0F;\n"
-"vp_optionalMask\n"
-" xyzwMask .or .true .emit 0x0F;\n"
-"xyzwMask\n"
-" dot_ne .and xyzwMask_1 .error INVALID_WRITEMASK;\n"
-"xyzwMask_1\n"
-" \"xyzw\" .emit 0x0F .or \"xyz\" .emit 0x0E .or \"xyw\" .emit 0x0D .or \"xy\" .emit 0x0C .or\n"
-" \"xzw\" .emit 0x0B .or \"xz\" .emit 0x0A .or \"xw\" .emit 0x09 .or \"x\" .emit 0x08 .or\n"
-" \"yzw\" .emit 0x07 .or \"yz\" .emit 0x06 .or \"yw\" .emit 0x05 .or \"y\" .emit 0x04 .or\n"
-" \"zw\" .emit 0x03 .or \"z\" .emit 0x02 .or \"w\" .emit 0x01;\n"
-"rgbaMask\n"
-" dot_ne .and rgbaMask_1;\n"
-"rgbaMask_1\n"
-" \"rgba\" .emit 0x0F .or \"rgb\" .emit 0x0E .or \"rga\" .emit 0x0D .or \"rg\" .emit 0x0C .or\n"
-" \"rba\" .emit 0x0B .or \"rb\" .emit 0x0A .or \"ra\" .emit 0x09 .or \"r\" .emit 0x08 .or\n"
-" \"gba\" .emit 0x07 .or \"gb\" .emit 0x06 .or \"ga\" .emit 0x05 .or \"g\" .emit 0x04 .or\n"
-" \"ba\" .emit 0x03 .or \"b\" .emit 0x02 .or \"a\" .emit 0x01;\n"
-"fp_namingStatement\n"
-" fp_ATTRIB_statement .emit ATTRIB .or\n"
-" fp_PARAM_statement .emit PARAM .or\n"
-" fp_TEMP_statement .emit TEMP .or\n"
-" fp_OUTPUT_statement .emit OUTPUT .or\n"
-" fp_ALIAS_statement .emit ALIAS;\n"
-"vp_namingStatement\n"
-" vp_ATTRIB_statement .emit ATTRIB .or\n"
-" vp_PARAM_statement .emit PARAM .or\n"
-" vp_TEMP_statement .emit TEMP .or\n"
-" ADDRESS_statement .emit ADDRESS .or\n"
-" vp_OUTPUT_statement .emit OUTPUT .or\n"
-" vp_ALIAS_statement .emit ALIAS;\n"
-"fp_ATTRIB_statement\n"
-" \"ATTRIB\" .and space .and fp_establishName .and equal .and\n"
-" fragAttribBinding .error FRAGMENT_EXPECTED;\n"
-"vp_ATTRIB_statement\n"
-" \"ATTRIB\" .and space .and vp_establishName .and equal .and\n"
-" vtxAttribBinding .error VERTEX_EXPECTED;\n"
-"fragAttribBinding\n"
-" \"fragment\" .and dot .and fragAttribItem .error INVALID_FRAGMENT_PROPERTY;\n"
-"vtxAttribBinding\n"
-" \"vertex\" .and dot .and vtxAttribItem .error INVALID_VERTEX_PROPERTY;\n"
-"fragAttribItem\n"
-" fragAttribItem_1 .emit FRAGMENT_ATTRIB_COLOR .or\n"
-" fragAttribItem_2 .emit FRAGMENT_ATTRIB_TEXCOORD .or\n"
-" .if (fog_coord != 0x00) \"fogcoord\" .emit FRAGMENT_ATTRIB_FOGCOORD .or\n"
-" \"position\" .emit FRAGMENT_ATTRIB_POSITION;\n"
-"fragAttribItem_1\n"
-" \"color\" .and optColorType;\n"
-"fragAttribItem_2\n"
-" \"texcoord\" .and optTexCoordNum;\n"
-"vtxAttribItem\n"
-" \"position\" .emit VERTEX_ATTRIB_POSITION .or\n"
-" .if (vertex_blend != 0x00) vtxAttribItem_1 .emit VERTEX_ATTRIB_WEIGHT .or\n"
-" \"normal\" .emit VERTEX_ATTRIB_NORMAL .or\n"
-" vtxAttribItem_2 .emit VERTEX_ATTRIB_COLOR .or\n"
-" \"fogcoord\" .emit VERTEX_ATTRIB_FOGCOORD .or\n"
-" vtxAttribItem_3 .emit VERTEX_ATTRIB_TEXCOORD .or\n"
-" .if (matrix_palette != 0x00) vtxAttribItem_4 .emit VERTEX_ATTRIB_MATRIXINDEX .or\n"
-" vtxAttribItem_5 .emit VERTEX_ATTRIB_GENERIC;\n"
-"vtxAttribItem_1\n"
-" \"weight\" .and vtxOptWeightNum;\n"
-"vtxAttribItem_2\n"
-" \"color\" .and optColorType;\n"
-"vtxAttribItem_3\n"
-" \"texcoord\" .and optTexCoordNum;\n"
-"vtxAttribItem_4\n"
-" \"matrixindex\" .and lbracket .and vtxWeightNum .and rbracket;\n"
-"vtxAttribItem_5\n"
-" \"attrib\" .and lbracket .and vtxAttribNum .and rbracket;\n"
-"vtxAttribNum\n"
-" integer;\n"
-"vtxOptWeightNum\n"
-" vtxOptWeightNum_1 .or .true .emit 0x00;\n"
-"vtxOptWeightNum_1\n"
-" lbracket_ne .and vtxWeightNum .and rbracket;\n"
-"vtxWeightNum\n"
-" integer;\n"
-"fp_PARAM_statement\n"
-" fp_PARAM_multipleStmt .or fp_PARAM_singleStmt;\n"
-"vp_PARAM_statement\n"
-" vp_PARAM_multipleStmt .or vp_PARAM_singleStmt;\n"
-"fp_PARAM_singleStmt\n"
-" \"PARAM\" .and space .and fp_establishName .and .true .emit 0x00 .and fp_paramSingleInit .and\n"
-" .true .emit PARAM_NULL;\n"
-"vp_PARAM_singleStmt\n"
-" \"PARAM\" .and space .and vp_establishName .and .true .emit 0x00 .and vp_paramSingleInit .and\n"
-" .true .emit PARAM_NULL;\n"
-"fp_PARAM_multipleStmt\n"
-" \"PARAM\" .and space .and fp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"
-" fp_paramMultipleInit .and .true .emit PARAM_NULL;\n"
-"vp_PARAM_multipleStmt\n"
-" \"PARAM\" .and space .and vp_establishName .and lbracket_ne .and optArraySize .and rbracket .and\n"
-" vp_paramMultipleInit .and .true .emit PARAM_NULL;\n"
-"optArraySize\n"
-" optional_integer;\n"
-"fp_paramSingleInit\n"
-" equal .and fp_paramSingleItemDecl;\n"
-"vp_paramSingleInit\n"
-" equal .and vp_paramSingleItemDecl;\n"
-"fp_paramMultipleInit\n"
-" equal .and lbrace .and fp_paramMultInitList .and rbrace;\n"
-"vp_paramMultipleInit\n"
-" equal .and lbrace .and vp_paramMultInitList .and rbrace;\n"
-"fp_paramMultInitList\n"
-" fp_paramMultInitList_1 .or fp_paramMultipleItem;\n"
-"vp_paramMultInitList\n"
-" vp_paramMultInitList_1 .or vp_paramMultipleItem;\n"
-"fp_paramMultInitList_1\n"
-" fp_paramMultipleItem .and comma_ne .and fp_paramMultInitList;\n"
-"vp_paramMultInitList_1\n"
-" vp_paramMultipleItem .and comma_ne .and vp_paramMultInitList;\n"
-"fp_paramSingleItemDecl\n"
-" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstDecl .emit PARAM_CONSTANT;\n"
-"vp_paramSingleItemDecl\n"
-" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstDecl .emit PARAM_CONSTANT;\n"
-"fp_paramSingleItemUse\n"
-" fp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstUse .emit PARAM_CONSTANT;\n"
-"vp_paramSingleItemUse\n"
-" vp_stateSingleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programSingleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstUse .emit PARAM_CONSTANT;\n"
-"fp_paramMultipleItem\n"
-" fp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstDecl .emit PARAM_CONSTANT;\n"
-"vp_paramMultipleItem\n"
-" vp_stateMultipleItem .emit PARAM_STATE_ELEMENT .or\n"
-" programMultipleItem .emit PARAM_PROGRAM_ELEMENT .or\n"
-" paramConstDecl .emit PARAM_CONSTANT;\n"
-"fp_stateMultipleItem\n"
-" stateMultipleItem_1 .or fp_stateSingleItem;\n"
-"vp_stateMultipleItem\n"
-" stateMultipleItem_1 .or vp_stateSingleItem;\n"
-"stateMultipleItem_1\n"
-" \"state\" .and dot .and stateMatrixRows .emit STATE_MATRIX_ROWS;\n"
-"fp_stateSingleItem\n"
-" \"state\" .and dot .and fp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"
-"vp_stateSingleItem\n"
-" \"state\" .and dot .and vp_stateSingleItem_1 .error INVALID_STATE_PROPERTY;\n"
-"fp_stateSingleItem_1\n"
-" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"
-" stateSingleItem_5 .or stateSingleItem_7 .or stateSingleItem_8 .or stateSingleItem_11;\n"
-"vp_stateSingleItem_1\n"
-" stateSingleItem_1 .or stateSingleItem_2 .or stateSingleItem_3 .or stateSingleItem_4 .or\n"
-" stateSingleItem_6 .or stateSingleItem_7 .or stateSingleItem_9 .or stateSingleItem_10 .or\n"
-" stateSingleItem_11;\n"
-"stateSingleItem_1\n"
-" stateMaterialItem .emit STATE_MATERIAL;\n"
-"stateSingleItem_2\n"
-" stateLightItem .emit STATE_LIGHT;\n"
-"stateSingleItem_3\n"
-" stateLightModelItem .emit STATE_LIGHT_MODEL;\n"
-"stateSingleItem_4\n"
-" stateLightProdItem .emit STATE_LIGHT_PROD;\n"
-"stateSingleItem_5\n"
-" stateTexEnvItem .emit STATE_TEX_ENV;\n"
-"stateSingleItem_6\n"
-" stateTexGenItem .emit STATE_TEX_GEN;\n"
-"stateSingleItem_7\n"
-" stateFogItem .emit STATE_FOG;\n"
-"stateSingleItem_8\n"
-" stateDepthItem .emit STATE_DEPTH;\n"
-"stateSingleItem_9\n"
-" stateClipPlaneItem .emit STATE_CLIP_PLANE;\n"
-"stateSingleItem_10\n"
-" statePointItem .emit STATE_POINT;\n"
-"stateSingleItem_11\n"
-" stateMatrixRow .emit STATE_MATRIX_ROWS;\n"
-"stateMaterialItem\n"
-" \"material\" .and optFaceType .and dot .and stateMatProperty .error INVALID_MATERIAL_PROPERTY;\n"
-"stateMatProperty\n"
-" \"ambient\" .emit MATERIAL_AMBIENT .or\n"
-" \"diffuse\" .emit MATERIAL_DIFFUSE .or\n"
-" \"specular\" .emit MATERIAL_SPECULAR .or\n"
-" \"emission\" .emit MATERIAL_EMISSION .or\n"
-" \"shininess\" .emit MATERIAL_SHININESS;\n"
-"stateLightItem\n"
-" \"light\" .and lbracket .and stateLightNumber .and rbracket .and dot .and\n"
-" stateLightProperty .error INVALID_LIGHT_PROPERTY;\n"
-"stateLightProperty\n"
-" \"ambient\" .emit LIGHT_AMBIENT .or\n"
-" \"diffuse\" .emit LIGHT_DIFFUSE .or\n"
-" \"specular\" .emit LIGHT_SPECULAR .or\n"
-" \"position\" .emit LIGHT_POSITION .or\n"
-" \"attenuation\" .emit LIGHT_ATTENUATION .or\n"
-" stateLightProperty_1 .emit LIGHT_SPOT_DIRECTION .or\n"
-" \"half\" .emit LIGHT_HALF;\n"
-"stateLightProperty_1\n"
-" \"spot\" .and dot .and stateSpotProperty .error INVALID_SPOT_PROPERTY;\n"
-"stateSpotProperty\n"
-" \"direction\";\n"
-"stateLightModelItem\n"
-" \"lightmodel\" .and stateLModProperty .error INVALID_LIGHTMODEL_PROPERTY;\n"
-"stateLModProperty\n"
-" stateLModProperty_1 .or stateLModProperty_2;\n"
-"stateLModProperty_1\n"
-" dot .and \"ambient\" .emit LIGHT_MODEL_AMBIENT;\n"
-"stateLModProperty_2\n"
-" stateLModProperty_3 .emit LIGHT_MODEL_SCENECOLOR;\n"
-"stateLModProperty_3\n"
-" optFaceType .and dot .and \"scenecolor\";\n"
-"stateLightProdItem\n"
-" \"lightprod\" .and lbracket .and stateLightNumber .and rbracket .and optFaceType .and dot .and\n"
-" stateLProdProperty .error INVALID_LIGHTPROD_PROPERTY;\n"
-"stateLProdProperty\n"
-" \"ambient\" .emit LIGHT_PROD_AMBIENT .or\n"
-" \"diffuse\" .emit LIGHT_PROD_DIFFUSE .or\n"
-" \"specular\" .emit LIGHT_PROD_SPECULAR;\n"
-"stateLightNumber\n"
-" integer;\n"
-"stateTexEnvItem\n"
-" \"texenv\" .and optLegacyTexUnitNum .and dot .and\n"
-" stateTexEnvProperty .error INVALID_TEXENV_PROPERTY;\n"
-"stateTexEnvProperty\n"
-" \"color\" .emit TEX_ENV_COLOR;\n"
-"optLegacyTexUnitNum\n"
-" optLegacyTexUnitNum_1 .or .true .emit 0x00;\n"
-"optLegacyTexUnitNum_1\n"
-" lbracket_ne .and legacyTexUnitNum .and rbracket;\n"
-"legacyTexUnitNum\n"
-" integer;\n"
-"stateTexGenItem\n"
-" \"texgen\" .and optTexCoordNum .and dot .and stateTexGenType .error INVALID_TEXGEN_PROPERTY .and\n"
-" dot .and stateTexGenCoord .error INVALID_TEXGEN_COORD;\n"
-"stateTexGenType\n"
-" \"eye\" .emit TEX_GEN_EYE .or\n"
-" \"object\" .emit TEX_GEN_OBJECT;\n"
-"stateTexGenCoord\n"
-" \"s\" .emit COMPONENT_X .or\n"
-" \"t\" .emit COMPONENT_Y .or\n"
-" \"r\" .emit COMPONENT_Z .or\n"
-" \"q\" .emit COMPONENT_W;\n"
-"stateFogItem\n"
-" \"fog\" .and dot .and stateFogProperty .error INVALID_FOG_PROPERTY;\n"
-"stateFogProperty\n"
-" \"color\" .emit FOG_COLOR .or\n"
-" \"params\" .emit FOG_PARAMS;\n"
-"stateDepthItem\n"
-" \"depth\" .and dot .and stateDepthProperty .error INVALID_DEPTH_PROPERTY;\n"
-"stateDepthProperty\n"
-" \"range\" .emit DEPTH_RANGE;\n"
-"stateClipPlaneItem\n"
-" \"clip\" .and lbracket .and stateClipPlaneNum .and rbracket .and dot .and\n"
-" \"plane\" .error INVALID_CLIPPLANE_PROPERTY;\n"
-"stateClipPlaneNum\n"
-" integer;\n"
-"statePointItem\n"
-" \"point\" .and dot .and statePointProperty .error INVALID_POINT_PROPERTY;\n"
-"statePointProperty\n"
-" \"size\" .emit POINT_SIZE .or\n"
-" .if (point_parameters != 0x00) \"attenuation\" .emit POINT_ATTENUATION;\n"
-"stateMatrixRow\n"
-" stateMatrixItem .and dot .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and\n"
-" lbracket .and stateMatrixRowNum .and rbracket .emit 0x0;\n"
-"stateMatrixRows\n"
-" stateMatrixItem .and optMatrixRows;\n"
-"optMatrixRows\n"
-" optMatrixRows_1 .or .true .emit 0x0 .emit '3' .emit 0x0 .emit $;\n"
-"optMatrixRows_1\n"
-" dot_ne .and \"row\" .error MATRIX_ROW_SELECTOR_OR_MODIFIER_EXPECTED .and lbracket .and\n"
-" stateMatrixRowNum .and dotdot .and stateMatrixRowNum .and rbracket;\n"
-"stateMatrixItem\n"
-" \"matrix\" .and dot .and stateMatrixName .error INVALID_MATRIX_NAME .and stateOptMatModifier;\n"
-"stateOptMatModifier\n"
-" stateOptMatModifier_1 .or .true .emit MATRIX_MODIFIER_IDENTITY;\n"
-"stateOptMatModifier_1\n"
-" dot_ne .and stateMatModifier;\n"
-"stateMatModifier\n"
-" \"inverse\" .emit MATRIX_MODIFIER_INVERSE .or\n"
-" \"transpose\" .emit MATRIX_MODIFIER_TRANSPOSE .or\n"
-" \"invtrans\" .emit MATRIX_MODIFIER_INVTRANS;\n"
-"stateMatrixRowNum\n"
-" integer_0_3;\n"
-"stateMatrixName\n"
-" stateMatrixName_1_1 .emit MATRIX_MODELVIEW .or\n"
-" \"projection\" .emit MATRIX_PROJECTION .or\n"
-" \"mvp\" .emit MATRIX_MVP .or\n"
-" stateMatrixName_1_2 .emit MATRIX_TEXTURE .or\n"
-" .if (matrix_palette != 0x00) stateMatrixName_1_3 .emit MATRIX_PALETTE .or\n"
-" stateMatrixName_1_4 .emit MATRIX_PROGRAM;\n"
-"stateMatrixName_1_1\n"
-" \"modelview\" .and stateOptModMatNum;\n"
-"stateMatrixName_1_2\n"
-" \"texture\" .and optTexCoordNum;\n"
-"stateMatrixName_1_3\n"
-" \"palette\" .and lbracket .and statePaletteMatNum .and rbracket;\n"
-"stateMatrixName_1_4\n"
-" \"program\" .and lbracket .and stateProgramMatNum .and rbracket;\n"
-"stateOptModMatNum\n"
-" .if (vertex_blend != 0x00) stateOptModMatNum_1 .or\n"
-" .true .emit 0x00;\n"
-"stateOptModMatNum_1\n"
-" lbracket_ne .and stateModMatNum .and rbracket;\n"
-"stateModMatNum\n"
-" integer;\n"
-"optTexCoordNum\n"
-" optTexCoordNum_1 .or .true .emit 0x00;\n"
-"optTexCoordNum_1\n"
-" lbracket_ne .and texCoordNum .and rbracket;\n"
-"texCoordNum\n"
-" integer;\n"
-"statePaletteMatNum\n"
-" integer;\n"
-"stateProgramMatNum\n"
-" integer;\n"
-"programSingleItem\n"
-" \"program\" .and dot .and programSingleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"
-"programSingleItem_1\n"
-" progEnvParam .or progLocalParam;\n"
-"programMultipleItem\n"
-" \"program\" .and dot .and programMultipleItem_1 .error INVALID_PROGRAM_PROPERTY;\n"
-"programMultipleItem_1\n"
-" progEnvParams .or progLocalParams;\n"
-"progEnvParams\n"
-" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNums .and rbracket;\n"
-"progEnvParamNums\n"
-" progEnvParamNums_1 .or progEnvParamNums_2;\n"
-"progEnvParamNums_1\n"
-" progEnvParamNum .and dotdot_ne .and progEnvParamNum;\n"
-"progEnvParamNums_2\n"
-" progEnvParamNum .and .true .emit 0x00;\n"
-"progEnvParam\n"
-" \"env\" .emit PROGRAM_PARAM_ENV .and lbracket .and progEnvParamNum .and rbracket .emit 0x00;\n"
-"progLocalParams\n"
-" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNums .and rbracket;\n"
-"progLocalParamNums\n"
-" progLocalParamNums_1 .or progLocalParamNums_2;\n"
-"progLocalParamNums_1\n"
-" progLocalParamNum .and dotdot_ne .and progLocalParamNum;\n"
-"progLocalParamNums_2\n"
-" progLocalParamNum .and .true .emit 0x00;\n"
-"progLocalParam\n"
-" \"local\" .emit PROGRAM_PARAM_LOCAL .and lbracket .and progLocalParamNum .and rbracket .emit 0x00;\n"
-"progEnvParamNum\n"
-" integer;\n"
-"progLocalParamNum\n"
-" integer;\n"
-"paramConstDecl\n"
-" paramConstScalarDecl .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"
-"paramConstUse\n"
-" paramConstScalarUse .emit CONSTANT_SCALAR .or paramConstVector .emit CONSTANT_VECTOR;\n"
-"paramConstScalarDecl\n"
-" signedFloatConstant;\n"
-"paramConstScalarUse\n"
-" floatConstant;\n"
-"paramConstVector\n"
-" paramConstVector_4 .emit 0x04 .or paramConstVector_3 .emit 0x03 .or\n"
-" paramConstVector_2 .emit 0x02 .or paramConstVector_1 .emit 0x01;\n"
-"paramConstVector_1\n"
-" lbrace_ne .and signedFloatConstant .and rbrace;\n"
-"paramConstVector_2\n"
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"
-"paramConstVector_3\n"
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"
-" signedFloatConstant .and rbrace;\n"
-"paramConstVector_4\n"
-" lbrace_ne .and signedFloatConstant .and comma_ne .and signedFloatConstant .and comma_ne .and\n"
-" signedFloatConstant .and comma_ne .and signedFloatConstant .and rbrace;\n"
-"signedFloatConstant\n"
-" optionalSign .and floatConstant;\n"
-"floatConstant\n"
-" float;\n"
-"optionalSign\n"
-" optional_sign_ne;\n"
-"fp_TEMP_statement\n"
-" \"TEMP\" .and space .and fp_varNameList .and .true .emit 0x00;\n"
-"vp_TEMP_statement\n"
-" \"TEMP\" .and space .and vp_varNameList .and .true .emit 0x00;\n"
-"ADDRESS_statement\n"
-" \"ADDRESS\" .and space .and vp_varNameList .and .true .emit 0x00;\n"
-"fp_varNameList\n"
-" fp_varNameList_1 .or fp_establishName;\n"
-"vp_varNameList\n"
-" vp_varNameList_1 .or vp_establishName;\n"
-"fp_varNameList_1\n"
-" fp_establishName .and comma_ne .and fp_varNameList;\n"
-"vp_varNameList_1\n"
-" vp_establishName .and comma_ne .and vp_varNameList;\n"
-"fp_OUTPUT_statement\n"
-" \"OUTPUT\" .and space .and fp_establishName .and equal .and\n"
-" fp_resultBinding .error RESULT_EXPECTED;\n"
-"vp_OUTPUT_statement\n"
-" \"OUTPUT\" .and space .and vp_establishName .and equal .and\n"
-" vp_resultBinding .error RESULT_EXPECTED;\n"
-"fp_resultBinding\n"
-" \"result\" .and dot .and fp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"
-"vp_resultBinding\n"
-" \"result\" .and dot .and vp_resultBinding_1 .error INVALID_RESULT_PROPERTY;\n"
-"fp_resultBinding_1\n"
-" fp_resultBinding_2 .emit FRAGMENT_RESULT_COLOR .or\n"
-" \"depth\" .emit FRAGMENT_RESULT_DEPTH;\n"
-"fp_resultBinding_2\n"
-" \"color\" .and optOutputColorNum;\n"
-"vp_resultBinding_1\n"
-" .if (ARB_position_invariant == 0x00) \"position\" .emit VERTEX_RESULT_POSITION .or\n"
-" resultColBinding .emit VERTEX_RESULT_COLOR .or\n"
-" \"fogcoord\" .emit VERTEX_RESULT_FOGCOORD .or\n"
-" \"pointsize\" .emit VERTEX_RESULT_POINTSIZE .or\n"
-" vp_resultBinding_2 .emit VERTEX_RESULT_TEXCOORD;\n"
-"vp_resultBinding_2\n"
-" \"texcoord\" .and optTexCoordNum;\n"
-"optOutputColorNum\n"
-" .if (ARB_draw_buffers != 0x00) optOutputColorNum_1 .or .true .emit 0x00;\n"
-"optOutputColorNum_1\n"
-" lbracket_ne .and outputColorNum .and rbracket;\n"
-"outputColorNum\n"
-" integer;\n"
-"resultColBinding\n"
-" \"color\" .and optFaceType .and optColorType;\n"
-"optFaceType\n"
-" FaceType .or .true .emit FACE_FRONT;\n"
-"FaceType\n"
-" dot_ne .and FaceProperty;\n"
-"FaceProperty\n"
-" \"front\" .emit FACE_FRONT .or \"back\" .emit FACE_BACK;\n"
-"optColorType\n"
-" ColorType .or .true .emit COLOR_PRIMARY;\n"
-"ColorType\n"
-" dot_ne .and ColorProperty;\n"
-"ColorProperty\n"
-" \"primary\" .emit COLOR_PRIMARY .or\n"
-" .if (secondary_color != 0x00) \"secondary\" .emit COLOR_SECONDARY;\n"
-"fp_ALIAS_statement\n"
-" \"ALIAS\" .and fp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and fp_establishedName;\n"
-"vp_ALIAS_statement\n"
-" \"ALIAS\" .and vp_ALIAS_statement_1 .error IDENTIFIER_EXPECTED .and equal .and vp_establishedName;\n"
-"fp_ALIAS_statement_1\n"
-" space .and fp_establishName;\n"
-"vp_ALIAS_statement_1\n"
-" space .and vp_establishName;\n"
-"fp_establishName\n"
-" fp_identifier;\n"
-"vp_establishName\n"
-" vp_identifier;\n"
-"fp_establishedName\n"
-" fp_identifier;\n"
-"vp_establishedName\n"
-" vp_identifier;\n"
-"fp_establishedName_no_error_on_identifier\n"
-" fp_identifier_ne;\n"
-"vp_establishedName_no_error_on_identifier\n"
-" vp_identifier_ne;\n"
-"fp_identifier\n"
-" fp_identifier_ne .error IDENTIFIER_EXPECTED;\n"
-"vp_identifier\n"
-" vp_identifier_ne .error IDENTIFIER_EXPECTED;\n"
-"fp_identifier_ne\n"
-" fp_not_reserved_identifier .and identifier_ne;\n"
-"vp_identifier_ne\n"
-" vp_not_reserved_identifier .and identifier_ne;\n"
-"fp_not_reserved_identifier\n"
-" fp_not_reserved_identifier_1 .or .true;\n"
-"fp_not_reserved_identifier_1\n"
-" fp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"
-"vp_not_reserved_identifier\n"
-" vp_not_reserved_identifier_1 .or .true;\n"
-"vp_not_reserved_identifier_1\n"
-" vp_reserved_identifier .and .false .error RESERVED_KEYWORD;\n"
-"fp_reserved_identifier\n"
-" \"ABS\" .or \"ABS_SAT\" .or \"ADD\" .or \"ADD_SAT\" .or \"ALIAS\" .or \"ATTRIB\" .or \"CMP\" .or \"CMP_SAT\" .or\n"
-" \"COS\" .or \"COS_SAT\" .or \"DP3\" .or \"DP3_SAT\" .or \"DP4\" .or \"DP4_SAT\" .or \"DPH\" .or \"DPH_SAT\" .or\n"
-" \"DST\" .or \"DST_SAT\" .or \"END\" .or \"EX2\" .or \"EX2_SAT\" .or \"FLR\" .or \"FLR_SAT\" .or \"FRC\" .or\n"
-" \"FRC_SAT\" .or \"KIL\" .or \"LG2\" .or \"LG2_SAT\" .or \"LIT\" .or \"LIT_SAT\" .or \"LRP\" .or \"LRP_SAT\" .or\n"
-" \"MAD\" .or \"MAD_SAT\" .or \"MAX\" .or \"MAX_SAT\" .or \"MIN\" .or \"MIN_SAT\" .or \"MOV\" .or \"MOV_SAT\" .or\n"
-" \"MUL\" .or \"MUL_SAT\" .or \"OPTION\" .or \"OUTPUT\" .or \"PARAM\" .or \"POW\" .or \"POW_SAT\" .or \"RCP\" .or\n"
-" \"RCP_SAT\" .or \"RSQ\" .or \"RSQ_SAT\" .or \"SIN\" .or \"SIN_SAT\" .or \"SCS\" .or \"SCS_SAT\" .or \"SGE\" .or\n"
-" \"SGE_SAT\" .or \"SLT\" .or \"SLT_SAT\" .or \"SUB\" .or \"SUB_SAT\" .or \"SWZ\" .or \"SWZ_SAT\" .or \"TEMP\" .or\n"
-" \"TEX\" .or \"TEX_SAT\" .or \"TXB\" .or \"TXB_SAT\" .or \"TXP\" .or \"TXP_SAT\" .or \"XPD\" .or \"XPD_SAT\" .or\n"
-" \"fragment\" .or \"program\" .or \"result\" .or \"state\" .or \"texture\";\n"
-"vp_reserved_identifier\n"
-" \"ABS\" .or \"ADD\" .or \"ADDRESS\" .or \"ALIAS\" .or \"ARL\" .or \"ATTRIB\" .or \"DP3\" .or \"DP4\" .or\n"
-" \"DPH\" .or \"DST\" .or \"END\" .or \"EX2\" .or \"EXP\" .or \"FLR\" .or \"FRC\" .or \"LG2\" .or \"LIT\" .or\n"
-" \"LOG\" .or \"MAD\" .or \"MAX\" .or \"MIN\" .or \"MOV\" .or \"MUL\" .or \"OPTION\" .or \"OUTPUT\" .or\n"
-" \"PARAM\" .or \"POW\" .or \"RCP\" .or \"RSQ\" .or \"SGE\" .or \"SLT\" .or \"SUB\" .or \"SWZ\" .or \"TEMP\" .or\n"
-" \"XPD\" .or \"program\" .or \"result\" .or \"state\" .or \"vertex\";\n"
-"integer\n"
-" integer_ne .error INTEGER_EXPECTED;\n"
-"zero\n"
-" '0';\n"
-"leading_zeroes\n"
-" .loop zero;\n"
-"no_digit\n"
-" no_digit_1 .or .true;\n"
-"no_digit_1\n"
-" digit10 .and .false .error INTEGER_OUT_OF_RANGE;\n"
-"all_zeroes\n"
-" all_zeroes_1 .or no_digit_1;\n"
-"all_zeroes_1\n"
-" '0' .and .loop zero .and no_digit;\n"
-"integer_0_3\n"
-" integer_0_3_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
-"integer_0_3_1\n"
-" integer_0_3_2 .or all_zeroes .emit '0';\n"
-"integer_0_3_2 \n"
-" leading_zeroes .and '1'-'3' .emit * .and no_digit;\n"
-"integer_0_63\n"
-" integer_0_63_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
-"integer_0_63_1\n"
-" integer_0_63_2 .or integer_0_63_3 .or integer_0_63_4 .or integer_0_63_5 .or\n"
-" all_zeroes .emit '0';\n"
-"integer_0_63_2 \n"
-" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"
-"integer_0_63_3 \n"
-" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"
-"integer_0_63_4 \n"
-" leading_zeroes .and '6' .emit * .and '0'-'3' .emit * .and no_digit;\n"
-"integer_0_63_5 \n"
-" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"
-"integer_0_64\n"
-" integer_0_64_1 .error INTEGER_EXPECTED .and .true .emit 0x00 .emit $;\n"
-"integer_0_64_1\n"
-" integer_0_64_2 .or integer_0_64_3 .or integer_0_64_4 .or integer_0_64_5 .or\n"
-" all_zeroes .emit '0';\n"
-"integer_0_64_2 \n"
-" leading_zeroes .and '7'-'9' .emit * .and no_digit;\n"
-"integer_0_64_3 \n"
-" leading_zeroes .and '1'-'5' .emit * .and '0'-'9' .emit * .and no_digit;\n"
-"integer_0_64_4 \n"
-" leading_zeroes .and '6' .emit * .and '0'-'4' .emit * .and no_digit;\n"
-"integer_0_64_5 \n"
-" leading_zeroes .and '1'-'6' .emit * .and no_digit;\n"
-"optional_space\n"
-" space .or .true;\n"
-"space_dst\n"
-" space .error OPERATION_NEEDS_DESTINATION_VARIABLE;\n"
-"space_src\n"
-" space .error OPERATION_NEEDS_SOURCE_VARIABLE;\n"
-"space\n"
-" single_space .and .loop single_space;\n"
-"single_space\n"
-" white_char .or comment_block;\n"
-"white_char\n"
-" ' ' .or '\\t' .or '\\n' .or '\\r';\n"
-"comment_block\n"
-" '#' .and .loop comment_char .and optional_new_line;\n"
-"comment_char\n"
-" '\\x0E'-'\\xFF' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"optional_new_line\n"
-" '\\n' .or crlf .or .true;\n"
-"crlf\n"
-" '\\r' .and '\\n';\n"
-"semicolon\n"
-" optional_space .and ';' .error MISSING_SEMICOLON .and optional_space;\n"
-"comma\n"
-" optional_space .and ',' .error MISSING_COMMA .and optional_space;\n"
-"comma_ne\n"
-" optional_space .and ',' .and optional_space;\n"
-"lbracket\n"
-" optional_space .and '[' .error MISSING_LBRACKET .and optional_space;\n"
-"lbracket_ne\n"
-" optional_space .and '[' .and optional_space;\n"
-"rbracket\n"
-" optional_space .and ']' .error MISSING_RBRACKET .and optional_space;\n"
-"dot\n"
-" optional_space .and '.' .error MISSING_DOT .and optional_space;\n"
-"dot_ne\n"
-" optional_space .and '.' .and optional_space;\n"
-"equal\n"
-" optional_space .and '=' .error MISSING_EQUAL .and optional_space;\n"
-"lbrace\n"
-" optional_space .and '{' .error MISSING_LBRACE .and optional_space;\n"
-"lbrace_ne\n"
-" optional_space .and '{' .and optional_space;\n"
-"rbrace\n"
-" optional_space .and '}' .error MISSING_RBRACE .and optional_space;\n"
-"dotdot\n"
-" optional_space .and '.' .and '.' .error MISSING_DOTDOT .and optional_space;\n"
-"dotdot_ne\n"
-" optional_space .and '.' .and '.' .and optional_space;\n"
-"float\n"
-" float_1 .or float_2 .or float_legacy;\n"
-"float_1\n"
-" '.' .emit 0x00 .and integer_ne .error MISSING_FRACTION_OR_EXPONENT .and optional_exponent;\n"
-"float_2\n"
-" integer_ne .and float_3;\n"
-"float_3\n"
-" float_4 .or float_5;\n"
-"float_4\n"
-" '.' .and optional_integer .and optional_exponent;\n"
-"float_5\n"
-" exponent .emit 0x00;\n"
-"float_legacy\n"
-" integer_ne .and .true .emit 0x00 .emit 0x00;\n"
-"integer_ne\n"
-" integer_ne_1 .and .true .emit 0x00 .emit $;\n"
-"integer_ne_1\n"
-" digit10 .emit * .and .loop digit10 .emit *;\n"
-"optional_integer\n"
-" integer_ne .or .true .emit 0x00;\n"
-"optional_exponent\n"
-" exponent .or .true .emit 0x00;\n"
-"exponent\n"
-" exponent_1 .and optional_sign_ne .and integer_ne .error EXPONENT_VALUE_EXPECTED;\n"
-"exponent_1\n"
-" 'e' .or 'E';\n"
-"optional_sign_ne\n"
-" minus_ne .or plus_ne .or .true;\n"
-"plus_ne\n"
-" optional_space .and '+' .and optional_space;\n"
-"minus_ne\n"
-" optional_space .and '-' .emit '-' .and optional_space;\n"
-"identifier_ne\n"
-" first_idchar .emit * .and .loop follow_idchar .emit * .and .true .emit 0x00 .emit $;\n"
-"follow_idchar\n"
-" first_idchar .or digit10;\n"
-"first_idchar\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"
-"digit10\n"
-" '0'-'9';\n"
-".string __string_filter;\n"
-"__string_filter\n"
-" .loop __identifier_char;\n"
-"__identifier_char\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$' .or '0'-'9';\n"
-"e_signature\n"
-" e_signature_char .and .loop e_signature_char;\n"
-"e_signature_char\n"
-" '!' .or '.' .or 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"
-"e_statement\n"
-" .loop e_statement_not_term;\n"
-"e_statement_not_term\n"
-" '\\x3C'-'\\xFF' .or '\\x0E'-'\\x3A' .or '\\x01'-'\\x09' .or '\\x0B'-'\\x0C';\n"
-"e_identifier\n"
-" e_identifier_first .and .loop e_identifier_next;\n"
-"e_identifier_first\n"
-" 'a'-'z' .or 'A'-'Z' .or '_' .or '$';\n"
-"e_identifier_next\n"
-" e_identifier_first .or '0'-'9';\n"
-"e_token\n"
-" e_identifier .or e_token_number .or '[' .or ']' .or '.' .or '{' .or '}' .or '=' .or '+' .or\n"
-" '-' .or ',' .or ';';\n"
-"e_token_number\n"
-" e_token_digit .and .loop e_token_digit;\n"
-"e_token_digit\n"
-" '0'-'9';\n"
-"e_charordigit\n"
-" 'A'-'Z' .or 'a'-'z' .or '0'-'9';\n"
-""
diff --git a/src/mesa/shader/hash_table.c b/src/mesa/shader/hash_table.c
new file mode 100644
index 0000000000..881179f9d8
--- /dev/null
+++ b/src/mesa/shader/hash_table.c
@@ -0,0 +1,163 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file hash_table.c
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+#include <stdlib.h>
+#include <string.h>
+
+#include <assert.h>
+
+#include "main/imports.h"
+#include "main/simple_list.h"
+#include "hash_table.h"
+
+struct node {
+ struct node *next;
+ struct node *prev;
+};
+
+struct hash_table {
+ hash_func_t hash;
+ hash_compare_func_t compare;
+
+ unsigned num_buckets;
+ struct node buckets[1];
+};
+
+
+struct hash_node {
+ struct node link;
+ const void *key;
+ void *data;
+};
+
+
+struct hash_table *
+hash_table_ctor(unsigned num_buckets, hash_func_t hash,
+ hash_compare_func_t compare)
+{
+ struct hash_table *ht;
+ unsigned i;
+
+
+ if (num_buckets < 16) {
+ num_buckets = 16;
+ }
+
+ ht = _mesa_malloc(sizeof(*ht) + ((num_buckets - 1)
+ * sizeof(ht->buckets[0])));
+ if (ht != NULL) {
+ ht->hash = hash;
+ ht->compare = compare;
+ ht->num_buckets = num_buckets;
+
+ for (i = 0; i < num_buckets; i++) {
+ make_empty_list(& ht->buckets[i]);
+ }
+ }
+
+ return ht;
+}
+
+
+void
+hash_table_dtor(struct hash_table *ht)
+{
+ hash_table_clear(ht);
+ _mesa_free(ht);
+}
+
+
+void
+hash_table_clear(struct hash_table *ht)
+{
+ struct node *node;
+ struct node *temp;
+ unsigned i;
+
+
+ for (i = 0; i < ht->num_buckets; i++) {
+ foreach_s(node, temp, & ht->buckets[i]) {
+ remove_from_list(node);
+ _mesa_free(node);
+ }
+
+ assert(is_empty_list(& ht->buckets[i]));
+ }
+}
+
+
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct node *node;
+
+ foreach(node, & ht->buckets[bucket]) {
+ struct hash_node *hn = (struct hash_node *) node;
+
+ if ((*ht->compare)(hn->key, key) == 0) {
+ return hn->data;
+ }
+ }
+
+ return NULL;
+}
+
+
+void
+hash_table_insert(struct hash_table *ht, void *data, const void *key)
+{
+ const unsigned hash_value = (*ht->hash)(key);
+ const unsigned bucket = hash_value % ht->num_buckets;
+ struct hash_node *node;
+
+ node = _mesa_calloc(sizeof(*node));
+
+ node->data = data;
+ node->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & node->link);
+}
+
+
+unsigned
+hash_table_string_hash(const void *key)
+{
+ const char *str = (const char *) key;
+ unsigned hash = 5381;
+
+
+ while (*str != '\0') {
+ hash = (hash * 33) + *str;
+ str++;
+ }
+
+ return hash;
+}
diff --git a/src/mesa/shader/hash_table.h b/src/mesa/shader/hash_table.h
new file mode 100644
index 0000000000..7b302f5dbe
--- /dev/null
+++ b/src/mesa/shader/hash_table.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file hash_table.h
+ * \brief Implementation of a generic, opaque hash table data type.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#ifndef HASH_TABLE_H
+#define HASH_TABLE_H
+
+#include <string.h>
+
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
+/**
+ * Hash table constructor
+ *
+ * Creates a hash table with the specified number of buckets. The supplied
+ * \c hash and \c compare routines are used when adding elements to the table
+ * and when searching for elements in the table.
+ *
+ * \param num_buckets Number of buckets (bins) in the hash table.
+ * \param hash Function used to compute hash value of input keys.
+ * \param compare Function used to compare keys.
+ */
+extern struct hash_table *hash_table_ctor(unsigned num_buckets,
+ hash_func_t hash, hash_compare_func_t compare);
+
+
+/**
+ * Release all memory associated with a hash table
+ *
+ * \warning
+ * This function cannot release memory occupied either by keys or data.
+ */
+extern void hash_table_dtor(struct hash_table *ht);
+
+
+/**
+ * Flush all entries from a hash table
+ *
+ * \param ht Table to be cleared of its entries.
+ */
+extern void hash_table_clear(struct hash_table *ht);
+
+
+/**
+ * Search a hash table for a specific element
+ *
+ * \param ht Table to be searched
+ * \param key Key of the desired element
+ *
+ * \return
+ * The \c data value supplied to \c hash_table_insert when the element with
+ * the matching key was added. If no matching key exists in the table,
+ * \c NULL is returned.
+ */
+extern void *hash_table_find(struct hash_table *ht, const void *key);
+
+
+/**
+ * Add an element to a hash table
+ */
+extern void hash_table_insert(struct hash_table *ht, void *data,
+ const void *key);
+
+
+/**
+ * Compute hash value of a string
+ *
+ * Computes the hash value of a string using the DJB2 algorithm developed by
+ * Professor Daniel J. Bernstein. It was published on comp.lang.c once upon
+ * a time. I was unable to find the original posting in the archives.
+ *
+ * \param key Pointer to a NUL terminated string to be hashed.
+ *
+ * \sa hash_table_string_compare
+ */
+extern unsigned hash_table_string_hash(const void *key);
+
+
+/**
+ * Compare two strings used as keys
+ *
+ * This is just a macro wrapper around \c strcmp.
+ *
+ * \sa hash_table_string_hash
+ */
+#define hash_table_string_compare ((hash_compare_func_t) strcmp)
+
+#endif /* HASH_TABLE_H */
diff --git a/src/mesa/shader/lex.yy.c b/src/mesa/shader/lex.yy.c
new file mode 100644
index 0000000000..283ba8d26e
--- /dev/null
+++ b/src/mesa/shader/lex.yy.c
@@ -0,0 +1,3578 @@
+
+#line 3 "lex.yy.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* An opaque pointer. */
+#ifndef YY_TYPEDEF_YY_SCANNER_T
+#define YY_TYPEDEF_YY_SCANNER_T
+typedef void* yyscan_t;
+#endif
+
+/* For convenience, these vars (plus the bison vars far below)
+ are macros in the reentrant scanner. */
+#define yyin yyg->yyin_r
+#define yyout yyg->yyout_r
+#define yyextra yyg->yyextra_r
+#define yyleng yyg->yyleng_r
+#define yytext yyg->yytext_r
+#define yylineno (YY_CURRENT_BUFFER_LVALUE->yy_bs_lineno)
+#define yycolumn (YY_CURRENT_BUFFER_LVALUE->yy_bs_column)
+#define yy_flex_debug yyg->yy_flex_debug_r
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN yyg->yy_start = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START ((yyg->yy_start - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin ,yyscanner )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = yyg->yy_hold_char; \
+ YY_RESTORE_YY_MORE_OFFSET \
+ yyg->yy_c_buf_p = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, yyg->yytext_ptr , yyscanner )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( yyg->yy_buffer_stack \
+ ? yyg->yy_buffer_stack[yyg->yy_buffer_stack_top] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE yyg->yy_buffer_stack[yyg->yy_buffer_stack_top]
+
+void yyrestart (FILE *input_file ,yyscan_t yyscanner );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ,yyscan_t yyscanner );
+void yy_delete_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yy_flush_buffer (YY_BUFFER_STATE b ,yyscan_t yyscanner );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer ,yyscan_t yyscanner );
+void yypop_buffer_state (yyscan_t yyscanner );
+
+static void yyensure_buffer_stack (yyscan_t yyscanner );
+static void yy_load_buffer_state (yyscan_t yyscanner );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ,yyscan_t yyscanner );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ,yyscanner)
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ,yyscan_t yyscanner );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ,yyscan_t yyscanner );
+
+void *yyalloc (yy_size_t ,yyscan_t yyscanner );
+void *yyrealloc (void *,yy_size_t ,yyscan_t yyscanner );
+void yyfree (void * ,yyscan_t yyscanner );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (yyscanner); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+typedef int yy_state_type;
+
+#define yytext_ptr yytext_r
+
+static yy_state_type yy_get_previous_state (yyscan_t yyscanner );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state ,yyscan_t yyscanner);
+static int yy_get_next_buffer (yyscan_t yyscanner );
+static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ yyg->yytext_ptr = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ yyg->yy_hold_char = *yy_cp; \
+ *yy_cp = '\0'; \
+ yyg->yy_c_buf_p = yy_cp;
+
+#define YY_NUM_RULES 183
+#define YY_END_OF_BUFFER 184
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_accept[675] =
+ { 0,
+ 0, 0, 184, 182, 180, 179, 182, 182, 152, 178,
+ 154, 154, 154, 154, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 180, 0, 0, 181, 152, 0,
+ 153, 155, 175, 175, 0, 0, 0, 0, 175, 0,
+ 0, 0, 0, 0, 0, 0, 132, 176, 133, 134,
+ 166, 166, 166, 166, 0, 154, 0, 140, 141, 142,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 174, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 173, 173, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 172, 172, 172, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 163, 163, 163, 164, 164, 165, 156,
+ 155, 156, 0, 157, 11, 13, 152, 15, 152, 152,
+ 16, 18, 152, 20, 22, 24, 26, 6, 28, 30,
+ 31, 33, 35, 38, 36, 40, 41, 43, 45, 47,
+
+ 49, 51, 152, 152, 152, 53, 55, 152, 57, 59,
+ 61, 152, 63, 65, 67, 69, 152, 71, 73, 75,
+ 77, 152, 152, 152, 152, 152, 152, 0, 0, 0,
+ 0, 155, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 93, 94, 96, 0, 171, 0, 0, 0,
+ 0, 0, 0, 110, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 170, 169, 169, 122, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 160, 160,
+ 161, 162, 0, 158, 152, 152, 152, 152, 152, 152,
+ 152, 152, 143, 152, 152, 152, 152, 152, 152, 152,
+
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 144, 152, 152, 152, 152, 152, 152,
+ 152, 152, 10, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 0, 177, 0, 0, 0, 86, 87,
+ 0, 0, 0, 0, 0, 0, 0, 98, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 168, 0, 0, 0,
+ 126, 0, 128, 0, 0, 0, 0, 0, 0, 167,
+ 159, 152, 152, 152, 4, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+
+ 152, 152, 152, 152, 152, 152, 9, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 82, 152, 152, 0, 0, 0,
+ 0, 0, 88, 89, 0, 0, 0, 0, 97, 0,
+ 0, 101, 104, 0, 0, 0, 0, 0, 0, 0,
+ 115, 116, 0, 0, 0, 0, 121, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 152, 152, 152,
+ 152, 152, 152, 5, 152, 152, 152, 152, 152, 152,
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 152,
+ 152, 7, 8, 152, 152, 152, 152, 152, 152, 152,
+
+ 152, 152, 152, 152, 152, 152, 152, 152, 152, 83,
+ 152, 79, 0, 0, 0, 0, 137, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 107, 0, 111, 112,
+ 0, 114, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 130, 131, 0, 0, 138, 12, 3, 14,
+ 148, 149, 152, 17, 19, 21, 23, 25, 27, 29,
+ 32, 34, 39, 37, 42, 44, 46, 48, 50, 52,
+ 54, 56, 58, 60, 62, 152, 152, 152, 64, 66,
+ 68, 70, 72, 74, 76, 78, 152, 81, 139, 0,
+ 0, 84, 0, 90, 0, 0, 0, 99, 0, 0,
+
+ 0, 0, 0, 0, 113, 0, 0, 119, 106, 0,
+ 0, 0, 0, 0, 0, 135, 0, 152, 145, 146,
+ 152, 80, 0, 0, 0, 0, 92, 95, 100, 0,
+ 0, 105, 0, 0, 0, 118, 0, 0, 0, 0,
+ 127, 129, 0, 152, 152, 2, 1, 0, 91, 0,
+ 103, 0, 109, 117, 0, 0, 124, 125, 136, 152,
+ 147, 0, 102, 0, 120, 123, 152, 85, 108, 152,
+ 152, 150, 151, 0
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 1, 4, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 5, 1, 6, 7, 1, 1, 1, 1,
+ 1, 1, 8, 1, 8, 9, 1, 10, 11, 12,
+ 13, 14, 15, 15, 15, 15, 15, 1, 1, 1,
+ 1, 1, 1, 1, 16, 17, 18, 19, 20, 21,
+ 22, 23, 24, 7, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+ 1, 1, 1, 1, 41, 1, 42, 43, 44, 45,
+
+ 46, 47, 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[68] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 2, 1, 3, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2
+ } ;
+
+static yyconst flex_int16_t yy_base[678] =
+ { 0,
+ 0, 0, 954, 955, 66, 955, 948, 949, 0, 69,
+ 85, 128, 140, 152, 151, 58, 39, 48, 75, 927,
+ 158, 160, 73, 59, 71, 170, 54, 920, 890, 889,
+ 901, 885, 899, 898, 142, 927, 939, 955, 0, 206,
+ 955, 189, 168, 171, 53, 27, 66, 119, 175, 899,
+ 885, 123, 170, 883, 895, 183, 955, 198, 225, 99,
+ 212, 219, 223, 227, 285, 297, 308, 955, 955, 955,
+ 904, 917, 911, 165, 900, 903, 899, 914, 224, 896,
+ 910, 194, 896, 909, 900, 913, 890, 901, 892, 294,
+ 893, 884, 893, 884, 883, 884, 878, 884, 895, 881,
+
+ 878, 890, 893, 880, 873, 889, 865, 193, 139, 885,
+ 861, 846, 841, 858, 834, 839, 865, 167, 854, 259,
+ 849, 325, 282, 851, 832, 302, 842, 838, 833, 43,
+ 839, 825, 841, 838, 829, 305, 309, 831, 820, 834,
+ 837, 819, 834, 821, 818, 825, 275, 833, 254, 299,
+ 317, 327, 331, 810, 827, 828, 821, 803, 310, 804,
+ 826, 817, 316, 327, 331, 335, 339, 343, 347, 955,
+ 405, 416, 422, 428, 825, 240, 849, 0, 848, 831,
+ 821, 820, 840, 818, 817, 816, 815, 0, 814, 0,
+ 813, 812, 0, 811, 810, 0, 809, 808, 807, 806,
+
+ 805, 804, 820, 813, 826, 800, 799, 805, 797, 796,
+ 795, 816, 793, 792, 791, 790, 800, 788, 787, 786,
+ 785, 777, 776, 761, 761, 760, 759, 802, 774, 762,
+ 434, 442, 416, 766, 186, 763, 757, 757, 751, 764,
+ 764, 749, 955, 955, 764, 752, 418, 759, 281, 756,
+ 762, 308, 757, 955, 748, 755, 754, 757, 743, 742,
+ 746, 741, 278, 746, 420, 428, 430, 955, 738, 736,
+ 736, 744, 745, 727, 421, 732, 738, 419, 426, 430,
+ 434, 438, 496, 502, 752, 764, 750, 749, 742, 756,
+ 746, 745, 0, 744, 743, 742, 741, 740, 739, 738,
+
+ 737, 736, 735, 734, 733, 732, 731, 730, 733, 726,
+ 733, 726, 725, 0, 724, 723, 722, 725, 720, 719,
+ 718, 717, 0, 716, 715, 714, 713, 691, 685, 690,
+ 696, 679, 694, 315, 955, 693, 683, 687, 955, 955,
+ 677, 686, 672, 689, 672, 675, 669, 955, 670, 669,
+ 666, 673, 666, 674, 670, 680, 677, 659, 665, 672,
+ 656, 655, 673, 655, 667, 666, 955, 665, 655, 659,
+ 955, 646, 955, 651, 651, 659, 642, 643, 653, 955,
+ 955, 685, 667, 683, 0, 507, 681, 681, 680, 679,
+ 678, 677, 676, 675, 674, 673, 672, 671, 670, 669,
+
+ 668, 667, 666, 665, 652, 645, 0, 662, 661, 660,
+ 659, 658, 636, 656, 655, 654, 653, 652, 651, 650,
+ 649, 618, 621, 601, 0, 602, 595, 602, 601, 602,
+ 594, 612, 955, 955, 594, 592, 602, 595, 955, 590,
+ 607, 330, 955, 598, 582, 583, 592, 583, 582, 582,
+ 955, 581, 590, 580, 596, 593, 955, 592, 590, 579,
+ 580, 576, 568, 575, 570, 571, 566, 592, 592, 590,
+ 604, 603, 598, 0, 586, 585, 584, 583, 582, 581,
+ 580, 579, 578, 577, 576, 575, 574, 573, 572, 571,
+ 570, 0, 0, 569, 568, 567, 566, 565, 509, 564,
+
+ 563, 562, 561, 560, 559, 558, 557, 535, 535, 0,
+ 542, 0, 576, 575, 524, 542, 955, 537, 532, 525,
+ 521, 533, 523, 521, 517, 533, 524, 523, 955, 955,
+ 526, 955, 521, 514, 503, 514, 506, 510, 523, 518,
+ 521, 503, 955, 955, 515, 504, 955, 0, 0, 0,
+ 0, 0, 543, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 539, 538, 536, 0, 0,
+ 0, 0, 0, 0, 0, 0, 494, 0, 0, 545,
+ 544, 955, 491, 955, 495, 495, 504, 955, 488, 502,
+
+ 483, 485, 482, 490, 955, 468, 479, 955, 955, 483,
+ 479, 472, 470, 470, 483, 955, 467, 507, 0, 0,
+ 507, 0, 514, 513, 472, 433, 955, 955, 955, 435,
+ 435, 955, 429, 386, 377, 955, 366, 365, 323, 328,
+ 955, 955, 339, 348, 337, 955, 955, 307, 955, 305,
+ 955, 257, 955, 955, 247, 221, 955, 955, 955, 236,
+ 0, 213, 955, 150, 955, 955, 232, 955, 955, 162,
+ 138, 0, 0, 955, 541, 108, 544
+ } ;
+
+static yyconst flex_int16_t yy_def[678] =
+ { 0,
+ 674, 1, 674, 674, 674, 674, 674, 675, 676, 674,
+ 674, 674, 674, 674, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 674, 674, 675, 674, 676, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 677, 674, 674, 674, 674, 674,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 676,
+ 676, 676, 676, 676, 676, 676, 676, 676, 676, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 676, 676, 676,
+ 676, 676, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 676, 676, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 676,
+ 676, 674, 674, 674, 674, 674, 676, 674, 674, 676,
+ 676, 676, 676, 0, 674, 674, 674
+ } ;
+
+static yyconst flex_int16_t yy_nxt[1023] =
+ { 0,
+ 4, 5, 6, 5, 7, 8, 9, 4, 10, 11,
+ 12, 13, 14, 11, 11, 15, 9, 16, 17, 18,
+ 19, 9, 9, 9, 20, 21, 22, 9, 23, 24,
+ 9, 25, 26, 27, 9, 9, 9, 28, 9, 9,
+ 9, 9, 9, 9, 9, 9, 29, 9, 9, 9,
+ 9, 9, 9, 9, 9, 9, 30, 9, 31, 32,
+ 33, 9, 34, 9, 9, 9, 9, 35, 79, 35,
+ 40, 80, 129, 108, 96, 81, 130, 41, 42, 42,
+ 42, 42, 42, 42, 76, 82, 77, 97, 98, 240,
+ 99, 109, 78, 65, 66, 66, 66, 66, 66, 66,
+
+ 83, 241, 94, 100, 67, 127, 84, 95, 128, 39,
+ 43, 44, 45, 46, 47, 48, 49, 50, 51, 131,
+ 132, 52, 53, 54, 55, 56, 57, 58, 59, 60,
+ 67, 133, 61, 62, 63, 64, 65, 66, 66, 66,
+ 66, 66, 66, 35, 160, 35, 68, 67, 65, 66,
+ 66, 66, 66, 66, 66, 219, 673, 161, 69, 67,
+ 65, 66, 66, 66, 66, 66, 66, 71, 220, 72,
+ 70, 67, 140, 67, 134, 90, 73, 135, 141, 86,
+ 672, 87, 74, 91, 75, 67, 88, 101, 92, 89,
+ 178, 102, 103, 104, 93, 105, 179, 67, 42, 42,
+
+ 42, 42, 42, 42, 106, 189, 107, 40, 122, 123,
+ 123, 142, 126, 123, 669, 123, 136, 137, 123, 217,
+ 124, 124, 123, 190, 147, 143, 123, 125, 125, 123,
+ 218, 337, 144, 123, 122, 148, 184, 185, 149, 151,
+ 152, 150, 670, 671, 338, 153, 186, 118, 119, 45,
+ 46, 47, 48, 154, 50, 51, 123, 162, 52, 53,
+ 54, 55, 56, 57, 120, 59, 60, 668, 155, 121,
+ 156, 286, 667, 157, 158, 163, 163, 163, 163, 666,
+ 287, 159, 164, 163, 165, 166, 167, 163, 163, 168,
+ 169, 163, 163, 163, 171, 171, 171, 171, 171, 171,
+
+ 230, 665, 664, 260, 172, 65, 66, 66, 66, 66,
+ 66, 66, 198, 261, 154, 173, 67, 174, 174, 174,
+ 174, 174, 174, 233, 233, 364, 349, 257, 365, 233,
+ 172, 199, 231, 258, 232, 232, 232, 232, 232, 232,
+ 233, 350, 67, 233, 233, 236, 233, 233, 262, 233,
+ 247, 233, 233, 353, 263, 273, 233, 663, 233, 233,
+ 233, 428, 662, 233, 233, 274, 354, 233, 265, 233,
+ 661, 264, 266, 267, 233, 233, 660, 429, 233, 278,
+ 278, 278, 278, 524, 659, 233, 525, 658, 657, 233,
+ 278, 278, 278, 278, 279, 278, 278, 280, 281, 278,
+
+ 278, 278, 278, 278, 278, 278, 282, 278, 278, 278,
+ 278, 278, 278, 278, 42, 42, 42, 42, 42, 42,
+ 656, 655, 654, 283, 122, 284, 284, 284, 284, 284,
+ 284, 174, 174, 174, 174, 174, 174, 174, 174, 174,
+ 174, 174, 174, 232, 232, 232, 232, 232, 232, 653,
+ 122, 232, 232, 232, 232, 232, 232, 335, 335, 335,
+ 335, 335, 335, 335, 374, 335, 375, 335, 376, 335,
+ 335, 367, 335, 652, 335, 335, 335, 335, 335, 651,
+ 650, 377, 380, 380, 380, 380, 335, 649, 335, 380,
+ 380, 380, 380, 381, 380, 380, 380, 380, 380, 380,
+
+ 380, 380, 380, 380, 380, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 471, 472, 576,
+ 577, 648, 647, 646, 645, 644, 643, 642, 641, 640,
+ 639, 638, 637, 636, 635, 634, 633, 632, 631, 473,
+ 578, 37, 37, 37, 170, 170, 630, 629, 628, 627,
+ 626, 625, 624, 623, 622, 621, 620, 619, 618, 617,
+ 616, 615, 614, 613, 612, 611, 610, 609, 608, 607,
+ 606, 605, 604, 603, 602, 601, 600, 599, 598, 597,
+ 596, 595, 594, 593, 592, 591, 590, 589, 588, 587,
+ 586, 585, 584, 583, 582, 581, 580, 579, 575, 574,
+
+ 573, 572, 571, 570, 569, 568, 567, 566, 565, 564,
+ 563, 562, 561, 560, 559, 558, 557, 556, 555, 554,
+ 553, 552, 551, 550, 549, 548, 547, 546, 545, 544,
+ 543, 542, 541, 540, 539, 538, 537, 536, 535, 534,
+ 533, 532, 531, 530, 529, 528, 527, 526, 523, 522,
+ 521, 520, 519, 518, 517, 516, 515, 514, 513, 512,
+ 511, 510, 509, 508, 507, 506, 505, 504, 503, 502,
+ 501, 500, 499, 498, 497, 496, 495, 494, 493, 492,
+ 491, 490, 489, 488, 487, 486, 485, 484, 483, 482,
+ 481, 480, 479, 478, 477, 476, 475, 474, 470, 469,
+
+ 468, 467, 466, 465, 464, 463, 462, 461, 460, 459,
+ 458, 457, 456, 455, 454, 453, 452, 451, 450, 449,
+ 448, 447, 446, 445, 444, 443, 442, 441, 440, 439,
+ 438, 437, 436, 435, 434, 433, 432, 431, 430, 427,
+ 426, 425, 424, 423, 422, 421, 420, 419, 418, 417,
+ 416, 415, 414, 413, 412, 411, 410, 409, 408, 407,
+ 406, 405, 404, 403, 402, 401, 400, 399, 398, 397,
+ 396, 395, 394, 393, 392, 391, 390, 389, 388, 387,
+ 386, 385, 384, 383, 382, 379, 378, 373, 372, 371,
+ 370, 369, 368, 366, 363, 362, 361, 360, 359, 358,
+
+ 357, 356, 355, 352, 351, 348, 347, 346, 345, 344,
+ 343, 342, 341, 340, 339, 336, 264, 236, 334, 333,
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 323,
+ 322, 321, 320, 319, 318, 317, 316, 315, 314, 313,
+ 312, 311, 310, 309, 308, 307, 306, 305, 304, 303,
+ 302, 301, 300, 299, 298, 297, 296, 295, 294, 293,
+ 292, 291, 290, 289, 288, 285, 277, 276, 275, 272,
+ 271, 270, 269, 268, 259, 256, 255, 254, 253, 252,
+ 251, 250, 249, 248, 246, 245, 244, 243, 242, 239,
+ 238, 237, 235, 234, 162, 229, 228, 227, 226, 225,
+
+ 224, 223, 222, 221, 216, 215, 214, 213, 212, 211,
+ 210, 209, 208, 207, 206, 205, 204, 203, 202, 201,
+ 200, 197, 196, 195, 194, 193, 192, 191, 188, 187,
+ 183, 182, 181, 180, 177, 176, 175, 146, 145, 139,
+ 138, 38, 117, 116, 115, 114, 113, 112, 111, 110,
+ 85, 38, 36, 674, 3, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674
+ } ;
+
+static yyconst flex_int16_t yy_chk[1023] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 5, 17, 5,
+ 10, 17, 46, 27, 24, 18, 46, 10, 10, 10,
+ 10, 10, 10, 10, 16, 18, 16, 24, 25, 130,
+ 25, 27, 16, 11, 11, 11, 11, 11, 11, 11,
+
+ 19, 130, 23, 25, 11, 45, 19, 23, 45, 676,
+ 10, 10, 10, 10, 10, 10, 10, 10, 10, 47,
+ 47, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+ 11, 47, 10, 10, 10, 10, 12, 12, 12, 12,
+ 12, 12, 12, 35, 60, 35, 12, 12, 13, 13,
+ 13, 13, 13, 13, 13, 109, 671, 60, 13, 13,
+ 14, 14, 14, 14, 14, 14, 14, 15, 109, 15,
+ 14, 14, 52, 12, 48, 22, 15, 48, 52, 21,
+ 670, 21, 15, 22, 15, 13, 21, 26, 22, 21,
+ 74, 26, 26, 26, 22, 26, 74, 14, 42, 42,
+
+ 42, 42, 42, 42, 26, 82, 26, 40, 42, 43,
+ 43, 53, 44, 44, 664, 43, 49, 49, 44, 108,
+ 118, 43, 49, 82, 56, 53, 43, 118, 43, 44,
+ 108, 235, 53, 49, 42, 56, 79, 79, 56, 58,
+ 58, 56, 667, 667, 235, 58, 79, 40, 40, 40,
+ 40, 40, 40, 58, 40, 40, 58, 61, 40, 40,
+ 40, 40, 40, 40, 40, 40, 40, 662, 59, 40,
+ 59, 176, 660, 59, 59, 61, 61, 61, 61, 656,
+ 176, 59, 62, 62, 62, 62, 63, 63, 63, 63,
+ 64, 64, 64, 64, 65, 65, 65, 65, 65, 65,
+
+ 120, 655, 652, 149, 65, 66, 66, 66, 66, 66,
+ 66, 66, 90, 149, 120, 67, 66, 67, 67, 67,
+ 67, 67, 67, 123, 123, 263, 249, 147, 263, 123,
+ 65, 90, 122, 147, 122, 122, 122, 122, 122, 122,
+ 123, 249, 66, 126, 126, 126, 136, 136, 150, 126,
+ 137, 137, 136, 252, 150, 159, 137, 650, 151, 151,
+ 126, 334, 648, 136, 151, 159, 252, 137, 152, 152,
+ 645, 151, 153, 153, 152, 151, 644, 334, 153, 163,
+ 163, 163, 163, 442, 643, 152, 442, 640, 639, 153,
+ 164, 164, 164, 164, 165, 165, 165, 165, 166, 166,
+
+ 166, 166, 167, 167, 167, 167, 168, 168, 168, 168,
+ 169, 169, 169, 169, 171, 171, 171, 171, 171, 171,
+ 638, 637, 635, 172, 171, 172, 172, 172, 172, 172,
+ 172, 173, 173, 173, 173, 173, 173, 174, 174, 174,
+ 174, 174, 174, 231, 231, 231, 231, 231, 231, 634,
+ 171, 232, 232, 232, 232, 232, 232, 233, 233, 247,
+ 247, 265, 265, 233, 275, 247, 275, 265, 275, 266,
+ 266, 267, 267, 633, 233, 266, 247, 267, 265, 631,
+ 630, 275, 278, 278, 278, 278, 266, 626, 267, 279,
+ 279, 279, 279, 280, 280, 280, 280, 281, 281, 281,
+
+ 281, 282, 282, 282, 282, 283, 283, 283, 283, 283,
+ 283, 284, 284, 284, 284, 284, 284, 386, 386, 499,
+ 499, 625, 624, 623, 621, 618, 617, 615, 614, 613,
+ 612, 611, 610, 607, 606, 604, 603, 602, 601, 386,
+ 499, 675, 675, 675, 677, 677, 600, 599, 597, 596,
+ 595, 593, 591, 590, 587, 578, 577, 576, 553, 546,
+ 545, 542, 541, 540, 539, 538, 537, 536, 535, 534,
+ 533, 531, 528, 527, 526, 525, 524, 523, 522, 521,
+ 520, 519, 518, 516, 515, 514, 513, 511, 509, 508,
+ 507, 506, 505, 504, 503, 502, 501, 500, 498, 497,
+
+ 496, 495, 494, 491, 490, 489, 488, 487, 486, 485,
+ 484, 483, 482, 481, 480, 479, 478, 477, 476, 475,
+ 473, 472, 471, 470, 469, 468, 467, 466, 465, 464,
+ 463, 462, 461, 460, 459, 458, 456, 455, 454, 453,
+ 452, 450, 449, 448, 447, 446, 445, 444, 441, 440,
+ 438, 437, 436, 435, 432, 431, 430, 429, 428, 427,
+ 426, 424, 423, 422, 421, 420, 419, 418, 417, 416,
+ 415, 414, 413, 412, 411, 410, 409, 408, 406, 405,
+ 404, 403, 402, 401, 400, 399, 398, 397, 396, 395,
+ 394, 393, 392, 391, 390, 389, 388, 387, 384, 383,
+
+ 382, 379, 378, 377, 376, 375, 374, 372, 370, 369,
+ 368, 366, 365, 364, 363, 362, 361, 360, 359, 358,
+ 357, 356, 355, 354, 353, 352, 351, 350, 349, 347,
+ 346, 345, 344, 343, 342, 341, 338, 337, 336, 333,
+ 332, 331, 330, 329, 328, 327, 326, 325, 324, 322,
+ 321, 320, 319, 318, 317, 316, 315, 313, 312, 311,
+ 310, 309, 308, 307, 306, 305, 304, 303, 302, 301,
+ 300, 299, 298, 297, 296, 295, 294, 292, 291, 290,
+ 289, 288, 287, 286, 285, 277, 276, 274, 273, 272,
+ 271, 270, 269, 264, 262, 261, 260, 259, 258, 257,
+
+ 256, 255, 253, 251, 250, 248, 246, 245, 242, 241,
+ 240, 239, 238, 237, 236, 234, 230, 229, 228, 227,
+ 226, 225, 224, 223, 222, 221, 220, 219, 218, 217,
+ 216, 215, 214, 213, 212, 211, 210, 209, 208, 207,
+ 206, 205, 204, 203, 202, 201, 200, 199, 198, 197,
+ 195, 194, 192, 191, 189, 187, 186, 185, 184, 183,
+ 182, 181, 180, 179, 177, 175, 162, 161, 160, 158,
+ 157, 156, 155, 154, 148, 146, 145, 144, 143, 142,
+ 141, 140, 139, 138, 135, 134, 133, 132, 131, 129,
+ 128, 127, 125, 124, 121, 119, 117, 116, 115, 114,
+
+ 113, 112, 111, 110, 107, 106, 105, 104, 103, 102,
+ 101, 100, 99, 98, 97, 96, 95, 94, 93, 92,
+ 91, 89, 88, 87, 86, 85, 84, 83, 81, 80,
+ 78, 77, 76, 75, 73, 72, 71, 55, 54, 51,
+ 50, 37, 36, 34, 33, 32, 31, 30, 29, 28,
+ 20, 8, 7, 3, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674, 674, 674, 674, 674, 674, 674, 674, 674,
+ 674, 674
+ } ;
+
+/* The intent behind this definition is that it'll catch
+ * any uses of REJECT which flex missed.
+ */
+#define REJECT reject_used_but_not_detected
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+#line 1 "program_lexer.l"
+#line 2 "program_lexer.l"
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "main/glheader.h"
+#include "prog_instruction.h"
+#include "prog_statevars.h"
+
+#include "program_parser.h"
+#include "program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect (yyextra->option.TexRect)
+#define require_texarray (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yylval->string = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+#define return_token_or_DOT(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yyless(1); \
+ return DOT; \
+ } \
+ } while (0)
+
+
+#define return_opcode(condition, token, opcode, sat) \
+ do { \
+ if (condition) { \
+ yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
+ yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
+ return token; \
+ } else { \
+ yylval->string = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+ SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return WRITEMASK_X;
+ case 'y':
+ case 'g':
+ return WRITEMASK_Y;
+ case 'z':
+ case 'b':
+ return WRITEMASK_Z;
+ case 'w':
+ case 'a':
+ return WRITEMASK_W;
+ }
+
+ return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return SWIZZLE_X;
+ case 'y':
+ case 'g':
+ return SWIZZLE_Y;
+ case 'z':
+ case 'b':
+ return SWIZZLE_Z;
+ case 'w':
+ case 'a':
+ return SWIZZLE_W;
+ }
+
+ return 0;
+}
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->last_column += yyleng; \
+ if ((yylloc->first_line == 1) \
+ && (yylloc->first_column == 1)) { \
+ yylloc->position = 1; \
+ } else { \
+ yylloc->position += yylloc->last_column - yylloc->first_column; \
+ } \
+ } while(0);
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+#line 1007 "lex.yy.c"
+
+#define INITIAL 0
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+/* Holds the entire state of the reentrant scanner. */
+struct yyguts_t
+ {
+
+ /* User-defined. Not touched by flex. */
+ YY_EXTRA_TYPE yyextra_r;
+
+ /* The rest are the same as the globals declared in the non-reentrant scanner. */
+ FILE *yyin_r, *yyout_r;
+ size_t yy_buffer_stack_top; /**< index of top of stack. */
+ size_t yy_buffer_stack_max; /**< capacity of stack. */
+ YY_BUFFER_STATE * yy_buffer_stack; /**< Stack as an array. */
+ char yy_hold_char;
+ int yy_n_chars;
+ int yyleng_r;
+ char *yy_c_buf_p;
+ int yy_init;
+ int yy_start;
+ int yy_did_buffer_switch_on_eof;
+ int yy_start_stack_ptr;
+ int yy_start_stack_depth;
+ int *yy_start_stack;
+ yy_state_type yy_last_accepting_state;
+ char* yy_last_accepting_cpos;
+
+ int yylineno_r;
+ int yy_flex_debug_r;
+
+ char *yytext_r;
+ int yy_more_flag;
+ int yy_more_len;
+
+ YYSTYPE * yylval_r;
+
+ YYLTYPE * yylloc_r;
+
+ }; /* end struct yyguts_t */
+
+static int yy_init_globals (yyscan_t yyscanner );
+
+ /* This must go here because YYSTYPE and YYLTYPE are included
+ * from bison output in section 1.*/
+ # define yylval yyg->yylval_r
+
+ # define yylloc yyg->yylloc_r
+
+int yylex_init (yyscan_t* scanner);
+
+int yylex_init_extra (YY_EXTRA_TYPE user_defined,yyscan_t* scanner);
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (yyscan_t yyscanner );
+
+int yyget_debug (yyscan_t yyscanner );
+
+void yyset_debug (int debug_flag ,yyscan_t yyscanner );
+
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined ,yyscan_t yyscanner );
+
+FILE *yyget_in (yyscan_t yyscanner );
+
+void yyset_in (FILE * in_str ,yyscan_t yyscanner );
+
+FILE *yyget_out (yyscan_t yyscanner );
+
+void yyset_out (FILE * out_str ,yyscan_t yyscanner );
+
+int yyget_leng (yyscan_t yyscanner );
+
+char *yyget_text (yyscan_t yyscanner );
+
+int yyget_lineno (yyscan_t yyscanner );
+
+void yyset_lineno (int line_number ,yyscan_t yyscanner );
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner );
+
+void yyset_lval (YYSTYPE * yylval_param ,yyscan_t yyscanner );
+
+ YYLTYPE *yyget_lloc (yyscan_t yyscanner );
+
+ void yyset_lloc (YYLTYPE * yylloc_param ,yyscan_t yyscanner );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (yyscan_t yyscanner );
+#else
+extern int yywrap (yyscan_t yyscanner );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr ,yyscan_t yyscanner);
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int ,yyscan_t yyscanner);
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * ,yyscan_t yyscanner);
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (yyscan_t yyscanner );
+#else
+static int input (yyscan_t yyscanner );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO fwrite( yytext, yyleng, 1, yyout )
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg , yyscanner)
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex \
+ (YYSTYPE * yylval_param,YYLTYPE * yylloc_param ,yyscan_t yyscanner);
+
+#define YY_DECL int yylex \
+ (YYSTYPE * yylval_param, YYLTYPE * yylloc_param , yyscan_t yyscanner)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+#line 136 "program_lexer.l"
+
+
+#line 1251 "lex.yy.c"
+
+ yylval = yylval_param;
+
+ yylloc = yylloc_param;
+
+ if ( !yyg->yy_init )
+ {
+ yyg->yy_init = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ if ( ! yyg->yy_start )
+ yyg->yy_start = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ yy_load_buffer_state(yyscanner );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* Support of yytext. */
+ *yy_cp = yyg->yy_hold_char;
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = yyg->yy_start;
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 675 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 955 );
+
+yy_find_action:
+ yy_act = yy_accept[yy_current_state];
+ if ( yy_act == 0 )
+ { /* have to back up */
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ yy_act = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+ case 0: /* must back up */
+ /* undo the effects of YY_DO_BEFORE_ACTION */
+ *yy_cp = yyg->yy_hold_char;
+ yy_cp = yyg->yy_last_accepting_cpos;
+ yy_current_state = yyg->yy_last_accepting_state;
+ goto yy_find_action;
+
+case 1:
+YY_RULE_SETUP
+#line 138 "program_lexer.l"
+{ return ARBvp_10; }
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 139 "program_lexer.l"
+{ return ARBfp_10; }
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 140 "program_lexer.l"
+{
+ yylval->integer = at_address;
+ return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 144 "program_lexer.l"
+{ return ALIAS; }
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 145 "program_lexer.l"
+{ return ATTRIB; }
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 146 "program_lexer.l"
+{ return END; }
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 147 "program_lexer.l"
+{ return OPTION; }
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 148 "program_lexer.l"
+{ return OUTPUT; }
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 149 "program_lexer.l"
+{ return PARAM; }
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 150 "program_lexer.l"
+{ yylval->integer = at_temp; return TEMP; }
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 152 "program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, ABS, OFF); }
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 153 "program_lexer.l"
+{ return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); }
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 154 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, ADD, OFF); }
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 155 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); }
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 156 "program_lexer.l"
+{ return_opcode(require_ARB_vp, ARL, ARL, OFF); }
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 158 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); }
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 159 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); }
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 160 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); }
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 161 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); }
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 163 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, DP3, OFF); }
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 164 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); }
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 165 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, DP4, OFF); }
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 166 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); }
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 167 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, DPH, OFF); }
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 168 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); }
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 169 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, DST, OFF); }
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 170 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); }
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 172 "program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, EX2, OFF); }
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 173 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); }
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 174 "program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); }
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 176 "program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, FLR, OFF); }
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 177 "program_lexer.l"
+{ return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); }
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 178 "program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, FRC, OFF); }
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 179 "program_lexer.l"
+{ return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); }
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 181 "program_lexer.l"
+{ return_opcode(require_ARB_fp, KIL, KIL, OFF); }
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 183 "program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, LIT, OFF); }
+ YY_BREAK
+case 37:
+YY_RULE_SETUP
+#line 184 "program_lexer.l"
+{ return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); }
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 185 "program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, LG2, OFF); }
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 186 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); }
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 187 "program_lexer.l"
+{ return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); }
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 188 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); }
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 189 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); }
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 191 "program_lexer.l"
+{ return_opcode( 1, TRI_OP, MAD, OFF); }
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 192 "program_lexer.l"
+{ return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); }
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 193 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, MAX, OFF); }
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 194 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); }
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 195 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, MIN, OFF); }
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 196 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); }
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 197 "program_lexer.l"
+{ return_opcode( 1, VECTOR_OP, MOV, OFF); }
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 198 "program_lexer.l"
+{ return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); }
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 199 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, MUL, OFF); }
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 200 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); }
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 202 "program_lexer.l"
+{ return_opcode( 1, BINSC_OP, POW, OFF); }
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 203 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); }
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 205 "program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, RCP, OFF); }
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 206 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); }
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 207 "program_lexer.l"
+{ return_opcode( 1, SCALAR_OP, RSQ, OFF); }
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 208 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); }
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 210 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); }
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 211 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); }
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 212 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, SGE, OFF); }
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 213 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); }
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 214 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); }
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 215 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); }
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 216 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, SLT, OFF); }
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 217 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); }
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 218 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, SUB, OFF); }
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 219 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); }
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 220 "program_lexer.l"
+{ return_opcode( 1, SWZ, SWZ, OFF); }
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 221 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); }
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 223 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); }
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 224 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); }
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 225 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); }
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 226 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); }
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 227 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); }
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 228 "program_lexer.l"
+{ return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); }
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 230 "program_lexer.l"
+{ return_opcode( 1, BIN_OP, XPD, OFF); }
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 231 "program_lexer.l"
+{ return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); }
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 233 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 234 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 235 "program_lexer.l"
+{ return PROGRAM; }
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 236 "program_lexer.l"
+{ return STATE; }
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 237 "program_lexer.l"
+{ return RESULT; }
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 239 "program_lexer.l"
+{ return AMBIENT; }
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 240 "program_lexer.l"
+{ return ATTENUATION; }
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 241 "program_lexer.l"
+{ return BACK; }
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 242 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, CLIP); }
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 243 "program_lexer.l"
+{ return COLOR; }
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 244 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, DEPTH); }
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 245 "program_lexer.l"
+{ return DIFFUSE; }
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 246 "program_lexer.l"
+{ return DIRECTION; }
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 247 "program_lexer.l"
+{ return EMISSION; }
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 248 "program_lexer.l"
+{ return ENV; }
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 249 "program_lexer.l"
+{ return EYE; }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 250 "program_lexer.l"
+{ return FOGCOORD; }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 251 "program_lexer.l"
+{ return FOG; }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 252 "program_lexer.l"
+{ return FRONT; }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 253 "program_lexer.l"
+{ return HALF; }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 254 "program_lexer.l"
+{ return INVERSE; }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 255 "program_lexer.l"
+{ return INVTRANS; }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 256 "program_lexer.l"
+{ return LIGHT; }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 257 "program_lexer.l"
+{ return LIGHTMODEL; }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 258 "program_lexer.l"
+{ return LIGHTPROD; }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 259 "program_lexer.l"
+{ return LOCAL; }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 260 "program_lexer.l"
+{ return MATERIAL; }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 261 "program_lexer.l"
+{ return MAT_PROGRAM; }
+ YY_BREAK
+case 107:
+YY_RULE_SETUP
+#line 262 "program_lexer.l"
+{ return MATRIX; }
+ YY_BREAK
+case 108:
+YY_RULE_SETUP
+#line 263 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+ YY_BREAK
+case 109:
+YY_RULE_SETUP
+#line 264 "program_lexer.l"
+{ return MODELVIEW; }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 265 "program_lexer.l"
+{ return MVP; }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 266 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, NORMAL); }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 267 "program_lexer.l"
+{ return OBJECT; }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 268 "program_lexer.l"
+{ return PALETTE; }
+ YY_BREAK
+case 114:
+YY_RULE_SETUP
+#line 269 "program_lexer.l"
+{ return PARAMS; }
+ YY_BREAK
+case 115:
+YY_RULE_SETUP
+#line 270 "program_lexer.l"
+{ return PLANE; }
+ YY_BREAK
+case 116:
+YY_RULE_SETUP
+#line 271 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 272 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+ YY_BREAK
+case 118:
+YY_RULE_SETUP
+#line 273 "program_lexer.l"
+{ return POSITION; }
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 274 "program_lexer.l"
+{ return PRIMARY; }
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 275 "program_lexer.l"
+{ return PROJECTION; }
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 276 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, RANGE); }
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 277 "program_lexer.l"
+{ return ROW; }
+ YY_BREAK
+case 123:
+YY_RULE_SETUP
+#line 278 "program_lexer.l"
+{ return SCENECOLOR; }
+ YY_BREAK
+case 124:
+YY_RULE_SETUP
+#line 279 "program_lexer.l"
+{ return SECONDARY; }
+ YY_BREAK
+case 125:
+YY_RULE_SETUP
+#line 280 "program_lexer.l"
+{ return SHININESS; }
+ YY_BREAK
+case 126:
+YY_RULE_SETUP
+#line 281 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+ YY_BREAK
+case 127:
+YY_RULE_SETUP
+#line 282 "program_lexer.l"
+{ return SPECULAR; }
+ YY_BREAK
+case 128:
+YY_RULE_SETUP
+#line 283 "program_lexer.l"
+{ return SPOT; }
+ YY_BREAK
+case 129:
+YY_RULE_SETUP
+#line 284 "program_lexer.l"
+{ return TEXCOORD; }
+ YY_BREAK
+case 130:
+YY_RULE_SETUP
+#line 285 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_fp, TEXENV); }
+ YY_BREAK
+case 131:
+YY_RULE_SETUP
+#line 286 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN); }
+ YY_BREAK
+case 132:
+YY_RULE_SETUP
+#line 287 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+ YY_BREAK
+case 133:
+YY_RULE_SETUP
+#line 288 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+ YY_BREAK
+case 134:
+YY_RULE_SETUP
+#line 289 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 290 "program_lexer.l"
+{ return TEXTURE; }
+ YY_BREAK
+case 136:
+YY_RULE_SETUP
+#line 291 "program_lexer.l"
+{ return TRANSPOSE; }
+ YY_BREAK
+case 137:
+YY_RULE_SETUP
+#line 292 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+ YY_BREAK
+case 138:
+YY_RULE_SETUP
+#line 293 "program_lexer.l"
+{ return_token_or_DOT(require_ARB_vp, WEIGHT); }
+ YY_BREAK
+case 139:
+YY_RULE_SETUP
+#line 295 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+ YY_BREAK
+case 140:
+YY_RULE_SETUP
+#line 296 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+ YY_BREAK
+case 141:
+YY_RULE_SETUP
+#line 297 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+ YY_BREAK
+case 142:
+YY_RULE_SETUP
+#line 298 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+ YY_BREAK
+case 143:
+YY_RULE_SETUP
+#line 299 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+ YY_BREAK
+case 144:
+YY_RULE_SETUP
+#line 300 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+ YY_BREAK
+case 145:
+YY_RULE_SETUP
+#line 301 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+ YY_BREAK
+case 146:
+YY_RULE_SETUP
+#line 302 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+ YY_BREAK
+case 147:
+YY_RULE_SETUP
+#line 303 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 304 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+ YY_BREAK
+case 149:
+YY_RULE_SETUP
+#line 305 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 306 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 307 "program_lexer.l"
+{ return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+ YY_BREAK
+case 152:
+YY_RULE_SETUP
+#line 309 "program_lexer.l"
+{
+ yylval->string = strdup(yytext);
+ return IDENTIFIER;
+}
+ YY_BREAK
+case 153:
+YY_RULE_SETUP
+#line 314 "program_lexer.l"
+{ return DOT_DOT; }
+ YY_BREAK
+case 154:
+YY_RULE_SETUP
+#line 316 "program_lexer.l"
+{
+ yylval->integer = strtol(yytext, NULL, 10);
+ return INTEGER;
+}
+ YY_BREAK
+case 155:
+YY_RULE_SETUP
+#line 320 "program_lexer.l"
+{
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 156:
+/* rule 156 can match eol */
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 324 "program_lexer.l"
+{
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 328 "program_lexer.l"
+{
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 158:
+YY_RULE_SETUP
+#line 332 "program_lexer.l"
+{
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 337 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return MASK4;
+}
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 343 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return MASK3;
+}
+ YY_BREAK
+case 161:
+YY_RULE_SETUP
+#line 349 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return MASK3;
+}
+ YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 354 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return MASK3;
+}
+ YY_BREAK
+case 163:
+YY_RULE_SETUP
+#line 360 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+ YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 366 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+ YY_BREAK
+case 165:
+YY_RULE_SETUP
+#line 372 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return MASK2;
+}
+ YY_BREAK
+case 166:
+YY_RULE_SETUP
+#line 378 "program_lexer.l"
+{
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return MASK1;
+}
+ YY_BREAK
+case 167:
+YY_RULE_SETUP
+#line 385 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return SWIZZLE;
+}
+ YY_BREAK
+case 168:
+YY_RULE_SETUP
+#line 394 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return_token_or_DOT(require_ARB_fp, MASK4);
+}
+ YY_BREAK
+case 169:
+YY_RULE_SETUP
+#line 400 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 170:
+YY_RULE_SETUP
+#line 406 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 171:
+YY_RULE_SETUP
+#line 411 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+ YY_BREAK
+case 172:
+YY_RULE_SETUP
+#line 417 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 173:
+YY_RULE_SETUP
+#line 423 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 174:
+YY_RULE_SETUP
+#line 429 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+ YY_BREAK
+case 175:
+YY_RULE_SETUP
+#line 435 "program_lexer.l"
+{
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return_token_or_DOT(require_ARB_fp, MASK1);
+}
+ YY_BREAK
+case 176:
+YY_RULE_SETUP
+#line 443 "program_lexer.l"
+{
+ if (require_ARB_vp) {
+ return TEXGEN_R;
+ } else {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+ SWIZZLE_X, SWIZZLE_X);
+ yylval->swiz_mask.mask = WRITEMASK_X;
+ return MASK1;
+ }
+}
+ YY_BREAK
+case 177:
+YY_RULE_SETUP
+#line 454 "program_lexer.l"
+{
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+ YY_BREAK
+case 178:
+YY_RULE_SETUP
+#line 463 "program_lexer.l"
+{ return DOT; }
+ YY_BREAK
+case 179:
+/* rule 179 can match eol */
+YY_RULE_SETUP
+#line 465 "program_lexer.l"
+{
+ yylloc->first_line++;
+ yylloc->first_column = 1;
+ yylloc->last_line++;
+ yylloc->last_column = 1;
+ yylloc->position++;
+}
+ YY_BREAK
+case 180:
+YY_RULE_SETUP
+#line 472 "program_lexer.l"
+/* eat whitespace */ ;
+ YY_BREAK
+case 181:
+*yy_cp = yyg->yy_hold_char; /* undo effects of setting up yytext */
+yyg->yy_c_buf_p = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 473 "program_lexer.l"
+/* eat comments */ ;
+ YY_BREAK
+case 182:
+YY_RULE_SETUP
+#line 474 "program_lexer.l"
+{ return yytext[0]; }
+ YY_BREAK
+case 183:
+YY_RULE_SETUP
+#line 475 "program_lexer.l"
+ECHO;
+ YY_BREAK
+#line 2383 "lex.yy.c"
+case YY_STATE_EOF(INITIAL):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - yyg->yytext_ptr) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = yyg->yy_hold_char;
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( yyg->yy_c_buf_p <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ yyg->yy_c_buf_p = yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state , yyscanner);
+
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++yyg->yy_c_buf_p;
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = yyg->yy_c_buf_p;
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ yyg->yy_did_buffer_switch_on_eof = 0;
+
+ if ( yywrap(yyscanner ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ yyg->yy_c_buf_p = yyg->yytext_ptr + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p =
+ yyg->yytext_ptr + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ yyg->yy_c_buf_p =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars];
+
+ yy_current_state = yy_get_previous_state( yyscanner );
+
+ yy_cp = yyg->yy_c_buf_p;
+ yy_bp = yyg->yytext_ptr + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = yyg->yytext_ptr;
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( yyg->yy_c_buf_p > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( yyg->yy_c_buf_p - yyg->yytext_ptr - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) (yyg->yy_c_buf_p - yyg->yytext_ptr) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ /* just a shorter name for the current buffer */
+ YY_BUFFER_STATE b = YY_CURRENT_BUFFER;
+
+ int yy_c_buf_p_offset =
+ (int) (yyg->yy_c_buf_p - b->yy_ch_buf);
+
+ if ( b->yy_is_our_buffer )
+ {
+ int new_size = b->yy_buf_size * 2;
+
+ if ( new_size <= 0 )
+ b->yy_buf_size += b->yy_buf_size / 8;
+ else
+ b->yy_buf_size *= 2;
+
+ b->yy_ch_buf = (char *)
+ /* Include room in for 2 EOB chars. */
+ yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ,yyscanner );
+ }
+ else
+ /* Can't grow it, we don't own it. */
+ b->yy_ch_buf = 0;
+
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR(
+ "fatal error - scanner input buffer overflow" );
+
+ yyg->yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
+
+ num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size -
+ number_to_move - 1;
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ yyg->yy_n_chars, (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ if ( yyg->yy_n_chars == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin ,yyscanner);
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) (yyg->yy_n_chars + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = yyg->yy_n_chars + number_to_move + (yyg->yy_n_chars >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size ,yyscanner );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ yyg->yy_n_chars += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
+
+ yyg->yytext_ptr = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (yyscan_t yyscanner)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_current_state = yyg->yy_start;
+
+ for ( yy_cp = yyg->yytext_ptr + YY_MORE_ADJ; yy_cp < yyg->yy_c_buf_p; ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 675 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state , yyscan_t yyscanner)
+{
+ register int yy_is_jam;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner; /* This var may be unused depending upon options. */
+ register char *yy_cp = yyg->yy_c_buf_p;
+
+ register YY_CHAR yy_c = 1;
+ if ( yy_accept[yy_current_state] )
+ {
+ yyg->yy_last_accepting_state = yy_current_state;
+ yyg->yy_last_accepting_cpos = yy_cp;
+ }
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 675 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 674);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp , yyscan_t yyscanner)
+{
+ register char *yy_cp;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_cp = yyg->yy_c_buf_p;
+
+ /* undo effects of setting up yytext */
+ *yy_cp = yyg->yy_hold_char;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = yyg->yy_n_chars + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ yyg->yytext_ptr = yy_bp;
+ yyg->yy_hold_char = *yy_cp;
+ yyg->yy_c_buf_p = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (yyscan_t yyscanner)
+#else
+ static int input (yyscan_t yyscanner)
+#endif
+
+{
+ int c;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+
+ if ( *yyg->yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( yyg->yy_c_buf_p < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[yyg->yy_n_chars] )
+ /* This was really a NUL. */
+ *yyg->yy_c_buf_p = '\0';
+
+ else
+ { /* need more input */
+ int offset = yyg->yy_c_buf_p - yyg->yytext_ptr;
+ ++yyg->yy_c_buf_p;
+
+ switch ( yy_get_next_buffer( yyscanner ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin ,yyscanner);
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap(yyscanner ) )
+ return EOF;
+
+ if ( ! yyg->yy_did_buffer_switch_on_eof )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput(yyscanner);
+#else
+ return input(yyscanner);
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ yyg->yy_c_buf_p = yyg->yytext_ptr + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) yyg->yy_c_buf_p; /* cast for 8-bit char's */
+ *yyg->yy_c_buf_p = '\0'; /* preserve yytext */
+ yyg->yy_hold_char = *++yyg->yy_c_buf_p;
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ * @param yyscanner The scanner object.
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack (yyscanner);
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE ,yyscanner);
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file ,yyscanner);
+ yy_load_buffer_state(yyscanner );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ * @param yyscanner The scanner object.
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack (yyscanner);
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state(yyscanner );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+static void yy_load_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyg->yy_n_chars = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ yyg->yytext_ptr = yyg->yy_c_buf_p = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ yyg->yy_hold_char = *yyg->yy_c_buf_p;
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ * @param yyscanner The scanner object.
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ,yyscanner );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file ,yyscanner);
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ * @param yyscanner The scanner object.
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf ,yyscanner );
+
+ yyfree((void *) b ,yyscanner );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file , yyscan_t yyscanner)
+
+{
+ int oerrno = errno;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ yy_flush_buffer(b ,yyscanner);
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ * @param yyscanner The scanner object.
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state(yyscanner );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ * @param yyscanner The scanner object.
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack(yyscanner);
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *yyg->yy_c_buf_p = yyg->yy_hold_char;
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = yyg->yy_c_buf_p;
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = yyg->yy_n_chars;
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ yyg->yy_buffer_stack_top++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ * @param yyscanner The scanner object.
+ */
+void yypop_buffer_state (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner);
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if (yyg->yy_buffer_stack_top > 0)
+ --yyg->yy_buffer_stack_top;
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state(yyscanner );
+ yyg->yy_did_buffer_switch_on_eof = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (yyscan_t yyscanner)
+{
+ int num_to_alloc;
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (!yyg->yy_buffer_stack) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset(yyg->yy_buffer_stack, 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ yyg->yy_buffer_stack_top = 0;
+ return;
+ }
+
+ if (yyg->yy_buffer_stack_top >= (yyg->yy_buffer_stack_max) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = yyg->yy_buffer_stack_max + grow_size;
+ yyg->yy_buffer_stack = (struct yy_buffer_state**)yyrealloc
+ (yyg->yy_buffer_stack,
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ , yyscanner);
+ if ( ! yyg->yy_buffer_stack )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset(yyg->yy_buffer_stack + yyg->yy_buffer_stack_max, 0, grow_size * sizeof(struct yy_buffer_state*));
+ yyg->yy_buffer_stack_max = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ,yyscanner );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b ,yyscanner );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr , yyscan_t yyscanner)
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) ,yyscanner);
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ * @param yyscanner The scanner object.
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len , yyscan_t yyscanner)
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n ,yyscanner );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n ,yyscanner);
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg , yyscan_t yyscanner)
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = yyg->yy_hold_char; \
+ yyg->yy_c_buf_p = yytext + yyless_macro_arg; \
+ yyg->yy_hold_char = *yyg->yy_c_buf_p; \
+ *yyg->yy_c_buf_p = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the user-defined data for this scanner.
+ * @param yyscanner The scanner object.
+ */
+YY_EXTRA_TYPE yyget_extra (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyextra;
+}
+
+/** Get the current line number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_lineno (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yylineno;
+}
+
+/** Get the current column number.
+ * @param yyscanner The scanner object.
+ */
+int yyget_column (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ if (! YY_CURRENT_BUFFER)
+ return 0;
+
+ return yycolumn;
+}
+
+/** Get the input stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_in (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyin;
+}
+
+/** Get the output stream.
+ * @param yyscanner The scanner object.
+ */
+FILE *yyget_out (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyout;
+}
+
+/** Get the length of the current token.
+ * @param yyscanner The scanner object.
+ */
+int yyget_leng (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yyleng;
+}
+
+/** Get the current token.
+ * @param yyscanner The scanner object.
+ */
+
+char *yyget_text (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yytext;
+}
+
+/** Set the user-defined data. This data is never touched by the scanner.
+ * @param user_defined The data to be associated with this scanner.
+ * @param yyscanner The scanner object.
+ */
+void yyset_extra (YY_EXTRA_TYPE user_defined , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyextra = user_defined ;
+}
+
+/** Set the current line number.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_lineno (int line_number , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* lineno is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_lineno called with no buffer" , yyscanner);
+
+ yylineno = line_number;
+}
+
+/** Set the current column.
+ * @param line_number
+ * @param yyscanner The scanner object.
+ */
+void yyset_column (int column_no , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* column is only valid if an input buffer exists. */
+ if (! YY_CURRENT_BUFFER )
+ yy_fatal_error( "yyset_column called with no buffer" , yyscanner);
+
+ yycolumn = column_no;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ * @param yyscanner The scanner object.
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yyout = out_str ;
+}
+
+int yyget_debug (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yy_flex_debug = bdebug ;
+}
+
+/* Accessor methods for yylval and yylloc */
+
+YYSTYPE * yyget_lval (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylval;
+}
+
+void yyset_lval (YYSTYPE * yylval_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylval = yylval_param;
+}
+
+YYLTYPE *yyget_lloc (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ return yylloc;
+}
+
+void yyset_lloc (YYLTYPE * yylloc_param , yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ yylloc = yylloc_param;
+}
+
+/* User-visible API */
+
+/* yylex_init is special because it creates the scanner itself, so it is
+ * the ONLY reentrant function that doesn't take the scanner as the last argument.
+ * That's why we explicitly handle the declaration, instead of using our macros.
+ */
+
+int yylex_init(yyscan_t* ptr_yy_globals)
+
+{
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), NULL );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+/* yylex_init_extra has the same functionality as yylex_init, but follows the
+ * convention of taking the scanner as the last argument. Note however, that
+ * this is a *pointer* to a scanner, as it will be allocated by this call (and
+ * is the reason, too, why this function also must handle its own declaration).
+ * The user defined value in the first argument will be available to yyalloc in
+ * the yyextra field.
+ */
+
+int yylex_init_extra(YY_EXTRA_TYPE yy_user_defined,yyscan_t* ptr_yy_globals )
+
+{
+ struct yyguts_t dummy_yyguts;
+
+ yyset_extra (yy_user_defined, &dummy_yyguts);
+
+ if (ptr_yy_globals == NULL){
+ errno = EINVAL;
+ return 1;
+ }
+
+ *ptr_yy_globals = (yyscan_t) yyalloc ( sizeof( struct yyguts_t ), &dummy_yyguts );
+
+ if (*ptr_yy_globals == NULL){
+ errno = ENOMEM;
+ return 1;
+ }
+
+ /* By setting to 0xAA, we expose bugs in
+ yy_init_globals. Leave at 0x00 for releases. */
+ memset(*ptr_yy_globals,0x00,sizeof(struct yyguts_t));
+
+ yyset_extra (yy_user_defined, *ptr_yy_globals);
+
+ return yy_init_globals ( *ptr_yy_globals );
+}
+
+static int yy_init_globals (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ yyg->yy_buffer_stack = 0;
+ yyg->yy_buffer_stack_top = 0;
+ yyg->yy_buffer_stack_max = 0;
+ yyg->yy_c_buf_p = (char *) 0;
+ yyg->yy_init = 0;
+ yyg->yy_start = 0;
+
+ yyg->yy_start_stack_ptr = 0;
+ yyg->yy_start_stack_depth = 0;
+ yyg->yy_start_stack = NULL;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (yyscan_t yyscanner)
+{
+ struct yyguts_t * yyg = (struct yyguts_t*)yyscanner;
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER ,yyscanner );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state(yyscanner);
+ }
+
+ /* Destroy the stack itself. */
+ yyfree(yyg->yy_buffer_stack ,yyscanner);
+ yyg->yy_buffer_stack = NULL;
+
+ /* Destroy the start condition stack. */
+ yyfree(yyg->yy_start_stack ,yyscanner );
+ yyg->yy_start_stack = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( yyscanner);
+
+ /* Destroy the main struct (reentrant only). */
+ yyfree ( yyscanner , yyscanner );
+ yyscanner = NULL;
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n , yyscan_t yyscanner)
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s , yyscan_t yyscanner)
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size , yyscan_t yyscanner)
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size , yyscan_t yyscanner)
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr , yyscan_t yyscanner)
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 475 "program_lexer.l"
+
+
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+ const char *string, size_t len)
+{
+ yylex_init_extra(state,scanner);
+ yy_scan_bytes(string,len,*scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+ yylex_destroy(scanner);
+}
+
diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c
index f4beb9a78b..c8a762f8ff 100644
--- a/src/mesa/shader/prog_execute.c
+++ b/src/mesa/shader/prog_execute.c
@@ -922,6 +922,11 @@ _mesa_execute_program(GLcontext * ctx,
{
GLfloat a[4];
fetch_vector4(&inst->SrcReg[0], machine, a);
+ if (DEBUG_PROG) {
+ printf("KIL if (%g %g %g %g) <= 0.0\n",
+ a[0], a[1], a[2], a[3]);
+ }
+
if (a[0] < 0.0F || a[1] < 0.0F || a[2] < 0.0F || a[3] < 0.0F) {
return GL_FALSE;
}
diff --git a/src/mesa/shader/prog_instruction.h b/src/mesa/shader/prog_instruction.h
index 40ad998f79..1c687bc16c 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
/*@}*/
@@ -133,6 +132,7 @@
#define NEGATE_Y 0x2
#define NEGATE_Z 0x4
#define NEGATE_W 0x8
+#define NEGATE_XYZ 0x7
#define NEGATE_XYZW 0xf
#define NEGATE_NONE 0x0
/*@}*/
@@ -303,11 +303,11 @@ struct prog_dst_register
* Condition code swizzle value.
*/
GLuint CondSwizzle:12;
-
+
/**
* Selects the condition code register to use for conditional destination
* update masking. In NV_fragmnet_program or NV_vertex_program2 mode, only
- * condition code register 0 is available. In NV_vertex_program3 mode,
+ * condition code register 0 is available. In NV_vertex_program3 mode,
* condition code registers 0 and 1 are available.
*/
GLuint CondSrc:1;
@@ -359,7 +359,7 @@ struct prog_instruction
* NV_fragment_program, NV_fragment_program_option, NV_vertex_program3.
*/
GLuint SaturateMode:2;
-
+
/**
* Per-instruction selectable precision: FLOAT32, FLOAT16, FIXED12.
*
@@ -374,7 +374,7 @@ struct prog_instruction
/*@{*/
/** Source texture unit. */
GLuint TexSrcUnit:5;
-
+
/** Source texture target, one of TEXTURE_{1D,2D,3D,CUBE,RECT}_INDEX */
GLuint TexSrcTarget:3;
diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c
index bcd8c5d9dc..6b9e73b2cb 100644
--- a/src/mesa/shader/prog_parameter.c
+++ b/src/mesa/shader/prog_parameter.c
@@ -44,6 +44,34 @@ _mesa_new_parameter_list(void)
}
+struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size)
+{
+ struct gl_program_parameter_list *p = _mesa_new_parameter_list();
+
+ if ((p != NULL) && (size != 0)) {
+ p->Size = size;
+
+ /* alloc arrays */
+ p->Parameters = (struct gl_program_parameter *)
+ _mesa_calloc(size * sizeof(struct gl_program_parameter));
+
+ p->ParameterValues = (GLfloat (*)[4])
+ _mesa_align_malloc(size * 4 *sizeof(GLfloat), 16);
+
+
+ if ((p->Parameters == NULL) || (p->ParameterValues == NULL)) {
+ _mesa_free(p->Parameters);
+ _mesa_align_free(p->ParameterValues);
+ _mesa_free(p);
+ p = NULL;
+ }
+ }
+
+ return p;
+}
+
+
/**
* Free a parameter list and all its parameters
*/
diff --git a/src/mesa/shader/prog_parameter.h b/src/mesa/shader/prog_parameter.h
index 01f5a0e179..d1fcf47e61 100644
--- a/src/mesa/shader/prog_parameter.h
+++ b/src/mesa/shader/prog_parameter.h
@@ -84,6 +84,9 @@ struct gl_program_parameter_list
extern struct gl_program_parameter_list *
_mesa_new_parameter_list(void);
+extern struct gl_program_parameter_list *
+_mesa_new_parameter_list_sized(unsigned size);
+
extern void
_mesa_free_parameter_list(struct gl_program_parameter_list *paramList);
diff --git a/src/mesa/shader/prog_parameter_layout.c b/src/mesa/shader/prog_parameter_layout.c
new file mode 100644
index 0000000000..1c37b3a7a5
--- /dev/null
+++ b/src/mesa/shader/prog_parameter_layout.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter_layout.c
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#include "main/mtypes.h"
+#include "prog_parameter.h"
+#include "prog_parameter_layout.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+unsigned
+_mesa_combine_swizzles(unsigned base, unsigned applied)
+{
+ unsigned swiz = 0;
+ unsigned i;
+
+ for (i = 0; i < 4; i++) {
+ const unsigned s = GET_SWZ(applied, i);
+
+ swiz |= ((s <= SWIZZLE_W) ? GET_SWZ(base, s) : s) << (i * 3);
+ }
+
+ return swiz;
+}
+
+
+/**
+ * Copy indirect access array from one parameter list to another
+ *
+ * \param src Parameter array copied from
+ * \param dst Parameter array copied to
+ * \param first Index of first element in \c src to copy
+ * \param count Number of elements to copy
+ *
+ * \return
+ * The location in \c dst of the first element copied from \c src on
+ * success. -1 on failure.
+ *
+ * \warning
+ * This function assumes that there is already enough space available in
+ * \c dst to hold all of the elements that will be copied over.
+ */
+static int
+copy_indirect_accessed_array(struct gl_program_parameter_list *src,
+ struct gl_program_parameter_list *dst,
+ unsigned first, unsigned count)
+{
+ const int base = dst->NumParameters;
+ unsigned i;
+ unsigned j;
+
+
+ for (i = first; i < (first + count); i++) {
+ struct gl_program_parameter *curr = & src->Parameters[i];
+
+
+ if (curr->Type == PROGRAM_CONSTANT) {
+ j = dst->NumParameters;
+ } else {
+ for (j = 0; j < dst->NumParameters; j++) {
+ if (memcmp(dst->Parameters[j].StateIndexes, curr->StateIndexes,
+ sizeof(curr->StateIndexes)) == 0) {
+ return -1;
+ }
+ }
+ }
+
+ assert(j == dst->NumParameters);
+
+ memcpy(& dst->Parameters[j], curr,
+ sizeof(dst->Parameters[j]));
+ memcpy(dst->ParameterValues[j], src->ParameterValues[i],
+ sizeof(GLfloat) * 4);
+ curr->Name = NULL;
+
+ dst->NumParameters++;
+ }
+
+ return base;
+}
+
+
+/**
+ * XXX description???
+ * \return GL_TRUE for success, GL_FALSE for failure
+ */
+GLboolean
+_mesa_layout_parameters(struct asm_parser_state *state)
+{
+ struct gl_program_parameter_list *layout;
+ struct asm_instruction *inst;
+ unsigned i;
+
+
+ layout =
+ _mesa_new_parameter_list_sized(state->prog->Parameters->NumParameters);
+
+
+ /* PASS 1: Move any parameters that are accessed indirectly from the
+ * original parameter list to the new parameter list.
+ */
+ for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+ for (i = 0; i < 3; i++) {
+ if (inst->SrcReg[i].Base.RelAddr) {
+ /* Only attempt to add the to the new parameter list once.
+ */
+ if (!inst->SrcReg[i].Symbol->pass1_done) {
+ const int new_begin =
+ copy_indirect_accessed_array(state->prog->Parameters, layout,
+ inst->SrcReg[i].Symbol->param_binding_begin,
+ inst->SrcReg[i].Symbol->param_binding_length);
+
+ if (new_begin < 0) {
+ return GL_FALSE;
+ }
+
+ inst->SrcReg[i].Symbol->param_binding_begin = new_begin;
+ inst->SrcReg[i].Symbol->pass1_done = 1;
+ }
+
+ /* Previously the Index was just the offset from the parameter
+ * array. Now that the base of the parameter array is known, the
+ * index can be updated to its actual value.
+ */
+ inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+ inst->Base.SrcReg[i].Index +=
+ inst->SrcReg[i].Symbol->param_binding_begin;
+ }
+ }
+ }
+
+
+ /* PASS 2: Move any parameters that are not accessed indirectly from the
+ * original parameter list to the new parameter list.
+ */
+ for (inst = state->inst_head; inst != NULL; inst = inst->next) {
+ for (i = 0; i < 3; i++) {
+ const struct gl_program_parameter *p;
+ const int idx = inst->SrcReg[i].Base.Index;
+ unsigned swizzle = SWIZZLE_NOOP;
+
+
+ /* All relative addressed operands were processed on the first
+ * pass. Just skip them here.
+ */
+ if (inst->SrcReg[i].Base.RelAddr) {
+ continue;
+ }
+
+
+ if ((inst->SrcReg[i].Base.File <= PROGRAM_VARYING )
+ || (inst->SrcReg[i].Base.File >= PROGRAM_WRITE_ONLY)) {
+ continue;
+ }
+
+ inst->Base.SrcReg[i] = inst->SrcReg[i].Base;
+ p = & state->prog->Parameters->Parameters[idx];
+
+ switch (p->Type) {
+ case PROGRAM_CONSTANT: {
+ const float *const v =
+ state->prog->Parameters->ParameterValues[idx];
+
+ inst->Base.SrcReg[i].Index =
+ _mesa_add_unnamed_constant(layout, v, p->Size, & swizzle);
+
+ inst->Base.SrcReg[i].Swizzle =
+ _mesa_combine_swizzles(swizzle, inst->Base.SrcReg[i].Swizzle);
+ break;
+ }
+
+ case PROGRAM_STATE_VAR:
+ inst->Base.SrcReg[i].Index =
+ _mesa_add_state_reference(layout, p->StateIndexes);
+ break;
+
+ default:
+ break;
+ }
+
+ inst->SrcReg[i].Base.File = p->Type;
+ inst->Base.SrcReg[i].File = p->Type;
+ }
+ }
+
+
+ _mesa_free_parameter_list(state->prog->Parameters);
+ state->prog->Parameters = layout;
+
+ return GL_TRUE;
+}
diff --git a/src/mesa/shader/prog_parameter_layout.h b/src/mesa/shader/prog_parameter_layout.h
new file mode 100644
index 0000000000..99a7b6c726
--- /dev/null
+++ b/src/mesa/shader/prog_parameter_layout.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file prog_parameter_layout.h
+ * \brief Helper functions to layout storage for program parameters
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+#pragma once
+
+#ifndef PROG_PARAMETER_LAYOUT_H
+#define PROG_PARAMETER_LAYOUT_H
+
+extern unsigned _mesa_combine_swizzles(unsigned base, unsigned applied);
+
+struct asm_parser_state;
+
+extern GLboolean _mesa_layout_parameters(struct asm_parser_state *state);
+
+#endif /* PROG_PARAMETER_LAYOUT_H */
diff --git a/src/mesa/shader/prog_print.c b/src/mesa/shader/prog_print.c
index de7fef1f86..b71735aa80 100644
--- a/src/mesa/shader/prog_print.c
+++ b/src/mesa/shader/prog_print.c
@@ -533,7 +533,7 @@ void
_mesa_print_alu_instruction(const struct prog_instruction *inst,
const char *opcode_string, GLuint numRegs)
{
- fprint_alu_instruction(stdout, inst, opcode_string,
+ fprint_alu_instruction(stderr, inst, opcode_string,
numRegs, PROG_PRINT_DEBUG, NULL);
}
@@ -541,7 +541,7 @@ _mesa_print_alu_instruction(const struct prog_instruction *inst,
/**
* Print a single vertex/fragment program instruction.
*/
-static GLint
+GLint
_mesa_fprint_instruction_opt(FILE *f,
const struct prog_instruction *inst,
GLint indent,
@@ -757,7 +757,7 @@ _mesa_print_instruction_opt(const struct prog_instruction *inst,
gl_prog_print_mode mode,
const struct gl_program *prog)
{
- return _mesa_fprint_instruction_opt(stdout, inst, indent, mode, prog);
+ return _mesa_fprint_instruction_opt(stderr, inst, indent, mode, prog);
}
@@ -765,7 +765,7 @@ void
_mesa_print_instruction(const struct prog_instruction *inst)
{
/* note: 4th param should be ignored for PROG_PRINT_DEBUG */
- _mesa_fprint_instruction_opt(stdout, inst, 0, PROG_PRINT_DEBUG, NULL);
+ _mesa_fprint_instruction_opt(stderr, inst, 0, PROG_PRINT_DEBUG, NULL);
}
@@ -811,12 +811,35 @@ _mesa_fprint_program_opt(FILE *f,
/**
- * Print program to stdout, default options.
+ * Print program to stderr, default options.
*/
void
_mesa_print_program(const struct gl_program *prog)
{
- _mesa_fprint_program_opt(stdout, prog, PROG_PRINT_DEBUG, GL_TRUE);
+ _mesa_fprint_program_opt(stderr, prog, PROG_PRINT_DEBUG, GL_TRUE);
+}
+
+
+/**
+ * Return binary representation of value (as a string).
+ * Insert a comma to separate each group of 8 bits.
+ * XXX move to imports.[ch] if useful elsewhere.
+ */
+static const char *
+binary(GLbitfield val)
+{
+ static char buf[50];
+ GLint i, len = 0;
+ for (i = 31; i >= 0; --i) {
+ if (val & (1 << i))
+ buf[len++] = '1';
+ else if (len > 0 || i == 0)
+ buf[len++] = '0';
+ if (len > 0 && ((i-1) % 8) == 7)
+ buf[len++] = ',';
+ }
+ buf[len] = '\0';
+ return buf;
}
@@ -830,13 +853,17 @@ _mesa_fprint_program_parameters(FILE *f,
{
GLuint i;
- _mesa_fprintf(f, "InputsRead: 0x%x\n", prog->InputsRead);
- _mesa_fprintf(f, "OutputsWritten: 0x%x\n", prog->OutputsWritten);
+ _mesa_fprintf(f, "InputsRead: 0x%x (0b%s)\n",
+ prog->InputsRead, binary(prog->InputsRead));
+ _mesa_fprintf(f, "OutputsWritten: 0x%x (0b%s)\n",
+ prog->OutputsWritten, binary(prog->OutputsWritten));
_mesa_fprintf(f, "NumInstructions=%d\n", prog->NumInstructions);
_mesa_fprintf(f, "NumTemporaries=%d\n", prog->NumTemporaries);
_mesa_fprintf(f, "NumParameters=%d\n", prog->NumParameters);
_mesa_fprintf(f, "NumAttributes=%d\n", prog->NumAttributes);
_mesa_fprintf(f, "NumAddressRegs=%d\n", prog->NumAddressRegs);
+ _mesa_fprintf(f, "SamplersUsed: 0x%x (0b%s)\n",
+ prog->SamplersUsed, binary(prog->SamplersUsed));
_mesa_fprintf(f, "Samplers=[ ");
for (i = 0; i < MAX_SAMPLERS; i++) {
_mesa_fprintf(f, "%d ", prog->SamplerUnits[i]);
@@ -857,12 +884,12 @@ _mesa_fprint_program_parameters(FILE *f,
/**
- * Print all of a program's parameters/fields to stdout.
+ * Print all of a program's parameters/fields to stderr.
*/
void
_mesa_print_program_parameters(GLcontext *ctx, const struct gl_program *prog)
{
- _mesa_fprint_program_parameters(stdout, ctx, prog);
+ _mesa_fprint_program_parameters(stderr, ctx, prog);
}
@@ -902,12 +929,12 @@ _mesa_fprint_parameter_list(FILE *f,
/**
- * Print a program parameter list to stdout.
+ * Print a program parameter list to stderr.
*/
void
_mesa_print_parameter_list(const struct gl_program_parameter_list *list)
{
- _mesa_fprint_parameter_list(stdout, list);
+ _mesa_fprint_parameter_list(stderr, list);
}
@@ -933,7 +960,7 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
return;
}
- fprintf(f, "/* Shader %u source */\n", shader->Name);
+ fprintf(f, "/* Shader %u source, checksum %u */\n", shader->Name, shader->SourceChecksum);
fputs(shader->Source, f);
fprintf(f, "\n");
@@ -958,3 +985,35 @@ _mesa_write_shader_to_file(const struct gl_shader *shader)
}
+/**
+ * Append the shader's uniform info/values to the shader log file.
+ * The log file will typically have been created by the
+ * _mesa_write_shader_to_file function.
+ */
+void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog)
+{
+ const char *type;
+ char filename[100];
+ FILE *f;
+
+ if (shader->Type == GL_FRAGMENT_SHADER)
+ type = "frag";
+ else
+ type = "vert";
+
+ _mesa_snprintf(filename, sizeof(filename), "shader_%u.%s", shader->Name, type);
+ f = fopen(filename, "a"); /* append */
+ if (!f) {
+ fprintf(stderr, "Unable to open %s for appending\n", filename);
+ return;
+ }
+
+ fprintf(f, "/* First-draw parameters / constants */\n");
+ fprintf(f, "/*\n");
+ _mesa_fprint_parameter_list(f, prog->Parameters);
+ fprintf(f, "*/\n");
+
+ fclose(f);
+}
diff --git a/src/mesa/shader/prog_print.h b/src/mesa/shader/prog_print.h
index d55661cebb..fc286ded54 100644
--- a/src/mesa/shader/prog_print.h
+++ b/src/mesa/shader/prog_print.h
@@ -57,6 +57,13 @@ extern void
_mesa_print_instruction(const struct prog_instruction *inst);
extern GLint
+_mesa_fprint_instruction_opt(FILE *f,
+ const struct prog_instruction *inst,
+ GLint indent,
+ gl_prog_print_mode mode,
+ const struct gl_program *prog);
+
+extern GLint
_mesa_print_instruction_opt(const struct prog_instruction *inst, GLint indent,
gl_prog_print_mode mode,
const struct gl_program *prog);
@@ -79,5 +86,9 @@ _mesa_print_parameter_list(const struct gl_program_parameter_list *list);
extern void
_mesa_write_shader_to_file(const struct gl_shader *shader);
+extern void
+_mesa_append_uniforms_to_file(const struct gl_shader *shader,
+ const struct gl_program *prog);
+
#endif /* PROG_PRINT_H */
diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c
index 4623ff60de..2cd6eb8a38 100644
--- a/src/mesa/shader/program.c
+++ b/src/mesa/shader/program.c
@@ -62,6 +62,12 @@ _mesa_init_program(GLcontext *ctx)
ASSERT(ctx->Const.FragmentProgram.MaxUniformComponents / 4
<= (1 << INST_INDEX_BITS));
+ /* If this fails, increase prog_instruction::TexSrcUnit size */
+ ASSERT(MAX_TEXTURE_UNITS < (1 << 5));
+
+ /* If this fails, increase prog_instruction::TexSrcTarget size */
+ ASSERT(NUM_TEXTURE_TARGETS < (1 << 3));
+
ctx->Program.ErrorPos = -1;
ctx->Program.ErrorString = _mesa_strdup("");
@@ -496,6 +502,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_lexer.l b/src/mesa/shader/program_lexer.l
new file mode 100644
index 0000000000..612f99a42d
--- /dev/null
+++ b/src/mesa/shader/program_lexer.l
@@ -0,0 +1,493 @@
+%{
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include "main/glheader.h"
+#include "prog_instruction.h"
+#include "prog_statevars.h"
+
+#include "program_parser.h"
+#include "program_parse.tab.h"
+
+#define require_ARB_vp (yyextra->mode == ARB_vertex)
+#define require_ARB_fp (yyextra->mode == ARB_fragment)
+#define require_shadow (yyextra->option.Shadow)
+#define require_rect (yyextra->option.TexRect)
+#define require_texarray (yyextra->option.TexArray)
+
+#ifndef HAVE_UNISTD_H
+#define YY_NO_UNISTD_H
+#endif
+
+#define return_token_or_IDENTIFIER(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yylval->string = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+#define return_token_or_DOT(condition, token) \
+ do { \
+ if (condition) { \
+ return token; \
+ } else { \
+ yyless(1); \
+ return DOT; \
+ } \
+ } while (0)
+
+
+#define return_opcode(condition, token, opcode, sat) \
+ do { \
+ if (condition) { \
+ yylval->temp_inst.Opcode = OPCODE_ ## opcode; \
+ yylval->temp_inst.SaturateMode = SATURATE_ ## sat; \
+ return token; \
+ } else { \
+ yylval->string = strdup(yytext); \
+ return IDENTIFIER; \
+ } \
+ } while (0)
+
+#define SWIZZLE_INVAL MAKE_SWIZZLE4(SWIZZLE_NIL, SWIZZLE_NIL, \
+ SWIZZLE_NIL, SWIZZLE_NIL)
+
+static unsigned
+mask_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return WRITEMASK_X;
+ case 'y':
+ case 'g':
+ return WRITEMASK_Y;
+ case 'z':
+ case 'b':
+ return WRITEMASK_Z;
+ case 'w':
+ case 'a':
+ return WRITEMASK_W;
+ }
+
+ return 0;
+}
+
+static unsigned
+swiz_from_char(char c)
+{
+ switch (c) {
+ case 'x':
+ case 'r':
+ return SWIZZLE_X;
+ case 'y':
+ case 'g':
+ return SWIZZLE_Y;
+ case 'z':
+ case 'b':
+ return SWIZZLE_Z;
+ case 'w':
+ case 'a':
+ return SWIZZLE_W;
+ }
+
+ return 0;
+}
+
+#define YY_USER_ACTION \
+ do { \
+ yylloc->first_column = yylloc->last_column; \
+ yylloc->last_column += yyleng; \
+ if ((yylloc->first_line == 1) \
+ && (yylloc->first_column == 1)) { \
+ yylloc->position = 1; \
+ } else { \
+ yylloc->position += yylloc->last_column - yylloc->first_column; \
+ } \
+ } while(0);
+
+#define YY_EXTRA_TYPE struct asm_parser_state *
+%}
+
+num [0-9]+
+exp [Ee][-+]?[0-9]+
+frac "."[0-9]+
+dot "."[ \t]*
+
+%option bison-bridge bison-locations reentrant noyywrap
+%%
+
+"!!ARBvp1.0" { return ARBvp_10; }
+"!!ARBfp1.0" { return ARBfp_10; }
+ADDRESS {
+ yylval->integer = at_address;
+ return_token_or_IDENTIFIER(require_ARB_vp, ADDRESS);
+}
+ALIAS { return ALIAS; }
+ATTRIB { return ATTRIB; }
+END { return END; }
+OPTION { return OPTION; }
+OUTPUT { return OUTPUT; }
+PARAM { return PARAM; }
+TEMP { yylval->integer = at_temp; return TEMP; }
+
+ABS { return_opcode( 1, VECTOR_OP, ABS, OFF); }
+ABS_SAT { return_opcode(require_ARB_fp, VECTOR_OP, ABS, ZERO_ONE); }
+ADD { return_opcode( 1, BIN_OP, ADD, OFF); }
+ADD_SAT { return_opcode(require_ARB_fp, BIN_OP, ADD, ZERO_ONE); }
+ARL { return_opcode(require_ARB_vp, ARL, ARL, OFF); }
+
+CMP { return_opcode(require_ARB_fp, TRI_OP, CMP, OFF); }
+CMP_SAT { return_opcode(require_ARB_fp, TRI_OP, CMP, ZERO_ONE); }
+COS { return_opcode(require_ARB_fp, SCALAR_OP, COS, OFF); }
+COS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, COS, ZERO_ONE); }
+
+DP3 { return_opcode( 1, BIN_OP, DP3, OFF); }
+DP3_SAT { return_opcode(require_ARB_fp, BIN_OP, DP3, ZERO_ONE); }
+DP4 { return_opcode( 1, BIN_OP, DP4, OFF); }
+DP4_SAT { return_opcode(require_ARB_fp, BIN_OP, DP4, ZERO_ONE); }
+DPH { return_opcode( 1, BIN_OP, DPH, OFF); }
+DPH_SAT { return_opcode(require_ARB_fp, BIN_OP, DPH, ZERO_ONE); }
+DST { return_opcode( 1, BIN_OP, DST, OFF); }
+DST_SAT { return_opcode(require_ARB_fp, BIN_OP, DST, ZERO_ONE); }
+
+EX2 { return_opcode( 1, SCALAR_OP, EX2, OFF); }
+EX2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, EX2, ZERO_ONE); }
+EXP { return_opcode(require_ARB_vp, SCALAR_OP, EXP, OFF); }
+
+FLR { return_opcode( 1, VECTOR_OP, FLR, OFF); }
+FLR_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FLR, ZERO_ONE); }
+FRC { return_opcode( 1, VECTOR_OP, FRC, OFF); }
+FRC_SAT { return_opcode(require_ARB_fp, VECTOR_OP, FRC, ZERO_ONE); }
+
+KIL { return_opcode(require_ARB_fp, KIL, KIL, OFF); }
+
+LIT { return_opcode( 1, VECTOR_OP, LIT, OFF); }
+LIT_SAT { return_opcode(require_ARB_fp, VECTOR_OP, LIT, ZERO_ONE); }
+LG2 { return_opcode( 1, SCALAR_OP, LG2, OFF); }
+LG2_SAT { return_opcode(require_ARB_fp, SCALAR_OP, LG2, ZERO_ONE); }
+LOG { return_opcode(require_ARB_vp, SCALAR_OP, LOG, OFF); }
+LRP { return_opcode(require_ARB_fp, TRI_OP, LRP, OFF); }
+LRP_SAT { return_opcode(require_ARB_fp, TRI_OP, LRP, ZERO_ONE); }
+
+MAD { return_opcode( 1, TRI_OP, MAD, OFF); }
+MAD_SAT { return_opcode(require_ARB_fp, TRI_OP, MAD, ZERO_ONE); }
+MAX { return_opcode( 1, BIN_OP, MAX, OFF); }
+MAX_SAT { return_opcode(require_ARB_fp, BIN_OP, MAX, ZERO_ONE); }
+MIN { return_opcode( 1, BIN_OP, MIN, OFF); }
+MIN_SAT { return_opcode(require_ARB_fp, BIN_OP, MIN, ZERO_ONE); }
+MOV { return_opcode( 1, VECTOR_OP, MOV, OFF); }
+MOV_SAT { return_opcode(require_ARB_fp, VECTOR_OP, MOV, ZERO_ONE); }
+MUL { return_opcode( 1, BIN_OP, MUL, OFF); }
+MUL_SAT { return_opcode(require_ARB_fp, BIN_OP, MUL, ZERO_ONE); }
+
+POW { return_opcode( 1, BINSC_OP, POW, OFF); }
+POW_SAT { return_opcode(require_ARB_fp, BINSC_OP, POW, ZERO_ONE); }
+
+RCP { return_opcode( 1, SCALAR_OP, RCP, OFF); }
+RCP_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RCP, ZERO_ONE); }
+RSQ { return_opcode( 1, SCALAR_OP, RSQ, OFF); }
+RSQ_SAT { return_opcode(require_ARB_fp, SCALAR_OP, RSQ, ZERO_ONE); }
+
+SCS { return_opcode(require_ARB_fp, SCALAR_OP, SCS, OFF); }
+SCS_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SCS, ZERO_ONE); }
+SGE { return_opcode( 1, BIN_OP, SGE, OFF); }
+SGE_SAT { return_opcode(require_ARB_fp, BIN_OP, SGE, ZERO_ONE); }
+SIN { return_opcode(require_ARB_fp, SCALAR_OP, SIN, OFF); }
+SIN_SAT { return_opcode(require_ARB_fp, SCALAR_OP, SIN, ZERO_ONE); }
+SLT { return_opcode( 1, BIN_OP, SLT, OFF); }
+SLT_SAT { return_opcode(require_ARB_fp, BIN_OP, SLT, ZERO_ONE); }
+SUB { return_opcode( 1, BIN_OP, SUB, OFF); }
+SUB_SAT { return_opcode(require_ARB_fp, BIN_OP, SUB, ZERO_ONE); }
+SWZ { return_opcode( 1, SWZ, SWZ, OFF); }
+SWZ_SAT { return_opcode(require_ARB_fp, SWZ, SWZ, ZERO_ONE); }
+
+TEX { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, OFF); }
+TEX_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TEX, ZERO_ONE); }
+TXB { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, OFF); }
+TXB_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXB, ZERO_ONE); }
+TXP { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, OFF); }
+TXP_SAT { return_opcode(require_ARB_fp, SAMPLE_OP, TXP, ZERO_ONE); }
+
+XPD { return_opcode( 1, BIN_OP, XPD, OFF); }
+XPD_SAT { return_opcode(require_ARB_fp, BIN_OP, XPD, ZERO_ONE); }
+
+vertex { return_token_or_IDENTIFIER(require_ARB_vp, VERTEX); }
+fragment { return_token_or_IDENTIFIER(require_ARB_fp, FRAGMENT); }
+program { return PROGRAM; }
+state { return STATE; }
+result { return RESULT; }
+
+{dot}ambient { return AMBIENT; }
+{dot}attenuation { return ATTENUATION; }
+{dot}back { return BACK; }
+{dot}clip { return_token_or_DOT(require_ARB_vp, CLIP); }
+{dot}color { return COLOR; }
+{dot}depth { return_token_or_DOT(require_ARB_fp, DEPTH); }
+{dot}diffuse { return DIFFUSE; }
+{dot}direction { return DIRECTION; }
+{dot}emission { return EMISSION; }
+{dot}env { return ENV; }
+{dot}eye { return EYE; }
+{dot}fogcoord { return FOGCOORD; }
+{dot}fog { return FOG; }
+{dot}front { return FRONT; }
+{dot}half { return HALF; }
+{dot}inverse { return INVERSE; }
+{dot}invtrans { return INVTRANS; }
+{dot}light { return LIGHT; }
+{dot}lightmodel { return LIGHTMODEL; }
+{dot}lightprod { return LIGHTPROD; }
+{dot}local { return LOCAL; }
+{dot}material { return MATERIAL; }
+{dot}program { return MAT_PROGRAM; }
+{dot}matrix { return MATRIX; }
+{dot}matrixindex { return_token_or_DOT(require_ARB_vp, MATRIXINDEX); }
+{dot}modelview { return MODELVIEW; }
+{dot}mvp { return MVP; }
+{dot}normal { return_token_or_DOT(require_ARB_vp, NORMAL); }
+{dot}object { return OBJECT; }
+{dot}palette { return PALETTE; }
+{dot}params { return PARAMS; }
+{dot}plane { return PLANE; }
+{dot}point { return_token_or_DOT(require_ARB_vp, POINT_TOK); }
+{dot}pointsize { return_token_or_DOT(require_ARB_vp, POINTSIZE); }
+{dot}position { return POSITION; }
+{dot}primary { return PRIMARY; }
+{dot}projection { return PROJECTION; }
+{dot}range { return_token_or_DOT(require_ARB_fp, RANGE); }
+{dot}row { return ROW; }
+{dot}scenecolor { return SCENECOLOR; }
+{dot}secondary { return SECONDARY; }
+{dot}shininess { return SHININESS; }
+{dot}size { return_token_or_DOT(require_ARB_vp, SIZE_TOK); }
+{dot}specular { return SPECULAR; }
+{dot}spot { return SPOT; }
+{dot}texcoord { return TEXCOORD; }
+{dot}texenv { return_token_or_DOT(require_ARB_fp, TEXENV); }
+{dot}texgen { return_token_or_DOT(require_ARB_vp, TEXGEN); }
+{dot}q { return_token_or_DOT(require_ARB_vp, TEXGEN_Q); }
+{dot}s { return_token_or_DOT(require_ARB_vp, TEXGEN_S); }
+{dot}t { return_token_or_DOT(require_ARB_vp, TEXGEN_T); }
+{dot}texture { return TEXTURE; }
+{dot}transpose { return TRANSPOSE; }
+{dot}attrib { return_token_or_DOT(require_ARB_vp, VTXATTRIB); }
+{dot}weight { return_token_or_DOT(require_ARB_vp, WEIGHT); }
+
+texture { return_token_or_IDENTIFIER(require_ARB_fp, TEXTURE_UNIT); }
+1D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_1D); }
+2D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_2D); }
+3D { return_token_or_IDENTIFIER(require_ARB_fp, TEX_3D); }
+CUBE { return_token_or_IDENTIFIER(require_ARB_fp, TEX_CUBE); }
+RECT { return_token_or_IDENTIFIER(require_ARB_fp && require_rect, TEX_RECT); }
+SHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW1D); }
+SHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow, TEX_SHADOW2D); }
+SHADOWRECT { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_rect, TEX_SHADOWRECT); }
+ARRAY1D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY1D); }
+ARRAY2D { return_token_or_IDENTIFIER(require_ARB_fp && require_texarray, TEX_ARRAY2D); }
+ARRAYSHADOW1D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW1D); }
+ARRAYSHADOW2D { return_token_or_IDENTIFIER(require_ARB_fp && require_shadow && require_texarray, TEX_ARRAYSHADOW2D); }
+
+[_a-zA-Z$][_a-zA-Z0-9$]* {
+ yylval->string = strdup(yytext);
+ return IDENTIFIER;
+}
+
+".." { return DOT_DOT; }
+
+{num} {
+ yylval->integer = strtol(yytext, NULL, 10);
+ return INTEGER;
+}
+{num}?{frac}{exp}? {
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+{num}"."/[^.] {
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+{num}{exp} {
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+{num}"."{exp} {
+ yylval->real = strtod(yytext, NULL);
+ return REAL;
+}
+
+".xyzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return MASK4;
+}
+
+".xy"[zw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return MASK3;
+}
+".xzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return MASK3;
+}
+".yzw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return MASK3;
+}
+
+".x"[yzw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+".y"[zw] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return MASK2;
+}
+".zw" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return MASK2;
+}
+
+"."[xyzw] {
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return MASK1;
+}
+
+"."[xyzw]{4} {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return SWIZZLE;
+}
+
+".rgba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_NOOP;
+ yylval->swiz_mask.mask = WRITEMASK_XYZW;
+ return_token_or_DOT(require_ARB_fp, MASK4);
+}
+
+".rg"[ba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XY
+ | mask_from_char(yytext[3]);
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".rba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_XZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+".gba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_YZW;
+ return_token_or_DOT(require_ARB_fp, MASK3);
+}
+
+".r"[gba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_X
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".g"[ba] {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_Y
+ | mask_from_char(yytext[2]);
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+".ba" {
+ yylval->swiz_mask.swizzle = SWIZZLE_INVAL;
+ yylval->swiz_mask.mask = WRITEMASK_ZW;
+ return_token_or_DOT(require_ARB_fp, MASK2);
+}
+
+"."[gba] {
+ const unsigned s = swiz_from_char(yytext[1]);
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(s, s, s, s);
+ yylval->swiz_mask.mask = mask_from_char(yytext[1]);
+ return_token_or_DOT(require_ARB_fp, MASK1);
+}
+
+
+".r" {
+ if (require_ARB_vp) {
+ return TEXGEN_R;
+ } else {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X,
+ SWIZZLE_X, SWIZZLE_X);
+ yylval->swiz_mask.mask = WRITEMASK_X;
+ return MASK1;
+ }
+}
+
+"."[rgba]{4} {
+ yylval->swiz_mask.swizzle = MAKE_SWIZZLE4(swiz_from_char(yytext[1]),
+ swiz_from_char(yytext[2]),
+ swiz_from_char(yytext[3]),
+ swiz_from_char(yytext[4]));
+ yylval->swiz_mask.mask = 0;
+ return_token_or_DOT(require_ARB_fp, SWIZZLE);
+}
+
+"." { return DOT; }
+
+\n {
+ yylloc->first_line++;
+ yylloc->first_column = 1;
+ yylloc->last_line++;
+ yylloc->last_column = 1;
+ yylloc->position++;
+}
+[ \t\r]+ /* eat whitespace */ ;
+#.*$ /* eat comments */ ;
+. { return yytext[0]; }
+%%
+
+void
+_mesa_program_lexer_ctor(void **scanner, struct asm_parser_state *state,
+ const char *string, size_t len)
+{
+ yylex_init_extra(state, scanner);
+ yy_scan_bytes(string, len, *scanner);
+}
+
+void
+_mesa_program_lexer_dtor(void *scanner)
+{
+ yylex_destroy(scanner);
+}
diff --git a/src/mesa/shader/program_parse.tab.c b/src/mesa/shader/program_parse.tab.c
new file mode 100644
index 0000000000..2de950b73b
--- /dev/null
+++ b/src/mesa/shader/program_parse.tab.c
@@ -0,0 +1,5253 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+ simplifying the original so-called "semantic" parser. */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+ infringing on user name space. This should be done even for local
+ variables, as they might otherwise be expanded by user macros.
+ There are some unavoidable exceptions within include files to
+ define necessary library symbols; they are noted "INFRINGES ON
+ USER NAME SPACE" below. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.4.1"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers. */
+#define YYPURE 1
+
+/* Push parsers. */
+#define YYPUSH 0
+
+/* Pull parsers. */
+#define YYPULL 1
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+
+
+/* Copy the first part of user declarations. */
+
+/* Line 189 of yacc.c */
+#line 1 "program_parse.y"
+
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program.h"
+#include "prog_parameter.h"
+#include "prog_parameter_layout.h"
+#include "prog_statevars.h"
+#include "prog_instruction.h"
+
+#include "symbol_table.h"
+#include "program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+ char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var, const struct asm_vector *vec);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+ const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+ struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (YYID(N)) { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 1).position; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } else { \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_line = (Current).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \
+ (Current).last_column = (Current).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 0).position \
+ + (Current).first_column; \
+ } \
+ } while(YYID(0))
+
+#define YYLEX_PARAM state->scanner
+
+
+/* Line 189 of yacc.c */
+#line 174 "program_parse.tab.c"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 1
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ARBvp_10 = 258,
+ ARBfp_10 = 259,
+ ADDRESS = 260,
+ ALIAS = 261,
+ ATTRIB = 262,
+ OPTION = 263,
+ OUTPUT = 264,
+ PARAM = 265,
+ TEMP = 266,
+ END = 267,
+ BIN_OP = 268,
+ BINSC_OP = 269,
+ SAMPLE_OP = 270,
+ SCALAR_OP = 271,
+ TRI_OP = 272,
+ VECTOR_OP = 273,
+ ARL = 274,
+ KIL = 275,
+ SWZ = 276,
+ INTEGER = 277,
+ REAL = 278,
+ AMBIENT = 279,
+ ATTENUATION = 280,
+ BACK = 281,
+ CLIP = 282,
+ COLOR = 283,
+ DEPTH = 284,
+ DIFFUSE = 285,
+ DIRECTION = 286,
+ EMISSION = 287,
+ ENV = 288,
+ EYE = 289,
+ FOG = 290,
+ FOGCOORD = 291,
+ FRAGMENT = 292,
+ FRONT = 293,
+ HALF = 294,
+ INVERSE = 295,
+ INVTRANS = 296,
+ LIGHT = 297,
+ LIGHTMODEL = 298,
+ LIGHTPROD = 299,
+ LOCAL = 300,
+ MATERIAL = 301,
+ MAT_PROGRAM = 302,
+ MATRIX = 303,
+ MATRIXINDEX = 304,
+ MODELVIEW = 305,
+ MVP = 306,
+ NORMAL = 307,
+ OBJECT = 308,
+ PALETTE = 309,
+ PARAMS = 310,
+ PLANE = 311,
+ POINT_TOK = 312,
+ POINTSIZE = 313,
+ POSITION = 314,
+ PRIMARY = 315,
+ PROGRAM = 316,
+ PROJECTION = 317,
+ RANGE = 318,
+ RESULT = 319,
+ ROW = 320,
+ SCENECOLOR = 321,
+ SECONDARY = 322,
+ SHININESS = 323,
+ SIZE_TOK = 324,
+ SPECULAR = 325,
+ SPOT = 326,
+ STATE = 327,
+ TEXCOORD = 328,
+ TEXENV = 329,
+ TEXGEN = 330,
+ TEXGEN_Q = 331,
+ TEXGEN_R = 332,
+ TEXGEN_S = 333,
+ TEXGEN_T = 334,
+ TEXTURE = 335,
+ TRANSPOSE = 336,
+ TEXTURE_UNIT = 337,
+ TEX_1D = 338,
+ TEX_2D = 339,
+ TEX_3D = 340,
+ TEX_CUBE = 341,
+ TEX_RECT = 342,
+ TEX_SHADOW1D = 343,
+ TEX_SHADOW2D = 344,
+ TEX_SHADOWRECT = 345,
+ TEX_ARRAY1D = 346,
+ TEX_ARRAY2D = 347,
+ TEX_ARRAYSHADOW1D = 348,
+ TEX_ARRAYSHADOW2D = 349,
+ VERTEX = 350,
+ VTXATTRIB = 351,
+ WEIGHT = 352,
+ IDENTIFIER = 353,
+ MASK4 = 354,
+ MASK3 = 355,
+ MASK2 = 356,
+ MASK1 = 357,
+ SWIZZLE = 358,
+ DOT_DOT = 359,
+ DOT = 360
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 214 of yacc.c */
+#line 107 "program_parse.y"
+
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+
+
+
+/* Line 214 of yacc.c */
+#line 343 "program_parse.tab.c"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations. */
+
+/* Line 264 of yacc.c */
+#line 249 "program_parse.y"
+
+extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ void *yyscanner);
+
+
+/* Line 264 of yacc.c */
+#line 374 "program_parse.tab.c"
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+# define YYSIZE_T __SIZE_TYPE__
+# elif defined size_t
+# define YYSIZE_T size_t
+# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
+# define YYSIZE_T size_t
+# else
+# define YYSIZE_T unsigned int
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int yyi)
+#else
+static int
+YYID (yyi)
+ int yyi;
+#endif
+{
+ return yyi;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols. */
+
+# ifdef YYSTACK_USE_ALLOCA
+# if YYSTACK_USE_ALLOCA
+# ifdef __GNUC__
+# define YYSTACK_ALLOC __builtin_alloca
+# elif defined __BUILTIN_VA_ARG_INCR
+# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+# elif defined _AIX
+# define YYSTACK_ALLOC __alloca
+# elif defined _MSC_VER
+# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+# define alloca _alloca
+# else
+# define YYSTACK_ALLOC alloca
+# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# endif
+# endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+ /* Pacify GCC's `empty if-body' warning. */
+# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+# ifndef YYSTACK_ALLOC_MAXIMUM
+ /* The OS might guarantee only one guard page at the bottom of the stack,
+ and a page size can be as small as 4096 bytes. So we cannot safely
+ invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
+ to allow for a few compiler-allocated temporary stack slots. */
+# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+# endif
+# else
+# define YYSTACK_ALLOC YYMALLOC
+# define YYSTACK_FREE YYFREE
+# ifndef YYSTACK_ALLOC_MAXIMUM
+# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+# endif
+# if (defined __cplusplus && ! defined _STDLIB_H \
+ && ! ((defined YYMALLOC || defined malloc) \
+ && (defined YYFREE || defined free)))
+# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+# ifndef _STDLIB_H
+# define _STDLIB_H 1
+# endif
+# endif
+# ifndef YYMALLOC
+# define YYMALLOC malloc
+# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# ifndef YYFREE
+# define YYFREE free
+# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+# endif
+# endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+ && (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member. */
+union yyalloc
+{
+ yytype_int16 yyss_alloc;
+ YYSTYPE yyvs_alloc;
+ YYLTYPE yyls_alloc;
+};
+
+/* The size of the maximum gap between one aligned stack and the next. */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+ N elements. */
+# define YYSTACK_BYTES(N) \
+ ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+ + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO. The source and destination do
+ not overlap. */
+# ifndef YYCOPY
+# if defined __GNUC__ && 1 < __GNUC__
+# define YYCOPY(To, From, Count) \
+ __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+# else
+# define YYCOPY(To, From, Count) \
+ do \
+ { \
+ YYSIZE_T yyi; \
+ for (yyi = 0; yyi < (Count); yyi++) \
+ (To)[yyi] = (From)[yyi]; \
+ } \
+ while (YYID (0))
+# endif
+# endif
+
+/* Relocate STACK from its old location to the new one. The
+ local variables YYSIZE and YYSTACKSIZE give the old and new number of
+ elements in the stack, and YYPTR gives the new location of the
+ stack. Advance YYPTR to a properly aligned location for the next
+ stack. */
+# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
+ do \
+ { \
+ YYSIZE_T yynewbytes; \
+ YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
+ Stack = &yyptr->Stack_alloc; \
+ yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+ yyptr += yynewbytes / sizeof (*yyptr); \
+ } \
+ while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 5
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 342
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 115
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 134
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 264
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 436
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 360
+
+#define YYTRANSLATE(YYX) \
+ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const yytype_uint8 yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 110, 107, 111, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 106,
+ 2, 112, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 108, 2, 109, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 113, 2, 114, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const yytype_uint16 yyprhs[] =
+{
+ 0, 0, 3, 8, 10, 12, 15, 16, 20, 23,
+ 24, 27, 30, 32, 34, 36, 38, 40, 42, 44,
+ 46, 48, 50, 52, 57, 62, 67, 74, 81, 90,
+ 99, 102, 105, 107, 109, 111, 113, 115, 117, 119,
+ 121, 123, 125, 127, 129, 136, 140, 144, 147, 150,
+ 158, 161, 163, 165, 167, 169, 174, 176, 178, 180,
+ 182, 184, 186, 188, 192, 193, 196, 199, 201, 203,
+ 205, 207, 209, 211, 213, 215, 217, 218, 220, 222,
+ 224, 226, 227, 229, 231, 233, 235, 237, 239, 244,
+ 247, 250, 252, 255, 257, 260, 262, 265, 270, 275,
+ 277, 278, 282, 284, 286, 289, 291, 294, 296, 298,
+ 302, 309, 310, 312, 315, 320, 322, 326, 328, 330,
+ 332, 334, 336, 338, 340, 342, 344, 346, 349, 352,
+ 355, 358, 361, 364, 367, 370, 373, 376, 379, 382,
+ 386, 388, 390, 392, 398, 400, 402, 404, 407, 409,
+ 411, 414, 416, 419, 426, 428, 432, 434, 436, 438,
+ 440, 442, 447, 449, 451, 453, 455, 457, 459, 462,
+ 464, 466, 472, 474, 477, 479, 481, 487, 490, 491,
+ 498, 502, 503, 505, 507, 509, 511, 513, 516, 518,
+ 520, 523, 528, 533, 534, 538, 540, 542, 544, 547,
+ 549, 551, 553, 555, 561, 563, 567, 573, 579, 581,
+ 585, 591, 593, 595, 597, 599, 601, 603, 605, 607,
+ 609, 613, 619, 627, 637, 640, 643, 645, 647, 648,
+ 649, 653, 654, 658, 662, 664, 669, 672, 675, 678,
+ 681, 685, 688, 692, 693, 695, 697, 698, 700, 702,
+ 703, 705, 707, 708, 710, 712, 713, 717, 718, 722,
+ 723, 727, 729, 731, 733
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const yytype_int16 yyrhs[] =
+{
+ 116, 0, -1, 117, 118, 120, 12, -1, 3, -1,
+ 4, -1, 118, 119, -1, -1, 8, 98, 106, -1,
+ 120, 121, -1, -1, 122, 106, -1, 158, 106, -1,
+ 123, -1, 124, -1, 125, -1, 126, -1, 127, -1,
+ 128, -1, 129, -1, 130, -1, 135, -1, 131, -1,
+ 132, -1, 19, 139, 107, 136, -1, 18, 138, 107,
+ 137, -1, 16, 138, 107, 136, -1, 14, 138, 107,
+ 136, 107, 136, -1, 13, 138, 107, 137, 107, 137,
+ -1, 17, 138, 107, 137, 107, 137, 107, 137, -1,
+ 15, 138, 107, 137, 107, 133, 107, 134, -1, 20,
+ 137, -1, 82, 243, -1, 83, -1, 84, -1, 85,
+ -1, 86, -1, 87, -1, 88, -1, 89, -1, 90,
+ -1, 91, -1, 92, -1, 93, -1, 94, -1, 21,
+ 138, 107, 143, 107, 140, -1, 229, 143, 155, -1,
+ 229, 143, 156, -1, 144, 157, -1, 152, 154, -1,
+ 141, 107, 141, 107, 141, 107, 141, -1, 229, 142,
+ -1, 22, -1, 98, -1, 98, -1, 160, -1, 145,
+ 108, 146, 109, -1, 174, -1, 236, -1, 98, -1,
+ 98, -1, 147, -1, 148, -1, 22, -1, 152, 153,
+ 149, -1, -1, 110, 150, -1, 111, 151, -1, 22,
+ -1, 22, -1, 98, -1, 102, -1, 102, -1, 102,
+ -1, 102, -1, 99, -1, 103, -1, -1, 99, -1,
+ 100, -1, 101, -1, 102, -1, -1, 159, -1, 166,
+ -1, 230, -1, 232, -1, 235, -1, 248, -1, 7,
+ 98, 112, 160, -1, 95, 161, -1, 37, 165, -1,
+ 59, -1, 97, 163, -1, 52, -1, 28, 241, -1,
+ 36, -1, 73, 242, -1, 49, 108, 164, 109, -1,
+ 96, 108, 162, 109, -1, 22, -1, -1, 108, 164,
+ 109, -1, 22, -1, 59, -1, 28, 241, -1, 36,
+ -1, 73, 242, -1, 167, -1, 168, -1, 10, 98,
+ 170, -1, 10, 98, 108, 169, 109, 171, -1, -1,
+ 22, -1, 112, 173, -1, 112, 113, 172, 114, -1,
+ 175, -1, 172, 107, 175, -1, 177, -1, 213, -1,
+ 223, -1, 177, -1, 213, -1, 224, -1, 176, -1,
+ 214, -1, 223, -1, 177, -1, 72, 201, -1, 72,
+ 178, -1, 72, 180, -1, 72, 183, -1, 72, 185,
+ -1, 72, 191, -1, 72, 187, -1, 72, 194, -1,
+ 72, 196, -1, 72, 198, -1, 72, 200, -1, 72,
+ 212, -1, 46, 240, 179, -1, 189, -1, 32, -1,
+ 68, -1, 42, 108, 190, 109, 181, -1, 189, -1,
+ 59, -1, 25, -1, 71, 182, -1, 39, -1, 31,
+ -1, 43, 184, -1, 24, -1, 240, 66, -1, 44,
+ 108, 190, 109, 240, 186, -1, 189, -1, 74, 244,
+ 188, -1, 28, -1, 24, -1, 30, -1, 70, -1,
+ 22, -1, 75, 242, 192, 193, -1, 34, -1, 53,
+ -1, 78, -1, 79, -1, 77, -1, 76, -1, 35,
+ 195, -1, 28, -1, 55, -1, 27, 108, 197, 109,
+ 56, -1, 22, -1, 57, 199, -1, 69, -1, 25,
+ -1, 203, 65, 108, 206, 109, -1, 203, 202, -1,
+ -1, 65, 108, 206, 104, 206, 109, -1, 48, 207,
+ 204, -1, -1, 205, -1, 40, -1, 81, -1, 41,
+ -1, 22, -1, 50, 208, -1, 62, -1, 51, -1,
+ 80, 242, -1, 54, 108, 210, 109, -1, 47, 108,
+ 211, 109, -1, -1, 108, 209, 109, -1, 22, -1,
+ 22, -1, 22, -1, 29, 63, -1, 217, -1, 220,
+ -1, 215, -1, 218, -1, 61, 33, 108, 216, 109,
+ -1, 221, -1, 221, 104, 221, -1, 61, 33, 108,
+ 221, 109, -1, 61, 45, 108, 219, 109, -1, 222,
+ -1, 222, 104, 222, -1, 61, 45, 108, 222, 109,
+ -1, 22, -1, 22, -1, 225, -1, 227, -1, 226,
+ -1, 227, -1, 228, -1, 23, -1, 22, -1, 113,
+ 228, 114, -1, 113, 228, 107, 228, 114, -1, 113,
+ 228, 107, 228, 107, 228, 114, -1, 113, 228, 107,
+ 228, 107, 228, 107, 228, 114, -1, 229, 23, -1,
+ 229, 22, -1, 110, -1, 111, -1, -1, -1, 11,
+ 231, 234, -1, -1, 5, 233, 234, -1, 234, 107,
+ 98, -1, 98, -1, 9, 98, 112, 236, -1, 64,
+ 59, -1, 64, 36, -1, 64, 237, -1, 64, 58,
+ -1, 64, 73, 242, -1, 64, 29, -1, 28, 238,
+ 239, -1, -1, 38, -1, 26, -1, -1, 60, -1,
+ 67, -1, -1, 38, -1, 26, -1, -1, 60, -1,
+ 67, -1, -1, 108, 245, 109, -1, -1, 108, 246,
+ 109, -1, -1, 108, 247, 109, -1, 22, -1, 22,
+ -1, 22, -1, 6, 98, 112, 98, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const yytype_uint16 yyrline[] =
+{
+ 0, 256, 256, 259, 267, 279, 280, 283, 305, 306,
+ 309, 324, 327, 332, 339, 340, 341, 342, 343, 344,
+ 345, 348, 349, 352, 358, 365, 372, 380, 387, 395,
+ 440, 447, 453, 454, 455, 456, 457, 458, 459, 460,
+ 461, 462, 463, 464, 467, 480, 493, 506, 528, 537,
+ 570, 577, 592, 642, 684, 695, 716, 726, 732, 763,
+ 780, 780, 782, 789, 801, 802, 803, 806, 820, 834,
+ 852, 863, 875, 877, 878, 879, 880, 883, 883, 883,
+ 883, 884, 887, 888, 889, 890, 891, 892, 895, 913,
+ 917, 923, 927, 931, 935, 944, 953, 957, 962, 968,
+ 979, 979, 980, 982, 986, 990, 994, 1000, 1000, 1002,
+ 1018, 1041, 1044, 1055, 1061, 1067, 1068, 1075, 1081, 1087,
+ 1095, 1101, 1107, 1115, 1121, 1127, 1135, 1136, 1139, 1140,
+ 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1152,
+ 1161, 1165, 1169, 1175, 1184, 1188, 1192, 1201, 1205, 1211,
+ 1217, 1224, 1229, 1237, 1247, 1249, 1257, 1263, 1267, 1271,
+ 1277, 1288, 1297, 1301, 1306, 1310, 1314, 1318, 1324, 1331,
+ 1335, 1341, 1349, 1360, 1367, 1371, 1377, 1387, 1398, 1402,
+ 1420, 1429, 1432, 1438, 1442, 1446, 1452, 1463, 1468, 1473,
+ 1478, 1483, 1488, 1496, 1499, 1504, 1517, 1525, 1536, 1544,
+ 1544, 1546, 1546, 1548, 1558, 1563, 1570, 1580, 1589, 1594,
+ 1601, 1611, 1621, 1633, 1633, 1634, 1634, 1636, 1646, 1654,
+ 1664, 1672, 1680, 1689, 1700, 1704, 1710, 1711, 1712, 1715,
+ 1715, 1718, 1718, 1721, 1727, 1735, 1748, 1757, 1766, 1770,
+ 1779, 1788, 1799, 1806, 1811, 1820, 1832, 1835, 1844, 1855,
+ 1856, 1857, 1860, 1861, 1862, 1865, 1866, 1869, 1870, 1873,
+ 1874, 1877, 1888, 1899, 1910
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "$end", "error", "$undefined", "ARBvp_10", "ARBfp_10", "ADDRESS",
+ "ALIAS", "ATTRIB", "OPTION", "OUTPUT", "PARAM", "TEMP", "END", "BIN_OP",
+ "BINSC_OP", "SAMPLE_OP", "SCALAR_OP", "TRI_OP", "VECTOR_OP", "ARL",
+ "KIL", "SWZ", "INTEGER", "REAL", "AMBIENT", "ATTENUATION", "BACK",
+ "CLIP", "COLOR", "DEPTH", "DIFFUSE", "DIRECTION", "EMISSION", "ENV",
+ "EYE", "FOG", "FOGCOORD", "FRAGMENT", "FRONT", "HALF", "INVERSE",
+ "INVTRANS", "LIGHT", "LIGHTMODEL", "LIGHTPROD", "LOCAL", "MATERIAL",
+ "MAT_PROGRAM", "MATRIX", "MATRIXINDEX", "MODELVIEW", "MVP", "NORMAL",
+ "OBJECT", "PALETTE", "PARAMS", "PLANE", "POINT_TOK", "POINTSIZE",
+ "POSITION", "PRIMARY", "PROGRAM", "PROJECTION", "RANGE", "RESULT", "ROW",
+ "SCENECOLOR", "SECONDARY", "SHININESS", "SIZE_TOK", "SPECULAR", "SPOT",
+ "STATE", "TEXCOORD", "TEXENV", "TEXGEN", "TEXGEN_Q", "TEXGEN_R",
+ "TEXGEN_S", "TEXGEN_T", "TEXTURE", "TRANSPOSE", "TEXTURE_UNIT", "TEX_1D",
+ "TEX_2D", "TEX_3D", "TEX_CUBE", "TEX_RECT", "TEX_SHADOW1D",
+ "TEX_SHADOW2D", "TEX_SHADOWRECT", "TEX_ARRAY1D", "TEX_ARRAY2D",
+ "TEX_ARRAYSHADOW1D", "TEX_ARRAYSHADOW2D", "VERTEX", "VTXATTRIB",
+ "WEIGHT", "IDENTIFIER", "MASK4", "MASK3", "MASK2", "MASK1", "SWIZZLE",
+ "DOT_DOT", "DOT", "';'", "','", "'['", "']'", "'+'", "'-'", "'='", "'{'",
+ "'}'", "$accept", "program", "language", "optionSequence", "option",
+ "statementSequence", "statement", "instruction", "ALU_instruction",
+ "TexInstruction", "ARL_instruction", "VECTORop_instruction",
+ "SCALARop_instruction", "BINSCop_instruction", "BINop_instruction",
+ "TRIop_instruction", "SAMPLE_instruction", "KIL_instruction",
+ "texImageUnit", "texTarget", "SWZ_instruction", "scalarSrcReg",
+ "swizzleSrcReg", "maskedDstReg", "maskedAddrReg", "extendedSwizzle",
+ "extSwizComp", "extSwizSel", "srcReg", "dstReg", "progParamArray",
+ "progParamArrayMem", "progParamArrayAbs", "progParamArrayRel",
+ "addrRegRelOffset", "addrRegPosOffset", "addrRegNegOffset", "addrReg",
+ "addrComponent", "addrWriteMask", "scalarSuffix", "swizzleSuffix",
+ "optionalMask", "namingStatement", "ATTRIB_statement", "attribBinding",
+ "vtxAttribItem", "vtxAttribNum", "vtxOptWeightNum", "vtxWeightNum",
+ "fragAttribItem", "PARAM_statement", "PARAM_singleStmt",
+ "PARAM_multipleStmt", "optArraySize", "paramSingleInit",
+ "paramMultipleInit", "paramMultInitList", "paramSingleItemDecl",
+ "paramSingleItemUse", "paramMultipleItem", "stateMultipleItem",
+ "stateSingleItem", "stateMaterialItem", "stateMatProperty",
+ "stateLightItem", "stateLightProperty", "stateSpotProperty",
+ "stateLightModelItem", "stateLModProperty", "stateLightProdItem",
+ "stateLProdProperty", "stateTexEnvItem", "stateTexEnvProperty",
+ "ambDiffSpecProperty", "stateLightNumber", "stateTexGenItem",
+ "stateTexGenType", "stateTexGenCoord", "stateFogItem",
+ "stateFogProperty", "stateClipPlaneItem", "stateClipPlaneNum",
+ "statePointItem", "statePointProperty", "stateMatrixRow",
+ "stateMatrixRows", "optMatrixRows", "stateMatrixItem",
+ "stateOptMatModifier", "stateMatModifier", "stateMatrixRowNum",
+ "stateMatrixName", "stateOptModMatNum", "stateModMatNum",
+ "statePaletteMatNum", "stateProgramMatNum", "stateDepthItem",
+ "programSingleItem", "programMultipleItem", "progEnvParams",
+ "progEnvParamNums", "progEnvParam", "progLocalParams",
+ "progLocalParamNums", "progLocalParam", "progEnvParamNum",
+ "progLocalParamNum", "paramConstDecl", "paramConstUse",
+ "paramConstScalarDecl", "paramConstScalarUse", "paramConstVector",
+ "signedFloatConstant", "optionalSign", "TEMP_statement", "@1",
+ "ADDRESS_statement", "@2", "varNameList", "OUTPUT_statement",
+ "resultBinding", "resultColBinding", "optResultFaceType",
+ "optResultColorType", "optFaceType", "optColorType",
+ "optTexCoordUnitNum", "optTexImageUnitNum", "optLegacyTexUnitNum",
+ "texCoordUnitNum", "texImageUnitNum", "legacyTexUnitNum",
+ "ALIAS_statement", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+ token YYLEX-NUM. */
+static const yytype_uint16 yytoknum[] =
+{
+ 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
+ 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
+ 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
+ 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
+ 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
+ 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
+ 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
+ 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
+ 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
+ 355, 356, 357, 358, 359, 360, 59, 44, 91, 93,
+ 43, 45, 61, 123, 125
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const yytype_uint8 yyr1[] =
+{
+ 0, 115, 116, 117, 117, 118, 118, 119, 120, 120,
+ 121, 121, 122, 122, 123, 123, 123, 123, 123, 123,
+ 123, 124, 124, 125, 126, 127, 128, 129, 130, 131,
+ 132, 133, 134, 134, 134, 134, 134, 134, 134, 134,
+ 134, 134, 134, 134, 135, 136, 137, 138, 139, 140,
+ 141, 142, 142, 143, 143, 143, 143, 144, 144, 145,
+ 146, 146, 147, 148, 149, 149, 149, 150, 151, 152,
+ 153, 154, 155, 156, 156, 156, 156, 157, 157, 157,
+ 157, 157, 158, 158, 158, 158, 158, 158, 159, 160,
+ 160, 161, 161, 161, 161, 161, 161, 161, 161, 162,
+ 163, 163, 164, 165, 165, 165, 165, 166, 166, 167,
+ 168, 169, 169, 170, 171, 172, 172, 173, 173, 173,
+ 174, 174, 174, 175, 175, 175, 176, 176, 177, 177,
+ 177, 177, 177, 177, 177, 177, 177, 177, 177, 178,
+ 179, 179, 179, 180, 181, 181, 181, 181, 181, 182,
+ 183, 184, 184, 185, 186, 187, 188, 189, 189, 189,
+ 190, 191, 192, 192, 193, 193, 193, 193, 194, 195,
+ 195, 196, 197, 198, 199, 199, 200, 201, 202, 202,
+ 203, 204, 204, 205, 205, 205, 206, 207, 207, 207,
+ 207, 207, 207, 208, 208, 209, 210, 211, 212, 213,
+ 213, 214, 214, 215, 216, 216, 217, 218, 219, 219,
+ 220, 221, 222, 223, 223, 224, 224, 225, 226, 226,
+ 227, 227, 227, 227, 228, 228, 229, 229, 229, 231,
+ 230, 233, 232, 234, 234, 235, 236, 236, 236, 236,
+ 236, 236, 237, 238, 238, 238, 239, 239, 239, 240,
+ 240, 240, 241, 241, 241, 242, 242, 243, 243, 244,
+ 244, 245, 246, 247, 248
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const yytype_uint8 yyr2[] =
+{
+ 0, 2, 4, 1, 1, 2, 0, 3, 2, 0,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 4, 4, 4, 6, 6, 8, 8,
+ 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 6, 3, 3, 2, 2, 7,
+ 2, 1, 1, 1, 1, 4, 1, 1, 1, 1,
+ 1, 1, 1, 3, 0, 2, 2, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 4, 2,
+ 2, 1, 2, 1, 2, 1, 2, 4, 4, 1,
+ 0, 3, 1, 1, 2, 1, 2, 1, 1, 3,
+ 6, 0, 1, 2, 4, 1, 3, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 3,
+ 1, 1, 1, 5, 1, 1, 1, 2, 1, 1,
+ 2, 1, 2, 6, 1, 3, 1, 1, 1, 1,
+ 1, 4, 1, 1, 1, 1, 1, 1, 2, 1,
+ 1, 5, 1, 2, 1, 1, 5, 2, 0, 6,
+ 3, 0, 1, 1, 1, 1, 1, 2, 1, 1,
+ 2, 4, 4, 0, 3, 1, 1, 1, 2, 1,
+ 1, 1, 1, 5, 1, 3, 5, 5, 1, 3,
+ 5, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 3, 5, 7, 9, 2, 2, 1, 1, 0, 0,
+ 3, 0, 3, 3, 1, 4, 2, 2, 2, 2,
+ 3, 2, 3, 0, 1, 1, 0, 1, 1, 0,
+ 1, 1, 0, 1, 1, 0, 3, 0, 3, 0,
+ 3, 1, 1, 1, 4
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+ STATE-NUM when YYTABLE doesn't specify something else to do. Zero
+ means the default is an error. */
+static const yytype_uint16 yydefact[] =
+{
+ 0, 3, 4, 0, 6, 1, 9, 0, 5, 0,
+ 0, 231, 0, 0, 0, 0, 229, 2, 0, 0,
+ 0, 0, 0, 0, 0, 228, 0, 8, 0, 12,
+ 13, 14, 15, 16, 17, 18, 19, 21, 22, 20,
+ 0, 82, 83, 107, 108, 84, 85, 86, 87, 7,
+ 0, 0, 0, 0, 0, 0, 0, 58, 0, 81,
+ 57, 0, 0, 0, 0, 0, 69, 0, 0, 226,
+ 227, 30, 0, 0, 10, 11, 234, 232, 0, 0,
+ 0, 111, 228, 109, 230, 243, 241, 237, 239, 236,
+ 255, 238, 228, 77, 78, 79, 80, 47, 228, 228,
+ 228, 228, 228, 228, 71, 48, 219, 218, 0, 0,
+ 0, 0, 53, 228, 76, 0, 54, 56, 120, 121,
+ 199, 200, 122, 215, 216, 0, 0, 264, 88, 235,
+ 112, 0, 113, 117, 118, 119, 213, 214, 217, 0,
+ 245, 244, 246, 0, 240, 0, 0, 0, 0, 25,
+ 0, 24, 23, 252, 105, 103, 255, 90, 0, 0,
+ 0, 0, 0, 0, 249, 0, 249, 0, 0, 259,
+ 255, 128, 129, 130, 131, 133, 132, 134, 135, 136,
+ 137, 0, 138, 252, 95, 0, 93, 91, 255, 0,
+ 100, 89, 0, 74, 73, 75, 46, 0, 0, 233,
+ 0, 225, 224, 247, 248, 242, 261, 0, 228, 228,
+ 0, 0, 228, 253, 254, 104, 106, 0, 0, 0,
+ 198, 169, 170, 168, 0, 151, 251, 250, 150, 0,
+ 0, 0, 0, 193, 189, 0, 188, 255, 181, 175,
+ 174, 173, 0, 0, 0, 0, 94, 0, 96, 0,
+ 0, 92, 228, 220, 62, 0, 60, 61, 0, 228,
+ 0, 110, 256, 27, 26, 72, 45, 257, 0, 0,
+ 211, 0, 212, 0, 172, 0, 160, 0, 152, 0,
+ 157, 158, 141, 142, 159, 139, 140, 0, 0, 187,
+ 0, 190, 183, 185, 184, 180, 182, 263, 0, 156,
+ 155, 162, 163, 0, 0, 102, 0, 99, 0, 0,
+ 0, 55, 70, 64, 44, 0, 0, 228, 0, 31,
+ 0, 228, 206, 210, 0, 0, 249, 197, 0, 195,
+ 0, 196, 0, 260, 167, 166, 164, 165, 161, 186,
+ 0, 97, 98, 101, 228, 221, 0, 0, 63, 228,
+ 51, 52, 50, 0, 0, 0, 115, 123, 126, 124,
+ 201, 202, 125, 262, 0, 32, 33, 34, 35, 36,
+ 37, 38, 39, 40, 41, 42, 43, 29, 28, 171,
+ 146, 148, 145, 0, 143, 144, 0, 192, 194, 191,
+ 176, 0, 67, 65, 68, 66, 0, 0, 0, 127,
+ 178, 228, 114, 258, 149, 147, 153, 154, 228, 222,
+ 228, 0, 0, 0, 177, 116, 0, 0, 0, 204,
+ 0, 208, 0, 223, 228, 203, 0, 207, 0, 0,
+ 49, 205, 209, 0, 0, 179
+};
+
+/* YYDEFGOTO[NTERM-NUM]. */
+static const yytype_int16 yydefgoto[] =
+{
+ -1, 3, 4, 6, 8, 9, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 268, 377,
+ 39, 146, 71, 58, 67, 314, 315, 352, 114, 59,
+ 115, 255, 256, 257, 348, 393, 395, 68, 313, 105,
+ 266, 196, 97, 40, 41, 116, 191, 308, 251, 306,
+ 157, 42, 43, 44, 131, 83, 261, 355, 132, 117,
+ 356, 357, 118, 171, 285, 172, 384, 405, 173, 228,
+ 174, 406, 175, 300, 286, 277, 176, 303, 338, 177,
+ 223, 178, 275, 179, 241, 180, 399, 414, 181, 295,
+ 296, 340, 238, 289, 330, 332, 328, 182, 119, 359,
+ 360, 418, 120, 361, 420, 121, 271, 273, 362, 122,
+ 136, 123, 124, 138, 72, 45, 55, 46, 50, 77,
+ 47, 60, 91, 142, 205, 229, 215, 144, 319, 243,
+ 207, 364, 298, 48
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -369
+static const yytype_int16 yypact[] =
+{
+ 143, -369, -369, 36, -369, -369, 45, -39, -369, 169,
+ -33, -369, -19, -6, -4, 12, -369, -369, -34, -34,
+ -34, -34, -34, -34, 15, 62, -34, -369, 26, -369,
+ -369, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ 60, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ 20, 56, 107, 110, 37, 20, -3, -369, 111, 109,
+ -369, 113, 114, 116, 117, 118, -369, 119, 125, -369,
+ -369, -369, -15, 121, -369, -369, -369, 122, 132, -18,
+ 167, 210, -11, -369, 122, 63, -369, -369, -369, -369,
+ 130, -369, 62, -369, -369, -369, -369, -369, 62, 62,
+ 62, 62, 62, 62, -369, -369, -369, -369, 9, 72,
+ 87, -1, 131, 62, 104, 134, -369, -369, -369, -369,
+ -369, -369, -369, -369, -369, -15, 142, -369, -369, -369,
+ -369, 135, -369, -369, -369, -369, -369, -369, -369, 182,
+ -369, -369, 52, 219, -369, 138, 139, -15, 140, -369,
+ 141, -369, -369, 61, -369, -369, 130, -369, 144, 145,
+ 146, 180, 11, 147, 85, 148, 99, 89, -2, 149,
+ 130, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ -369, 184, -369, 61, -369, 150, -369, -369, 130, 151,
+ 152, -369, 27, -369, -369, -369, -369, -10, 154, -369,
+ 153, -369, -369, -369, -369, -369, -369, 155, 62, 62,
+ 161, 168, 62, -369, -369, -369, -369, 229, 244, 246,
+ -369, -369, -369, -369, 247, -369, -369, -369, -369, 204,
+ 247, 17, 163, 164, -369, 165, -369, 130, 67, -369,
+ -369, -369, 252, 248, 18, 170, -369, 253, -369, 255,
+ 253, -369, 62, -369, -369, 171, -369, -369, 177, 62,
+ 172, -369, -369, -369, -369, -369, -369, 173, 175, 176,
+ -369, 178, -369, 179, -369, 181, -369, 183, -369, 185,
+ -369, -369, -369, -369, -369, -369, -369, 262, 264, -369,
+ 267, -369, -369, -369, -369, -369, -369, -369, 186, -369,
+ -369, -369, -369, 136, 269, -369, 187, -369, 188, 190,
+ 43, -369, -369, 106, -369, 193, -5, -7, 271, -369,
+ 108, 62, -369, -369, 245, 4, 99, -369, 194, -369,
+ 195, -369, 196, -369, -369, -369, -369, -369, -369, -369,
+ 197, -369, -369, -369, 62, -369, 280, 285, -369, 62,
+ -369, -369, -369, 93, 87, 53, -369, -369, -369, -369,
+ -369, -369, -369, -369, 199, -369, -369, -369, -369, -369,
+ -369, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ -369, -369, -369, 278, -369, -369, 8, -369, -369, -369,
+ -369, 57, -369, -369, -369, -369, 203, 205, 206, -369,
+ 250, -7, -369, -369, -369, -369, -369, -369, 62, -369,
+ 62, 229, 244, 208, -369, -369, 198, 211, 202, 213,
+ 214, 218, 269, -369, 62, -369, 229, -369, 244, 54,
+ -369, -369, -369, 269, 215, -369
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const yytype_int16 yypgoto[] =
+{
+ -369, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ -369, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ -369, -94, -88, 133, -369, -369, -334, -369, -85, -369,
+ -369, -369, -369, -369, -369, -369, -369, 128, -369, -369,
+ -369, -369, -369, -369, -369, 251, -369, -369, -369, 77,
+ -369, -369, -369, -369, -369, -369, -369, -369, -369, -369,
+ -72, -369, -81, -369, -369, -369, -369, -369, -369, -369,
+ -369, -369, -369, -369, -305, 101, -369, -369, -369, -369,
+ -369, -369, -369, -369, -369, -369, -369, -369, -22, -369,
+ -369, -336, -369, -369, -369, -369, -369, -369, 254, -369,
+ -369, -369, -369, -369, -369, -369, -342, -368, 256, -369,
+ -369, -369, -80, -110, -82, -369, -369, -369, -369, 279,
+ -369, 257, -369, -369, -369, -161, 156, -146, -369, -369,
+ -369, -369, -369, -369
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -60
+static const yytype_int16 yytable[] =
+{
+ 139, 133, 137, 192, 145, 231, 149, 106, 107, 152,
+ 216, 148, 254, 150, 151, 396, 147, 350, 147, 108,
+ 385, 147, 108, 239, 244, 85, 86, 183, 280, 380,
+ 56, 139, 280, 87, 281, 184, 5, 153, 281, 221,
+ 198, 280, 248, 381, 421, 154, 109, 281, 185, 282,
+ 109, 186, 301, 7, 353, 88, 89, 110, 187, 10,
+ 432, 110, 210, 382, 57, 354, 222, 240, 155, 419,
+ 90, 302, 188, 49, 284, 383, 417, 111, 284, 51,
+ 111, 407, 156, 112, 431, 283, 429, 284, 66, 140,
+ 430, 291, 52, 351, 53, 189, 190, 434, 113, 69,
+ 70, 141, 113, 69, 70, 158, 113, 292, 293, 225,
+ 54, 226, 203, 66, 160, 264, 161, 159, 76, 204,
+ 263, 213, 162, 227, 269, 226, 397, 147, 214, 163,
+ 164, 165, 74, 166, 252, 167, 232, 227, 398, 233,
+ 234, 253, 310, 235, 168, 81, 1, 2, 294, 82,
+ 344, 236, 61, 62, 63, 64, 65, 345, 433, 73,
+ 401, 169, 170, 390, 408, 386, 75, 402, 78, 237,
+ 139, 409, 69, 70, 11, 12, 13, 316, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 365, 366, 367, 368, 369, 370, 371, 372, 373,
+ 374, 375, 376, 193, 201, 202, 194, 195, 93, 94,
+ 95, 96, 334, 335, 336, 337, 346, 347, 92, 79,
+ 98, 99, 80, 100, 101, 102, 103, 104, 125, 126,
+ 127, 56, 130, 378, 391, 139, 358, 137, 143, -59,
+ 199, 206, 197, 220, 200, 208, 209, 211, 212, 245,
+ 267, 270, 217, 218, 219, 224, 230, 242, 247, 249,
+ 250, 259, 139, 265, 262, 260, 272, 316, 274, 276,
+ 278, 287, 288, 290, 297, 305, 299, 307, 304, 312,
+ 311, 318, 320, 321, 327, 317, 329, 322, 323, 331,
+ 324, 339, 325, 363, 326, 333, 341, 342, 416, 343,
+ 349, 379, 392, 387, 388, 389, 390, 394, 403, 404,
+ 410, 425, 423, 411, 412, 413, 422, 426, 424, 139,
+ 358, 137, 428, 427, 435, 258, 139, 309, 316, 415,
+ 128, 279, 400, 0, 84, 0, 134, 129, 135, 246,
+ 0, 0, 316
+};
+
+static const yytype_int16 yycheck[] =
+{
+ 82, 82, 82, 113, 92, 166, 100, 22, 23, 103,
+ 156, 99, 22, 101, 102, 349, 98, 22, 100, 37,
+ 325, 103, 37, 25, 170, 28, 29, 28, 24, 25,
+ 64, 113, 24, 36, 30, 36, 0, 28, 30, 28,
+ 125, 24, 188, 39, 412, 36, 61, 30, 49, 32,
+ 61, 52, 34, 8, 61, 58, 59, 72, 59, 98,
+ 428, 72, 147, 59, 98, 72, 55, 69, 59, 411,
+ 73, 53, 73, 106, 70, 71, 410, 95, 70, 98,
+ 95, 386, 73, 98, 426, 68, 422, 70, 98, 26,
+ 424, 237, 98, 98, 98, 96, 97, 433, 113, 110,
+ 111, 38, 113, 110, 111, 33, 113, 40, 41, 24,
+ 98, 26, 60, 98, 27, 209, 29, 45, 98, 67,
+ 208, 60, 35, 38, 212, 26, 33, 209, 67, 42,
+ 43, 44, 106, 46, 107, 48, 47, 38, 45, 50,
+ 51, 114, 252, 54, 57, 108, 3, 4, 81, 112,
+ 107, 62, 19, 20, 21, 22, 23, 114, 104, 26,
+ 107, 74, 75, 109, 107, 326, 106, 114, 112, 80,
+ 252, 114, 110, 111, 5, 6, 7, 259, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 83, 84, 85, 86, 87, 88, 89, 90, 91,
+ 92, 93, 94, 99, 22, 23, 102, 103, 99, 100,
+ 101, 102, 76, 77, 78, 79, 110, 111, 107, 112,
+ 107, 107, 112, 107, 107, 107, 107, 102, 107, 107,
+ 98, 64, 22, 321, 344, 317, 317, 317, 108, 108,
+ 98, 22, 108, 63, 109, 107, 107, 107, 107, 65,
+ 82, 22, 108, 108, 108, 108, 108, 108, 108, 108,
+ 108, 107, 344, 102, 109, 112, 22, 349, 22, 22,
+ 66, 108, 108, 108, 22, 22, 28, 22, 108, 102,
+ 109, 108, 107, 107, 22, 113, 22, 109, 109, 22,
+ 109, 22, 109, 22, 109, 109, 109, 109, 408, 109,
+ 107, 56, 22, 109, 109, 109, 109, 22, 109, 31,
+ 107, 109, 114, 108, 108, 65, 108, 104, 107, 401,
+ 401, 401, 104, 109, 109, 197, 408, 250, 410, 401,
+ 79, 230, 354, -1, 55, -1, 82, 80, 82, 183,
+ -1, -1, 424
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const yytype_uint8 yystos[] =
+{
+ 0, 3, 4, 116, 117, 0, 118, 8, 119, 120,
+ 98, 5, 6, 7, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 121, 122, 123,
+ 124, 125, 126, 127, 128, 129, 130, 131, 132, 135,
+ 158, 159, 166, 167, 168, 230, 232, 235, 248, 106,
+ 233, 98, 98, 98, 98, 231, 64, 98, 138, 144,
+ 236, 138, 138, 138, 138, 138, 98, 139, 152, 110,
+ 111, 137, 229, 138, 106, 106, 98, 234, 112, 112,
+ 112, 108, 112, 170, 234, 28, 29, 36, 58, 59,
+ 73, 237, 107, 99, 100, 101, 102, 157, 107, 107,
+ 107, 107, 107, 107, 102, 154, 22, 23, 37, 61,
+ 72, 95, 98, 113, 143, 145, 160, 174, 177, 213,
+ 217, 220, 224, 226, 227, 107, 107, 98, 160, 236,
+ 22, 169, 173, 177, 213, 223, 225, 227, 228, 229,
+ 26, 38, 238, 108, 242, 137, 136, 229, 137, 136,
+ 137, 137, 136, 28, 36, 59, 73, 165, 33, 45,
+ 27, 29, 35, 42, 43, 44, 46, 48, 57, 74,
+ 75, 178, 180, 183, 185, 187, 191, 194, 196, 198,
+ 200, 203, 212, 28, 36, 49, 52, 59, 73, 96,
+ 97, 161, 228, 99, 102, 103, 156, 108, 143, 98,
+ 109, 22, 23, 60, 67, 239, 22, 245, 107, 107,
+ 143, 107, 107, 60, 67, 241, 242, 108, 108, 108,
+ 63, 28, 55, 195, 108, 24, 26, 38, 184, 240,
+ 108, 240, 47, 50, 51, 54, 62, 80, 207, 25,
+ 69, 199, 108, 244, 242, 65, 241, 108, 242, 108,
+ 108, 163, 107, 114, 22, 146, 147, 148, 152, 107,
+ 112, 171, 109, 137, 136, 102, 155, 82, 133, 137,
+ 22, 221, 22, 222, 22, 197, 22, 190, 66, 190,
+ 24, 30, 32, 68, 70, 179, 189, 108, 108, 208,
+ 108, 242, 40, 41, 81, 204, 205, 22, 247, 28,
+ 188, 34, 53, 192, 108, 22, 164, 22, 162, 164,
+ 228, 109, 102, 153, 140, 141, 229, 113, 108, 243,
+ 107, 107, 109, 109, 109, 109, 109, 22, 211, 22,
+ 209, 22, 210, 109, 76, 77, 78, 79, 193, 22,
+ 206, 109, 109, 109, 107, 114, 110, 111, 149, 107,
+ 22, 98, 142, 61, 72, 172, 175, 176, 177, 214,
+ 215, 218, 223, 22, 246, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 134, 137, 56,
+ 25, 39, 59, 71, 181, 189, 240, 109, 109, 109,
+ 109, 228, 22, 150, 22, 151, 141, 33, 45, 201,
+ 203, 107, 114, 109, 31, 182, 186, 189, 107, 114,
+ 107, 108, 108, 65, 202, 175, 228, 141, 216, 221,
+ 219, 222, 108, 114, 107, 109, 104, 109, 104, 206,
+ 141, 221, 222, 104, 206, 109
+};
+
+#define yyerrok (yyerrstatus = 0)
+#define yyclearin (yychar = YYEMPTY)
+#define YYEMPTY (-2)
+#define YYEOF 0
+
+#define YYACCEPT goto yyacceptlab
+#define YYABORT goto yyabortlab
+#define YYERROR goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror. This remains here temporarily
+ to ease the transition to the new meaning of YYERROR, for GCC.
+ Once GCC version 2 has supplanted version 1, this can go. */
+
+#define YYFAIL goto yyerrlab
+
+#define YYRECOVERING() (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value) \
+do \
+ if (yychar == YYEMPTY && yylen == 1) \
+ { \
+ yychar = (Token); \
+ yylval = (Value); \
+ yytoken = YYTRANSLATE (yychar); \
+ YYPOPSTACK (1); \
+ goto yybackup; \
+ } \
+ else \
+ { \
+ yyerror (&yylloc, state, YY_("syntax error: cannot back up")); \
+ YYERROR; \
+ } \
+while (YYID (0))
+
+
+#define YYTERROR 1
+#define YYERRCODE 256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+# else
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, scanner)
+#endif
+
+/* Enable debugging if requested. */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, \
+ Type, Value, Location, state); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+ YYUSE (state);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, struct asm_parser_state *state)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, state)
+ FILE *yyoutput;
+ int yytype;
+ YYSTYPE const * const yyvaluep;
+ YYLTYPE const * const yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, state);
+ YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included). |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
+#else
+static void
+yy_stack_print (yybottom, yytop)
+ yytype_int16 *yybottom;
+ yytype_int16 *yytop;
+#endif
+{
+ YYFPRINTF (stderr, "Stack now");
+ for (; yybottom <= yytop; yybottom++)
+ {
+ int yybot = *yybottom;
+ YYFPRINTF (stderr, " %d", yybot);
+ }
+ YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top) \
+do { \
+ if (yydebug) \
+ yy_stack_print ((Bottom), (Top)); \
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced. |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, struct asm_parser_state *state)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, state)
+ YYSTYPE *yyvsp;
+ YYLTYPE *yylsp;
+ int yyrule;
+ struct asm_parser_state *state;
+#endif
+{
+ int yynrhs = yyr2[yyrule];
+ int yyi;
+ unsigned long int yylno = yyrline[yyrule];
+ YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+ yyrule - 1, yylno);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ YYFPRINTF (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(yyvsp[(yyi + 1) - (yynrhs)])
+ , &(yylsp[(yyi + 1) - (yynrhs)]) , state);
+ YYFPRINTF (stderr, "\n");
+ }
+}
+
+# define YY_REDUCE_PRINT(Rule) \
+do { \
+ if (yydebug) \
+ yy_reduce_print (yyvsp, yylsp, Rule, state); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+# if defined __GLIBC__ && defined _STRING_H
+# define yystrlen strlen
+# else
+/* Return the length of YYSTR. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+ const char *yystr;
+#endif
+{
+ YYSIZE_T yylen;
+ for (yylen = 0; yystr[yylen]; yylen++)
+ continue;
+ return yylen;
+}
+# endif
+# endif
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+ char *yydest;
+ const char *yysrc;
+#endif
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ YYSIZE_T yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return yystrlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+ YYCHAR while in state YYSTATE. Return the number of bytes copied,
+ including the terminating null byte. If YYRESULT is null, do not
+ copy anything; just return the number of bytes that would be
+ copied. As a special case, return 0 if an ordinary "syntax error"
+ message will do. Return YYSIZE_MAXIMUM if overflow occurs during
+ size calculation. */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+ int yyn = yypact[yystate];
+
+ if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+ return 0;
+ else
+ {
+ int yytype = YYTRANSLATE (yychar);
+ YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+ YYSIZE_T yysize = yysize0;
+ YYSIZE_T yysize1;
+ int yysize_overflow = 0;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+
+# if 0
+ /* This is so xgettext sees the translatable formats that are
+ constructed on the fly. */
+ YY_("syntax error, unexpected %s");
+ YY_("syntax error, unexpected %s, expecting %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+ YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytname[yytype];
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytname[yyx];
+ yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + yystrlen (yyf);
+ yysize_overflow |= (yysize1 < yysize);
+ yysize = yysize1;
+
+ if (yysize_overflow)
+ return YYSIZE_MAXIMUM;
+
+ if (yyresult)
+ {
+ /* Avoid sprintf, as that infringes on the user's name space.
+ Don't have undefined behavior even if the translation
+ produced a string with the wrong number of "%s"s. */
+ char *yyp = yyresult;
+ int yyi = 0;
+ while ((*yyp = *yyf) != '\0')
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ }
+ return yysize;
+ }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, struct asm_parser_state *state)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, state)
+ const char *yymsg;
+ int yytype;
+ YYSTYPE *yyvaluep;
+ YYLTYPE *yylocationp;
+ struct asm_parser_state *state;
+#endif
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+ YYUSE (state);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/* Prevent warnings from -Wmissing-prototypes. */
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (struct asm_parser_state *state);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+/*-------------------------.
+| yyparse or yypush_parse. |
+`-------------------------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+ void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (struct asm_parser_state *state)
+#else
+int
+yyparse (state)
+ struct asm_parser_state *state;
+#endif
+#endif
+{
+/* The lookahead symbol. */
+int yychar;
+
+/* The semantic value of the lookahead symbol. */
+YYSTYPE yylval;
+
+/* Location data for the lookahead symbol. */
+YYLTYPE yylloc;
+
+ /* Number of syntax errors so far. */
+ int yynerrs;
+
+ int yystate;
+ /* Number of tokens to shift before error messages enabled. */
+ int yyerrstatus;
+
+ /* The stacks and their tools:
+ `yyss': related to states.
+ `yyvs': related to semantic values.
+ `yyls': related to locations.
+
+ Refer to the stacks thru separate pointers, to allow yyoverflow
+ to reallocate them elsewhere. */
+
+ /* The state stack. */
+ yytype_int16 yyssa[YYINITDEPTH];
+ yytype_int16 *yyss;
+ yytype_int16 *yyssp;
+
+ /* The semantic value stack. */
+ YYSTYPE yyvsa[YYINITDEPTH];
+ YYSTYPE *yyvs;
+ YYSTYPE *yyvsp;
+
+ /* The location stack. */
+ YYLTYPE yylsa[YYINITDEPTH];
+ YYLTYPE *yyls;
+ YYLTYPE *yylsp;
+
+ /* The locations where the error started and ended. */
+ YYLTYPE yyerror_range[2];
+
+ YYSIZE_T yystacksize;
+
+ int yyn;
+ int yyresult;
+ /* Lookahead token as an internal (translated) token number. */
+ int yytoken;
+ /* The variables used to return semantic value and location from the
+ action routines. */
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+
+#if YYERROR_VERBOSE
+ /* Buffer for error messages, and its allocated size. */
+ char yymsgbuf[128];
+ char *yymsg = yymsgbuf;
+ YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+ /* The number of symbols on the RHS of the reduced rule.
+ Keep to zero when no symbol should be popped. */
+ int yylen = 0;
+
+ yytoken = 0;
+ yyss = yyssa;
+ yyvs = yyvsa;
+ yyls = yylsa;
+ yystacksize = YYINITDEPTH;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yystate = 0;
+ yyerrstatus = 0;
+ yynerrs = 0;
+ yychar = YYEMPTY; /* Cause a token to be read. */
+
+ /* Initialize stack pointers.
+ Waste one element of value and location stack
+ so that they stay on the same level as the state stack.
+ The wasted elements are never initialized. */
+ yyssp = yyss;
+ yyvsp = yyvs;
+ yylsp = yyls;
+
+#if YYLTYPE_IS_TRIVIAL
+ /* Initialize the default location before parsing starts. */
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 1;
+#endif
+
+ goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate. |
+`------------------------------------------------------------*/
+ yynewstate:
+ /* In all cases, when you get here, the value and location stacks
+ have just been pushed. So pushing a state here evens the stacks. */
+ yyssp++;
+
+ yysetstate:
+ *yyssp = yystate;
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ {
+ /* Get the current used size of the three stacks, in elements. */
+ YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+ {
+ /* Give user a chance to reallocate the stack. Use copies of
+ these so that the &'s don't force the real ones into
+ memory. */
+ YYSTYPE *yyvs1 = yyvs;
+ yytype_int16 *yyss1 = yyss;
+ YYLTYPE *yyls1 = yyls;
+
+ /* Each stack pointer address is followed by the size of the
+ data in use in that stack, in bytes. This used to be a
+ conditional around just the two extra args, but that might
+ be undefined if yyoverflow is a macro. */
+ yyoverflow (YY_("memory exhausted"),
+ &yyss1, yysize * sizeof (*yyssp),
+ &yyvs1, yysize * sizeof (*yyvsp),
+ &yyls1, yysize * sizeof (*yylsp),
+ &yystacksize);
+
+ yyls = yyls1;
+ yyss = yyss1;
+ yyvs = yyvs1;
+ }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+ goto yyexhaustedlab;
+# else
+ /* Extend the stack our own way. */
+ if (YYMAXDEPTH <= yystacksize)
+ goto yyexhaustedlab;
+ yystacksize *= 2;
+ if (YYMAXDEPTH < yystacksize)
+ yystacksize = YYMAXDEPTH;
+
+ {
+ yytype_int16 *yyss1 = yyss;
+ union yyalloc *yyptr =
+ (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+ if (! yyptr)
+ goto yyexhaustedlab;
+ YYSTACK_RELOCATE (yyss_alloc, yyss);
+ YYSTACK_RELOCATE (yyvs_alloc, yyvs);
+ YYSTACK_RELOCATE (yyls_alloc, yyls);
+# undef YYSTACK_RELOCATE
+ if (yyss1 != yyssa)
+ YYSTACK_FREE (yyss1);
+ }
+# endif
+#endif /* no yyoverflow */
+
+ yyssp = yyss + yysize - 1;
+ yyvsp = yyvs + yysize - 1;
+ yylsp = yyls + yysize - 1;
+
+ YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+ (unsigned long int) yystacksize));
+
+ if (yyss + yystacksize - 1 <= yyssp)
+ YYABORT;
+ }
+
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+ if (yystate == YYFINAL)
+ YYACCEPT;
+
+ goto yybackup;
+
+/*-----------.
+| yybackup. |
+`-----------*/
+yybackup:
+
+ /* Do appropriate processing given the current state. Read a
+ lookahead token if we need one and don't already have one. */
+
+ /* First try to decide what to do without reference to lookahead token. */
+ yyn = yypact[yystate];
+ if (yyn == YYPACT_NINF)
+ goto yydefault;
+
+ /* Not known => get a lookahead token if don't already have one. */
+
+ /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ }
+
+ if (yychar <= YYEOF)
+ {
+ yychar = yytoken = YYEOF;
+ YYDPRINTF ((stderr, "Now at end of input.\n"));
+ }
+ else
+ {
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+
+ /* If the proper action on seeing token YYTOKEN is to reduce or to
+ detect an error, take that action. */
+ yyn += yytoken;
+ if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+ goto yydefault;
+ yyn = yytable[yyn];
+ if (yyn <= 0)
+ {
+ if (yyn == 0 || yyn == YYTABLE_NINF)
+ goto yyerrlab;
+ yyn = -yyn;
+ goto yyreduce;
+ }
+
+ /* Count tokens shifted since error; after three, turn off error
+ status. */
+ if (yyerrstatus)
+ yyerrstatus--;
+
+ /* Shift the lookahead token. */
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+ /* Discard the shifted token. */
+ yychar = YYEMPTY;
+
+ yystate = yyn;
+ *++yyvsp = yylval;
+ *++yylsp = yylloc;
+ goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state. |
+`-----------------------------------------------------------*/
+yydefault:
+ yyn = yydefact[yystate];
+ if (yyn == 0)
+ goto yyerrlab;
+ goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction. |
+`-----------------------------*/
+yyreduce:
+ /* yyn is the number of a rule to reduce with. */
+ yylen = yyr2[yyn];
+
+ /* If YYLEN is nonzero, implement the default value of the action:
+ `$$ = $1'.
+
+ Otherwise, the following line sets YYVAL to garbage.
+ This behavior is undocumented and Bison
+ users should not rely upon it. Assigning to YYVAL
+ unconditionally makes the parser a bit smaller, and it avoids a
+ GCC warning that YYVAL may be used uninitialized. */
+ yyval = yyvsp[1-yylen];
+
+ /* Default location. */
+ YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+ YY_REDUCE_PRINT (yyn);
+ switch (yyn)
+ {
+ case 3:
+
+/* Line 1455 of yacc.c */
+#line 260 "program_parse.y"
+ {
+ if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid fragment program header");
+
+ }
+ state->mode = ARB_vertex;
+ ;}
+ break;
+
+ case 4:
+
+/* Line 1455 of yacc.c */
+#line 268 "program_parse.y"
+ {
+ if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex program header");
+ }
+ state->mode = ARB_fragment;
+
+ state->option.TexRect =
+ (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+ ;}
+ break;
+
+ case 7:
+
+/* Line 1455 of yacc.c */
+#line 284 "program_parse.y"
+ {
+ int valid = 0;
+
+ if (state->mode == ARB_vertex) {
+ valid = _mesa_ARBvp_parse_option(state, (yyvsp[(2) - (3)].string));
+ } else if (state->mode == ARB_fragment) {
+ valid = _mesa_ARBfp_parse_option(state, (yyvsp[(2) - (3)].string));
+ }
+
+
+ if (!valid) {
+ const char *const err_str = (state->mode == ARB_vertex)
+ ? "invalid ARB vertex program option"
+ : "invalid ARB fragment program option";
+
+ yyerror(& (yylsp[(2) - (3)]), state, err_str);
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 10:
+
+/* Line 1455 of yacc.c */
+#line 310 "program_parse.y"
+ {
+ if ((yyvsp[(1) - (2)].inst) != NULL) {
+ if (state->inst_tail == NULL) {
+ state->inst_head = (yyvsp[(1) - (2)].inst);
+ } else {
+ state->inst_tail->next = (yyvsp[(1) - (2)].inst);
+ }
+
+ state->inst_tail = (yyvsp[(1) - (2)].inst);
+ (yyvsp[(1) - (2)].inst)->next = NULL;
+
+ state->prog->NumInstructions++;
+ }
+ ;}
+ break;
+
+ case 12:
+
+/* Line 1455 of yacc.c */
+#line 328 "program_parse.y"
+ {
+ (yyval.inst) = (yyvsp[(1) - (1)].inst);
+ state->prog->NumAluInstructions++;
+ ;}
+ break;
+
+ case 13:
+
+/* Line 1455 of yacc.c */
+#line 333 "program_parse.y"
+ {
+ (yyval.inst) = (yyvsp[(1) - (1)].inst);
+ state->prog->NumTexInstructions++;
+ ;}
+ break;
+
+ case 23:
+
+/* Line 1455 of yacc.c */
+#line 353 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor(OPCODE_ARL, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ ;}
+ break;
+
+ case 24:
+
+/* Line 1455 of yacc.c */
+#line 359 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (4)].temp_inst).Opcode, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (4)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 25:
+
+/* Line 1455 of yacc.c */
+#line 366 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (4)].temp_inst).Opcode, & (yyvsp[(2) - (4)].dst_reg), & (yyvsp[(4) - (4)].src_reg), NULL, NULL);
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (4)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 26:
+
+/* Line 1455 of yacc.c */
+#line 373 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (6)].temp_inst).Opcode, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 27:
+
+/* Line 1455 of yacc.c */
+#line 381 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (6)].temp_inst).Opcode, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), & (yyvsp[(6) - (6)].src_reg), NULL);
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 28:
+
+/* Line 1455 of yacc.c */
+#line 389 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (8)].temp_inst).Opcode, & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), & (yyvsp[(6) - (8)].src_reg), & (yyvsp[(8) - (8)].src_reg));
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (8)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 29:
+
+/* Line 1455 of yacc.c */
+#line 396 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor((yyvsp[(1) - (8)].temp_inst).Opcode, & (yyvsp[(2) - (8)].dst_reg), & (yyvsp[(4) - (8)].src_reg), NULL, NULL);
+ if ((yyval.inst) != NULL) {
+ const GLbitfield tex_mask = (1U << (yyvsp[(6) - (8)].integer));
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (8)].temp_inst).SaturateMode;
+ (yyval.inst)->Base.TexSrcUnit = (yyvsp[(6) - (8)].integer);
+
+ if ((yyvsp[(8) - (8)].integer) < 0) {
+ shadow_tex = tex_mask;
+
+ (yyval.inst)->Base.TexSrcTarget = -(yyvsp[(8) - (8)].integer);
+ (yyval.inst)->Base.TexShadow = 1;
+ } else {
+ (yyval.inst)->Base.TexSrcTarget = (yyvsp[(8) - (8)].integer);
+ }
+
+ target_mask = (1U << (yyval.inst)->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != 0)
+ && ((state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& (yylsp[(8) - (8)]), state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[(yyvsp[(6) - (8)].integer)] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ ;}
+ break;
+
+ case 30:
+
+/* Line 1455 of yacc.c */
+#line 441 "program_parse.y"
+ {
+ (yyval.inst) = asm_instruction_ctor(OPCODE_KIL, NULL, & (yyvsp[(2) - (2)].src_reg), NULL, NULL);
+ state->fragment.UsesKill = 1;
+ ;}
+ break;
+
+ case 31:
+
+/* Line 1455 of yacc.c */
+#line 448 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 32:
+
+/* Line 1455 of yacc.c */
+#line 453 "program_parse.y"
+ { (yyval.integer) = TEXTURE_1D_INDEX; ;}
+ break;
+
+ case 33:
+
+/* Line 1455 of yacc.c */
+#line 454 "program_parse.y"
+ { (yyval.integer) = TEXTURE_2D_INDEX; ;}
+ break;
+
+ case 34:
+
+/* Line 1455 of yacc.c */
+#line 455 "program_parse.y"
+ { (yyval.integer) = TEXTURE_3D_INDEX; ;}
+ break;
+
+ case 35:
+
+/* Line 1455 of yacc.c */
+#line 456 "program_parse.y"
+ { (yyval.integer) = TEXTURE_CUBE_INDEX; ;}
+ break;
+
+ case 36:
+
+/* Line 1455 of yacc.c */
+#line 457 "program_parse.y"
+ { (yyval.integer) = TEXTURE_RECT_INDEX; ;}
+ break;
+
+ case 37:
+
+/* Line 1455 of yacc.c */
+#line 458 "program_parse.y"
+ { (yyval.integer) = -TEXTURE_1D_INDEX; ;}
+ break;
+
+ case 38:
+
+/* Line 1455 of yacc.c */
+#line 459 "program_parse.y"
+ { (yyval.integer) = -TEXTURE_2D_INDEX; ;}
+ break;
+
+ case 39:
+
+/* Line 1455 of yacc.c */
+#line 460 "program_parse.y"
+ { (yyval.integer) = -TEXTURE_RECT_INDEX; ;}
+ break;
+
+ case 40:
+
+/* Line 1455 of yacc.c */
+#line 461 "program_parse.y"
+ { (yyval.integer) = TEXTURE_1D_ARRAY_INDEX; ;}
+ break;
+
+ case 41:
+
+/* Line 1455 of yacc.c */
+#line 462 "program_parse.y"
+ { (yyval.integer) = TEXTURE_2D_ARRAY_INDEX; ;}
+ break;
+
+ case 42:
+
+/* Line 1455 of yacc.c */
+#line 463 "program_parse.y"
+ { (yyval.integer) = -TEXTURE_1D_ARRAY_INDEX; ;}
+ break;
+
+ case 43:
+
+/* Line 1455 of yacc.c */
+#line 464 "program_parse.y"
+ { (yyval.integer) = -TEXTURE_2D_ARRAY_INDEX; ;}
+ break;
+
+ case 44:
+
+/* Line 1455 of yacc.c */
+#line 468 "program_parse.y"
+ {
+ /* FIXME: Is this correct? Should the extenedSwizzle be applied
+ * FIXME: to the existing swizzle?
+ */
+ (yyvsp[(4) - (6)].src_reg).Base.Swizzle = (yyvsp[(6) - (6)].swiz_mask).swizzle;
+ (yyvsp[(4) - (6)].src_reg).Base.Negate = (yyvsp[(6) - (6)].swiz_mask).mask;
+
+ (yyval.inst) = asm_instruction_ctor(OPCODE_SWZ, & (yyvsp[(2) - (6)].dst_reg), & (yyvsp[(4) - (6)].src_reg), NULL, NULL);
+ (yyval.inst)->Base.SaturateMode = (yyvsp[(1) - (6)].temp_inst).SaturateMode;
+ ;}
+ break;
+
+ case 45:
+
+/* Line 1455 of yacc.c */
+#line 481 "program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
+
+ if ((yyvsp[(1) - (3)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+
+ (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+ (yyvsp[(3) - (3)].swiz_mask).swizzle);
+ ;}
+ break;
+
+ case 46:
+
+/* Line 1455 of yacc.c */
+#line 494 "program_parse.y"
+ {
+ (yyval.src_reg) = (yyvsp[(2) - (3)].src_reg);
+
+ if ((yyvsp[(1) - (3)].negate)) {
+ (yyval.src_reg).Base.Negate = ~(yyval.src_reg).Base.Negate;
+ }
+
+ (yyval.src_reg).Base.Swizzle = _mesa_combine_swizzles((yyval.src_reg).Base.Swizzle,
+ (yyvsp[(3) - (3)].swiz_mask).swizzle);
+ ;}
+ break;
+
+ case 47:
+
+/* Line 1455 of yacc.c */
+#line 507 "program_parse.y"
+ {
+ (yyval.dst_reg) = (yyvsp[(1) - (2)].dst_reg);
+ (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
+
+ if ((yyval.dst_reg).File == PROGRAM_OUTPUT) {
+ /* Technically speaking, this should check that it is in
+ * vertex program mode. However, PositionInvariant can never be
+ * set in fragment program mode, so it is somewhat irrelevant.
+ */
+ if (state->option.PositionInvariant
+ && ((yyval.dst_reg).Index == VERT_RESULT_HPOS)) {
+ yyerror(& (yylsp[(1) - (2)]), state, "position-invariant programs cannot "
+ "write position");
+ YYERROR;
+ }
+
+ state->prog->OutputsWritten |= (1U << (yyval.dst_reg).Index);
+ }
+ ;}
+ break;
+
+ case 48:
+
+/* Line 1455 of yacc.c */
+#line 529 "program_parse.y"
+ {
+ init_dst_reg(& (yyval.dst_reg));
+ (yyval.dst_reg).File = PROGRAM_ADDRESS;
+ (yyval.dst_reg).Index = 0;
+ (yyval.dst_reg).WriteMask = (yyvsp[(2) - (2)].swiz_mask).mask;
+ ;}
+ break;
+
+ case 49:
+
+/* Line 1455 of yacc.c */
+#line 538 "program_parse.y"
+ {
+ const unsigned xyzw_valid =
+ ((yyvsp[(1) - (7)].ext_swizzle).xyzw_valid << 0)
+ | ((yyvsp[(3) - (7)].ext_swizzle).xyzw_valid << 1)
+ | ((yyvsp[(5) - (7)].ext_swizzle).xyzw_valid << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).xyzw_valid << 3);
+ const unsigned rgba_valid =
+ ((yyvsp[(1) - (7)].ext_swizzle).rgba_valid << 0)
+ | ((yyvsp[(3) - (7)].ext_swizzle).rgba_valid << 1)
+ | ((yyvsp[(5) - (7)].ext_swizzle).rgba_valid << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).rgba_valid << 3);
+
+ /* All of the swizzle components have to be valid in either RGBA
+ * or XYZW. Note that 0 and 1 are valid in both, so both masks
+ * can have some bits set.
+ *
+ * We somewhat deviate from the spec here. It would be really hard
+ * to figure out which component is the error, and there probably
+ * isn't a lot of benefit.
+ */
+ if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+ yyerror(& (yylsp[(1) - (7)]), state, "cannot combine RGBA and XYZW swizzle "
+ "components");
+ YYERROR;
+ }
+
+ (yyval.swiz_mask).swizzle = MAKE_SWIZZLE4((yyvsp[(1) - (7)].ext_swizzle).swz, (yyvsp[(3) - (7)].ext_swizzle).swz, (yyvsp[(5) - (7)].ext_swizzle).swz, (yyvsp[(7) - (7)].ext_swizzle).swz);
+ (yyval.swiz_mask).mask = ((yyvsp[(1) - (7)].ext_swizzle).negate) | ((yyvsp[(3) - (7)].ext_swizzle).negate << 1) | ((yyvsp[(5) - (7)].ext_swizzle).negate << 2)
+ | ((yyvsp[(7) - (7)].ext_swizzle).negate << 3);
+ ;}
+ break;
+
+ case 50:
+
+/* Line 1455 of yacc.c */
+#line 571 "program_parse.y"
+ {
+ (yyval.ext_swizzle) = (yyvsp[(2) - (2)].ext_swizzle);
+ (yyval.ext_swizzle).negate = ((yyvsp[(1) - (2)].negate)) ? 1 : 0;
+ ;}
+ break;
+
+ case 51:
+
+/* Line 1455 of yacc.c */
+#line 578 "program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) != 0) && ((yyvsp[(1) - (1)].integer) != 1)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ (yyval.ext_swizzle).swz = ((yyvsp[(1) - (1)].integer) == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+
+ /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+ * swizzle names.
+ */
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ ;}
+ break;
+
+ case 52:
+
+/* Line 1455 of yacc.c */
+#line 593 "program_parse.y"
+ {
+ if (strlen((yyvsp[(1) - (1)].string)) > 1) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ switch ((yyvsp[(1) - (1)].string)[0]) {
+ case 'x':
+ (yyval.ext_swizzle).swz = SWIZZLE_X;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'y':
+ (yyval.ext_swizzle).swz = SWIZZLE_Y;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'z':
+ (yyval.ext_swizzle).swz = SWIZZLE_Z;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+ case 'w':
+ (yyval.ext_swizzle).swz = SWIZZLE_W;
+ (yyval.ext_swizzle).xyzw_valid = 1;
+ break;
+
+ case 'r':
+ (yyval.ext_swizzle).swz = SWIZZLE_X;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'g':
+ (yyval.ext_swizzle).swz = SWIZZLE_Y;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'b':
+ (yyval.ext_swizzle).swz = SWIZZLE_Z;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+ case 'a':
+ (yyval.ext_swizzle).swz = SWIZZLE_W;
+ (yyval.ext_swizzle).rgba_valid = 1;
+ break;
+
+ default:
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid extended swizzle selector");
+ YYERROR;
+ break;
+ }
+ ;}
+ break;
+
+ case 53:
+
+/* Line 1455 of yacc.c */
+#line 643 "program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) && (s->type != at_temp)
+ && (s->type != at_attrib)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type == at_param) && s->param_is_array) {
+ yyerror(& (yylsp[(1) - (1)]), state, "non-array access to array PARAM");
+ YYERROR;
+ }
+
+ init_src_reg(& (yyval.src_reg));
+ switch (s->type) {
+ case at_temp:
+ (yyval.src_reg).Base.File = PROGRAM_TEMPORARY;
+ (yyval.src_reg).Base.Index = s->temp_binding;
+ break;
+ case at_param:
+ (yyval.src_reg).Base.File = s->param_binding_type;
+ (yyval.src_reg).Base.Index = s->param_binding_begin;
+ break;
+ case at_attrib:
+ (yyval.src_reg).Base.File = PROGRAM_INPUT;
+ (yyval.src_reg).Base.Index = s->attrib_binding;
+ state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
+
+ if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+ YYERROR;
+ }
+ break;
+
+ default:
+ YYERROR;
+ break;
+ }
+ ;}
+ break;
+
+ case 54:
+
+/* Line 1455 of yacc.c */
+#line 685 "program_parse.y"
+ {
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.File = PROGRAM_INPUT;
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].attrib);
+ state->prog->InputsRead |= (1U << (yyval.src_reg).Base.Index);
+
+ if (!validate_inputs(& (yylsp[(1) - (1)]), state)) {
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 55:
+
+/* Line 1455 of yacc.c */
+#line 696 "program_parse.y"
+ {
+ if (! (yyvsp[(3) - (4)].src_reg).Base.RelAddr
+ && ((unsigned) (yyvsp[(3) - (4)].src_reg).Base.Index >= (yyvsp[(1) - (4)].sym)->param_binding_length)) {
+ yyerror(& (yylsp[(3) - (4)]), state, "out of bounds array access");
+ YYERROR;
+ }
+
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.File = (yyvsp[(1) - (4)].sym)->param_binding_type;
+
+ if ((yyvsp[(3) - (4)].src_reg).Base.RelAddr) {
+ (yyvsp[(1) - (4)].sym)->param_accessed_indirectly = 1;
+
+ (yyval.src_reg).Base.RelAddr = 1;
+ (yyval.src_reg).Base.Index = (yyvsp[(3) - (4)].src_reg).Base.Index;
+ (yyval.src_reg).Symbol = (yyvsp[(1) - (4)].sym);
+ } else {
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (4)].sym)->param_binding_begin + (yyvsp[(3) - (4)].src_reg).Base.Index;
+ }
+ ;}
+ break;
+
+ case 56:
+
+/* Line 1455 of yacc.c */
+#line 717 "program_parse.y"
+ {
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.File = ((yyvsp[(1) - (1)].temp_sym).name != NULL)
+ ? (yyvsp[(1) - (1)].temp_sym).param_binding_type
+ : PROGRAM_CONSTANT;
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].temp_sym).param_binding_begin;
+ ;}
+ break;
+
+ case 57:
+
+/* Line 1455 of yacc.c */
+#line 727 "program_parse.y"
+ {
+ init_dst_reg(& (yyval.dst_reg));
+ (yyval.dst_reg).File = PROGRAM_OUTPUT;
+ (yyval.dst_reg).Index = (yyvsp[(1) - (1)].result);
+ ;}
+ break;
+
+ case 58:
+
+/* Line 1455 of yacc.c */
+#line 733 "program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_output) && (s->type != at_temp)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ }
+
+ init_dst_reg(& (yyval.dst_reg));
+ switch (s->type) {
+ case at_temp:
+ (yyval.dst_reg).File = PROGRAM_TEMPORARY;
+ (yyval.dst_reg).Index = s->temp_binding;
+ break;
+ case at_output:
+ (yyval.dst_reg).File = PROGRAM_OUTPUT;
+ (yyval.dst_reg).Index = s->output_binding;
+ break;
+ default:
+ (yyval.dst_reg).File = s->param_binding_type;
+ (yyval.dst_reg).Index = s->param_binding_begin;
+ break;
+ }
+ ;}
+ break;
+
+ case 59:
+
+/* Line 1455 of yacc.c */
+#line 764 "program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) || !s->param_is_array) {
+ yyerror(& (yylsp[(1) - (1)]), state, "array access to non-PARAM variable");
+ YYERROR;
+ } else {
+ (yyval.sym) = s;
+ }
+ ;}
+ break;
+
+ case 62:
+
+/* Line 1455 of yacc.c */
+#line 783 "program_parse.y"
+ {
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.Index = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 63:
+
+/* Line 1455 of yacc.c */
+#line 790 "program_parse.y"
+ {
+ /* FINISHME: Add support for multiple address registers.
+ */
+ /* FINISHME: Add support for 4-component address registers.
+ */
+ init_src_reg(& (yyval.src_reg));
+ (yyval.src_reg).Base.RelAddr = 1;
+ (yyval.src_reg).Base.Index = (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 64:
+
+/* Line 1455 of yacc.c */
+#line 801 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 65:
+
+/* Line 1455 of yacc.c */
+#line 802 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (2)].integer); ;}
+ break;
+
+ case 66:
+
+/* Line 1455 of yacc.c */
+#line 803 "program_parse.y"
+ { (yyval.integer) = -(yyvsp[(2) - (2)].integer); ;}
+ break;
+
+ case 67:
+
+/* Line 1455 of yacc.c */
+#line 807 "program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 63)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+ yyerror(& (yylsp[(1) - (1)]), state, s);
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ ;}
+ break;
+
+ case 68:
+
+/* Line 1455 of yacc.c */
+#line 821 "program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 0) || ((yyvsp[(1) - (1)].integer) > 64)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", (yyvsp[(1) - (1)].integer));
+ yyerror(& (yylsp[(1) - (1)]), state, s);
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ ;}
+ break;
+
+ case 69:
+
+/* Line 1455 of yacc.c */
+#line 835 "program_parse.y"
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(1) - (1)].string));
+
+ if (s == NULL) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid array member");
+ YYERROR;
+ } else if (s->type != at_address) {
+ yyerror(& (yylsp[(1) - (1)]), state,
+ "invalid variable for indexed array access");
+ YYERROR;
+ } else {
+ (yyval.sym) = s;
+ }
+ ;}
+ break;
+
+ case 70:
+
+/* Line 1455 of yacc.c */
+#line 853 "program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid address component selector");
+ YYERROR;
+ } else {
+ (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+ }
+ ;}
+ break;
+
+ case 71:
+
+/* Line 1455 of yacc.c */
+#line 864 "program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].swiz_mask).mask != WRITEMASK_X) {
+ yyerror(& (yylsp[(1) - (1)]), state,
+ "address register write mask must be \".x\"");
+ YYERROR;
+ } else {
+ (yyval.swiz_mask) = (yyvsp[(1) - (1)].swiz_mask);
+ }
+ ;}
+ break;
+
+ case 76:
+
+/* Line 1455 of yacc.c */
+#line 880 "program_parse.y"
+ { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
+ break;
+
+ case 81:
+
+/* Line 1455 of yacc.c */
+#line 884 "program_parse.y"
+ { (yyval.swiz_mask).swizzle = SWIZZLE_NOOP; (yyval.swiz_mask).mask = WRITEMASK_XYZW; ;}
+ break;
+
+ case 88:
+
+/* Line 1455 of yacc.c */
+#line 896 "program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (4)].string), at_attrib, & (yylsp[(2) - (4)]));
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->attrib_binding = (yyvsp[(4) - (4)].attrib);
+ state->InputsBound |= (1U << s->attrib_binding);
+
+ if (!validate_inputs(& (yylsp[(4) - (4)]), state)) {
+ YYERROR;
+ }
+ }
+ ;}
+ break;
+
+ case 89:
+
+/* Line 1455 of yacc.c */
+#line 914 "program_parse.y"
+ {
+ (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+ ;}
+ break;
+
+ case 90:
+
+/* Line 1455 of yacc.c */
+#line 918 "program_parse.y"
+ {
+ (yyval.attrib) = (yyvsp[(2) - (2)].attrib);
+ ;}
+ break;
+
+ case 91:
+
+/* Line 1455 of yacc.c */
+#line 924 "program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_POS;
+ ;}
+ break;
+
+ case 92:
+
+/* Line 1455 of yacc.c */
+#line 928 "program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_WEIGHT;
+ ;}
+ break;
+
+ case 93:
+
+/* Line 1455 of yacc.c */
+#line 932 "program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_NORMAL;
+ ;}
+ break;
+
+ case 94:
+
+/* Line 1455 of yacc.c */
+#line 936 "program_parse.y"
+ {
+ if (!state->ctx->Extensions.EXT_secondary_color) {
+ yyerror(& (yylsp[(2) - (2)]), state, "GL_EXT_secondary_color not supported");
+ YYERROR;
+ }
+
+ (yyval.attrib) = VERT_ATTRIB_COLOR0 + (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 95:
+
+/* Line 1455 of yacc.c */
+#line 945 "program_parse.y"
+ {
+ if (!state->ctx->Extensions.EXT_fog_coord) {
+ yyerror(& (yylsp[(1) - (1)]), state, "GL_EXT_fog_coord not supported");
+ YYERROR;
+ }
+
+ (yyval.attrib) = VERT_ATTRIB_FOG;
+ ;}
+ break;
+
+ case 96:
+
+/* Line 1455 of yacc.c */
+#line 954 "program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 97:
+
+/* Line 1455 of yacc.c */
+#line 958 "program_parse.y"
+ {
+ yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ ;}
+ break;
+
+ case 98:
+
+/* Line 1455 of yacc.c */
+#line 963 "program_parse.y"
+ {
+ (yyval.attrib) = VERT_ATTRIB_GENERIC0 + (yyvsp[(3) - (4)].integer);
+ ;}
+ break;
+
+ case 99:
+
+/* Line 1455 of yacc.c */
+#line 969 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxAttribs) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid vertex attribute reference");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 103:
+
+/* Line 1455 of yacc.c */
+#line 983 "program_parse.y"
+ {
+ (yyval.attrib) = FRAG_ATTRIB_WPOS;
+ ;}
+ break;
+
+ case 104:
+
+/* Line 1455 of yacc.c */
+#line 987 "program_parse.y"
+ {
+ (yyval.attrib) = FRAG_ATTRIB_COL0 + (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 105:
+
+/* Line 1455 of yacc.c */
+#line 991 "program_parse.y"
+ {
+ (yyval.attrib) = FRAG_ATTRIB_FOGC;
+ ;}
+ break;
+
+ case 106:
+
+/* Line 1455 of yacc.c */
+#line 995 "program_parse.y"
+ {
+ (yyval.attrib) = FRAG_ATTRIB_TEX0 + (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 109:
+
+/* Line 1455 of yacc.c */
+#line 1003 "program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (3)].string), at_param, & (yylsp[(2) - (3)]));
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->param_binding_type = (yyvsp[(3) - (3)].temp_sym).param_binding_type;
+ s->param_binding_begin = (yyvsp[(3) - (3)].temp_sym).param_binding_begin;
+ s->param_binding_length = (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+ s->param_is_array = 0;
+ }
+ ;}
+ break;
+
+ case 110:
+
+/* Line 1455 of yacc.c */
+#line 1019 "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,
+ "parameter array size and number of bindings must match");
+ YYERROR;
+ } else {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (6)].string), (yyvsp[(6) - (6)].temp_sym).type, & (yylsp[(2) - (6)]));
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->param_binding_type = (yyvsp[(6) - (6)].temp_sym).param_binding_type;
+ s->param_binding_begin = (yyvsp[(6) - (6)].temp_sym).param_binding_begin;
+ s->param_binding_length = (yyvsp[(6) - (6)].temp_sym).param_binding_length;
+ s->param_is_array = 1;
+ }
+ }
+ ;}
+ break;
+
+ case 111:
+
+/* Line 1455 of yacc.c */
+#line 1041 "program_parse.y"
+ {
+ (yyval.integer) = 0;
+ ;}
+ break;
+
+ case 112:
+
+/* Line 1455 of yacc.c */
+#line 1045 "program_parse.y"
+ {
+ if (((yyvsp[(1) - (1)].integer) < 1) || ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxParameters)) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid parameter array size");
+ YYERROR;
+ } else {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ }
+ ;}
+ break;
+
+ case 113:
+
+/* Line 1455 of yacc.c */
+#line 1056 "program_parse.y"
+ {
+ (yyval.temp_sym) = (yyvsp[(2) - (2)].temp_sym);
+ ;}
+ break;
+
+ case 114:
+
+/* Line 1455 of yacc.c */
+#line 1062 "program_parse.y"
+ {
+ (yyval.temp_sym) = (yyvsp[(3) - (4)].temp_sym);
+ ;}
+ break;
+
+ case 116:
+
+/* Line 1455 of yacc.c */
+#line 1069 "program_parse.y"
+ {
+ (yyvsp[(1) - (3)].temp_sym).param_binding_length += (yyvsp[(3) - (3)].temp_sym).param_binding_length;
+ (yyval.temp_sym) = (yyvsp[(1) - (3)].temp_sym);
+ ;}
+ break;
+
+ case 117:
+
+/* Line 1455 of yacc.c */
+#line 1076 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 118:
+
+/* Line 1455 of yacc.c */
+#line 1082 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 119:
+
+/* Line 1455 of yacc.c */
+#line 1088 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+ ;}
+ break;
+
+ case 120:
+
+/* Line 1455 of yacc.c */
+#line 1096 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 121:
+
+/* Line 1455 of yacc.c */
+#line 1102 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 122:
+
+/* Line 1455 of yacc.c */
+#line 1108 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+ ;}
+ break;
+
+ case 123:
+
+/* Line 1455 of yacc.c */
+#line 1116 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 124:
+
+/* Line 1455 of yacc.c */
+#line 1122 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & (yyval.temp_sym), (yyvsp[(1) - (1)].state));
+ ;}
+ break;
+
+ case 125:
+
+/* Line 1455 of yacc.c */
+#line 1128 "program_parse.y"
+ {
+ memset(& (yyval.temp_sym), 0, sizeof((yyval.temp_sym)));
+ (yyval.temp_sym).param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & (yyval.temp_sym), & (yyvsp[(1) - (1)].vector));
+ ;}
+ break;
+
+ case 126:
+
+/* Line 1455 of yacc.c */
+#line 1135 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(1) - (1)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 127:
+
+/* Line 1455 of yacc.c */
+#line 1136 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 128:
+
+/* Line 1455 of yacc.c */
+#line 1139 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 129:
+
+/* Line 1455 of yacc.c */
+#line 1140 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 130:
+
+/* Line 1455 of yacc.c */
+#line 1141 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 131:
+
+/* Line 1455 of yacc.c */
+#line 1142 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 132:
+
+/* Line 1455 of yacc.c */
+#line 1143 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 133:
+
+/* Line 1455 of yacc.c */
+#line 1144 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 134:
+
+/* Line 1455 of yacc.c */
+#line 1145 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 135:
+
+/* Line 1455 of yacc.c */
+#line 1146 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 136:
+
+/* Line 1455 of yacc.c */
+#line 1147 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 137:
+
+/* Line 1455 of yacc.c */
+#line 1148 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 138:
+
+/* Line 1455 of yacc.c */
+#line 1149 "program_parse.y"
+ { memcpy((yyval.state), (yyvsp[(2) - (2)].state), sizeof((yyval.state))); ;}
+ break;
+
+ case 139:
+
+/* Line 1455 of yacc.c */
+#line 1153 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_MATERIAL;
+ (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+ (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 140:
+
+/* Line 1455 of yacc.c */
+#line 1162 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 141:
+
+/* Line 1455 of yacc.c */
+#line 1166 "program_parse.y"
+ {
+ (yyval.integer) = STATE_EMISSION;
+ ;}
+ break;
+
+ case 142:
+
+/* Line 1455 of yacc.c */
+#line 1170 "program_parse.y"
+ {
+ (yyval.integer) = STATE_SHININESS;
+ ;}
+ break;
+
+ case 143:
+
+/* Line 1455 of yacc.c */
+#line 1176 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHT;
+ (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+ (yyval.state)[2] = (yyvsp[(5) - (5)].integer);
+ ;}
+ break;
+
+ case 144:
+
+/* Line 1455 of yacc.c */
+#line 1185 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 145:
+
+/* Line 1455 of yacc.c */
+#line 1189 "program_parse.y"
+ {
+ (yyval.integer) = STATE_POSITION;
+ ;}
+ break;
+
+ case 146:
+
+/* Line 1455 of yacc.c */
+#line 1193 "program_parse.y"
+ {
+ if (!state->ctx->Extensions.EXT_point_parameters) {
+ yyerror(& (yylsp[(1) - (1)]), state, "GL_ARB_point_parameters not supported");
+ YYERROR;
+ }
+
+ (yyval.integer) = STATE_ATTENUATION;
+ ;}
+ break;
+
+ case 147:
+
+/* Line 1455 of yacc.c */
+#line 1202 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 148:
+
+/* Line 1455 of yacc.c */
+#line 1206 "program_parse.y"
+ {
+ (yyval.integer) = STATE_HALF_VECTOR;
+ ;}
+ break;
+
+ case 149:
+
+/* Line 1455 of yacc.c */
+#line 1212 "program_parse.y"
+ {
+ (yyval.integer) = STATE_SPOT_DIRECTION;
+ ;}
+ break;
+
+ case 150:
+
+/* Line 1455 of yacc.c */
+#line 1218 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(2) - (2)].state)[0];
+ (yyval.state)[1] = (yyvsp[(2) - (2)].state)[1];
+ ;}
+ break;
+
+ case 151:
+
+/* Line 1455 of yacc.c */
+#line 1225 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTMODEL_AMBIENT;
+ ;}
+ break;
+
+ case 152:
+
+/* Line 1455 of yacc.c */
+#line 1230 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTMODEL_SCENECOLOR;
+ (yyval.state)[1] = (yyvsp[(1) - (2)].integer);
+ ;}
+ break;
+
+ case 153:
+
+/* Line 1455 of yacc.c */
+#line 1238 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_LIGHTPROD;
+ (yyval.state)[1] = (yyvsp[(3) - (6)].integer);
+ (yyval.state)[2] = (yyvsp[(5) - (6)].integer);
+ (yyval.state)[3] = (yyvsp[(6) - (6)].integer);
+ ;}
+ break;
+
+ case 155:
+
+/* Line 1455 of yacc.c */
+#line 1250 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(3) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(2) - (3)].integer);
+ ;}
+ break;
+
+ case 156:
+
+/* Line 1455 of yacc.c */
+#line 1258 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXENV_COLOR;
+ ;}
+ break;
+
+ case 157:
+
+/* Line 1455 of yacc.c */
+#line 1264 "program_parse.y"
+ {
+ (yyval.integer) = STATE_AMBIENT;
+ ;}
+ break;
+
+ case 158:
+
+/* Line 1455 of yacc.c */
+#line 1268 "program_parse.y"
+ {
+ (yyval.integer) = STATE_DIFFUSE;
+ ;}
+ break;
+
+ case 159:
+
+/* Line 1455 of yacc.c */
+#line 1272 "program_parse.y"
+ {
+ (yyval.integer) = STATE_SPECULAR;
+ ;}
+ break;
+
+ case 160:
+
+/* Line 1455 of yacc.c */
+#line 1278 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxLights) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid light selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 161:
+
+/* Line 1455 of yacc.c */
+#line 1289 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_TEXGEN;
+ (yyval.state)[1] = (yyvsp[(2) - (4)].integer);
+ (yyval.state)[2] = (yyvsp[(3) - (4)].integer) + (yyvsp[(4) - (4)].integer);
+ ;}
+ break;
+
+ case 162:
+
+/* Line 1455 of yacc.c */
+#line 1298 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_S;
+ ;}
+ break;
+
+ case 163:
+
+/* Line 1455 of yacc.c */
+#line 1302 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_OBJECT_S;
+ ;}
+ break;
+
+ case 164:
+
+/* Line 1455 of yacc.c */
+#line 1307 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+ ;}
+ break;
+
+ case 165:
+
+/* Line 1455 of yacc.c */
+#line 1311 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+ ;}
+ break;
+
+ case 166:
+
+/* Line 1455 of yacc.c */
+#line 1315 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+ ;}
+ break;
+
+ case 167:
+
+/* Line 1455 of yacc.c */
+#line 1319 "program_parse.y"
+ {
+ (yyval.integer) = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+ ;}
+ break;
+
+ case 168:
+
+/* Line 1455 of yacc.c */
+#line 1325 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 169:
+
+/* Line 1455 of yacc.c */
+#line 1332 "program_parse.y"
+ {
+ (yyval.integer) = STATE_FOG_COLOR;
+ ;}
+ break;
+
+ case 170:
+
+/* Line 1455 of yacc.c */
+#line 1336 "program_parse.y"
+ {
+ (yyval.integer) = STATE_FOG_PARAMS;
+ ;}
+ break;
+
+ case 171:
+
+/* Line 1455 of yacc.c */
+#line 1342 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_CLIPPLANE;
+ (yyval.state)[1] = (yyvsp[(3) - (5)].integer);
+ ;}
+ break;
+
+ case 172:
+
+/* Line 1455 of yacc.c */
+#line 1350 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxClipPlanes) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid clip plane selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 173:
+
+/* Line 1455 of yacc.c */
+#line 1361 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 174:
+
+/* Line 1455 of yacc.c */
+#line 1368 "program_parse.y"
+ {
+ (yyval.integer) = STATE_POINT_SIZE;
+ ;}
+ break;
+
+ case 175:
+
+/* Line 1455 of yacc.c */
+#line 1372 "program_parse.y"
+ {
+ (yyval.integer) = STATE_POINT_ATTENUATION;
+ ;}
+ break;
+
+ case 176:
+
+/* Line 1455 of yacc.c */
+#line 1378 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (5)].state)[0];
+ (yyval.state)[1] = (yyvsp[(1) - (5)].state)[1];
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[4] = (yyvsp[(1) - (5)].state)[2];
+ ;}
+ break;
+
+ case 177:
+
+/* Line 1455 of yacc.c */
+#line 1388 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (2)].state)[0];
+ (yyval.state)[1] = (yyvsp[(1) - (2)].state)[1];
+ (yyval.state)[2] = (yyvsp[(2) - (2)].state)[2];
+ (yyval.state)[3] = (yyvsp[(2) - (2)].state)[3];
+ (yyval.state)[4] = (yyvsp[(1) - (2)].state)[2];
+ ;}
+ break;
+
+ case 178:
+
+/* Line 1455 of yacc.c */
+#line 1398 "program_parse.y"
+ {
+ (yyval.state)[2] = 0;
+ (yyval.state)[3] = 3;
+ ;}
+ break;
+
+ case 179:
+
+/* Line 1455 of yacc.c */
+#line 1403 "program_parse.y"
+ {
+ /* It seems logical that the matrix row range specifier would have
+ * to specify a range or more than one row (i.e., $5 > $3).
+ * However, the ARB_vertex_program spec says "a program will fail
+ * to load if <a> is greater than <b>." This means that $3 == $5
+ * is valid.
+ */
+ if ((yyvsp[(3) - (6)].integer) > (yyvsp[(5) - (6)].integer)) {
+ yyerror(& (yylsp[(3) - (6)]), state, "invalid matrix row range");
+ YYERROR;
+ }
+
+ (yyval.state)[2] = (yyvsp[(3) - (6)].integer);
+ (yyval.state)[3] = (yyvsp[(5) - (6)].integer);
+ ;}
+ break;
+
+ case 180:
+
+/* Line 1455 of yacc.c */
+#line 1421 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(2) - (3)].state)[0];
+ (yyval.state)[1] = (yyvsp[(2) - (3)].state)[1];
+ (yyval.state)[2] = (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 181:
+
+/* Line 1455 of yacc.c */
+#line 1429 "program_parse.y"
+ {
+ (yyval.integer) = 0;
+ ;}
+ break;
+
+ case 182:
+
+/* Line 1455 of yacc.c */
+#line 1433 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 183:
+
+/* Line 1455 of yacc.c */
+#line 1439 "program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_INVERSE;
+ ;}
+ break;
+
+ case 184:
+
+/* Line 1455 of yacc.c */
+#line 1443 "program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_TRANSPOSE;
+ ;}
+ break;
+
+ case 185:
+
+/* Line 1455 of yacc.c */
+#line 1447 "program_parse.y"
+ {
+ (yyval.integer) = STATE_MATRIX_INVTRANS;
+ ;}
+ break;
+
+ case 186:
+
+/* Line 1455 of yacc.c */
+#line 1453 "program_parse.y"
+ {
+ if ((yyvsp[(1) - (1)].integer) > 3) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid matrix row reference");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 187:
+
+/* Line 1455 of yacc.c */
+#line 1464 "program_parse.y"
+ {
+ (yyval.state)[0] = STATE_MODELVIEW_MATRIX;
+ (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 188:
+
+/* Line 1455 of yacc.c */
+#line 1469 "program_parse.y"
+ {
+ (yyval.state)[0] = STATE_PROJECTION_MATRIX;
+ (yyval.state)[1] = 0;
+ ;}
+ break;
+
+ case 189:
+
+/* Line 1455 of yacc.c */
+#line 1474 "program_parse.y"
+ {
+ (yyval.state)[0] = STATE_MVP_MATRIX;
+ (yyval.state)[1] = 0;
+ ;}
+ break;
+
+ case 190:
+
+/* Line 1455 of yacc.c */
+#line 1479 "program_parse.y"
+ {
+ (yyval.state)[0] = STATE_TEXTURE_MATRIX;
+ (yyval.state)[1] = (yyvsp[(2) - (2)].integer);
+ ;}
+ break;
+
+ case 191:
+
+/* Line 1455 of yacc.c */
+#line 1484 "program_parse.y"
+ {
+ yyerror(& (yylsp[(1) - (4)]), state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ ;}
+ break;
+
+ case 192:
+
+/* Line 1455 of yacc.c */
+#line 1489 "program_parse.y"
+ {
+ (yyval.state)[0] = STATE_PROGRAM_MATRIX;
+ (yyval.state)[1] = (yyvsp[(3) - (4)].integer);
+ ;}
+ break;
+
+ case 193:
+
+/* Line 1455 of yacc.c */
+#line 1496 "program_parse.y"
+ {
+ (yyval.integer) = 0;
+ ;}
+ break;
+
+ case 194:
+
+/* Line 1455 of yacc.c */
+#line 1500 "program_parse.y"
+ {
+ (yyval.integer) = (yyvsp[(2) - (3)].integer);
+ ;}
+ break;
+
+ case 195:
+
+/* Line 1455 of yacc.c */
+#line 1505 "program_parse.y"
+ {
+ /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+ * zero is valid.
+ */
+ if ((yyvsp[(1) - (1)].integer) != 0) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid modelview matrix index");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 196:
+
+/* Line 1455 of yacc.c */
+#line 1518 "program_parse.y"
+ {
+ /* Since GL_ARB_matrix_palette isn't supported, just let any value
+ * through here. The error will be generated later.
+ */
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 197:
+
+/* Line 1455 of yacc.c */
+#line 1526 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxProgramMatrices) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program matrix selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 198:
+
+/* Line 1455 of yacc.c */
+#line 1537 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = STATE_DEPTH_RANGE;
+ ;}
+ break;
+
+ case 203:
+
+/* Line 1455 of yacc.c */
+#line 1549 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_ENV;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+ (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+ ;}
+ break;
+
+ case 204:
+
+/* Line 1455 of yacc.c */
+#line 1559 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+ (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 205:
+
+/* Line 1455 of yacc.c */
+#line 1564 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 206:
+
+/* Line 1455 of yacc.c */
+#line 1571 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_ENV;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ ;}
+ break;
+
+ case 207:
+
+/* Line 1455 of yacc.c */
+#line 1581 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_LOCAL;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].state)[0];
+ (yyval.state)[3] = (yyvsp[(4) - (5)].state)[1];
+ ;}
+ break;
+
+ case 208:
+
+/* Line 1455 of yacc.c */
+#line 1590 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (1)].integer);
+ (yyval.state)[1] = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 209:
+
+/* Line 1455 of yacc.c */
+#line 1595 "program_parse.y"
+ {
+ (yyval.state)[0] = (yyvsp[(1) - (3)].integer);
+ (yyval.state)[1] = (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 210:
+
+/* Line 1455 of yacc.c */
+#line 1602 "program_parse.y"
+ {
+ memset((yyval.state), 0, sizeof((yyval.state)));
+ (yyval.state)[0] = state->state_param_enum;
+ (yyval.state)[1] = STATE_LOCAL;
+ (yyval.state)[2] = (yyvsp[(4) - (5)].integer);
+ (yyval.state)[3] = (yyvsp[(4) - (5)].integer);
+ ;}
+ break;
+
+ case 211:
+
+/* Line 1455 of yacc.c */
+#line 1612 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxEnvParams) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid environment parameter reference");
+ YYERROR;
+ }
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 212:
+
+/* Line 1455 of yacc.c */
+#line 1622 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->limits->MaxLocalParams) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid local parameter reference");
+ YYERROR;
+ }
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 217:
+
+/* Line 1455 of yacc.c */
+#line 1637 "program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
+ ;}
+ break;
+
+ case 218:
+
+/* Line 1455 of yacc.c */
+#line 1647 "program_parse.y"
+ {
+ (yyval.vector).count = 1;
+ (yyval.vector).data[0] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[1] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[2] = (yyvsp[(1) - (1)].real);
+ (yyval.vector).data[3] = (yyvsp[(1) - (1)].real);
+ ;}
+ break;
+
+ case 219:
+
+/* Line 1455 of yacc.c */
+#line 1655 "program_parse.y"
+ {
+ (yyval.vector).count = 1;
+ (yyval.vector).data[0] = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[1] = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[2] = (float) (yyvsp[(1) - (1)].integer);
+ (yyval.vector).data[3] = (float) (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 220:
+
+/* Line 1455 of yacc.c */
+#line 1665 "program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0] = (yyvsp[(2) - (3)].real);
+ (yyval.vector).data[1] = 0.0f;
+ (yyval.vector).data[2] = 0.0f;
+ (yyval.vector).data[3] = 1.0f;
+ ;}
+ break;
+
+ case 221:
+
+/* Line 1455 of yacc.c */
+#line 1673 "program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0] = (yyvsp[(2) - (5)].real);
+ (yyval.vector).data[1] = (yyvsp[(4) - (5)].real);
+ (yyval.vector).data[2] = 0.0f;
+ (yyval.vector).data[3] = 1.0f;
+ ;}
+ break;
+
+ case 222:
+
+/* Line 1455 of yacc.c */
+#line 1682 "program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0] = (yyvsp[(2) - (7)].real);
+ (yyval.vector).data[1] = (yyvsp[(4) - (7)].real);
+ (yyval.vector).data[2] = (yyvsp[(6) - (7)].real);
+ (yyval.vector).data[3] = 1.0f;
+ ;}
+ break;
+
+ case 223:
+
+/* Line 1455 of yacc.c */
+#line 1691 "program_parse.y"
+ {
+ (yyval.vector).count = 4;
+ (yyval.vector).data[0] = (yyvsp[(2) - (9)].real);
+ (yyval.vector).data[1] = (yyvsp[(4) - (9)].real);
+ (yyval.vector).data[2] = (yyvsp[(6) - (9)].real);
+ (yyval.vector).data[3] = (yyvsp[(8) - (9)].real);
+ ;}
+ break;
+
+ case 224:
+
+/* Line 1455 of yacc.c */
+#line 1701 "program_parse.y"
+ {
+ (yyval.real) = ((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].real) : (yyvsp[(2) - (2)].real);
+ ;}
+ break;
+
+ case 225:
+
+/* Line 1455 of yacc.c */
+#line 1705 "program_parse.y"
+ {
+ (yyval.real) = (float)(((yyvsp[(1) - (2)].negate)) ? -(yyvsp[(2) - (2)].integer) : (yyvsp[(2) - (2)].integer));
+ ;}
+ break;
+
+ case 226:
+
+/* Line 1455 of yacc.c */
+#line 1710 "program_parse.y"
+ { (yyval.negate) = FALSE; ;}
+ break;
+
+ case 227:
+
+/* Line 1455 of yacc.c */
+#line 1711 "program_parse.y"
+ { (yyval.negate) = TRUE; ;}
+ break;
+
+ case 228:
+
+/* Line 1455 of yacc.c */
+#line 1712 "program_parse.y"
+ { (yyval.negate) = FALSE; ;}
+ break;
+
+ case 229:
+
+/* Line 1455 of yacc.c */
+#line 1715 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
+ break;
+
+ case 231:
+
+/* Line 1455 of yacc.c */
+#line 1718 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(1) - (1)].integer); ;}
+ break;
+
+ case 233:
+
+/* Line 1455 of yacc.c */
+#line 1722 "program_parse.y"
+ {
+ if (!declare_variable(state, (yyvsp[(3) - (3)].string), (yyvsp[(0) - (3)].integer), & (yylsp[(3) - (3)]))) {
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 234:
+
+/* Line 1455 of yacc.c */
+#line 1728 "program_parse.y"
+ {
+ if (!declare_variable(state, (yyvsp[(1) - (1)].string), (yyvsp[(0) - (1)].integer), & (yylsp[(1) - (1)]))) {
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 235:
+
+/* Line 1455 of yacc.c */
+#line 1736 "program_parse.y"
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, (yyvsp[(2) - (4)].string), at_output, & (yylsp[(2) - (4)]));
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->output_binding = (yyvsp[(4) - (4)].result);
+ }
+ ;}
+ break;
+
+ case 236:
+
+/* Line 1455 of yacc.c */
+#line 1749 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VERT_RESULT_HPOS;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 237:
+
+/* Line 1455 of yacc.c */
+#line 1758 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VERT_RESULT_FOGC;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 238:
+
+/* Line 1455 of yacc.c */
+#line 1767 "program_parse.y"
+ {
+ (yyval.result) = (yyvsp[(2) - (2)].result);
+ ;}
+ break;
+
+ case 239:
+
+/* Line 1455 of yacc.c */
+#line 1771 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VERT_RESULT_PSIZ;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 240:
+
+/* Line 1455 of yacc.c */
+#line 1780 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.result) = VERT_RESULT_TEX0 + (yyvsp[(3) - (3)].integer);
+ } else {
+ yyerror(& (yylsp[(2) - (3)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 241:
+
+/* Line 1455 of yacc.c */
+#line 1789 "program_parse.y"
+ {
+ if (state->mode == ARB_fragment) {
+ (yyval.result) = FRAG_RESULT_DEPTH;
+ } else {
+ yyerror(& (yylsp[(2) - (2)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 242:
+
+/* Line 1455 of yacc.c */
+#line 1800 "program_parse.y"
+ {
+ (yyval.result) = (yyvsp[(2) - (3)].integer) + (yyvsp[(3) - (3)].integer);
+ ;}
+ break;
+
+ case 243:
+
+/* Line 1455 of yacc.c */
+#line 1806 "program_parse.y"
+ {
+ (yyval.integer) = (state->mode == ARB_vertex)
+ ? VERT_RESULT_COL0
+ : FRAG_RESULT_COLOR;
+ ;}
+ break;
+
+ case 244:
+
+/* Line 1455 of yacc.c */
+#line 1812 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = VERT_RESULT_COL0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 245:
+
+/* Line 1455 of yacc.c */
+#line 1821 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = VERT_RESULT_BFC0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 246:
+
+/* Line 1455 of yacc.c */
+#line 1832 "program_parse.y"
+ {
+ (yyval.integer) = 0;
+ ;}
+ break;
+
+ case 247:
+
+/* Line 1455 of yacc.c */
+#line 1836 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = 0;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 248:
+
+/* Line 1455 of yacc.c */
+#line 1845 "program_parse.y"
+ {
+ if (state->mode == ARB_vertex) {
+ (yyval.integer) = 1;
+ } else {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid program result name");
+ YYERROR;
+ }
+ ;}
+ break;
+
+ case 249:
+
+/* Line 1455 of yacc.c */
+#line 1855 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 250:
+
+/* Line 1455 of yacc.c */
+#line 1856 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 251:
+
+/* Line 1455 of yacc.c */
+#line 1857 "program_parse.y"
+ { (yyval.integer) = 1; ;}
+ break;
+
+ case 252:
+
+/* Line 1455 of yacc.c */
+#line 1860 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 253:
+
+/* Line 1455 of yacc.c */
+#line 1861 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 254:
+
+/* Line 1455 of yacc.c */
+#line 1862 "program_parse.y"
+ { (yyval.integer) = 1; ;}
+ break;
+
+ case 255:
+
+/* Line 1455 of yacc.c */
+#line 1865 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 256:
+
+/* Line 1455 of yacc.c */
+#line 1866 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+ break;
+
+ case 257:
+
+/* Line 1455 of yacc.c */
+#line 1869 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 258:
+
+/* Line 1455 of yacc.c */
+#line 1870 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+ break;
+
+ case 259:
+
+/* Line 1455 of yacc.c */
+#line 1873 "program_parse.y"
+ { (yyval.integer) = 0; ;}
+ break;
+
+ case 260:
+
+/* Line 1455 of yacc.c */
+#line 1874 "program_parse.y"
+ { (yyval.integer) = (yyvsp[(2) - (3)].integer); ;}
+ break;
+
+ case 261:
+
+/* Line 1455 of yacc.c */
+#line 1878 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureCoordUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture coordinate unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 262:
+
+/* Line 1455 of yacc.c */
+#line 1889 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureImageUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture image unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 263:
+
+/* Line 1455 of yacc.c */
+#line 1900 "program_parse.y"
+ {
+ if ((unsigned) (yyvsp[(1) - (1)].integer) >= state->MaxTextureUnits) {
+ yyerror(& (yylsp[(1) - (1)]), state, "invalid texture unit selector");
+ YYERROR;
+ }
+
+ (yyval.integer) = (yyvsp[(1) - (1)].integer);
+ ;}
+ break;
+
+ case 264:
+
+/* Line 1455 of yacc.c */
+#line 1911 "program_parse.y"
+ {
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(2) - (4)].string));
+ struct asm_symbol *target = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, (yyvsp[(4) - (4)].string));
+
+
+ if (exist != NULL) {
+ yyerror(& (yylsp[(2) - (4)]), state, "redeclared identifier");
+ YYERROR;
+ } else if (target == NULL) {
+ yyerror(& (yylsp[(4) - (4)]), state,
+ "undefined variable binding in ALIAS statement");
+ YYERROR;
+ } else {
+ _mesa_symbol_table_add_symbol(state->st, 0, (yyvsp[(2) - (4)].string), target);
+ }
+ ;}
+ break;
+
+
+
+/* Line 1455 of yacc.c */
+#line 4581 "program_parse.tab.c"
+ default: break;
+ }
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+
+ *++yyvsp = yyval;
+ *++yylsp = yyloc;
+
+ /* Now `shift' the result of the reduction. Determine what state
+ that goes to, based on the state we popped back to and the rule
+ number reduced by. */
+
+ yyn = yyr1[yyn];
+
+ yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+ if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+ yystate = yytable[yystate];
+ else
+ yystate = yydefgoto[yyn - YYNTOKENS];
+
+ goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+ /* If not already recovering from an error, report this error. */
+ if (!yyerrstatus)
+ {
+ ++yynerrs;
+#if ! YYERROR_VERBOSE
+ yyerror (&yylloc, state, YY_("syntax error"));
+#else
+ {
+ YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+ if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+ {
+ YYSIZE_T yyalloc = 2 * yysize;
+ if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+ yyalloc = YYSTACK_ALLOC_MAXIMUM;
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+ yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+ if (yymsg)
+ yymsg_alloc = yyalloc;
+ else
+ {
+ yymsg = yymsgbuf;
+ yymsg_alloc = sizeof yymsgbuf;
+ }
+ }
+
+ if (0 < yysize && yysize <= yymsg_alloc)
+ {
+ (void) yysyntax_error (yymsg, yystate, yychar);
+ yyerror (&yylloc, state, yymsg);
+ }
+ else
+ {
+ yyerror (&yylloc, state, YY_("syntax error"));
+ if (yysize != 0)
+ goto yyexhaustedlab;
+ }
+ }
+#endif
+ }
+
+ yyerror_range[0] = yylloc;
+
+ if (yyerrstatus == 3)
+ {
+ /* If just tried and failed to reuse lookahead token after an
+ error, discard it. */
+
+ if (yychar <= YYEOF)
+ {
+ /* Return failure if at end of input. */
+ if (yychar == YYEOF)
+ YYABORT;
+ }
+ else
+ {
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc, state);
+ yychar = YYEMPTY;
+ }
+ }
+
+ /* Else will try to reuse lookahead token after shifting the error
+ token. */
+ goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR. |
+`---------------------------------------------------*/
+yyerrorlab:
+
+ /* Pacify compilers like GCC when the user code never invokes
+ YYERROR and the label yyerrorlab therefore never appears in user
+ code. */
+ if (/*CONSTCOND*/ 0)
+ goto yyerrorlab;
+
+ yyerror_range[0] = yylsp[1-yylen];
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYERROR. */
+ YYPOPSTACK (yylen);
+ yylen = 0;
+ YY_STACK_PRINT (yyss, yyssp);
+ yystate = *yyssp;
+ goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR. |
+`-------------------------------------------------------------*/
+yyerrlab1:
+ yyerrstatus = 3; /* Each real token shifted decrements this. */
+
+ for (;;)
+ {
+ yyn = yypact[yystate];
+ if (yyn != YYPACT_NINF)
+ {
+ yyn += YYTERROR;
+ if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+ {
+ yyn = yytable[yyn];
+ if (0 < yyn)
+ break;
+ }
+ }
+
+ /* Pop the current state because it cannot handle the error token. */
+ if (yyssp == yyss)
+ YYABORT;
+
+ yyerror_range[0] = *yylsp;
+ yydestruct ("Error: popping",
+ yystos[yystate], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ yystate = *yyssp;
+ YY_STACK_PRINT (yyss, yyssp);
+ }
+
+ *++yyvsp = yylval;
+
+ yyerror_range[1] = yylloc;
+ /* Using YYLLOC is tempting, but would change the location of
+ the lookahead. YYLOC is available though. */
+ YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+ *++yylsp = yyloc;
+
+ /* Shift the error token. */
+ YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+ yystate = yyn;
+ goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here. |
+`-------------------------------------*/
+yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here. |
+`-----------------------------------*/
+yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+#if !defined(yyoverflow) || YYERROR_VERBOSE
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here. |
+`-------------------------------------------------*/
+yyexhaustedlab:
+ yyerror (&yylloc, state, YY_("memory exhausted"));
+ yyresult = 2;
+ /* Fall through. */
+#endif
+
+yyreturn:
+ if (yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ yytoken, &yylval, &yylloc, state);
+ /* Do not reclaim the symbols of the rule which action triggered
+ this YYABORT or YYACCEPT. */
+ YYPOPSTACK (yylen);
+ YY_STACK_PRINT (yyss, yyssp);
+ while (yyssp != yyss)
+ {
+ yydestruct ("Cleanup: popping",
+ yystos[*yyssp], yyvsp, yylsp, state);
+ YYPOPSTACK (1);
+ }
+#ifndef yyoverflow
+ if (yyss != yyssa)
+ YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+ if (yymsg != yymsgbuf)
+ YYSTACK_FREE (yymsg);
+#endif
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+
+
+/* Line 1675 of yacc.c */
+#line 1931 "program_parse.y"
+
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction));
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = op;
+
+ /* In the core ARB extensions only the KIL instruction doesn't have a
+ * destination register.
+ */
+ if (dst == NULL) {
+ init_dst_reg(& inst->Base.DstReg);
+ } else {
+ inst->Base.DstReg = *dst;
+ }
+
+ inst->Base.SrcReg[0] = src0->Base;
+ inst->SrcReg[0] = *src0;
+
+ if (src1 != NULL) {
+ inst->Base.SrcReg[1] = src1->Base;
+ inst->SrcReg[1] = *src1;
+ } else {
+ init_src_reg(& inst->SrcReg[1]);
+ }
+
+ if (src2 != NULL) {
+ inst->Base.SrcReg[2] = src2->Base;
+ inst->SrcReg[2] = *src2;
+ } else {
+ init_src_reg(& inst->SrcReg[2]);
+ }
+ }
+
+ return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->File = PROGRAM_UNDEFINED;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->Base.File = PROGRAM_UNDEFINED;
+ r->Base.Swizzle = SWIZZLE_NOOP;
+ r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program. In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+ const int inputs = state->prog->InputsRead | state->InputsBound;
+
+ if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+ yyerror(locp, state, "illegal use of generic attribute and name attribute");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+ struct YYLTYPE *locp)
+{
+ struct asm_symbol *s = NULL;
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+ if (exist != NULL) {
+ yyerror(locp, state, "redeclared identifier");
+ } else {
+ s = calloc(1, sizeof(struct asm_symbol));
+ s->name = name;
+ s->type = t;
+
+ switch (t) {
+ case at_temp:
+ if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+ yyerror(locp, state, "too many temporaries declared");
+ free(s);
+ return NULL;
+ }
+
+ s->temp_binding = state->prog->NumTemporaries;
+ state->prog->NumTemporaries++;
+ break;
+
+ case at_address:
+ if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+ yyerror(locp, state, "too many address registers declared");
+ free(s);
+ return NULL;
+ }
+
+ /* FINISHME: Add support for multiple address registers.
+ */
+ state->prog->NumAddressRegs++;
+ break;
+
+ default:
+ break;
+ }
+
+ _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+ s->next = state->sym;
+ state->sym = s;
+ }
+
+ return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ char *name;
+ GLint index;
+
+ name = _mesa_program_state_string(tokens);
+ index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+ size, GL_NONE, NULL, tokens, 0x0);
+ param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ _mesa_free(name);
+
+ return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+ * unroll it and call add_state_reference() for each row
+ */
+ if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+ state_tokens[0] == STATE_PROJECTION_MATRIX ||
+ state_tokens[0] == STATE_MVP_MATRIX ||
+ state_tokens[0] == STATE_TEXTURE_MATRIX ||
+ state_tokens[0] == STATE_PROGRAM_MATRIX)
+ && (state_tokens[2] != state_tokens[3])) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+ || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+ assert((state_tokens[1] == STATE_ENV)
+ || (state_tokens[1] == STATE_LOCAL));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
+ ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
+
+ /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+ * we need to unroll it and call add_state_reference() for each row
+ */
+ if (state_tokens[2] != state_tokens[3]) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const struct asm_vector *vec)
+{
+ const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
+ NULL, vec->count, GL_NONE, vec->data,
+ NULL, 0x0);
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_CONSTANT;
+
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+
+ return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+ int length;
+ char *str;
+ va_list args;
+
+ va_start(args, fmt);
+
+ /* Call vsnprintf once to determine how large the final string is. Call it
+ * again to do the actual formatting. from the vsnprintf manual page:
+ *
+ * Upon successful return, these functions return the number of
+ * characters printed (not including the trailing '\0' used to end
+ * output to strings).
+ */
+ length = 1 + vsnprintf(NULL, 0, fmt, args);
+
+ str = _mesa_malloc(length);
+ if (str) {
+ vsnprintf(str, length, fmt, args);
+ }
+
+ va_end(args);
+
+ return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+ char *err_str;
+
+
+ err_str = make_error_string("glProgramStringARB(%s)\n", s);
+ if (err_str) {
+ _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
+ _mesa_free(err_str);
+ }
+
+ err_str = make_error_string("line %u, char %u: error: %s\n",
+ locp->first_line, locp->first_column, s);
+ _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+ if (err_str) {
+ _mesa_free(err_str);
+ }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
+ GLsizei len, struct asm_parser_state *state)
+{
+ struct asm_instruction *inst;
+ unsigned i;
+ GLubyte *strz;
+ GLboolean result = GL_FALSE;
+ void *temp;
+ struct asm_symbol *sym;
+
+ state->ctx = ctx;
+ state->prog->Target = target;
+ state->prog->Parameters = _mesa_new_parameter_list();
+
+ /* Make a copy of the program string and force it to be NUL-terminated.
+ */
+ strz = (GLubyte *) _mesa_malloc(len + 1);
+ if (strz == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return GL_FALSE;
+ }
+ _mesa_memcpy (strz, str, len);
+ strz[len] = '\0';
+
+ state->prog->String = strz;
+
+ state->st = _mesa_symbol_table_ctor();
+
+ state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+ ? & ctx->Const.VertexProgram
+ : & ctx->Const.FragmentProgram;
+
+ state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+ state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+ state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ state->MaxLights = ctx->Const.MaxLights;
+ state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+
+ state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+ ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+ _mesa_set_program_error(ctx, -1, NULL);
+
+ _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+ yyparse(state);
+ _mesa_program_lexer_dtor(state->scanner);
+
+
+ if (ctx->Program.ErrorPos != -1) {
+ goto error;
+ }
+
+ if (! _mesa_layout_parameters(state)) {
+ struct YYLTYPE loc;
+
+ loc.first_line = 0;
+ loc.first_column = 0;
+ loc.position = len;
+
+ yyerror(& loc, state, "invalid PARAM usage");
+ goto error;
+ }
+
+
+
+ /* Add one instruction to store the "END" instruction.
+ */
+ state->prog->Instructions =
+ _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+ inst = state->inst_head;
+ for (i = 0; i < state->prog->NumInstructions; i++) {
+ struct asm_instruction *const temp = inst->next;
+
+ state->prog->Instructions[i] = inst->Base;
+ inst = temp;
+ }
+
+ /* Finally, tag on an OPCODE_END instruction */
+ {
+ const GLuint numInst = state->prog->NumInstructions;
+ _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+ state->prog->Instructions[numInst].Opcode = OPCODE_END;
+ }
+ state->prog->NumInstructions++;
+
+ state->prog->NumParameters = state->prog->Parameters->NumParameters;
+ state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+
+ /*
+ * Initialize native counts to logical counts. The device driver may
+ * change them if program is translated into a hardware program.
+ */
+ state->prog->NumNativeInstructions = state->prog->NumInstructions;
+ state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+ state->prog->NumNativeParameters = state->prog->NumParameters;
+ state->prog->NumNativeAttributes = state->prog->NumAttributes;
+ state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+ result = GL_TRUE;
+
+error:
+ for (inst = state->inst_head; inst != NULL; inst = temp) {
+ temp = inst->next;
+ _mesa_free(inst);
+ }
+
+ state->inst_head = NULL;
+ state->inst_tail = NULL;
+
+ for (sym = state->sym; sym != NULL; sym = temp) {
+ temp = sym->next;
+
+ _mesa_free((void *) sym->name);
+ _mesa_free(sym);
+ }
+ state->sym = NULL;
+
+ _mesa_symbol_table_dtor(state->st);
+ state->st = NULL;
+
+ return result;
+}
+
diff --git a/src/mesa/shader/program_parse.tab.h b/src/mesa/shader/program_parse.tab.h
new file mode 100644
index 0000000000..dabb3bf1a3
--- /dev/null
+++ b/src/mesa/shader/program_parse.tab.h
@@ -0,0 +1,207 @@
+
+/* A Bison parser, made by GNU Bison 2.4.1. */
+
+/* Skeleton interface for Bison's Yacc-like parsers in C
+
+ Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ ARBvp_10 = 258,
+ ARBfp_10 = 259,
+ ADDRESS = 260,
+ ALIAS = 261,
+ ATTRIB = 262,
+ OPTION = 263,
+ OUTPUT = 264,
+ PARAM = 265,
+ TEMP = 266,
+ END = 267,
+ BIN_OP = 268,
+ BINSC_OP = 269,
+ SAMPLE_OP = 270,
+ SCALAR_OP = 271,
+ TRI_OP = 272,
+ VECTOR_OP = 273,
+ ARL = 274,
+ KIL = 275,
+ SWZ = 276,
+ INTEGER = 277,
+ REAL = 278,
+ AMBIENT = 279,
+ ATTENUATION = 280,
+ BACK = 281,
+ CLIP = 282,
+ COLOR = 283,
+ DEPTH = 284,
+ DIFFUSE = 285,
+ DIRECTION = 286,
+ EMISSION = 287,
+ ENV = 288,
+ EYE = 289,
+ FOG = 290,
+ FOGCOORD = 291,
+ FRAGMENT = 292,
+ FRONT = 293,
+ HALF = 294,
+ INVERSE = 295,
+ INVTRANS = 296,
+ LIGHT = 297,
+ LIGHTMODEL = 298,
+ LIGHTPROD = 299,
+ LOCAL = 300,
+ MATERIAL = 301,
+ MAT_PROGRAM = 302,
+ MATRIX = 303,
+ MATRIXINDEX = 304,
+ MODELVIEW = 305,
+ MVP = 306,
+ NORMAL = 307,
+ OBJECT = 308,
+ PALETTE = 309,
+ PARAMS = 310,
+ PLANE = 311,
+ POINT_TOK = 312,
+ POINTSIZE = 313,
+ POSITION = 314,
+ PRIMARY = 315,
+ PROGRAM = 316,
+ PROJECTION = 317,
+ RANGE = 318,
+ RESULT = 319,
+ ROW = 320,
+ SCENECOLOR = 321,
+ SECONDARY = 322,
+ SHININESS = 323,
+ SIZE_TOK = 324,
+ SPECULAR = 325,
+ SPOT = 326,
+ STATE = 327,
+ TEXCOORD = 328,
+ TEXENV = 329,
+ TEXGEN = 330,
+ TEXGEN_Q = 331,
+ TEXGEN_R = 332,
+ TEXGEN_S = 333,
+ TEXGEN_T = 334,
+ TEXTURE = 335,
+ TRANSPOSE = 336,
+ TEXTURE_UNIT = 337,
+ TEX_1D = 338,
+ TEX_2D = 339,
+ TEX_3D = 340,
+ TEX_CUBE = 341,
+ TEX_RECT = 342,
+ TEX_SHADOW1D = 343,
+ TEX_SHADOW2D = 344,
+ TEX_SHADOWRECT = 345,
+ TEX_ARRAY1D = 346,
+ TEX_ARRAY2D = 347,
+ TEX_ARRAYSHADOW1D = 348,
+ TEX_ARRAYSHADOW2D = 349,
+ VERTEX = 350,
+ VTXATTRIB = 351,
+ WEIGHT = 352,
+ IDENTIFIER = 353,
+ MASK4 = 354,
+ MASK3 = 355,
+ MASK2 = 356,
+ MASK1 = 357,
+ SWIZZLE = 358,
+ DOT_DOT = 359,
+ DOT = 360
+ };
+#endif
+
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+{
+
+/* Line 1676 of yacc.c */
+#line 107 "program_parse.y"
+
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+
+
+
+/* Line 1676 of yacc.c */
+#line 185 "program_parse.tab.h"
+} YYSTYPE;
+# define YYSTYPE_IS_TRIVIAL 1
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+#endif
+
+
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+
diff --git a/src/mesa/shader/program_parse.y b/src/mesa/shader/program_parse.y
new file mode 100644
index 0000000000..89da91064b
--- /dev/null
+++ b/src/mesa/shader/program_parse.y
@@ -0,0 +1,2383 @@
+%{
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "main/mtypes.h"
+#include "main/imports.h"
+#include "program.h"
+#include "prog_parameter.h"
+#include "prog_parameter_layout.h"
+#include "prog_statevars.h"
+#include "prog_instruction.h"
+
+#include "symbol_table.h"
+#include "program_parser.h"
+
+extern void *yy_scan_string(char *);
+extern void yy_delete_buffer(void *);
+
+static struct asm_symbol *declare_variable(struct asm_parser_state *state,
+ char *name, enum asm_type t, struct YYLTYPE *locp);
+
+static int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var, const gl_state_index tokens[STATE_LENGTH]);
+
+static int initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var, const struct asm_vector *vec);
+
+static int yyparse(struct asm_parser_state *state);
+
+static char *make_error_string(const char *fmt, ...);
+
+static void yyerror(struct YYLTYPE *locp, struct asm_parser_state *state,
+ const char *s);
+
+static int validate_inputs(struct YYLTYPE *locp,
+ struct asm_parser_state *state);
+
+static void init_dst_reg(struct prog_dst_register *r);
+
+static void init_src_reg(struct asm_src_register *r);
+
+static struct asm_instruction *asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst, const struct asm_src_register *src0,
+ const struct asm_src_register *src1, const struct asm_src_register *src2);
+
+#ifndef FALSE
+#define FALSE 0
+#define TRUE (!FALSE)
+#endif
+
+#define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do { \
+ if (YYID(N)) { \
+ (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 1).position; \
+ (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC(Rhs, N).last_column; \
+ } else { \
+ (Current).first_line = YYRHSLOC(Rhs, 0).last_line; \
+ (Current).last_line = (Current).first_line; \
+ (Current).first_column = YYRHSLOC(Rhs, 0).last_column; \
+ (Current).last_column = (Current).first_column; \
+ (Current).position = YYRHSLOC(Rhs, 0).position \
+ + (Current).first_column; \
+ } \
+ } while(YYID(0))
+
+#define YYLEX_PARAM state->scanner
+%}
+
+%pure-parser
+%locations
+%parse-param { struct asm_parser_state *state }
+%error-verbose
+%lex-param { void *scanner }
+
+%union {
+ struct asm_instruction *inst;
+ struct asm_symbol *sym;
+ struct asm_symbol temp_sym;
+ struct asm_swizzle_mask swiz_mask;
+ struct asm_src_register src_reg;
+ struct prog_dst_register dst_reg;
+ struct prog_instruction temp_inst;
+ char *string;
+ unsigned result;
+ unsigned attrib;
+ int integer;
+ float real;
+ gl_state_index state[STATE_LENGTH];
+ int negate;
+ struct asm_vector vector;
+ gl_inst_opcode opcode;
+
+ struct {
+ unsigned swz;
+ unsigned rgba_valid:1;
+ unsigned xyzw_valid:1;
+ unsigned negate:1;
+ } ext_swizzle;
+}
+
+%token ARBvp_10 ARBfp_10
+
+/* Tokens for assembler pseudo-ops */
+%token <integer> ADDRESS
+%token ALIAS ATTRIB
+%token OPTION OUTPUT
+%token PARAM
+%token <integer> TEMP
+%token END
+
+ /* Tokens for instructions */
+%token <temp_inst> BIN_OP BINSC_OP SAMPLE_OP SCALAR_OP TRI_OP VECTOR_OP
+%token <temp_inst> ARL KIL SWZ
+
+%token <integer> INTEGER
+%token <real> REAL
+
+%token AMBIENT ATTENUATION
+%token BACK
+%token CLIP COLOR
+%token DEPTH DIFFUSE DIRECTION
+%token EMISSION ENV EYE
+%token FOG FOGCOORD FRAGMENT FRONT
+%token HALF
+%token INVERSE INVTRANS
+%token LIGHT LIGHTMODEL LIGHTPROD LOCAL
+%token MATERIAL MAT_PROGRAM MATRIX MATRIXINDEX MODELVIEW MVP
+%token NORMAL
+%token OBJECT
+%token PALETTE PARAMS PLANE POINT_TOK POINTSIZE POSITION PRIMARY PROGRAM PROJECTION
+%token RANGE RESULT ROW
+%token SCENECOLOR SECONDARY SHININESS SIZE_TOK SPECULAR SPOT STATE
+%token TEXCOORD TEXENV TEXGEN TEXGEN_Q TEXGEN_R TEXGEN_S TEXGEN_T TEXTURE TRANSPOSE
+%token TEXTURE_UNIT TEX_1D TEX_2D TEX_3D TEX_CUBE TEX_RECT
+%token TEX_SHADOW1D TEX_SHADOW2D TEX_SHADOWRECT
+%token TEX_ARRAY1D TEX_ARRAY2D TEX_ARRAYSHADOW1D TEX_ARRAYSHADOW2D
+%token VERTEX VTXATTRIB
+%token WEIGHT
+
+%token <string> IDENTIFIER
+%token <swiz_mask> MASK4 MASK3 MASK2 MASK1 SWIZZLE
+%token DOT_DOT
+%token DOT
+
+%type <inst> instruction ALU_instruction TexInstruction
+%type <inst> ARL_instruction VECTORop_instruction
+%type <inst> SCALARop_instruction BINSCop_instruction BINop_instruction
+%type <inst> TRIop_instruction SWZ_instruction SAMPLE_instruction
+%type <inst> KIL_instruction
+
+%type <dst_reg> dstReg maskedDstReg maskedAddrReg
+%type <src_reg> srcReg scalarSrcReg swizzleSrcReg
+%type <swiz_mask> scalarSuffix swizzleSuffix extendedSwizzle
+%type <ext_swizzle> extSwizComp extSwizSel
+%type <swiz_mask> optionalMask
+
+%type <sym> progParamArray
+%type <integer> addrRegRelOffset addrRegPosOffset addrRegNegOffset
+%type <src_reg> progParamArrayMem progParamArrayAbs progParamArrayRel
+%type <sym> addrReg
+%type <swiz_mask> addrComponent addrWriteMask
+
+%type <result> resultBinding resultColBinding
+%type <integer> optFaceType optColorType
+%type <integer> optResultFaceType optResultColorType
+
+%type <integer> optTexImageUnitNum texImageUnitNum
+%type <integer> optTexCoordUnitNum texCoordUnitNum
+%type <integer> optLegacyTexUnitNum legacyTexUnitNum
+%type <integer> texImageUnit texTarget
+%type <integer> vtxAttribNum
+
+%type <attrib> attribBinding vtxAttribItem fragAttribItem
+
+%type <temp_sym> paramSingleInit paramSingleItemDecl
+%type <integer> optArraySize
+
+%type <state> stateSingleItem stateMultipleItem
+%type <state> stateMaterialItem
+%type <state> stateLightItem stateLightModelItem stateLightProdItem
+%type <state> stateTexGenItem stateFogItem stateClipPlaneItem statePointItem
+%type <state> stateMatrixItem stateMatrixRow stateMatrixRows
+%type <state> stateTexEnvItem stateDepthItem
+
+%type <state> stateLModProperty
+%type <state> stateMatrixName optMatrixRows
+
+%type <integer> stateMatProperty
+%type <integer> stateLightProperty stateSpotProperty
+%type <integer> stateLightNumber stateLProdProperty
+%type <integer> stateTexGenType stateTexGenCoord
+%type <integer> stateTexEnvProperty
+%type <integer> stateFogProperty
+%type <integer> stateClipPlaneNum
+%type <integer> statePointProperty
+
+%type <integer> stateOptMatModifier stateMatModifier stateMatrixRowNum
+%type <integer> stateOptModMatNum stateModMatNum statePaletteMatNum
+%type <integer> stateProgramMatNum
+
+%type <integer> ambDiffSpecProperty
+
+%type <state> programSingleItem progEnvParam progLocalParam
+%type <state> programMultipleItem progEnvParams progLocalParams
+
+%type <temp_sym> paramMultipleInit paramMultInitList paramMultipleItem
+%type <temp_sym> paramSingleItemUse
+
+%type <integer> progEnvParamNum progLocalParamNum
+%type <state> progEnvParamNums progLocalParamNums
+
+%type <vector> paramConstDecl paramConstUse
+%type <vector> paramConstScalarDecl paramConstScalarUse paramConstVector
+%type <real> signedFloatConstant
+%type <negate> optionalSign
+
+%{
+extern int yylex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param,
+ void *yyscanner);
+%}
+
+%%
+
+program: language optionSequence statementSequence END
+ ;
+
+language: ARBvp_10
+ {
+ if (state->prog->Target != GL_VERTEX_PROGRAM_ARB) {
+ yyerror(& @1, state, "invalid fragment program header");
+
+ }
+ state->mode = ARB_vertex;
+ }
+ | ARBfp_10
+ {
+ if (state->prog->Target != GL_FRAGMENT_PROGRAM_ARB) {
+ yyerror(& @1, state, "invalid vertex program header");
+ }
+ state->mode = ARB_fragment;
+
+ state->option.TexRect =
+ (state->ctx->Extensions.NV_texture_rectangle != GL_FALSE);
+ }
+ ;
+
+optionSequence: optionSequence option
+ |
+ ;
+
+option: OPTION IDENTIFIER ';'
+ {
+ int valid = 0;
+
+ if (state->mode == ARB_vertex) {
+ valid = _mesa_ARBvp_parse_option(state, $2);
+ } else if (state->mode == ARB_fragment) {
+ valid = _mesa_ARBfp_parse_option(state, $2);
+ }
+
+
+ if (!valid) {
+ const char *const err_str = (state->mode == ARB_vertex)
+ ? "invalid ARB vertex program option"
+ : "invalid ARB fragment program option";
+
+ yyerror(& @2, state, err_str);
+ YYERROR;
+ }
+ }
+ ;
+
+statementSequence: statementSequence statement
+ |
+ ;
+
+statement: instruction ';'
+ {
+ if ($1 != NULL) {
+ if (state->inst_tail == NULL) {
+ state->inst_head = $1;
+ } else {
+ state->inst_tail->next = $1;
+ }
+
+ state->inst_tail = $1;
+ $1->next = NULL;
+
+ state->prog->NumInstructions++;
+ }
+ }
+ | namingStatement ';'
+ ;
+
+instruction: ALU_instruction
+ {
+ $$ = $1;
+ state->prog->NumAluInstructions++;
+ }
+ | TexInstruction
+ {
+ $$ = $1;
+ state->prog->NumTexInstructions++;
+ }
+ ;
+
+ALU_instruction: ARL_instruction
+ | VECTORop_instruction
+ | SCALARop_instruction
+ | BINSCop_instruction
+ | BINop_instruction
+ | TRIop_instruction
+ | SWZ_instruction
+ ;
+
+TexInstruction: SAMPLE_instruction
+ | KIL_instruction
+ ;
+
+ARL_instruction: ARL maskedAddrReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_ctor(OPCODE_ARL, & $2, & $4, NULL, NULL);
+ }
+ ;
+
+VECTORop_instruction: VECTOR_OP maskedDstReg ',' swizzleSrcReg
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+SCALARop_instruction: SCALAR_OP maskedDstReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+BINSCop_instruction: BINSC_OP maskedDstReg ',' scalarSrcReg ',' scalarSrcReg
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+
+BINop_instruction: BIN_OP maskedDstReg ',' swizzleSrcReg ',' swizzleSrcReg
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, NULL);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+TRIop_instruction: TRI_OP maskedDstReg ','
+ swizzleSrcReg ',' swizzleSrcReg ',' swizzleSrcReg
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, & $6, & $8);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+SAMPLE_instruction: SAMPLE_OP maskedDstReg ',' swizzleSrcReg ',' texImageUnit ',' texTarget
+ {
+ $$ = asm_instruction_ctor($1.Opcode, & $2, & $4, NULL, NULL);
+ if ($$ != NULL) {
+ const GLbitfield tex_mask = (1U << $6);
+ GLbitfield shadow_tex = 0;
+ GLbitfield target_mask = 0;
+
+
+ $$->Base.SaturateMode = $1.SaturateMode;
+ $$->Base.TexSrcUnit = $6;
+
+ if ($8 < 0) {
+ shadow_tex = tex_mask;
+
+ $$->Base.TexSrcTarget = -$8;
+ $$->Base.TexShadow = 1;
+ } else {
+ $$->Base.TexSrcTarget = $8;
+ }
+
+ target_mask = (1U << $$->Base.TexSrcTarget);
+
+ /* If this texture unit was previously accessed and that access
+ * had a different texture target, generate an error.
+ *
+ * If this texture unit was previously accessed and that access
+ * had a different shadow mode, generate an error.
+ */
+ if ((state->prog->TexturesUsed[$6] != 0)
+ && ((state->prog->TexturesUsed[$6] != target_mask)
+ || ((state->prog->ShadowSamplers & tex_mask)
+ != shadow_tex))) {
+ yyerror(& @8, state,
+ "multiple targets used on one texture image unit");
+ YYERROR;
+ }
+
+
+ state->prog->TexturesUsed[$6] |= target_mask;
+ state->prog->ShadowSamplers |= shadow_tex;
+ }
+ }
+ ;
+
+KIL_instruction: KIL swizzleSrcReg
+ {
+ $$ = asm_instruction_ctor(OPCODE_KIL, NULL, & $2, NULL, NULL);
+ state->fragment.UsesKill = 1;
+ }
+ ;
+
+texImageUnit: TEXTURE_UNIT optTexImageUnitNum
+ {
+ $$ = $2;
+ }
+ ;
+
+texTarget: TEX_1D { $$ = TEXTURE_1D_INDEX; }
+ | TEX_2D { $$ = TEXTURE_2D_INDEX; }
+ | TEX_3D { $$ = TEXTURE_3D_INDEX; }
+ | TEX_CUBE { $$ = TEXTURE_CUBE_INDEX; }
+ | TEX_RECT { $$ = TEXTURE_RECT_INDEX; }
+ | TEX_SHADOW1D { $$ = -TEXTURE_1D_INDEX; }
+ | TEX_SHADOW2D { $$ = -TEXTURE_2D_INDEX; }
+ | TEX_SHADOWRECT { $$ = -TEXTURE_RECT_INDEX; }
+ | TEX_ARRAY1D { $$ = TEXTURE_1D_ARRAY_INDEX; }
+ | TEX_ARRAY2D { $$ = TEXTURE_2D_ARRAY_INDEX; }
+ | TEX_ARRAYSHADOW1D { $$ = -TEXTURE_1D_ARRAY_INDEX; }
+ | TEX_ARRAYSHADOW2D { $$ = -TEXTURE_2D_ARRAY_INDEX; }
+ ;
+
+SWZ_instruction: SWZ maskedDstReg ',' srcReg ',' extendedSwizzle
+ {
+ /* FIXME: Is this correct? Should the extenedSwizzle be applied
+ * FIXME: to the existing swizzle?
+ */
+ $4.Base.Swizzle = $6.swizzle;
+ $4.Base.Negate = $6.mask;
+
+ $$ = asm_instruction_ctor(OPCODE_SWZ, & $2, & $4, NULL, NULL);
+ $$->Base.SaturateMode = $1.SaturateMode;
+ }
+ ;
+
+scalarSrcReg: optionalSign srcReg scalarSuffix
+ {
+ $$ = $2;
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $3.swizzle);
+ }
+ ;
+
+swizzleSrcReg: optionalSign srcReg swizzleSuffix
+ {
+ $$ = $2;
+
+ if ($1) {
+ $$.Base.Negate = ~$$.Base.Negate;
+ }
+
+ $$.Base.Swizzle = _mesa_combine_swizzles($$.Base.Swizzle,
+ $3.swizzle);
+ }
+ ;
+
+maskedDstReg: dstReg optionalMask
+ {
+ $$ = $1;
+ $$.WriteMask = $2.mask;
+
+ if ($$.File == PROGRAM_OUTPUT) {
+ /* Technically speaking, this should check that it is in
+ * vertex program mode. However, PositionInvariant can never be
+ * set in fragment program mode, so it is somewhat irrelevant.
+ */
+ if (state->option.PositionInvariant
+ && ($$.Index == VERT_RESULT_HPOS)) {
+ yyerror(& @1, state, "position-invariant programs cannot "
+ "write position");
+ YYERROR;
+ }
+
+ state->prog->OutputsWritten |= (1U << $$.Index);
+ }
+ }
+ ;
+
+maskedAddrReg: addrReg addrWriteMask
+ {
+ init_dst_reg(& $$);
+ $$.File = PROGRAM_ADDRESS;
+ $$.Index = 0;
+ $$.WriteMask = $2.mask;
+ }
+ ;
+
+extendedSwizzle: extSwizComp ',' extSwizComp ',' extSwizComp ',' extSwizComp
+ {
+ const unsigned xyzw_valid =
+ ($1.xyzw_valid << 0)
+ | ($3.xyzw_valid << 1)
+ | ($5.xyzw_valid << 2)
+ | ($7.xyzw_valid << 3);
+ const unsigned rgba_valid =
+ ($1.rgba_valid << 0)
+ | ($3.rgba_valid << 1)
+ | ($5.rgba_valid << 2)
+ | ($7.rgba_valid << 3);
+
+ /* All of the swizzle components have to be valid in either RGBA
+ * or XYZW. Note that 0 and 1 are valid in both, so both masks
+ * can have some bits set.
+ *
+ * We somewhat deviate from the spec here. It would be really hard
+ * to figure out which component is the error, and there probably
+ * isn't a lot of benefit.
+ */
+ if ((rgba_valid != 0x0f) && (xyzw_valid != 0x0f)) {
+ yyerror(& @1, state, "cannot combine RGBA and XYZW swizzle "
+ "components");
+ YYERROR;
+ }
+
+ $$.swizzle = MAKE_SWIZZLE4($1.swz, $3.swz, $5.swz, $7.swz);
+ $$.mask = ($1.negate) | ($3.negate << 1) | ($5.negate << 2)
+ | ($7.negate << 3);
+ }
+ ;
+
+extSwizComp: optionalSign extSwizSel
+ {
+ $$ = $2;
+ $$.negate = ($1) ? 1 : 0;
+ }
+ ;
+
+extSwizSel: INTEGER
+ {
+ if (($1 != 0) && ($1 != 1)) {
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ $$.swz = ($1 == 0) ? SWIZZLE_ZERO : SWIZZLE_ONE;
+
+ /* 0 and 1 are valid for both RGBA swizzle names and XYZW
+ * swizzle names.
+ */
+ $$.xyzw_valid = 1;
+ $$.rgba_valid = 1;
+ }
+ | IDENTIFIER
+ {
+ if (strlen($1) > 1) {
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ }
+
+ switch ($1[0]) {
+ case 'x':
+ $$.swz = SWIZZLE_X;
+ $$.xyzw_valid = 1;
+ break;
+ case 'y':
+ $$.swz = SWIZZLE_Y;
+ $$.xyzw_valid = 1;
+ break;
+ case 'z':
+ $$.swz = SWIZZLE_Z;
+ $$.xyzw_valid = 1;
+ break;
+ case 'w':
+ $$.swz = SWIZZLE_W;
+ $$.xyzw_valid = 1;
+ break;
+
+ case 'r':
+ $$.swz = SWIZZLE_X;
+ $$.rgba_valid = 1;
+ break;
+ case 'g':
+ $$.swz = SWIZZLE_Y;
+ $$.rgba_valid = 1;
+ break;
+ case 'b':
+ $$.swz = SWIZZLE_Z;
+ $$.rgba_valid = 1;
+ break;
+ case 'a':
+ $$.swz = SWIZZLE_W;
+ $$.rgba_valid = 1;
+ break;
+
+ default:
+ yyerror(& @1, state, "invalid extended swizzle selector");
+ YYERROR;
+ break;
+ }
+ }
+ ;
+
+srcReg: IDENTIFIER /* temporaryReg | progParamSingle */
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) && (s->type != at_temp)
+ && (s->type != at_attrib)) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type == at_param) && s->param_is_array) {
+ yyerror(& @1, state, "non-array access to array PARAM");
+ YYERROR;
+ }
+
+ init_src_reg(& $$);
+ switch (s->type) {
+ case at_temp:
+ $$.Base.File = PROGRAM_TEMPORARY;
+ $$.Base.Index = s->temp_binding;
+ break;
+ case at_param:
+ $$.Base.File = s->param_binding_type;
+ $$.Base.Index = s->param_binding_begin;
+ break;
+ case at_attrib:
+ $$.Base.File = PROGRAM_INPUT;
+ $$.Base.Index = s->attrib_binding;
+ state->prog->InputsRead |= (1U << $$.Base.Index);
+
+ if (!validate_inputs(& @1, state)) {
+ YYERROR;
+ }
+ break;
+
+ default:
+ YYERROR;
+ break;
+ }
+ }
+ | attribBinding
+ {
+ init_src_reg(& $$);
+ $$.Base.File = PROGRAM_INPUT;
+ $$.Base.Index = $1;
+ state->prog->InputsRead |= (1U << $$.Base.Index);
+
+ if (!validate_inputs(& @1, state)) {
+ YYERROR;
+ }
+ }
+ | progParamArray '[' progParamArrayMem ']'
+ {
+ if (! $3.Base.RelAddr
+ && ((unsigned) $3.Base.Index >= $1->param_binding_length)) {
+ yyerror(& @3, state, "out of bounds array access");
+ YYERROR;
+ }
+
+ init_src_reg(& $$);
+ $$.Base.File = $1->param_binding_type;
+
+ if ($3.Base.RelAddr) {
+ $1->param_accessed_indirectly = 1;
+
+ $$.Base.RelAddr = 1;
+ $$.Base.Index = $3.Base.Index;
+ $$.Symbol = $1;
+ } else {
+ $$.Base.Index = $1->param_binding_begin + $3.Base.Index;
+ }
+ }
+ | paramSingleItemUse
+ {
+ init_src_reg(& $$);
+ $$.Base.File = ($1.name != NULL)
+ ? $1.param_binding_type
+ : PROGRAM_CONSTANT;
+ $$.Base.Index = $1.param_binding_begin;
+ }
+ ;
+
+dstReg: resultBinding
+ {
+ init_dst_reg(& $$);
+ $$.File = PROGRAM_OUTPUT;
+ $$.Index = $1;
+ }
+ | IDENTIFIER /* temporaryReg | vertexResultReg */
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_output) && (s->type != at_temp)) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ }
+
+ init_dst_reg(& $$);
+ switch (s->type) {
+ case at_temp:
+ $$.File = PROGRAM_TEMPORARY;
+ $$.Index = s->temp_binding;
+ break;
+ case at_output:
+ $$.File = PROGRAM_OUTPUT;
+ $$.Index = s->output_binding;
+ break;
+ default:
+ $$.File = s->param_binding_type;
+ $$.Index = s->param_binding_begin;
+ break;
+ }
+ }
+ ;
+
+progParamArray: IDENTIFIER
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid operand variable");
+ YYERROR;
+ } else if ((s->type != at_param) || !s->param_is_array) {
+ yyerror(& @1, state, "array access to non-PARAM variable");
+ YYERROR;
+ } else {
+ $$ = s;
+ }
+ }
+ ;
+
+progParamArrayMem: progParamArrayAbs | progParamArrayRel;
+
+progParamArrayAbs: INTEGER
+ {
+ init_src_reg(& $$);
+ $$.Base.Index = $1;
+ }
+ ;
+
+progParamArrayRel: addrReg addrComponent addrRegRelOffset
+ {
+ /* FINISHME: Add support for multiple address registers.
+ */
+ /* FINISHME: Add support for 4-component address registers.
+ */
+ init_src_reg(& $$);
+ $$.Base.RelAddr = 1;
+ $$.Base.Index = $3;
+ }
+ ;
+
+addrRegRelOffset: { $$ = 0; }
+ | '+' addrRegPosOffset { $$ = $2; }
+ | '-' addrRegNegOffset { $$ = -$2; }
+ ;
+
+addrRegPosOffset: INTEGER
+ {
+ if (($1 < 0) || ($1 > 63)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrRegNegOffset: INTEGER
+ {
+ if (($1 < 0) || ($1 > 64)) {
+ char s[100];
+ _mesa_snprintf(s, sizeof(s),
+ "relative address offset too large (%d)", $1);
+ yyerror(& @1, state, s);
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrReg: IDENTIFIER
+ {
+ struct asm_symbol *const s = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $1);
+
+ if (s == NULL) {
+ yyerror(& @1, state, "invalid array member");
+ YYERROR;
+ } else if (s->type != at_address) {
+ yyerror(& @1, state,
+ "invalid variable for indexed array access");
+ YYERROR;
+ } else {
+ $$ = s;
+ }
+ }
+ ;
+
+addrComponent: MASK1
+ {
+ if ($1.mask != WRITEMASK_X) {
+ yyerror(& @1, state, "invalid address component selector");
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+addrWriteMask: MASK1
+ {
+ if ($1.mask != WRITEMASK_X) {
+ yyerror(& @1, state,
+ "address register write mask must be \".x\"");
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+scalarSuffix: MASK1;
+
+swizzleSuffix: MASK1
+ | MASK4
+ | SWIZZLE
+ | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+ ;
+
+optionalMask: MASK4 | MASK3 | MASK2 | MASK1
+ | { $$.swizzle = SWIZZLE_NOOP; $$.mask = WRITEMASK_XYZW; }
+ ;
+
+namingStatement: ATTRIB_statement
+ | PARAM_statement
+ | TEMP_statement
+ | ADDRESS_statement
+ | OUTPUT_statement
+ | ALIAS_statement
+ ;
+
+ATTRIB_statement: ATTRIB IDENTIFIER '=' attribBinding
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, at_attrib, & @2);
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->attrib_binding = $4;
+ state->InputsBound |= (1U << s->attrib_binding);
+
+ if (!validate_inputs(& @4, state)) {
+ YYERROR;
+ }
+ }
+ }
+ ;
+
+attribBinding: VERTEX vtxAttribItem
+ {
+ $$ = $2;
+ }
+ | FRAGMENT fragAttribItem
+ {
+ $$ = $2;
+ }
+ ;
+
+vtxAttribItem: POSITION
+ {
+ $$ = VERT_ATTRIB_POS;
+ }
+ | WEIGHT vtxOptWeightNum
+ {
+ $$ = VERT_ATTRIB_WEIGHT;
+ }
+ | NORMAL
+ {
+ $$ = VERT_ATTRIB_NORMAL;
+ }
+ | COLOR optColorType
+ {
+ if (!state->ctx->Extensions.EXT_secondary_color) {
+ yyerror(& @2, state, "GL_EXT_secondary_color not supported");
+ YYERROR;
+ }
+
+ $$ = VERT_ATTRIB_COLOR0 + $2;
+ }
+ | FOGCOORD
+ {
+ if (!state->ctx->Extensions.EXT_fog_coord) {
+ yyerror(& @1, state, "GL_EXT_fog_coord not supported");
+ YYERROR;
+ }
+
+ $$ = VERT_ATTRIB_FOG;
+ }
+ | TEXCOORD optTexCoordUnitNum
+ {
+ $$ = VERT_ATTRIB_TEX0 + $2;
+ }
+ | MATRIXINDEX '[' vtxWeightNum ']'
+ {
+ yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ | VTXATTRIB '[' vtxAttribNum ']'
+ {
+ $$ = VERT_ATTRIB_GENERIC0 + $3;
+ }
+ ;
+
+vtxAttribNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxAttribs) {
+ yyerror(& @1, state, "invalid vertex attribute reference");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+vtxOptWeightNum: | '[' vtxWeightNum ']';
+vtxWeightNum: INTEGER;
+
+fragAttribItem: POSITION
+ {
+ $$ = FRAG_ATTRIB_WPOS;
+ }
+ | COLOR optColorType
+ {
+ $$ = FRAG_ATTRIB_COL0 + $2;
+ }
+ | FOGCOORD
+ {
+ $$ = FRAG_ATTRIB_FOGC;
+ }
+ | TEXCOORD optTexCoordUnitNum
+ {
+ $$ = FRAG_ATTRIB_TEX0 + $2;
+ }
+ ;
+
+PARAM_statement: PARAM_singleStmt | PARAM_multipleStmt;
+
+PARAM_singleStmt: PARAM IDENTIFIER paramSingleInit
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, at_param, & @2);
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->param_binding_type = $3.param_binding_type;
+ s->param_binding_begin = $3.param_binding_begin;
+ s->param_binding_length = $3.param_binding_length;
+ s->param_is_array = 0;
+ }
+ }
+ ;
+
+PARAM_multipleStmt: PARAM IDENTIFIER '[' optArraySize ']' paramMultipleInit
+ {
+ if (($4 != 0) && ((unsigned) $4 != $6.param_binding_length)) {
+ yyerror(& @4, state,
+ "parameter array size and number of bindings must match");
+ YYERROR;
+ } else {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, $6.type, & @2);
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->param_binding_type = $6.param_binding_type;
+ s->param_binding_begin = $6.param_binding_begin;
+ s->param_binding_length = $6.param_binding_length;
+ s->param_is_array = 1;
+ }
+ }
+ }
+ ;
+
+optArraySize:
+ {
+ $$ = 0;
+ }
+ | INTEGER
+ {
+ if (($1 < 1) || ((unsigned) $1 >= state->limits->MaxParameters)) {
+ yyerror(& @1, state, "invalid parameter array size");
+ YYERROR;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+paramSingleInit: '=' paramSingleItemDecl
+ {
+ $$ = $2;
+ }
+ ;
+
+paramMultipleInit: '=' '{' paramMultInitList '}'
+ {
+ $$ = $3;
+ }
+ ;
+
+paramMultInitList: paramMultipleItem
+ | paramMultInitList ',' paramMultipleItem
+ {
+ $1.param_binding_length += $3.param_binding_length;
+ $$ = $1;
+ }
+ ;
+
+paramSingleItemDecl: stateSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstDecl
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1);
+ }
+ ;
+
+paramSingleItemUse: stateSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programSingleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstUse
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1);
+ }
+ ;
+
+paramMultipleItem: stateMultipleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_state(state->prog, & $$, $1);
+ }
+ | programMultipleItem
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_param(state->prog, & $$, $1);
+ }
+ | paramConstDecl
+ {
+ memset(& $$, 0, sizeof($$));
+ $$.param_binding_begin = ~0;
+ initialize_symbol_from_const(state->prog, & $$, & $1);
+ }
+ ;
+
+stateMultipleItem: stateSingleItem { memcpy($$, $1, sizeof($$)); }
+ | STATE stateMatrixRows { memcpy($$, $2, sizeof($$)); }
+ ;
+
+stateSingleItem: STATE stateMaterialItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightModelItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateLightProdItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateTexGenItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateTexEnvItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateFogItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateClipPlaneItem { memcpy($$, $2, sizeof($$)); }
+ | STATE statePointItem { memcpy($$, $2, sizeof($$)); }
+ | STATE stateMatrixRow { memcpy($$, $2, sizeof($$)); }
+ | STATE stateDepthItem { memcpy($$, $2, sizeof($$)); }
+ ;
+
+stateMaterialItem: MATERIAL optFaceType stateMatProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_MATERIAL;
+ $$[1] = $2;
+ $$[2] = $3;
+ }
+ ;
+
+stateMatProperty: ambDiffSpecProperty
+ {
+ $$ = $1;
+ }
+ | EMISSION
+ {
+ $$ = STATE_EMISSION;
+ }
+ | SHININESS
+ {
+ $$ = STATE_SHININESS;
+ }
+ ;
+
+stateLightItem: LIGHT '[' stateLightNumber ']' stateLightProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHT;
+ $$[1] = $3;
+ $$[2] = $5;
+ }
+ ;
+
+stateLightProperty: ambDiffSpecProperty
+ {
+ $$ = $1;
+ }
+ | POSITION
+ {
+ $$ = STATE_POSITION;
+ }
+ | ATTENUATION
+ {
+ if (!state->ctx->Extensions.EXT_point_parameters) {
+ yyerror(& @1, state, "GL_ARB_point_parameters not supported");
+ YYERROR;
+ }
+
+ $$ = STATE_ATTENUATION;
+ }
+ | SPOT stateSpotProperty
+ {
+ $$ = $2;
+ }
+ | HALF
+ {
+ $$ = STATE_HALF_VECTOR;
+ }
+ ;
+
+stateSpotProperty: DIRECTION
+ {
+ $$ = STATE_SPOT_DIRECTION;
+ }
+ ;
+
+stateLightModelItem: LIGHTMODEL stateLModProperty
+ {
+ $$[0] = $2[0];
+ $$[1] = $2[1];
+ }
+ ;
+
+stateLModProperty: AMBIENT
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTMODEL_AMBIENT;
+ }
+ | optFaceType SCENECOLOR
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTMODEL_SCENECOLOR;
+ $$[1] = $1;
+ }
+ ;
+
+stateLightProdItem: LIGHTPROD '[' stateLightNumber ']' optFaceType stateLProdProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_LIGHTPROD;
+ $$[1] = $3;
+ $$[2] = $5;
+ $$[3] = $6;
+ }
+ ;
+
+stateLProdProperty: ambDiffSpecProperty;
+
+stateTexEnvItem: TEXENV optLegacyTexUnitNum stateTexEnvProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $3;
+ $$[1] = $2;
+ }
+ ;
+
+stateTexEnvProperty: COLOR
+ {
+ $$ = STATE_TEXENV_COLOR;
+ }
+ ;
+
+ambDiffSpecProperty: AMBIENT
+ {
+ $$ = STATE_AMBIENT;
+ }
+ | DIFFUSE
+ {
+ $$ = STATE_DIFFUSE;
+ }
+ | SPECULAR
+ {
+ $$ = STATE_SPECULAR;
+ }
+ ;
+
+stateLightNumber: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxLights) {
+ yyerror(& @1, state, "invalid light selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateTexGenItem: TEXGEN optTexCoordUnitNum stateTexGenType stateTexGenCoord
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_TEXGEN;
+ $$[1] = $2;
+ $$[2] = $3 + $4;
+ }
+ ;
+
+stateTexGenType: EYE
+ {
+ $$ = STATE_TEXGEN_EYE_S;
+ }
+ | OBJECT
+ {
+ $$ = STATE_TEXGEN_OBJECT_S;
+ }
+ ;
+stateTexGenCoord: TEXGEN_S
+ {
+ $$ = STATE_TEXGEN_EYE_S - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_T
+ {
+ $$ = STATE_TEXGEN_EYE_T - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_R
+ {
+ $$ = STATE_TEXGEN_EYE_R - STATE_TEXGEN_EYE_S;
+ }
+ | TEXGEN_Q
+ {
+ $$ = STATE_TEXGEN_EYE_Q - STATE_TEXGEN_EYE_S;
+ }
+ ;
+
+stateFogItem: FOG stateFogProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $2;
+ }
+ ;
+
+stateFogProperty: COLOR
+ {
+ $$ = STATE_FOG_COLOR;
+ }
+ | PARAMS
+ {
+ $$ = STATE_FOG_PARAMS;
+ }
+ ;
+
+stateClipPlaneItem: CLIP '[' stateClipPlaneNum ']' PLANE
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_CLIPPLANE;
+ $$[1] = $3;
+ }
+ ;
+
+stateClipPlaneNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxClipPlanes) {
+ yyerror(& @1, state, "invalid clip plane selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+statePointItem: POINT_TOK statePointProperty
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = $2;
+ }
+ ;
+
+statePointProperty: SIZE_TOK
+ {
+ $$ = STATE_POINT_SIZE;
+ }
+ | ATTENUATION
+ {
+ $$ = STATE_POINT_ATTENUATION;
+ }
+ ;
+
+stateMatrixRow: stateMatrixItem ROW '[' stateMatrixRowNum ']'
+ {
+ $$[0] = $1[0];
+ $$[1] = $1[1];
+ $$[2] = $4;
+ $$[3] = $4;
+ $$[4] = $1[2];
+ }
+ ;
+
+stateMatrixRows: stateMatrixItem optMatrixRows
+ {
+ $$[0] = $1[0];
+ $$[1] = $1[1];
+ $$[2] = $2[2];
+ $$[3] = $2[3];
+ $$[4] = $1[2];
+ }
+ ;
+
+optMatrixRows:
+ {
+ $$[2] = 0;
+ $$[3] = 3;
+ }
+ | ROW '[' stateMatrixRowNum DOT_DOT stateMatrixRowNum ']'
+ {
+ /* It seems logical that the matrix row range specifier would have
+ * to specify a range or more than one row (i.e., $5 > $3).
+ * However, the ARB_vertex_program spec says "a program will fail
+ * to load if <a> is greater than <b>." This means that $3 == $5
+ * is valid.
+ */
+ if ($3 > $5) {
+ yyerror(& @3, state, "invalid matrix row range");
+ YYERROR;
+ }
+
+ $$[2] = $3;
+ $$[3] = $5;
+ }
+ ;
+
+stateMatrixItem: MATRIX stateMatrixName stateOptMatModifier
+ {
+ $$[0] = $2[0];
+ $$[1] = $2[1];
+ $$[2] = $3;
+ }
+ ;
+
+stateOptMatModifier:
+ {
+ $$ = 0;
+ }
+ | stateMatModifier
+ {
+ $$ = $1;
+ }
+ ;
+
+stateMatModifier: INVERSE
+ {
+ $$ = STATE_MATRIX_INVERSE;
+ }
+ | TRANSPOSE
+ {
+ $$ = STATE_MATRIX_TRANSPOSE;
+ }
+ | INVTRANS
+ {
+ $$ = STATE_MATRIX_INVTRANS;
+ }
+ ;
+
+stateMatrixRowNum: INTEGER
+ {
+ if ($1 > 3) {
+ yyerror(& @1, state, "invalid matrix row reference");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateMatrixName: MODELVIEW stateOptModMatNum
+ {
+ $$[0] = STATE_MODELVIEW_MATRIX;
+ $$[1] = $2;
+ }
+ | PROJECTION
+ {
+ $$[0] = STATE_PROJECTION_MATRIX;
+ $$[1] = 0;
+ }
+ | MVP
+ {
+ $$[0] = STATE_MVP_MATRIX;
+ $$[1] = 0;
+ }
+ | TEXTURE optTexCoordUnitNum
+ {
+ $$[0] = STATE_TEXTURE_MATRIX;
+ $$[1] = $2;
+ }
+ | PALETTE '[' statePaletteMatNum ']'
+ {
+ yyerror(& @1, state, "GL_ARB_matrix_palette not supported");
+ YYERROR;
+ }
+ | MAT_PROGRAM '[' stateProgramMatNum ']'
+ {
+ $$[0] = STATE_PROGRAM_MATRIX;
+ $$[1] = $3;
+ }
+ ;
+
+stateOptModMatNum:
+ {
+ $$ = 0;
+ }
+ | '[' stateModMatNum ']'
+ {
+ $$ = $2;
+ }
+ ;
+stateModMatNum: INTEGER
+ {
+ /* Since GL_ARB_vertex_blend isn't supported, only modelview matrix
+ * zero is valid.
+ */
+ if ($1 != 0) {
+ yyerror(& @1, state, "invalid modelview matrix index");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+statePaletteMatNum: INTEGER
+ {
+ /* Since GL_ARB_matrix_palette isn't supported, just let any value
+ * through here. The error will be generated later.
+ */
+ $$ = $1;
+ }
+ ;
+stateProgramMatNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxProgramMatrices) {
+ yyerror(& @1, state, "invalid program matrix selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+stateDepthItem: DEPTH RANGE
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = STATE_DEPTH_RANGE;
+ }
+ ;
+
+
+programSingleItem: progEnvParam | progLocalParam;
+
+programMultipleItem: progEnvParams | progLocalParams;
+
+progEnvParams: PROGRAM ENV '[' progEnvParamNums ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_ENV;
+ $$[2] = $4[0];
+ $$[3] = $4[1];
+ }
+ ;
+
+progEnvParamNums: progEnvParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $1;
+ }
+ | progEnvParamNum DOT_DOT progEnvParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $3;
+ }
+ ;
+
+progEnvParam: PROGRAM ENV '[' progEnvParamNum ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_ENV;
+ $$[2] = $4;
+ $$[3] = $4;
+ }
+ ;
+
+progLocalParams: PROGRAM LOCAL '[' progLocalParamNums ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_LOCAL;
+ $$[2] = $4[0];
+ $$[3] = $4[1];
+ }
+
+progLocalParamNums: progLocalParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $1;
+ }
+ | progLocalParamNum DOT_DOT progLocalParamNum
+ {
+ $$[0] = $1;
+ $$[1] = $3;
+ }
+ ;
+
+progLocalParam: PROGRAM LOCAL '[' progLocalParamNum ']'
+ {
+ memset($$, 0, sizeof($$));
+ $$[0] = state->state_param_enum;
+ $$[1] = STATE_LOCAL;
+ $$[2] = $4;
+ $$[3] = $4;
+ }
+ ;
+
+progEnvParamNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxEnvParams) {
+ yyerror(& @1, state, "invalid environment parameter reference");
+ YYERROR;
+ }
+ $$ = $1;
+ }
+ ;
+
+progLocalParamNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->limits->MaxLocalParams) {
+ yyerror(& @1, state, "invalid local parameter reference");
+ YYERROR;
+ }
+ $$ = $1;
+ }
+ ;
+
+
+
+paramConstDecl: paramConstScalarDecl | paramConstVector;
+paramConstUse: paramConstScalarUse | paramConstVector;
+
+paramConstScalarDecl: signedFloatConstant
+ {
+ $$.count = 4;
+ $$.data[0] = $1;
+ $$.data[1] = $1;
+ $$.data[2] = $1;
+ $$.data[3] = $1;
+ }
+ ;
+
+paramConstScalarUse: REAL
+ {
+ $$.count = 1;
+ $$.data[0] = $1;
+ $$.data[1] = $1;
+ $$.data[2] = $1;
+ $$.data[3] = $1;
+ }
+ | INTEGER
+ {
+ $$.count = 1;
+ $$.data[0] = (float) $1;
+ $$.data[1] = (float) $1;
+ $$.data[2] = (float) $1;
+ $$.data[3] = (float) $1;
+ }
+ ;
+
+paramConstVector: '{' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0] = $2;
+ $$.data[1] = 0.0f;
+ $$.data[2] = 0.0f;
+ $$.data[3] = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0] = $2;
+ $$.data[1] = $4;
+ $$.data[2] = 0.0f;
+ $$.data[3] = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant ','
+ signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0] = $2;
+ $$.data[1] = $4;
+ $$.data[2] = $6;
+ $$.data[3] = 1.0f;
+ }
+ | '{' signedFloatConstant ',' signedFloatConstant ','
+ signedFloatConstant ',' signedFloatConstant '}'
+ {
+ $$.count = 4;
+ $$.data[0] = $2;
+ $$.data[1] = $4;
+ $$.data[2] = $6;
+ $$.data[3] = $8;
+ }
+ ;
+
+signedFloatConstant: optionalSign REAL
+ {
+ $$ = ($1) ? -$2 : $2;
+ }
+ | optionalSign INTEGER
+ {
+ $$ = (float)(($1) ? -$2 : $2);
+ }
+ ;
+
+optionalSign: '+' { $$ = FALSE; }
+ | '-' { $$ = TRUE; }
+ | { $$ = FALSE; }
+ ;
+
+TEMP_statement: TEMP { $<integer>$ = $1; } varNameList
+ ;
+
+ADDRESS_statement: ADDRESS { $<integer>$ = $1; } varNameList
+ ;
+
+varNameList: varNameList ',' IDENTIFIER
+ {
+ if (!declare_variable(state, $3, $<integer>0, & @3)) {
+ YYERROR;
+ }
+ }
+ | IDENTIFIER
+ {
+ if (!declare_variable(state, $1, $<integer>0, & @1)) {
+ YYERROR;
+ }
+ }
+ ;
+
+OUTPUT_statement: OUTPUT IDENTIFIER '=' resultBinding
+ {
+ struct asm_symbol *const s =
+ declare_variable(state, $2, at_output, & @2);
+
+ if (s == NULL) {
+ YYERROR;
+ } else {
+ s->output_binding = $4;
+ }
+ }
+ ;
+
+resultBinding: RESULT POSITION
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_HPOS;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT FOGCOORD
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_FOGC;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT resultColBinding
+ {
+ $$ = $2;
+ }
+ | RESULT POINTSIZE
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_PSIZ;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT TEXCOORD optTexCoordUnitNum
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_TEX0 + $3;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | RESULT DEPTH
+ {
+ if (state->mode == ARB_fragment) {
+ $$ = FRAG_RESULT_DEPTH;
+ } else {
+ yyerror(& @2, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+resultColBinding: COLOR optResultFaceType optResultColorType
+ {
+ $$ = $2 + $3;
+ }
+ ;
+
+optResultFaceType:
+ {
+ $$ = (state->mode == ARB_vertex)
+ ? VERT_RESULT_COL0
+ : FRAG_RESULT_COLOR;
+ }
+ | FRONT
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_COL0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | BACK
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = VERT_RESULT_BFC0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+optResultColorType:
+ {
+ $$ = 0;
+ }
+ | PRIMARY
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = 0;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ | SECONDARY
+ {
+ if (state->mode == ARB_vertex) {
+ $$ = 1;
+ } else {
+ yyerror(& @1, state, "invalid program result name");
+ YYERROR;
+ }
+ }
+ ;
+
+optFaceType: { $$ = 0; }
+ | FRONT { $$ = 0; }
+ | BACK { $$ = 1; }
+ ;
+
+optColorType: { $$ = 0; }
+ | PRIMARY { $$ = 0; }
+ | SECONDARY { $$ = 1; }
+ ;
+
+optTexCoordUnitNum: { $$ = 0; }
+ | '[' texCoordUnitNum ']' { $$ = $2; }
+ ;
+
+optTexImageUnitNum: { $$ = 0; }
+ | '[' texImageUnitNum ']' { $$ = $2; }
+ ;
+
+optLegacyTexUnitNum: { $$ = 0; }
+ | '[' legacyTexUnitNum ']' { $$ = $2; }
+ ;
+
+texCoordUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureCoordUnits) {
+ yyerror(& @1, state, "invalid texture coordinate unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+texImageUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureImageUnits) {
+ yyerror(& @1, state, "invalid texture image unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+legacyTexUnitNum: INTEGER
+ {
+ if ((unsigned) $1 >= state->MaxTextureUnits) {
+ yyerror(& @1, state, "invalid texture unit selector");
+ YYERROR;
+ }
+
+ $$ = $1;
+ }
+ ;
+
+ALIAS_statement: ALIAS IDENTIFIER '=' IDENTIFIER
+ {
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $2);
+ struct asm_symbol *target = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, $4);
+
+
+ if (exist != NULL) {
+ yyerror(& @2, state, "redeclared identifier");
+ YYERROR;
+ } else if (target == NULL) {
+ yyerror(& @4, state,
+ "undefined variable binding in ALIAS statement");
+ YYERROR;
+ } else {
+ _mesa_symbol_table_add_symbol(state->st, 0, $2, target);
+ }
+ }
+ ;
+
+%%
+
+struct asm_instruction *
+asm_instruction_ctor(gl_inst_opcode op,
+ const struct prog_dst_register *dst,
+ const struct asm_src_register *src0,
+ const struct asm_src_register *src1,
+ const struct asm_src_register *src2)
+{
+ struct asm_instruction *inst = calloc(1, sizeof(struct asm_instruction));
+
+ if (inst) {
+ _mesa_init_instructions(& inst->Base, 1);
+ inst->Base.Opcode = op;
+
+ /* In the core ARB extensions only the KIL instruction doesn't have a
+ * destination register.
+ */
+ if (dst == NULL) {
+ init_dst_reg(& inst->Base.DstReg);
+ } else {
+ inst->Base.DstReg = *dst;
+ }
+
+ inst->Base.SrcReg[0] = src0->Base;
+ inst->SrcReg[0] = *src0;
+
+ if (src1 != NULL) {
+ inst->Base.SrcReg[1] = src1->Base;
+ inst->SrcReg[1] = *src1;
+ } else {
+ init_src_reg(& inst->SrcReg[1]);
+ }
+
+ if (src2 != NULL) {
+ inst->Base.SrcReg[2] = src2->Base;
+ inst->SrcReg[2] = *src2;
+ } else {
+ init_src_reg(& inst->SrcReg[2]);
+ }
+ }
+
+ return inst;
+}
+
+
+void
+init_dst_reg(struct prog_dst_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->File = PROGRAM_UNDEFINED;
+ r->WriteMask = WRITEMASK_XYZW;
+ r->CondMask = COND_TR;
+ r->CondSwizzle = SWIZZLE_NOOP;
+}
+
+
+void
+init_src_reg(struct asm_src_register *r)
+{
+ memset(r, 0, sizeof(*r));
+ r->Base.File = PROGRAM_UNDEFINED;
+ r->Base.Swizzle = SWIZZLE_NOOP;
+ r->Symbol = NULL;
+}
+
+
+/**
+ * Validate the set of inputs used by a program
+ *
+ * Validates that legal sets of inputs are used by the program. In this case
+ * "used" included both reading the input or binding the input to a name using
+ * the \c ATTRIB command.
+ *
+ * \return
+ * \c TRUE if the combination of inputs used is valid, \c FALSE otherwise.
+ */
+int
+validate_inputs(struct YYLTYPE *locp, struct asm_parser_state *state)
+{
+ const int inputs = state->prog->InputsRead | state->InputsBound;
+
+ if (((inputs & 0x0ffff) & (inputs >> 16)) != 0) {
+ yyerror(locp, state, "illegal use of generic attribute and name attribute");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+struct asm_symbol *
+declare_variable(struct asm_parser_state *state, char *name, enum asm_type t,
+ struct YYLTYPE *locp)
+{
+ struct asm_symbol *s = NULL;
+ struct asm_symbol *exist = (struct asm_symbol *)
+ _mesa_symbol_table_find_symbol(state->st, 0, name);
+
+
+ if (exist != NULL) {
+ yyerror(locp, state, "redeclared identifier");
+ } else {
+ s = calloc(1, sizeof(struct asm_symbol));
+ s->name = name;
+ s->type = t;
+
+ switch (t) {
+ case at_temp:
+ if (state->prog->NumTemporaries >= state->limits->MaxTemps) {
+ yyerror(locp, state, "too many temporaries declared");
+ free(s);
+ return NULL;
+ }
+
+ s->temp_binding = state->prog->NumTemporaries;
+ state->prog->NumTemporaries++;
+ break;
+
+ case at_address:
+ if (state->prog->NumAddressRegs >= state->limits->MaxAddressRegs) {
+ yyerror(locp, state, "too many address registers declared");
+ free(s);
+ return NULL;
+ }
+
+ /* FINISHME: Add support for multiple address registers.
+ */
+ state->prog->NumAddressRegs++;
+ break;
+
+ default:
+ break;
+ }
+
+ _mesa_symbol_table_add_symbol(state->st, 0, s->name, s);
+ s->next = state->sym;
+ state->sym = s;
+ }
+
+ return s;
+}
+
+
+int add_state_reference(struct gl_program_parameter_list *param_list,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ const GLuint size = 4; /* XXX fix */
+ char *name;
+ GLint index;
+
+ name = _mesa_program_state_string(tokens);
+ index = _mesa_add_parameter(param_list, PROGRAM_STATE_VAR, name,
+ size, GL_NONE, NULL, tokens, 0x0);
+ param_list->StateFlags |= _mesa_program_state_flags(tokens);
+
+ /* free name string here since we duplicated it in add_parameter() */
+ _mesa_free(name);
+
+ return index;
+}
+
+
+int
+initialize_symbol_from_state(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_STATE_VAR;
+
+ /* If we are adding a STATE_MATRIX that has multiple rows, we need to
+ * unroll it and call add_state_reference() for each row
+ */
+ if ((state_tokens[0] == STATE_MODELVIEW_MATRIX ||
+ state_tokens[0] == STATE_PROJECTION_MATRIX ||
+ state_tokens[0] == STATE_MVP_MATRIX ||
+ state_tokens[0] == STATE_TEXTURE_MATRIX ||
+ state_tokens[0] == STATE_PROGRAM_MATRIX)
+ && (state_tokens[2] != state_tokens[3])) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_param(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const gl_state_index tokens[STATE_LENGTH])
+{
+ int idx = -1;
+ gl_state_index state_tokens[STATE_LENGTH];
+
+
+ memcpy(state_tokens, tokens, sizeof(state_tokens));
+
+ assert((state_tokens[0] == STATE_VERTEX_PROGRAM)
+ || (state_tokens[0] == STATE_FRAGMENT_PROGRAM));
+ assert((state_tokens[1] == STATE_ENV)
+ || (state_tokens[1] == STATE_LOCAL));
+
+ param_var->type = at_param;
+ param_var->param_binding_type = (state_tokens[1] == STATE_ENV)
+ ? PROGRAM_ENV_PARAM : PROGRAM_LOCAL_PARAM;
+
+ /* If we are adding a STATE_ENV or STATE_LOCAL that has multiple elements,
+ * we need to unroll it and call add_state_reference() for each row
+ */
+ if (state_tokens[2] != state_tokens[3]) {
+ int row;
+ const int first_row = state_tokens[2];
+ const int last_row = state_tokens[3];
+
+ for (row = first_row; row <= last_row; row++) {
+ state_tokens[2] = state_tokens[3] = row;
+
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+ }
+ else {
+ idx = add_state_reference(prog->Parameters, state_tokens);
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+ }
+
+ return idx;
+}
+
+
+int
+initialize_symbol_from_const(struct gl_program *prog,
+ struct asm_symbol *param_var,
+ const struct asm_vector *vec)
+{
+ const int idx = _mesa_add_parameter(prog->Parameters, PROGRAM_CONSTANT,
+ NULL, vec->count, GL_NONE, vec->data,
+ NULL, 0x0);
+
+ param_var->type = at_param;
+ param_var->param_binding_type = PROGRAM_CONSTANT;
+
+ if (param_var->param_binding_begin == ~0U)
+ param_var->param_binding_begin = idx;
+ param_var->param_binding_length++;
+
+ return idx;
+}
+
+
+char *
+make_error_string(const char *fmt, ...)
+{
+ int length;
+ char *str;
+ va_list args;
+
+ va_start(args, fmt);
+
+ /* Call vsnprintf once to determine how large the final string is. Call it
+ * again to do the actual formatting. from the vsnprintf manual page:
+ *
+ * Upon successful return, these functions return the number of
+ * characters printed (not including the trailing '\0' used to end
+ * output to strings).
+ */
+ length = 1 + vsnprintf(NULL, 0, fmt, args);
+
+ str = _mesa_malloc(length);
+ if (str) {
+ vsnprintf(str, length, fmt, args);
+ }
+
+ va_end(args);
+
+ return str;
+}
+
+
+void
+yyerror(YYLTYPE *locp, struct asm_parser_state *state, const char *s)
+{
+ char *err_str;
+
+
+ err_str = make_error_string("glProgramStringARB(%s)\n", s);
+ if (err_str) {
+ _mesa_error(state->ctx, GL_INVALID_OPERATION, err_str);
+ _mesa_free(err_str);
+ }
+
+ err_str = make_error_string("line %u, char %u: error: %s\n",
+ locp->first_line, locp->first_column, s);
+ _mesa_set_program_error(state->ctx, locp->position, err_str);
+
+ if (err_str) {
+ _mesa_free(err_str);
+ }
+}
+
+
+GLboolean
+_mesa_parse_arb_program(GLcontext *ctx, GLenum target, const GLubyte *str,
+ GLsizei len, struct asm_parser_state *state)
+{
+ struct asm_instruction *inst;
+ unsigned i;
+ GLubyte *strz;
+ GLboolean result = GL_FALSE;
+ void *temp;
+ struct asm_symbol *sym;
+
+ state->ctx = ctx;
+ state->prog->Target = target;
+ state->prog->Parameters = _mesa_new_parameter_list();
+
+ /* Make a copy of the program string and force it to be NUL-terminated.
+ */
+ strz = (GLubyte *) _mesa_malloc(len + 1);
+ if (strz == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glProgramStringARB");
+ return GL_FALSE;
+ }
+ _mesa_memcpy (strz, str, len);
+ strz[len] = '\0';
+
+ state->prog->String = strz;
+
+ state->st = _mesa_symbol_table_ctor();
+
+ state->limits = (target == GL_VERTEX_PROGRAM_ARB)
+ ? & ctx->Const.VertexProgram
+ : & ctx->Const.FragmentProgram;
+
+ state->MaxTextureImageUnits = ctx->Const.MaxTextureImageUnits;
+ state->MaxTextureCoordUnits = ctx->Const.MaxTextureCoordUnits;
+ state->MaxTextureUnits = ctx->Const.MaxTextureUnits;
+ state->MaxClipPlanes = ctx->Const.MaxClipPlanes;
+ state->MaxLights = ctx->Const.MaxLights;
+ state->MaxProgramMatrices = ctx->Const.MaxProgramMatrices;
+
+ state->state_param_enum = (target == GL_VERTEX_PROGRAM_ARB)
+ ? STATE_VERTEX_PROGRAM : STATE_FRAGMENT_PROGRAM;
+
+ _mesa_set_program_error(ctx, -1, NULL);
+
+ _mesa_program_lexer_ctor(& state->scanner, state, (const char *) str, len);
+ yyparse(state);
+ _mesa_program_lexer_dtor(state->scanner);
+
+
+ if (ctx->Program.ErrorPos != -1) {
+ goto error;
+ }
+
+ if (! _mesa_layout_parameters(state)) {
+ struct YYLTYPE loc;
+
+ loc.first_line = 0;
+ loc.first_column = 0;
+ loc.position = len;
+
+ yyerror(& loc, state, "invalid PARAM usage");
+ goto error;
+ }
+
+
+
+ /* Add one instruction to store the "END" instruction.
+ */
+ state->prog->Instructions =
+ _mesa_alloc_instructions(state->prog->NumInstructions + 1);
+ inst = state->inst_head;
+ for (i = 0; i < state->prog->NumInstructions; i++) {
+ struct asm_instruction *const temp = inst->next;
+
+ state->prog->Instructions[i] = inst->Base;
+ inst = temp;
+ }
+
+ /* Finally, tag on an OPCODE_END instruction */
+ {
+ const GLuint numInst = state->prog->NumInstructions;
+ _mesa_init_instructions(state->prog->Instructions + numInst, 1);
+ state->prog->Instructions[numInst].Opcode = OPCODE_END;
+ }
+ state->prog->NumInstructions++;
+
+ state->prog->NumParameters = state->prog->Parameters->NumParameters;
+ state->prog->NumAttributes = _mesa_bitcount(state->prog->InputsRead);
+
+ /*
+ * Initialize native counts to logical counts. The device driver may
+ * change them if program is translated into a hardware program.
+ */
+ state->prog->NumNativeInstructions = state->prog->NumInstructions;
+ state->prog->NumNativeTemporaries = state->prog->NumTemporaries;
+ state->prog->NumNativeParameters = state->prog->NumParameters;
+ state->prog->NumNativeAttributes = state->prog->NumAttributes;
+ state->prog->NumNativeAddressRegs = state->prog->NumAddressRegs;
+
+ result = GL_TRUE;
+
+error:
+ for (inst = state->inst_head; inst != NULL; inst = temp) {
+ temp = inst->next;
+ _mesa_free(inst);
+ }
+
+ state->inst_head = NULL;
+ state->inst_tail = NULL;
+
+ for (sym = state->sym; sym != NULL; sym = temp) {
+ temp = sym->next;
+
+ _mesa_free((void *) sym->name);
+ _mesa_free(sym);
+ }
+ state->sym = NULL;
+
+ _mesa_symbol_table_dtor(state->st);
+ state->st = NULL;
+
+ return result;
+}
diff --git a/src/mesa/shader/program_parse_extra.c b/src/mesa/shader/program_parse_extra.c
new file mode 100644
index 0000000000..8e4be606f1
--- /dev/null
+++ b/src/mesa/shader/program_parse_extra.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <string.h>
+#include "main/mtypes.h"
+#include "prog_instruction.h"
+#include "program_parser.h"
+
+
+/**
+ * Extra assembly-level parser routines
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+
+int
+_mesa_ARBvp_parse_option(struct asm_parser_state *state, const char *option)
+{
+ if (strcmp(option, "ARB_position_invariant") == 0) {
+ state->option.PositionInvariant = 1;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+int
+_mesa_ARBfp_parse_option(struct asm_parser_state *state, const char *option)
+{
+ /* All of the options currently supported start with "ARB_". The code is
+ * currently structured with nested if-statements because eventually options
+ * that start with "NV_" will be supported. This structure will result in
+ * less churn when those options are added.
+ */
+ if (strncmp(option, "ARB_", 4) == 0) {
+ /* Advance the pointer past the "ARB_" prefix.
+ */
+ option += 4;
+
+
+ if (strncmp(option, "fog_", 4) == 0) {
+ option += 4;
+
+ if (state->option.Fog == OPTION_NONE) {
+ if (strcmp(option, "exp") == 0) {
+ state->option.Fog = OPTION_FOG_EXP;
+ return 1;
+ } else if (strcmp(option, "exp2") == 0) {
+ state->option.Fog = OPTION_FOG_EXP2;
+ return 1;
+ } else if (strcmp(option, "linear") == 0) {
+ state->option.Fog = OPTION_FOG_LINEAR;
+ return 1;
+ }
+ }
+
+ return 0;
+ } else if (strncmp(option, "precision_hint_", 15) == 0) {
+ option += 15;
+
+ if (state->option.PrecisionHint == OPTION_NONE) {
+ if (strcmp(option, "nicest") == 0) {
+ state->option.PrecisionHint = OPTION_NICEST;
+ return 1;
+ } else if (strcmp(option, "fastest") == 0) {
+ state->option.PrecisionHint = OPTION_FASTEST;
+ return 1;
+ }
+ }
+
+ return 0;
+ } else if (strcmp(option, "draw_buffers") == 0) {
+ /* Don't need to check extension availability because all Mesa-based
+ * drivers support GL_ARB_draw_buffers.
+ */
+ state->option.DrawBuffers = 1;
+ return 1;
+ } else if (strcmp(option, "fragment_program_shadow") == 0) {
+ if (state->ctx->Extensions.ARB_fragment_program_shadow) {
+ state->option.Shadow = 1;
+ return 1;
+ }
+ }
+ } else if (strncmp(option, "MESA_", 5) == 0) {
+ option += 5;
+
+ if (strcmp(option, "texture_array") == 0) {
+ if (state->ctx->Extensions.MESA_texture_array) {
+ state->option.TexArray = 1;
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
diff --git a/src/mesa/shader/program_parser.h b/src/mesa/shader/program_parser.h
new file mode 100644
index 0000000000..fa47d84565
--- /dev/null
+++ b/src/mesa/shader/program_parser.h
@@ -0,0 +1,266 @@
+/*
+ * Copyright © 2009 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#pragma once
+
+#include "main/config.h"
+
+#ifndef MTYPES_H
+struct __GLcontextRec;
+typedef struct __GLcontextRec GLcontext;
+#endif
+
+enum asm_type {
+ at_none,
+ at_address,
+ at_attrib,
+ at_param,
+ at_temp,
+ at_output,
+};
+
+struct asm_symbol {
+ struct asm_symbol *next; /**< List linkage for freeing. */
+ const char *name;
+ enum asm_type type;
+ unsigned attrib_binding;
+ unsigned output_binding; /**< Output / result register number. */
+
+ /**
+ * One of PROGRAM_STATE_VAR, PROGRAM_LOCAL_PARAM, or PROGRAM_ENV_PARAM.
+ */
+ unsigned param_binding_type;
+
+ /**
+ * Offset into the program_parameter_list where the tokens representing our
+ * bound state (or constants) start.
+ */
+ unsigned param_binding_begin;
+
+ /* This is how many entries in the the program_parameter_list we take up
+ * with our state tokens or constants. Note that this is _not_ the same as
+ * the number of param registers we eventually use.
+ */
+ unsigned param_binding_length;
+
+ /**
+ * Index of the temp register assigned to this variable.
+ */
+ unsigned temp_binding;
+
+ /**
+ * Flag whether or not a PARAM is an array
+ */
+ unsigned param_is_array:1;
+
+
+ /**
+ * Flag whether or not a PARAM array is accessed indirectly
+ */
+ unsigned param_accessed_indirectly:1;
+
+
+ /**
+ * \brief Is first pass of parameter layout done with this variable?
+ *
+ * The parameter layout routine operates in two passes. This flag tracks
+ * whether or not the first pass has handled this variable.
+ *
+ * \sa _mesa_layout_parameters
+ */
+ unsigned pass1_done:1;
+};
+
+
+struct asm_vector {
+ unsigned count;
+ float data[4];
+};
+
+
+struct asm_swizzle_mask {
+ unsigned swizzle:12;
+ unsigned mask:4;
+};
+
+
+struct asm_src_register {
+ struct prog_src_register Base;
+
+ /**
+ * Symbol associated with indirect access to parameter arrays.
+ *
+ * If \c Base::RelAddr is 1, this will point to the symbol for the parameter
+ * that is being dereferenced. Further, \c Base::Index will be the offset
+ * from the address register being used.
+ */
+ struct asm_symbol *Symbol;
+};
+
+
+struct asm_instruction {
+ struct prog_instruction Base;
+ struct asm_instruction *next;
+ struct asm_src_register SrcReg[3];
+};
+
+
+struct asm_parser_state {
+ GLcontext *ctx;
+ struct gl_program *prog;
+
+ /**
+ * Per-program target limits
+ */
+ struct gl_program_constants *limits;
+
+ struct _mesa_symbol_table *st;
+
+ /**
+ * Linked list of symbols
+ *
+ * This list is \b only used when cleaning up compiler state and freeing
+ * memory.
+ */
+ struct asm_symbol *sym;
+
+ /**
+ * State for the lexer.
+ */
+ void *scanner;
+
+ /**
+ * Linked list of instructions generated during parsing.
+ */
+ /*@{*/
+ struct asm_instruction *inst_head;
+ struct asm_instruction *inst_tail;
+ /*@}*/
+
+
+ /**
+ * Selected limits copied from gl_constants
+ *
+ * These are limits from the GL context, but various bits in the program
+ * must be validated against these values.
+ */
+ /*@{*/
+ unsigned MaxTextureCoordUnits;
+ unsigned MaxTextureImageUnits;
+ unsigned MaxTextureUnits;
+ unsigned MaxClipPlanes;
+ unsigned MaxLights;
+ unsigned MaxProgramMatrices;
+ /*@}*/
+
+ /**
+ * Value to use in state vector accessors for environment and local
+ * parameters
+ */
+ unsigned state_param_enum;
+
+
+ /**
+ * Input attributes bound to specific names
+ *
+ * This is only needed so that errors can be properly produced when
+ * multiple ATTRIB statements bind illegal combinations of vertex
+ * attributes.
+ */
+ unsigned InputsBound;
+
+ enum {
+ invalid_mode = 0,
+ ARB_vertex,
+ ARB_fragment
+ } mode;
+
+ struct {
+ unsigned PositionInvariant:1;
+ unsigned Fog:2;
+ unsigned PrecisionHint:2;
+ unsigned DrawBuffers:1;
+ unsigned Shadow:1;
+ unsigned TexRect:1;
+ unsigned TexArray:1;
+ } option;
+
+ struct {
+ unsigned UsesKill:1;
+ } fragment;
+};
+
+#define OPTION_NONE 0
+#define OPTION_FOG_EXP 1
+#define OPTION_FOG_EXP2 2
+#define OPTION_FOG_LINEAR 3
+#define OPTION_NICEST 1
+#define OPTION_FASTEST 2
+
+typedef struct YYLTYPE {
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+ int position;
+} YYLTYPE;
+
+#define YYLTYPE_IS_DECLARED 1
+#define YYLTYPE_IS_TRIVIAL 1
+
+
+extern GLboolean _mesa_parse_arb_program(GLcontext *ctx, GLenum target,
+ const GLubyte *str, GLsizei len, struct asm_parser_state *state);
+
+
+
+/* From program_lexer.l. */
+extern void _mesa_program_lexer_dtor(void *scanner);
+
+extern void _mesa_program_lexer_ctor(void **scanner,
+ struct asm_parser_state *state, const char *string, size_t len);
+
+
+/**
+ *\name From program_parse_extra.c
+ */
+/*@{*/
+
+/**
+ * Parses and processes an option string to an ARB vertex program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBvp_parse_option(struct asm_parser_state *state,
+ const char *option);
+
+/**
+ * Parses and processes an option string to an ARB fragment program
+ *
+ * \return
+ * Non-zero on success, zero on failure.
+ */
+extern int _mesa_ARBfp_parse_option(struct asm_parser_state *state,
+ const char *option);
+
+/*@}*/
diff --git a/src/mesa/shader/programopt.c b/src/mesa/shader/programopt.c
index ac5fe0f691..f70c75cec8 100644
--- a/src/mesa/shader/programopt.c
+++ b/src/mesa/shader/programopt.c
@@ -396,7 +396,6 @@ _mesa_append_fog_code(GLcontext *ctx, struct gl_fragment_program *fprog)
fprog->Base.Instructions = newInst;
fprog->Base.NumInstructions = inst - newInst;
fprog->Base.InputsRead |= FRAG_BIT_FOGC;
- fprog->UsesFogFragCoord = GL_TRUE;
/* XXX do this? fprog->FogOption = GL_NONE; */
}
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 648fbc186b..178b7d0dba 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -1,6 +1,6 @@
/*
* Mesa 3-D graphics library
- * Version: 7.5
+ * Version: 7.6
*
* Copyright (C) 2004-2008 Brian Paul All Rights Reserved.
* Copyright (C) 2009 VMware, Inc. All Rights Reserved.
@@ -885,7 +885,7 @@ _mesa_get_active_attrib(GLcontext *ctx, GLuint program, GLuint index,
static struct gl_program_parameter *
get_uniform_parameter(const struct gl_shader_program *shProg, GLuint index)
{
- const struct gl_program *prog;
+ const struct gl_program *prog = NULL;
GLint progPos;
progPos = shProg->Uniforms->Uniforms[index].VertPos;
@@ -915,7 +915,7 @@ _mesa_get_active_uniform(GLcontext *ctx, GLuint program, GLuint index,
GLenum *type, GLchar *nameOut)
{
const struct gl_shader_program *shProg;
- const struct gl_program *prog;
+ const struct gl_program *prog = NULL;
const struct gl_program_parameter *param;
GLint progPos;
@@ -1431,6 +1431,9 @@ _mesa_shader_source(GLcontext *ctx, GLuint shader, const GLchar *source)
}
sh->Source = source;
sh->CompileStatus = GL_FALSE;
+#ifdef DEBUG
+ sh->SourceChecksum = _mesa_str_checksum(sh->Source);
+#endif
}
@@ -1471,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);
+ }
+ }
}
@@ -1506,9 +1524,10 @@ _mesa_use_program(GLcontext *ctx, GLuint program)
GLuint i;
_mesa_printf("Use Shader %u\n", shProg->Name);
for (i = 0; i < shProg->NumShaders; i++) {
- _mesa_printf(" shader %u, type 0x%x\n",
+ _mesa_printf(" shader %u, type 0x%x, checksum %u\n",
shProg->Shaders[i]->Name,
- shProg->Shaders[i]->Type);
+ shProg->Shaders[i]->Type,
+ shProg->Shaders[i]->SourceChecksum);
}
if (shProg->VertexProgram)
printf(" vert prog %u\n", shProg->VertexProgram->Base.Id);
@@ -1549,10 +1568,11 @@ _mesa_update_shader_textures_used(struct gl_program *prog)
for (s = 0; s < MAX_SAMPLERS; s++) {
if (prog->SamplersUsed & (1 << s)) {
- GLuint u = prog->SamplerUnits[s];
- GLuint t = prog->SamplerTargets[s];
- assert(u < MAX_TEXTURE_IMAGE_UNITS);
- prog->TexturesUsed[u] |= (1 << t);
+ GLuint unit = prog->SamplerUnits[s];
+ GLuint tgt = prog->SamplerTargets[s];
+ assert(unit < MAX_TEXTURE_IMAGE_UNITS);
+ assert(tgt < NUM_TEXTURE_TARGETS);
+ prog->TexturesUsed[unit] |= (1 << tgt);
}
}
}
@@ -1607,10 +1627,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
GLenum type, GLsizei count, GLint elems,
const void *values)
{
- struct gl_program_parameter *param =
+ const struct gl_program_parameter *param =
&program->Parameters->Parameters[index];
- const GLboolean isUniformBool = is_boolean_type(param->DataType);
- const GLboolean areIntValues = is_integer_type(type);
assert(offset >= 0);
assert(elems >= 1);
@@ -1628,23 +1646,17 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
if (param->Type == PROGRAM_SAMPLER) {
/* This controls which texture unit which is used by a sampler */
- GLuint texUnit, sampler;
+ GLboolean changed = GL_FALSE;
GLint i;
- /* data type for setting samplers must be int */
- if (type != GL_INT) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glUniform(only glUniform1i can be used "
- "to set sampler uniforms)");
- return;
- }
+ /* this should have been caught by the compatible_types() check */
+ ASSERT(type == GL_INT);
- /* XXX arrays of samplers haven't been tested much, but it's not a
- * common thing...
- */
+ /* loop over number of samplers to change */
for (i = 0; i < count; i++) {
- sampler = (GLuint) program->Parameters->ParameterValues[index + i][0];
- texUnit = ((GLuint *) values)[i];
+ GLuint sampler =
+ (GLuint) program->Parameters->ParameterValues[index + offset + i][0];
+ GLuint texUnit = ((GLuint *) values)[i];
/* check that the sampler (tex unit index) is legal */
if (texUnit >= ctx->Const.MaxTextureImageUnits) {
@@ -1655,19 +1667,35 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
/* This maps a sampler to a texture unit: */
if (sampler < MAX_SAMPLERS) {
- program->SamplerUnits[sampler] = texUnit;
+#if 0
+ _mesa_printf("Set program %p sampler %d '%s' to unit %u\n",
+ program, sampler, param->Name, texUnit);
+#endif
+ if (program->SamplerUnits[sampler] != texUnit) {
+ program->SamplerUnits[sampler] = texUnit;
+ changed = GL_TRUE;
+ }
}
}
- _mesa_update_shader_textures_used(program);
-
- FLUSH_VERTICES(ctx, _NEW_TEXTURE);
+ if (changed) {
+ /* When a sampler's value changes it usually requires rewriting
+ * a GPU program's TEX instructions since there may not be a
+ * sampler->texture lookup table. We signal this with the
+ * ProgramStringNotify() callback.
+ */
+ FLUSH_VERTICES(ctx, _NEW_TEXTURE | _NEW_PROGRAM);
+ _mesa_update_shader_textures_used(program);
+ ctx->Driver.ProgramStringNotify(ctx, program->Target, program);
+ }
}
else {
/* ordinary uniform variable */
- GLsizei k, i;
+ const GLboolean isUniformBool = is_boolean_type(param->DataType);
+ const GLboolean areIntValues = is_integer_type(type);
const GLint slots = (param->Size + 3) / 4;
const GLint typeSize = sizeof_glsl_type(param->DataType);
+ GLsizei k, i;
if (param->Size > typeSize) {
/* an array */
@@ -1962,19 +1990,74 @@ _mesa_uniform_matrix(GLcontext *ctx, GLint cols, GLint rows,
}
-static void
-_mesa_validate_program(GLcontext *ctx, GLuint program)
+/**
+ * Validate a program's samplers.
+ * Specifically, check that there aren't two samplers of different types
+ * pointing to the same texture unit.
+ * \return GL_TRUE if valid, GL_FALSE if invalid
+ */
+static GLboolean
+validate_samplers(GLcontext *ctx, const struct gl_program *prog, char *errMsg)
{
- struct gl_shader_program *shProg;
+ static const char *targetName[] = {
+ "TEXTURE_2D_ARRAY",
+ "TEXTURE_1D_ARRAY",
+ "TEXTURE_CUBE",
+ "TEXTURE_3D",
+ "TEXTURE_RECT",
+ "TEXTURE_2D",
+ "TEXTURE_1D",
+ };
+ GLint targetUsed[MAX_TEXTURE_IMAGE_UNITS];
+ GLbitfield samplersUsed = prog->SamplersUsed;
+ GLuint i;
- shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
- if (!shProg) {
- return;
+ assert(Elements(targetName) == NUM_TEXTURE_TARGETS);
+
+ if (samplersUsed == 0x0)
+ return GL_TRUE;
+
+ for (i = 0; i < Elements(targetUsed); i++)
+ targetUsed[i] = -1;
+
+ /* walk over bits which are set in 'samplers' */
+ while (samplersUsed) {
+ GLuint unit;
+ gl_texture_index target;
+ GLint sampler = _mesa_ffs(samplersUsed) - 1;
+ assert(sampler >= 0);
+ assert(sampler < MAX_TEXTURE_IMAGE_UNITS);
+ unit = prog->SamplerUnits[sampler];
+ target = prog->SamplerTargets[sampler];
+ if (targetUsed[unit] != -1 && targetUsed[unit] != target) {
+ _mesa_snprintf(errMsg, 100,
+ "Texture unit %d is accessed both as %s and %s",
+ unit, targetName[targetUsed[unit]], targetName[target]);
+ return GL_FALSE;
+ }
+ targetUsed[unit] = target;
+ samplersUsed ^= (1 << sampler);
}
+ return GL_TRUE;
+}
+
+
+/**
+ * Do validation of the given shader program.
+ * \param errMsg returns error message if validation fails.
+ * \return GL_TRUE if valid, GL_FALSE if invalid (and set errMsg)
+ */
+GLboolean
+_mesa_validate_shader_program(GLcontext *ctx,
+ const struct gl_shader_program *shProg,
+ char *errMsg)
+{
+ const struct gl_vertex_program *vp = shProg->VertexProgram;
+ const struct gl_fragment_program *fp = shProg->FragmentProgram;
+
if (!shProg->LinkStatus) {
- shProg->Validated = GL_FALSE;
- return;
+ return GL_FALSE;
}
/* From the GL spec, a program is invalid if any of these are true:
@@ -1992,7 +2075,44 @@ _mesa_validate_program(GLcontext *ctx, GLuint program)
image units allowed.
*/
- shProg->Validated = GL_TRUE;
+
+ /*
+ * Check: any two active samplers in the current program object are of
+ * different types, but refer to the same texture image unit,
+ */
+ if (vp && !validate_samplers(ctx, &vp->Base, errMsg)) {
+ return GL_FALSE;
+ }
+ if (fp && !validate_samplers(ctx, &fp->Base, errMsg)) {
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Called via glValidateProgram()
+ */
+static void
+_mesa_validate_program(GLcontext *ctx, GLuint program)
+{
+ struct gl_shader_program *shProg;
+ char errMsg[100];
+
+ shProg = _mesa_lookup_shader_program_err(ctx, program, "glValidateProgram");
+ if (!shProg) {
+ return;
+ }
+
+ shProg->Validated = _mesa_validate_shader_program(ctx, shProg, errMsg);
+ if (!shProg->Validated) {
+ /* update info log */
+ if (shProg->InfoLog) {
+ _mesa_free(shProg->InfoLog);
+ }
+ shProg->InfoLog = _mesa_strdup(errMsg);
+ }
}
diff --git a/src/mesa/shader/shader_api.h b/src/mesa/shader/shader_api.h
index ec1996ee98..d08d47373e 100644
--- a/src/mesa/shader/shader_api.h
+++ b/src/mesa/shader/shader_api.h
@@ -1,8 +1,9 @@
/*
* Mesa 3-D graphics library
- * Version: 6.5
+ * Version: 7.6
*
* Copyright (C) 2004-2006 Brian Paul All Rights Reserved.
+ * Copyright (C) 2009 VMware, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
@@ -87,6 +88,11 @@ extern void
_mesa_use_program(GLcontext *ctx, GLuint program);
+extern GLboolean
+_mesa_validate_shader_program(GLcontext *ctx,
+ const struct gl_shader_program *shProg,
+ char *errMsg);
+
extern void
_mesa_init_glsl_driver_functions(struct dd_function_table *driver);
diff --git a/src/mesa/shader/slang/slang_builtin.c b/src/mesa/shader/slang/slang_builtin.c
index 289d94644f..bef0f85653 100644
--- a/src/mesa/shader/slang/slang_builtin.c
+++ b/src/mesa/shader/slang/slang_builtin.c
@@ -436,7 +436,7 @@ emit_statevars(const char *name, int array_len,
struct gl_program_parameter_list *paramList)
{
if (type->type == SLANG_SPEC_ARRAY) {
- GLint i, pos;
+ GLint i, pos = -1;
assert(array_len > 0);
if (strcmp(name, "gl_ClipPlane") == 0) {
tokens[0] = STATE_CLIPPLANE;
@@ -710,3 +710,186 @@ _slang_alloc_statevar(slang_ir_node *n,
*direct = GL_FALSE;
return alloc_state_var_array(n->Var, paramList);
}
+
+
+
+
+#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
+
+
+/** Predefined shader inputs */
+struct input_info
+{
+ const char *Name;
+ GLuint Attrib;
+ GLenum Type;
+ GLuint Swizzle;
+};
+
+/** Predefined vertex shader inputs/attributes */
+static const struct input_info vertInputs[] = {
+ { "gl_Vertex", VERT_ATTRIB_POS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_Normal", VERT_ATTRIB_NORMAL, GL_FLOAT_VEC3, SWIZZLE_NOOP },
+ { "gl_Color", VERT_ATTRIB_COLOR0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_FogCoord", VERT_ATTRIB_FOG, GL_FLOAT, SWIZZLE_XXXX },
+ { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { NULL, 0, SWIZZLE_NOOP }
+};
+
+/** Predefined fragment shader inputs */
+static const struct input_info fragInputs[] = {
+ { "gl_FragCoord", FRAG_ATTRIB_WPOS, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_Color", FRAG_ATTRIB_COL0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_SecondaryColor", FRAG_ATTRIB_COL1, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ { "gl_TexCoord", FRAG_ATTRIB_TEX0, GL_FLOAT_VEC4, SWIZZLE_NOOP },
+ /* note: we're packing several quantities into the fogcoord vector */
+ { "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 }
+};
+
+
+/**
+ * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
+ * a vertex or fragment program input variable. Return -1 if the input
+ * name is invalid.
+ * XXX return size too
+ */
+GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
+{
+ const struct input_info *inputs;
+ GLuint i;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ inputs = vertInputs;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ inputs = fragInputs;
+ break;
+ /* XXX geom program */
+ default:
+ _mesa_problem(NULL, "bad target in _slang_input_index");
+ return -1;
+ }
+
+ ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
+
+ for (i = 0; inputs[i].Name; i++) {
+ if (strcmp(inputs[i].Name, name) == 0) {
+ /* found */
+ *swizzleOut = inputs[i].Swizzle;
+ return inputs[i].Attrib;
+ }
+ }
+ return -1;
+}
+
+
+/**
+ * Return name of the given vertex attribute (VERT_ATTRIB_x).
+ */
+const char *
+_slang_vert_attrib_name(GLuint attrib)
+{
+ GLuint i;
+ assert(attrib < VERT_ATTRIB_GENERIC0);
+ for (i = 0; vertInputs[i].Name; i++) {
+ if (vertInputs[i].Attrib == attrib)
+ return vertInputs[i].Name;
+ }
+ return NULL;
+}
+
+
+/**
+ * Return type (GL_FLOAT, GL_FLOAT_VEC2, etc) of the given vertex
+ * attribute (VERT_ATTRIB_x).
+ */
+GLenum
+_slang_vert_attrib_type(GLuint attrib)
+{
+ GLuint i;
+ assert(attrib < VERT_ATTRIB_GENERIC0);
+ for (i = 0; vertInputs[i].Name; i++) {
+ if (vertInputs[i].Attrib == attrib)
+ return vertInputs[i].Type;
+ }
+ return GL_NONE;
+}
+
+
+
+
+
+/** Predefined shader output info */
+struct output_info
+{
+ const char *Name;
+ GLuint Attrib;
+};
+
+/** Predefined vertex shader outputs */
+static const struct output_info vertOutputs[] = {
+ { "gl_Position", VERT_RESULT_HPOS },
+ { "gl_FrontColor", VERT_RESULT_COL0 },
+ { "gl_BackColor", VERT_RESULT_BFC0 },
+ { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
+ { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
+ { "gl_TexCoord", VERT_RESULT_TEX0 },
+ { "gl_FogFragCoord", VERT_RESULT_FOGC },
+ { "gl_PointSize", VERT_RESULT_PSIZ },
+ { NULL, 0 }
+};
+
+/** Predefined fragment shader outputs */
+static const struct output_info fragOutputs[] = {
+ { "gl_FragColor", FRAG_RESULT_COLOR },
+ { "gl_FragDepth", FRAG_RESULT_DEPTH },
+ { "gl_FragData", FRAG_RESULT_DATA0 },
+ { NULL, 0 }
+};
+
+
+/**
+ * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
+ * a vertex or fragment program output variable. Return -1 for an invalid
+ * output name.
+ */
+GLint
+_slang_output_index(const char *name, GLenum target)
+{
+ const struct output_info *outputs;
+ GLuint i;
+
+ switch (target) {
+ case GL_VERTEX_PROGRAM_ARB:
+ outputs = vertOutputs;
+ break;
+ case GL_FRAGMENT_PROGRAM_ARB:
+ outputs = fragOutputs;
+ break;
+ /* XXX geom program */
+ default:
+ _mesa_problem(NULL, "bad target in _slang_output_index");
+ return -1;
+ }
+
+ for (i = 0; outputs[i].Name; i++) {
+ if (strcmp(outputs[i].Name, name) == 0) {
+ /* found */
+ return outputs[i].Attrib;
+ }
+ }
+ return -1;
+}
diff --git a/src/mesa/shader/slang/slang_builtin.h b/src/mesa/shader/slang/slang_builtin.h
index 7f6fe80fcc..f814d11ac7 100644
--- a/src/mesa/shader/slang/slang_builtin.h
+++ b/src/mesa/shader/slang/slang_builtin.h
@@ -37,4 +37,18 @@ _slang_alloc_statevar(slang_ir_node *n,
GLboolean *direct);
+extern GLint
+_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut);
+
+extern GLint
+_slang_output_index(const char *name, GLenum target);
+
+
+extern const char *
+_slang_vert_attrib_name(GLuint attrib);
+
+extern GLenum
+_slang_vert_attrib_type(GLuint attrib);
+
+
#endif /* SLANG_BUILTIN_H */
diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c
index 2b7e781f98..349f432dec 100644
--- a/src/mesa/shader/slang/slang_codegen.c
+++ b/src/mesa/shader/slang/slang_codegen.c
@@ -46,6 +46,7 @@
#include "shader/prog_print.h"
#include "shader/prog_statevars.h"
#include "slang_typeinfo.h"
+#include "slang_builtin.h"
#include "slang_codegen.h"
#include "slang_compile.h"
#include "slang_label.h"
@@ -342,109 +343,6 @@ slang_operation_identifier(slang_operation *oper,
}
-#define SWIZZLE_ZWWW MAKE_SWIZZLE4(SWIZZLE_Z, SWIZZLE_W, SWIZZLE_W, SWIZZLE_W)
-
-/**
- * Return the VERT_ATTRIB_* or FRAG_ATTRIB_* value that corresponds to
- * a vertex or fragment program input variable. Return -1 if the input
- * name is invalid.
- * XXX return size too
- */
-static GLint
-_slang_input_index(const char *name, GLenum target, GLuint *swizzleOut)
-{
- struct input_info {
- const char *Name;
- GLuint Attrib;
- GLuint Swizzle;
- };
- static const struct input_info vertInputs[] = {
- { "gl_Vertex", VERT_ATTRIB_POS, SWIZZLE_NOOP },
- { "gl_Normal", VERT_ATTRIB_NORMAL, SWIZZLE_NOOP },
- { "gl_Color", VERT_ATTRIB_COLOR0, SWIZZLE_NOOP },
- { "gl_SecondaryColor", VERT_ATTRIB_COLOR1, SWIZZLE_NOOP },
- { "gl_FogCoord", VERT_ATTRIB_FOG, SWIZZLE_XXXX },
- { "gl_MultiTexCoord0", VERT_ATTRIB_TEX0, SWIZZLE_NOOP },
- { "gl_MultiTexCoord1", VERT_ATTRIB_TEX1, SWIZZLE_NOOP },
- { "gl_MultiTexCoord2", VERT_ATTRIB_TEX2, SWIZZLE_NOOP },
- { "gl_MultiTexCoord3", VERT_ATTRIB_TEX3, SWIZZLE_NOOP },
- { "gl_MultiTexCoord4", VERT_ATTRIB_TEX4, SWIZZLE_NOOP },
- { "gl_MultiTexCoord5", VERT_ATTRIB_TEX5, SWIZZLE_NOOP },
- { "gl_MultiTexCoord6", VERT_ATTRIB_TEX6, SWIZZLE_NOOP },
- { "gl_MultiTexCoord7", VERT_ATTRIB_TEX7, SWIZZLE_NOOP },
- { NULL, 0, SWIZZLE_NOOP }
- };
- static const struct input_info fragInputs[] = {
- { "gl_FragCoord", FRAG_ATTRIB_WPOS, SWIZZLE_NOOP },
- { "gl_Color", FRAG_ATTRIB_COL0, SWIZZLE_NOOP },
- { "gl_SecondaryColor", FRAG_ATTRIB_COL1, SWIZZLE_NOOP },
- { "gl_TexCoord", FRAG_ATTRIB_TEX0, SWIZZLE_NOOP },
- /* note: we're packing several quantities into the fogcoord vector */
- { "gl_FogFragCoord", FRAG_ATTRIB_FOGC, SWIZZLE_XXXX },
- { "gl_FrontFacing", FRAG_ATTRIB_FOGC, SWIZZLE_YYYY }, /*XXX*/
- { "gl_PointCoord", FRAG_ATTRIB_FOGC, SWIZZLE_ZWWW },
- { NULL, 0, SWIZZLE_NOOP }
- };
- GLuint i;
- const struct input_info *inputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertInputs : fragInputs;
-
- ASSERT(MAX_TEXTURE_COORD_UNITS == 8); /* if this fails, fix vertInputs above */
-
- for (i = 0; inputs[i].Name; i++) {
- if (strcmp(inputs[i].Name, name) == 0) {
- /* found */
- *swizzleOut = inputs[i].Swizzle;
- return inputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
-/**
- * Return the VERT_RESULT_* or FRAG_RESULT_* value that corresponds to
- * a vertex or fragment program output variable. Return -1 for an invalid
- * output name.
- */
-static GLint
-_slang_output_index(const char *name, GLenum target)
-{
- struct output_info {
- const char *Name;
- GLuint Attrib;
- };
- static const struct output_info vertOutputs[] = {
- { "gl_Position", VERT_RESULT_HPOS },
- { "gl_FrontColor", VERT_RESULT_COL0 },
- { "gl_BackColor", VERT_RESULT_BFC0 },
- { "gl_FrontSecondaryColor", VERT_RESULT_COL1 },
- { "gl_BackSecondaryColor", VERT_RESULT_BFC1 },
- { "gl_TexCoord", VERT_RESULT_TEX0 },
- { "gl_FogFragCoord", VERT_RESULT_FOGC },
- { "gl_PointSize", VERT_RESULT_PSIZ },
- { NULL, 0 }
- };
- static const struct output_info fragOutputs[] = {
- { "gl_FragColor", FRAG_RESULT_COLOR },
- { "gl_FragDepth", FRAG_RESULT_DEPTH },
- { "gl_FragData", FRAG_RESULT_DATA0 },
- { NULL, 0 }
- };
- GLuint i;
- const struct output_info *outputs
- = (target == GL_VERTEX_PROGRAM_ARB) ? vertOutputs : fragOutputs;
-
- for (i = 0; outputs[i].Name; i++) {
- if (strcmp(outputs[i].Name, name) == 0) {
- /* found */
- return outputs[i].Attrib;
- }
- }
- return -1;
-}
-
-
/**
* Called when we begin code/IR generation for a new while/do/for loop.
*/
diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c
index f6032d1e9a..8f2b40d5df 100644
--- a/src/mesa/shader/slang/slang_link.c
+++ b/src/mesa/shader/slang/slang_link.c
@@ -40,6 +40,7 @@
#include "shader/prog_statevars.h"
#include "shader/prog_uniform.h"
#include "shader/shader_api.h"
+#include "slang_builtin.h"
#include "slang_link.h"
@@ -287,6 +288,7 @@ link_uniform_vars(GLcontext *ctx,
for (i = 0; i < prog->NumInstructions; i++) {
struct prog_instruction *inst = prog->Instructions + i;
if (_mesa_is_tex_instruction(inst->Opcode)) {
+ /* here, inst->TexSrcUnit is really the sampler unit */
const GLint oldSampNum = inst->TexSrcUnit;
#if 0
@@ -294,7 +296,6 @@ link_uniform_vars(GLcontext *ctx,
inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
#endif
- /* here, texUnit is really samplerUnit */
if (oldSampNum < Elements(samplerMap)) {
const GLuint newSampNum = samplerMap[oldSampNum];
inst->TexSrcUnit = newSampNum;
@@ -327,6 +328,7 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
GLint attribMap[MAX_VERTEX_GENERIC_ATTRIBS];
GLuint i, j;
GLbitfield usedAttributes; /* generics only, not legacy attributes */
+ GLbitfield inputsRead = 0x0;
assert(origProg != linkedProg);
assert(origProg->Target == GL_VERTEX_PROGRAM_ARB);
@@ -370,6 +372,10 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
for (i = 0; i < linkedProg->NumInstructions; i++) {
struct prog_instruction *inst = linkedProg->Instructions + i;
for (j = 0; j < 3; j++) {
+ if (inst->SrcReg[j].File == PROGRAM_INPUT) {
+ inputsRead |= (1 << inst->SrcReg[j].Index);
+ }
+
if (inst->SrcReg[j].File == PROGRAM_INPUT &&
inst->SrcReg[j].Index >= VERT_ATTRIB_GENERIC0) {
/*
@@ -431,6 +437,20 @@ _slang_resolve_attributes(struct gl_shader_program *shProg,
}
}
+ /* Handle pre-defined attributes here (gl_Vertex, gl_Normal, etc).
+ * When the user queries the active attributes we need to include both
+ * the user-defined attributes and the built-in ones.
+ */
+ for (i = VERT_ATTRIB_POS; i < VERT_ATTRIB_GENERIC0; i++) {
+ if (inputsRead & (1 << i)) {
+ _mesa_add_attribute(linkedProg->Attributes,
+ _slang_vert_attrib_name(i),
+ 4, /* size in floats */
+ _slang_vert_attrib_type(i),
+ -1 /* attrib/input */);
+ }
+ }
+
return GL_TRUE;
}
@@ -484,20 +504,6 @@ _slang_update_inputs_outputs(struct gl_program *prog)
for (j = 0; j < numSrc; j++) {
if (inst->SrcReg[j].File == PROGRAM_INPUT) {
prog->InputsRead |= 1 << inst->SrcReg[j].Index;
- if (prog->Target == GL_FRAGMENT_PROGRAM_ARB &&
- inst->SrcReg[j].Index == FRAG_ATTRIB_FOGC) {
- /* The fragment shader FOGC input is used for fog,
- * front-facing and sprite/point coord.
- */
- struct gl_fragment_program *fp = fragment_program(prog);
- const GLint swz = GET_SWZ(inst->SrcReg[j].Swizzle, 0);
- if (swz == SWIZZLE_X)
- fp->UsesFogFragCoord = GL_TRUE;
- else if (swz == SWIZZLE_Y)
- fp->UsesFrontFacing = GL_TRUE;
- else if (swz == SWIZZLE_Z || swz == SWIZZLE_W)
- fp->UsesPointCoord = GL_TRUE;
- }
}
else if (inst->SrcReg[j].File == PROGRAM_ADDRESS) {
maxAddrReg = MAX2(maxAddrReg, (GLuint) (inst->SrcReg[j].Index + 1));
@@ -540,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;
+ }
+ }
+}
+
/**
@@ -587,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/shader/symbol_table.c b/src/mesa/shader/symbol_table.c
new file mode 100644
index 0000000000..7a9aa7b8f6
--- /dev/null
+++ b/src/mesa/shader/symbol_table.c
@@ -0,0 +1,350 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+
+#include "symbol_table.h"
+#include "hash_table.h"
+
+struct symbol {
+ /**
+ * Link to the next symbol in the table with the same name
+ *
+ * The linked list of symbols with the same name is ordered by scope
+ * from inner-most to outer-most.
+ */
+ struct symbol *next_with_same_name;
+
+
+ /**
+ * Link to the next symbol in the table with the same scope
+ *
+ * The linked list of symbols with the same scope is unordered. Symbols
+ * in this list my have unique names.
+ */
+ struct symbol *next_with_same_scope;
+
+
+ /**
+ * Header information for the list of symbols with the same name.
+ */
+ struct symbol_header *hdr;
+
+
+ /**
+ * Name space of the symbol
+ *
+ * Name space are arbitrary user assigned integers. No two symbols can
+ * exist in the same name space at the same scope level.
+ */
+ int name_space;
+
+
+ /**
+ * Arbitrary user supplied data.
+ */
+ void *data;
+};
+
+
+/**
+ */
+struct symbol_header {
+ /** Symbol name. */
+ const char *name;
+
+ /** Linked list of symbols with the same name. */
+ struct symbol *symbols;
+};
+
+
+/**
+ * Element of the scope stack.
+ */
+struct scope_level {
+ /** Link to next (inner) scope level. */
+ struct scope_level *next;
+
+ /** Linked list of symbols with the same scope. */
+ struct symbol *symbols;
+};
+
+
+/**
+ *
+ */
+struct _mesa_symbol_table {
+ /** Hash table containing all symbols in the symbol table. */
+ struct hash_table *ht;
+
+ /** Top of scope stack. */
+ struct scope_level *current_scope;
+};
+
+
+struct _mesa_symbol_table_iterator {
+ /**
+ * Name space of symbols returned by this iterator.
+ */
+ int name_space;
+
+
+ /**
+ * Currently iterated symbol
+ *
+ * The next call to \c _mesa_symbol_table_iterator_get will return this
+ * value. It will also update this value to the value that should be
+ * returned by the next call.
+ */
+ struct symbol *curr;
+};
+
+
+static void
+check_symbol_table(struct _mesa_symbol_table *table)
+{
+#if 1
+ struct scope_level *scope;
+
+ for (scope = table->current_scope; scope != NULL; scope = scope->next) {
+ struct symbol *sym;
+
+ for (sym = scope->symbols
+ ; sym != NULL
+ ; sym = sym->next_with_same_name) {
+ const struct symbol_header *const hdr = sym->hdr;
+ struct symbol *sym2;
+
+ for (sym2 = hdr->symbols
+ ; sym2 != NULL
+ ; sym2 = sym2->next_with_same_name) {
+ assert(sym2->hdr == hdr);
+ }
+ }
+ }
+#endif
+}
+
+void
+_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = table->current_scope;
+ struct symbol *sym = scope->symbols;
+
+ table->current_scope = scope->next;
+
+ free(scope);
+
+ while (sym != NULL) {
+ struct symbol *const next = sym->next_with_same_scope;
+ struct symbol_header *const hdr = sym->hdr;
+
+ assert(hdr->symbols == sym);
+
+ hdr->symbols = sym->next_with_same_name;
+
+ free(sym);
+
+ sym = next;
+ }
+
+ check_symbol_table(table);
+}
+
+
+void
+_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
+{
+ struct scope_level *const scope = calloc(1, sizeof(*scope));
+
+ scope->next = table->current_scope;
+ table->current_scope = scope;
+}
+
+
+static struct symbol_header *
+find_symbol(struct _mesa_symbol_table *table, const char *name)
+{
+ return (struct symbol_header *) hash_table_find(table->ht, name);
+}
+
+
+struct _mesa_symbol_table_iterator *
+_mesa_symbol_table_iterator_ctor(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct _mesa_symbol_table_iterator *iter = calloc(1, sizeof(*iter));
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ iter->name_space = name_space;
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ iter->curr = sym;
+ break;
+ }
+ }
+ }
+
+ return iter;
+}
+
+
+void
+_mesa_symbol_table_iterator_dtor(struct _mesa_symbol_table_iterator *iter)
+{
+ free(iter);
+}
+
+
+void *
+_mesa_symbol_table_iterator_get(struct _mesa_symbol_table_iterator *iter)
+{
+ return (iter->curr == NULL) ? NULL : iter->curr->data;
+}
+
+
+int
+_mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter)
+{
+ struct symbol_header *hdr;
+
+ if (iter->curr == NULL) {
+ return 0;
+ }
+
+ hdr = iter->curr->hdr;
+ iter->curr = iter->curr->next_with_same_name;
+
+ while (iter->curr != NULL) {
+ assert(iter->curr->hdr == hdr);
+
+ if ((iter->name_space == -1)
+ || (iter->curr->name_space == iter->name_space)) {
+ return 1;
+ }
+
+ iter->curr = iter->curr->next_with_same_name;
+ }
+
+ return 0;
+}
+
+
+void *
+_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name)
+{
+ struct symbol_header *const hdr = find_symbol(table, name);
+
+ if (hdr != NULL) {
+ struct symbol *sym;
+
+
+ for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) {
+ assert(sym->hdr == hdr);
+
+ if ((name_space == -1) || (sym->name_space == name_space)) {
+ return sym->data;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+
+int
+_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
+ int name_space, const char *name,
+ void *declaration)
+{
+ struct symbol_header *hdr;
+ struct symbol *sym;
+
+ check_symbol_table(table);
+
+ hdr = find_symbol(table, name);
+
+ check_symbol_table(table);
+
+ if (hdr == NULL) {
+ hdr = calloc(1, sizeof(*hdr));
+ hdr->name = name;
+
+ hash_table_insert(table->ht, hdr, name);
+ }
+
+ check_symbol_table(table);
+
+ sym = calloc(1, sizeof(*sym));
+ sym->next_with_same_name = hdr->symbols;
+ sym->next_with_same_scope = table->current_scope->symbols;
+ sym->hdr = hdr;
+ sym->name_space = name_space;
+ sym->data = declaration;
+
+ assert(sym->hdr == hdr);
+
+ hdr->symbols = sym;
+ table->current_scope->symbols = sym;
+
+ check_symbol_table(table);
+ return 0;
+}
+
+
+struct _mesa_symbol_table *
+_mesa_symbol_table_ctor(void)
+{
+ struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
+
+ if (table != NULL) {
+ table->ht = hash_table_ctor(32, hash_table_string_hash,
+ hash_table_string_compare);
+
+ _mesa_symbol_table_push_scope(table);
+ }
+
+ return table;
+}
+
+
+void
+_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
+{
+ while (table->current_scope != NULL) {
+ _mesa_symbol_table_pop_scope(table);
+ }
+
+ hash_table_dtor(table->ht);
+ free(table);
+}
diff --git a/src/mesa/shader/symbol_table.h b/src/mesa/shader/symbol_table.h
new file mode 100644
index 0000000000..0c054ef139
--- /dev/null
+++ b/src/mesa/shader/symbol_table.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright © 2008 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+#ifndef MESA_SYMBOL_TABLE_H
+#define MESA_SYMBOL_TABLE_H
+
+struct _mesa_symbol_table;
+struct _mesa_symbol_table_iterator;
+
+extern void _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table);
+
+extern void _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table);
+
+extern int _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *symtab,
+ int name_space, const char *name, void *declaration);
+
+extern void *_mesa_symbol_table_find_symbol(
+ struct _mesa_symbol_table *symtab, int name_space, const char *name);
+
+extern struct _mesa_symbol_table *_mesa_symbol_table_ctor(void);
+
+extern void _mesa_symbol_table_dtor(struct _mesa_symbol_table *);
+
+extern struct _mesa_symbol_table_iterator *_mesa_symbol_table_iterator_ctor(
+ struct _mesa_symbol_table *table, int name_space, const char *name);
+
+extern void _mesa_symbol_table_iterator_dtor(
+ struct _mesa_symbol_table_iterator *);
+
+extern void *_mesa_symbol_table_iterator_get(
+ struct _mesa_symbol_table_iterator *iter);
+
+extern int _mesa_symbol_table_iterator_next(
+ struct _mesa_symbol_table_iterator *iter);
+
+#endif /* MESA_SYMBOL_TABLE_H */
diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak
index b4b36368cf..7107538cee 100644
--- a/src/mesa/sources.mak
+++ b/src/mesa/sources.mak
@@ -61,6 +61,7 @@ MAIN_SOURCES = \
main/shared.c \
main/state.c \
main/stencil.c \
+ main/syncobj.c \
main/texcompress.c \
main/texcompress_s3tc.c \
main/texcompress_fxt1.c \
@@ -114,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 \
@@ -124,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
@@ -218,21 +217,27 @@ SHADER_SOURCES = \
shader/arbprogram.c \
shader/atifragshader.c \
shader/grammar/grammar_mesa.c \
+ shader/hash_table.c \
+ shader/lex.yy.c \
shader/nvfragparse.c \
shader/nvprogram.c \
shader/nvvertparse.c \
shader/program.c \
+ shader/program_parse.tab.c \
+ shader/program_parse_extra.c \
shader/prog_cache.c \
shader/prog_execute.c \
shader/prog_instruction.c \
shader/prog_noise.c \
shader/prog_optimize.c \
shader/prog_parameter.c \
+ shader/prog_parameter_layout.c \
shader/prog_print.c \
shader/prog_statevars.c \
shader/prog_uniform.c \
shader/programopt.c \
- shader/shader_api.c \
+ shader/symbol_table.c \
+ shader/shader_api.c
SLANG_SOURCES = \
shader/slang/slang_builtin.c \
@@ -303,7 +308,8 @@ SPARC_API = \
sparc/glapi_sparc.S
COMMON_DRIVER_SOURCES = \
- drivers/common/driverfuncs.c
+ drivers/common/driverfuncs.c \
+ drivers/common/meta.c
# Sources for building non-Gallium drivers
@@ -364,5 +370,4 @@ INCLUDE_DIRS = \
-I$(TOP)/include \
-I$(TOP)/src/mesa \
-I$(TOP)/src/gallium/include \
- -I$(TOP)/src/gallium/drivers \
-I$(TOP)/src/gallium/auxiliary
diff --git a/src/mesa/sparc/clip.S b/src/mesa/sparc/clip.S
index 208843c606..dc239171ff 100644
--- a/src/mesa/sparc/clip.S
+++ b/src/mesa/sparc/clip.S
@@ -58,7 +58,8 @@ clip_table:
.byte 31, 29, 31, 30, 27, 25, 27, 26
/* GLvector4f *clip_vec, GLvector4f *proj_vec,
- GLubyte clipMask[], GLubyte *orMask, GLubyte *andMask */
+ GLubyte clipMask[], GLubyte *orMask, GLubyte *andMask,
+ GLboolean viewport_z_enable */
.align 64
__pc_tramp:
diff --git a/src/mesa/sparc/glapi_sparc.S b/src/mesa/sparc/glapi_sparc.S
index 12d74fa4fb..aaa17e6a3b 100644
--- a/src/mesa/sparc/glapi_sparc.S
+++ b/src/mesa/sparc/glapi_sparc.S
@@ -764,23 +764,33 @@ gl_dispatch_functions_start:
GL_STUB(glBindVertexArray, _gloffset_BindVertexArray)
GL_STUB(glGenVertexArrays, _gloffset_GenVertexArrays)
GL_STUB(glCopyBufferSubData, _gloffset_CopyBufferSubData)
+ GL_STUB(glClientWaitSync, _gloffset_ClientWaitSync)
+ GL_STUB(glDeleteSync, _gloffset_DeleteSync)
+ GL_STUB(glFenceSync, _gloffset_FenceSync)
+ GL_STUB(glGetInteger64v, _gloffset_GetInteger64v)
+ GL_STUB(glGetSynciv, _gloffset_GetSynciv)
+ GL_STUB(glIsSync, _gloffset_IsSync)
+ GL_STUB(glWaitSync, _gloffset_WaitSync)
+ GL_STUB(glDrawElementsBaseVertex, _gloffset_DrawElementsBaseVertex)
+ GL_STUB(glDrawRangeElementsBaseVertex, _gloffset_DrawRangeElementsBaseVertex)
+ GL_STUB(glMultiDrawElementsBaseVertex, _gloffset_MultiDrawElementsBaseVertex)
GL_STUB(glPolygonOffsetEXT, _gloffset_PolygonOffsetEXT)
- GL_STUB(gl_dispatch_stub_568, _gloffset_GetPixelTexGenParameterfvSGIS)
- HIDDEN(gl_dispatch_stub_568)
- GL_STUB(gl_dispatch_stub_569, _gloffset_GetPixelTexGenParameterivSGIS)
- HIDDEN(gl_dispatch_stub_569)
- GL_STUB(gl_dispatch_stub_570, _gloffset_PixelTexGenParameterfSGIS)
- HIDDEN(gl_dispatch_stub_570)
- GL_STUB(gl_dispatch_stub_571, _gloffset_PixelTexGenParameterfvSGIS)
- HIDDEN(gl_dispatch_stub_571)
- GL_STUB(gl_dispatch_stub_572, _gloffset_PixelTexGenParameteriSGIS)
- HIDDEN(gl_dispatch_stub_572)
- GL_STUB(gl_dispatch_stub_573, _gloffset_PixelTexGenParameterivSGIS)
- HIDDEN(gl_dispatch_stub_573)
- GL_STUB(gl_dispatch_stub_574, _gloffset_SampleMaskSGIS)
- HIDDEN(gl_dispatch_stub_574)
- GL_STUB(gl_dispatch_stub_575, _gloffset_SamplePatternSGIS)
- HIDDEN(gl_dispatch_stub_575)
+ GL_STUB(gl_dispatch_stub_578, _gloffset_GetPixelTexGenParameterfvSGIS)
+ HIDDEN(gl_dispatch_stub_578)
+ GL_STUB(gl_dispatch_stub_579, _gloffset_GetPixelTexGenParameterivSGIS)
+ HIDDEN(gl_dispatch_stub_579)
+ GL_STUB(gl_dispatch_stub_580, _gloffset_PixelTexGenParameterfSGIS)
+ HIDDEN(gl_dispatch_stub_580)
+ GL_STUB(gl_dispatch_stub_581, _gloffset_PixelTexGenParameterfvSGIS)
+ HIDDEN(gl_dispatch_stub_581)
+ GL_STUB(gl_dispatch_stub_582, _gloffset_PixelTexGenParameteriSGIS)
+ HIDDEN(gl_dispatch_stub_582)
+ GL_STUB(gl_dispatch_stub_583, _gloffset_PixelTexGenParameterivSGIS)
+ HIDDEN(gl_dispatch_stub_583)
+ GL_STUB(gl_dispatch_stub_584, _gloffset_SampleMaskSGIS)
+ HIDDEN(gl_dispatch_stub_584)
+ GL_STUB(gl_dispatch_stub_585, _gloffset_SamplePatternSGIS)
+ HIDDEN(gl_dispatch_stub_585)
GL_STUB(glColorPointerEXT, _gloffset_ColorPointerEXT)
GL_STUB(glEdgeFlagPointerEXT, _gloffset_EdgeFlagPointerEXT)
GL_STUB(glIndexPointerEXT, _gloffset_IndexPointerEXT)
@@ -791,10 +801,10 @@ gl_dispatch_functions_start:
GL_STUB(glPointParameterfvEXT, _gloffset_PointParameterfvEXT)
GL_STUB(glLockArraysEXT, _gloffset_LockArraysEXT)
GL_STUB(glUnlockArraysEXT, _gloffset_UnlockArraysEXT)
- GL_STUB(gl_dispatch_stub_586, _gloffset_CullParameterdvEXT)
- HIDDEN(gl_dispatch_stub_586)
- GL_STUB(gl_dispatch_stub_587, _gloffset_CullParameterfvEXT)
- HIDDEN(gl_dispatch_stub_587)
+ GL_STUB(gl_dispatch_stub_596, _gloffset_CullParameterdvEXT)
+ HIDDEN(gl_dispatch_stub_596)
+ GL_STUB(gl_dispatch_stub_597, _gloffset_CullParameterfvEXT)
+ HIDDEN(gl_dispatch_stub_597)
GL_STUB(glSecondaryColor3bEXT, _gloffset_SecondaryColor3bEXT)
GL_STUB(glSecondaryColor3bvEXT, _gloffset_SecondaryColor3bvEXT)
GL_STUB(glSecondaryColor3dEXT, _gloffset_SecondaryColor3dEXT)
@@ -819,8 +829,8 @@ gl_dispatch_functions_start:
GL_STUB(glFogCoorddvEXT, _gloffset_FogCoorddvEXT)
GL_STUB(glFogCoordfEXT, _gloffset_FogCoordfEXT)
GL_STUB(glFogCoordfvEXT, _gloffset_FogCoordfvEXT)
- GL_STUB(gl_dispatch_stub_612, _gloffset_PixelTexGenSGIX)
- HIDDEN(gl_dispatch_stub_612)
+ GL_STUB(gl_dispatch_stub_622, _gloffset_PixelTexGenSGIX)
+ HIDDEN(gl_dispatch_stub_622)
GL_STUB(glBlendFuncSeparateEXT, _gloffset_BlendFuncSeparateEXT)
GL_STUB(glFlushVertexArrayRangeNV, _gloffset_FlushVertexArrayRangeNV)
GL_STUB(glVertexArrayRangeNV, _gloffset_VertexArrayRangeNV)
@@ -862,24 +872,24 @@ gl_dispatch_functions_start:
GL_STUB(glWindowPos4ivMESA, _gloffset_WindowPos4ivMESA)
GL_STUB(glWindowPos4sMESA, _gloffset_WindowPos4sMESA)
GL_STUB(glWindowPos4svMESA, _gloffset_WindowPos4svMESA)
- GL_STUB(gl_dispatch_stub_654, _gloffset_MultiModeDrawArraysIBM)
- HIDDEN(gl_dispatch_stub_654)
- GL_STUB(gl_dispatch_stub_655, _gloffset_MultiModeDrawElementsIBM)
- HIDDEN(gl_dispatch_stub_655)
- GL_STUB(gl_dispatch_stub_656, _gloffset_DeleteFencesNV)
- HIDDEN(gl_dispatch_stub_656)
- GL_STUB(gl_dispatch_stub_657, _gloffset_FinishFenceNV)
- HIDDEN(gl_dispatch_stub_657)
- GL_STUB(gl_dispatch_stub_658, _gloffset_GenFencesNV)
- HIDDEN(gl_dispatch_stub_658)
- GL_STUB(gl_dispatch_stub_659, _gloffset_GetFenceivNV)
- HIDDEN(gl_dispatch_stub_659)
- GL_STUB(gl_dispatch_stub_660, _gloffset_IsFenceNV)
- HIDDEN(gl_dispatch_stub_660)
- GL_STUB(gl_dispatch_stub_661, _gloffset_SetFenceNV)
- HIDDEN(gl_dispatch_stub_661)
- GL_STUB(gl_dispatch_stub_662, _gloffset_TestFenceNV)
- HIDDEN(gl_dispatch_stub_662)
+ GL_STUB(gl_dispatch_stub_664, _gloffset_MultiModeDrawArraysIBM)
+ HIDDEN(gl_dispatch_stub_664)
+ GL_STUB(gl_dispatch_stub_665, _gloffset_MultiModeDrawElementsIBM)
+ HIDDEN(gl_dispatch_stub_665)
+ GL_STUB(gl_dispatch_stub_666, _gloffset_DeleteFencesNV)
+ HIDDEN(gl_dispatch_stub_666)
+ GL_STUB(gl_dispatch_stub_667, _gloffset_FinishFenceNV)
+ HIDDEN(gl_dispatch_stub_667)
+ GL_STUB(gl_dispatch_stub_668, _gloffset_GenFencesNV)
+ HIDDEN(gl_dispatch_stub_668)
+ GL_STUB(gl_dispatch_stub_669, _gloffset_GetFenceivNV)
+ HIDDEN(gl_dispatch_stub_669)
+ GL_STUB(gl_dispatch_stub_670, _gloffset_IsFenceNV)
+ HIDDEN(gl_dispatch_stub_670)
+ GL_STUB(gl_dispatch_stub_671, _gloffset_SetFenceNV)
+ HIDDEN(gl_dispatch_stub_671)
+ GL_STUB(gl_dispatch_stub_672, _gloffset_TestFenceNV)
+ HIDDEN(gl_dispatch_stub_672)
GL_STUB(glAreProgramsResidentNV, _gloffset_AreProgramsResidentNV)
GL_STUB(glBindProgramNV, _gloffset_BindProgramNV)
GL_STUB(glDeleteProgramsNV, _gloffset_DeleteProgramsNV)
@@ -960,26 +970,26 @@ gl_dispatch_functions_start:
GL_STUB(glSetFragmentShaderConstantATI, _gloffset_SetFragmentShaderConstantATI)
GL_STUB(glPointParameteriNV, _gloffset_PointParameteriNV)
GL_STUB(glPointParameterivNV, _gloffset_PointParameterivNV)
- GL_STUB(gl_dispatch_stub_743, _gloffset_ActiveStencilFaceEXT)
- HIDDEN(gl_dispatch_stub_743)
- GL_STUB(gl_dispatch_stub_744, _gloffset_BindVertexArrayAPPLE)
- HIDDEN(gl_dispatch_stub_744)
- GL_STUB(gl_dispatch_stub_745, _gloffset_DeleteVertexArraysAPPLE)
- HIDDEN(gl_dispatch_stub_745)
- GL_STUB(gl_dispatch_stub_746, _gloffset_GenVertexArraysAPPLE)
- HIDDEN(gl_dispatch_stub_746)
- GL_STUB(gl_dispatch_stub_747, _gloffset_IsVertexArrayAPPLE)
- HIDDEN(gl_dispatch_stub_747)
+ GL_STUB(gl_dispatch_stub_753, _gloffset_ActiveStencilFaceEXT)
+ HIDDEN(gl_dispatch_stub_753)
+ GL_STUB(gl_dispatch_stub_754, _gloffset_BindVertexArrayAPPLE)
+ HIDDEN(gl_dispatch_stub_754)
+ GL_STUB(gl_dispatch_stub_755, _gloffset_DeleteVertexArraysAPPLE)
+ HIDDEN(gl_dispatch_stub_755)
+ GL_STUB(gl_dispatch_stub_756, _gloffset_GenVertexArraysAPPLE)
+ HIDDEN(gl_dispatch_stub_756)
+ GL_STUB(gl_dispatch_stub_757, _gloffset_IsVertexArrayAPPLE)
+ HIDDEN(gl_dispatch_stub_757)
GL_STUB(glGetProgramNamedParameterdvNV, _gloffset_GetProgramNamedParameterdvNV)
GL_STUB(glGetProgramNamedParameterfvNV, _gloffset_GetProgramNamedParameterfvNV)
GL_STUB(glProgramNamedParameter4dNV, _gloffset_ProgramNamedParameter4dNV)
GL_STUB(glProgramNamedParameter4dvNV, _gloffset_ProgramNamedParameter4dvNV)
GL_STUB(glProgramNamedParameter4fNV, _gloffset_ProgramNamedParameter4fNV)
GL_STUB(glProgramNamedParameter4fvNV, _gloffset_ProgramNamedParameter4fvNV)
- GL_STUB(gl_dispatch_stub_754, _gloffset_DepthBoundsEXT)
- HIDDEN(gl_dispatch_stub_754)
- GL_STUB(gl_dispatch_stub_755, _gloffset_BlendEquationSeparateEXT)
- HIDDEN(gl_dispatch_stub_755)
+ GL_STUB(gl_dispatch_stub_764, _gloffset_DepthBoundsEXT)
+ HIDDEN(gl_dispatch_stub_764)
+ GL_STUB(gl_dispatch_stub_765, _gloffset_BlendEquationSeparateEXT)
+ HIDDEN(gl_dispatch_stub_765)
GL_STUB(glBindFramebufferEXT, _gloffset_BindFramebufferEXT)
GL_STUB(glBindRenderbufferEXT, _gloffset_BindRenderbufferEXT)
GL_STUB(glCheckFramebufferStatusEXT, _gloffset_CheckFramebufferStatusEXT)
@@ -997,20 +1007,28 @@ gl_dispatch_functions_start:
GL_STUB(glIsFramebufferEXT, _gloffset_IsFramebufferEXT)
GL_STUB(glIsRenderbufferEXT, _gloffset_IsRenderbufferEXT)
GL_STUB(glRenderbufferStorageEXT, _gloffset_RenderbufferStorageEXT)
- GL_STUB(gl_dispatch_stub_773, _gloffset_BlitFramebufferEXT)
- HIDDEN(gl_dispatch_stub_773)
+ GL_STUB(gl_dispatch_stub_783, _gloffset_BlitFramebufferEXT)
+ HIDDEN(gl_dispatch_stub_783)
+ GL_STUB(gl_dispatch_stub_784, _gloffset_BufferParameteriAPPLE)
+ HIDDEN(gl_dispatch_stub_784)
+ GL_STUB(gl_dispatch_stub_785, _gloffset_FlushMappedBufferRangeAPPLE)
+ HIDDEN(gl_dispatch_stub_785)
GL_STUB(glFramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT)
GL_STUB(glProvokingVertexEXT, _gloffset_ProvokingVertexEXT)
- GL_STUB(gl_dispatch_stub_776, _gloffset_StencilFuncSeparateATI)
- HIDDEN(gl_dispatch_stub_776)
- GL_STUB(gl_dispatch_stub_777, _gloffset_ProgramEnvParameters4fvEXT)
- HIDDEN(gl_dispatch_stub_777)
- GL_STUB(gl_dispatch_stub_778, _gloffset_ProgramLocalParameters4fvEXT)
- HIDDEN(gl_dispatch_stub_778)
- GL_STUB(gl_dispatch_stub_779, _gloffset_GetQueryObjecti64vEXT)
- HIDDEN(gl_dispatch_stub_779)
- GL_STUB(gl_dispatch_stub_780, _gloffset_GetQueryObjectui64vEXT)
- HIDDEN(gl_dispatch_stub_780)
+ GL_STUB(gl_dispatch_stub_788, _gloffset_GetTexParameterPointervAPPLE)
+ HIDDEN(gl_dispatch_stub_788)
+ GL_STUB(gl_dispatch_stub_789, _gloffset_TextureRangeAPPLE)
+ HIDDEN(gl_dispatch_stub_789)
+ GL_STUB(gl_dispatch_stub_790, _gloffset_StencilFuncSeparateATI)
+ HIDDEN(gl_dispatch_stub_790)
+ GL_STUB(gl_dispatch_stub_791, _gloffset_ProgramEnvParameters4fvEXT)
+ HIDDEN(gl_dispatch_stub_791)
+ GL_STUB(gl_dispatch_stub_792, _gloffset_ProgramLocalParameters4fvEXT)
+ HIDDEN(gl_dispatch_stub_792)
+ GL_STUB(gl_dispatch_stub_793, _gloffset_GetQueryObjecti64vEXT)
+ HIDDEN(gl_dispatch_stub_793)
+ GL_STUB(gl_dispatch_stub_794, _gloffset_GetQueryObjectui64vEXT)
+ HIDDEN(gl_dispatch_stub_794)
GL_STUB_ALIAS(glArrayElementEXT, glArrayElement)
GL_STUB_ALIAS(glBindTextureEXT, glBindTexture)
GL_STUB_ALIAS(glDrawArraysEXT, glDrawArrays)
@@ -1344,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/sparc/sparc.c b/src/mesa/sparc/sparc.c
index d2286a2c83..cea0c7cecf 100644
--- a/src/mesa/sparc/sparc.c
+++ b/src/mesa/sparc/sparc.c
@@ -78,13 +78,15 @@ extern GLvector4f *_mesa_sparc_cliptest_points4(GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask);
+ GLubyte *andMask,
+ GLboolean viewport_z_clip);
extern GLvector4f *_mesa_sparc_cliptest_points4_np(GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask);
+ GLubyte *andMask,
+ GLboolean viewport_z_clip);
#define NORM_ARGS const GLmatrix *mat, \
GLfloat scale, \
diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c
index 8b3bb5cc03..ee649be885 100644
--- a/src/mesa/state_tracker/st_atom_shader.c
+++ b/src/mesa/state_tracker/st_atom_shader.c
@@ -139,23 +139,6 @@ find_translated_vp(struct st_context *st,
if (fragInputsRead & (1 << inAttr)) {
stfp->input_to_slot[inAttr] = numIn;
numIn++;
- if (((1 << inAttr) & FRAG_BIT_FOGC)) {
- /* leave placeholders for the
- * extra registers we extract from fog */
- if (stfp->Base.UsesFrontFacing) {
- if (!stfp->Base.UsesFogFragCoord)
- --stfp->input_to_slot[inAttr];
- else
- ++numIn;
- }
- if (stfp->Base.UsesPointCoord) {
- if (!stfp->Base.UsesFrontFacing &&
- !stfp->Base.UsesFogFragCoord)
- stfp->input_to_slot[inAttr] -= 2;
- else
- ++numIn;
- }
- }
}
else {
stfp->input_to_slot[inAttr] = UNUSED;
diff --git a/src/mesa/state_tracker/st_cb_bitmap.c b/src/mesa/state_tracker/st_cb_bitmap.c
index 8709633557..902fb38d1a 100644
--- a/src/mesa/state_tracker/st_cb_bitmap.c
+++ b/src/mesa/state_tracker/st_cb_bitmap.c
@@ -94,6 +94,9 @@ struct bitmap_cache
GLfloat color[4];
+ /** Bitmap's Z position */
+ GLfloat zpos;
+
struct pipe_texture *texture;
struct pipe_transfer *trans;
@@ -104,6 +107,8 @@ struct bitmap_cache
};
+/** Epsilon for Z comparisons */
+#define Z_EPSILON 1e-06
/**
@@ -236,7 +241,7 @@ combined_bitmap_fragment_program(GLcontext *ctx)
/**
* Copy user-provide bitmap bits into texture buffer, expanding
* bits into texels.
- * "On" bits will set texels to 0xff.
+ * "On" bits will set texels to 0x0.
* "Off" bits will not modify texels.
* Note that the image is actually going to be upside down in
* the texture. We deal with that with texcoords.
@@ -248,63 +253,10 @@ unpack_bitmap(struct st_context *st,
const GLubyte *bitmap,
ubyte *destBuffer, uint destStride)
{
- GLint row, col;
-
-#define SET_PIXEL(COL, ROW) \
- destBuffer[(py + (ROW)) * destStride + px + (COL)] = 0x0;
-
- for (row = 0; row < height; row++) {
- const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack,
- bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0);
-
- if (unpack->LsbFirst) {
- /* Lsb first */
- GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
- for (col = 0; col < width; col++) {
-
- if (*src & mask) {
- SET_PIXEL(col, row);
- }
-
- if (mask == 128U) {
- src++;
- mask = 1U;
- }
- else {
- mask = mask << 1;
- }
- }
-
- /* get ready for next row */
- if (mask != 1)
- src++;
- }
- else {
- /* Msb first */
- GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
- for (col = 0; col < width; col++) {
-
- if (*src & mask) {
- SET_PIXEL(col, row);
- }
-
- if (mask == 1U) {
- src++;
- mask = 128U;
- }
- else {
- mask = mask >> 1;
- }
- }
-
- /* get ready for next row */
- if (mask != 128)
- src++;
- }
-
- } /* row */
+ destBuffer += py * destStride + px;
-#undef SET_PIXEL
+ _mesa_expand_bitmap(width, height, unpack, bitmap,
+ destBuffer, destStride, 0x0);
}
@@ -323,7 +275,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
struct pipe_texture *pt;
/* PBO source... */
- bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
+ bitmap = _mesa_map_pbo_source(ctx, unpack, bitmap);
if (!bitmap) {
return NULL;
}
@@ -335,7 +287,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
0, width, height, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
- _mesa_unmap_bitmap_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
return NULL;
}
@@ -350,7 +302,7 @@ make_bitmap_texture(GLcontext *ctx, GLsizei width, GLsizei height,
unpack_bitmap(ctx->st, 0, 0, width, height, unpack, bitmap,
dest, transfer->stride);
- _mesa_unmap_bitmap_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
/* Release transfer */
screen->transfer_unmap(screen, transfer);
@@ -538,9 +490,7 @@ draw_bitmap_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
}
/* draw textured quad */
- offset = setup_bitmap_vertex_data(st, x, y, width, height,
- ctx->Current.RasterPos[2],
- color);
+ offset = setup_bitmap_vertex_data(st, x, y, width, height, z, color);
util_draw_vertex_buffer(pipe, st->bitmap.vbuf, offset,
PIPE_PRIM_TRIANGLE_FAN,
@@ -647,7 +597,7 @@ st_flush_bitmap_cache(struct st_context *st)
draw_bitmap_quad(st->ctx,
cache->xpos,
cache->ypos,
- st->ctx->Current.RasterPos[2],
+ cache->zpos,
BITMAP_CACHE_WIDTH, BITMAP_CACHE_HEIGHT,
cache->texture,
cache->color);
@@ -687,6 +637,7 @@ accum_bitmap(struct st_context *st,
{
struct bitmap_cache *cache = st->bitmap.cache;
int px = -999, py;
+ const GLfloat z = st->ctx->Current.RasterPos[2];
if (width > BITMAP_CACHE_WIDTH ||
height > BITMAP_CACHE_HEIGHT)
@@ -697,7 +648,8 @@ accum_bitmap(struct st_context *st,
py = y - cache->ypos;
if (px < 0 || px + width > BITMAP_CACHE_WIDTH ||
py < 0 || py + height > BITMAP_CACHE_HEIGHT ||
- !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color)) {
+ !TEST_EQ_4V(st->ctx->Current.RasterColor, cache->color) ||
+ ((fabs(z - cache->zpos) > Z_EPSILON))) {
/* This bitmap would extend beyond cache bounds, or the bitmap
* color is changing
* so flush and continue.
@@ -712,6 +664,7 @@ accum_bitmap(struct st_context *st,
py = (BITMAP_CACHE_HEIGHT - height) / 2;
cache->xpos = x;
cache->ypos = y - py;
+ cache->zpos = z;
cache->empty = GL_FALSE;
COPY_4FV(cache->color, st->ctx->Current.RasterColor);
}
diff --git a/src/mesa/state_tracker/st_cb_blit.c b/src/mesa/state_tracker/st_cb_blit.c
index 2852623472..5626e25323 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"
@@ -69,34 +70,140 @@ st_BlitFramebuffer(GLcontext *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
+ const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT |
+ GL_STENCIL_BUFFER_BIT);
struct st_context *st = ctx->st;
-
const uint pFilter = ((filter == GL_NEAREST)
? PIPE_TEX_MIPFILTER_NEAREST
: PIPE_TEX_MIPFILTER_LINEAR);
+ struct gl_framebuffer *readFB = ctx->ReadBuffer;
+ struct gl_framebuffer *drawFB = ctx->DrawBuffer;
+
+ if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
+ &dstX0, &dstY0, &dstX1, &dstY1)) {
+ return; /* nothing to draw/blit */
+ }
+
+ if (st_fb_orientation(drawFB) == Y_0_TOP) {
+ /* invert Y for dest */
+ dstY0 = drawFB->Height - dstY0;
+ dstY1 = drawFB->Height - dstY1;
+ }
+
+ if (st_fb_orientation(readFB) == Y_0_TOP) {
+ /* invert Y for src */
+ srcY0 = readFB->Height - srcY0;
+ srcY1 = readFB->Height - srcY1;
+ }
+
+ if (srcY0 > srcY1 && dstY0 > dstY1) {
+ /* Both src and dst are upside down. Swap Y to make it
+ * right-side up to increase odds of using a fast path.
+ * Recall that all Gallium raster coords have Y=0=top.
+ */
+ GLint tmp;
+ tmp = srcY0;
+ srcY0 = srcY1;
+ srcY1 = tmp;
+ tmp = dstY0;
+ dstY0 = dstY1;
+ dstY1 = tmp;
+ }
if (mask & GL_COLOR_BUFFER_BIT) {
- struct st_renderbuffer *srcRb =
- st_renderbuffer(ctx->ReadBuffer->_ColorReadBuffer);
- struct st_renderbuffer *dstRb =
- st_renderbuffer(ctx->DrawBuffer->_ColorDrawBuffers[0]);
- struct pipe_surface *srcSurf = srcRb->surface;
- struct pipe_surface *dstSurf = dstRb->surface;
-
- if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
- /* invert Y */
- srcY0 = srcRb->Base.Height - srcY0;
- srcY1 = srcRb->Base.Height - srcY1;
-
- dstY0 = dstRb->Base.Height - dstY0;
- dstY1 = dstRb->Base.Height - dstY1;
+ 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);
+ }
+ }
- util_blit_pixels(st->blit,
- srcSurf, srcX0, srcY0, srcX1, srcY1,
- dstSurf, dstX0, dstY0, dstX1, dstY1,
- 0.0, pFilter);
-
+ if (mask & depthStencil) {
+ /* depth and/or stencil blit */
+
+ /* get src/dst depth surfaces */
+ struct st_renderbuffer *srcDepthRb =
+ st_renderbuffer(readFB->Attachment[BUFFER_DEPTH].Renderbuffer);
+ struct st_renderbuffer *dstDepthRb =
+ st_renderbuffer(drawFB->Attachment[BUFFER_DEPTH].Renderbuffer);
+ struct pipe_surface *srcDepthSurf =
+ srcDepthRb ? srcDepthRb->surface : NULL;
+ struct pipe_surface *dstDepthSurf =
+ dstDepthRb ? dstDepthRb->surface : NULL;
+
+ /* get src/dst stencil surfaces */
+ struct st_renderbuffer *srcStencilRb =
+ st_renderbuffer(readFB->Attachment[BUFFER_STENCIL].Renderbuffer);
+ struct st_renderbuffer *dstStencilRb =
+ st_renderbuffer(drawFB->Attachment[BUFFER_STENCIL].Renderbuffer);
+ struct pipe_surface *srcStencilSurf =
+ srcStencilRb ? srcStencilRb->surface : NULL;
+ struct pipe_surface *dstStencilSurf =
+ dstStencilRb ? dstStencilRb->surface : NULL;
+
+ if ((mask & depthStencil) == depthStencil &&
+ srcDepthSurf == srcStencilSurf &&
+ dstDepthSurf == dstStencilSurf) {
+ /* Blitting depth and stencil values between combined
+ * depth/stencil buffers. This is the ideal case for such buffers.
+ */
+ util_blit_pixels(st->blit,
+ srcDepthSurf, srcX0, srcY0, srcX1, srcY1,
+ dstDepthSurf, dstX0, dstY0, dstX1, dstY1,
+ 0.0, pFilter);
+ }
+ else {
+ /* blitting depth and stencil separately */
+
+ if (mask & GL_DEPTH_BUFFER_BIT) {
+ /* blit Z only */
+ _mesa_problem(ctx, "st_BlitFramebuffer(DEPTH) not completed");
+ }
+
+ if (mask & GL_STENCIL_BUFFER_BIT) {
+ /* blit stencil only */
+ _mesa_problem(ctx, "st_BlitFramebuffer(STENCIL) not completed");
+ }
+ }
}
}
diff --git a/src/mesa/state_tracker/st_cb_bufferobjects.c b/src/mesa/state_tracker/st_cb_bufferobjects.c
index 8c1fd5ce02..8e09d0b932 100644
--- a/src/mesa/state_tracker/st_cb_bufferobjects.c
+++ b/src/mesa/state_tracker/st_cb_bufferobjects.c
@@ -134,9 +134,10 @@ st_bufferobj_get_subdata(GLcontext *ctx,
* Allocate space for and store data in a buffer object. Any data that was
* previously stored in the buffer object is lost. If data is NULL,
* memory will be allocated, but no copy will occur.
- * Called via glBufferDataARB().
+ * Called via ctx->Driver.BufferData().
+ * \return GL_TRUE for success, GL_FALSE if out of memory
*/
-static void
+static GLboolean
st_bufferobj_data(GLcontext *ctx,
GLenum target,
GLsizeiptrARB size,
@@ -172,13 +173,13 @@ st_bufferobj_data(GLcontext *ctx,
st_obj->buffer = pipe_buffer_create( pipe->screen, 32, buffer_usage, size );
if (!st_obj->buffer) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferDataARB");
- return;
+ return GL_FALSE;
}
if (data)
st_no_flush_pipe_buffer_write(st_context(ctx), st_obj->buffer, 0,
size, data);
+ return GL_TRUE;
}
@@ -228,7 +229,6 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
struct pipe_context *pipe = st_context(ctx)->pipe;
struct st_buffer_object *st_obj = st_buffer_object(obj);
uint flags = 0x0;
- char *map;
if (access & GL_MAP_WRITE_BIT)
flags |= PIPE_BUFFER_USAGE_CPU_WRITE;
@@ -250,14 +250,15 @@ st_bufferobj_map_range(GLcontext *ctx, GLenum target,
assert(offset < obj->Size);
assert(offset + length <= obj->Size);
- map = obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
- if(obj->Pointer) {
+ obj->Pointer = pipe_buffer_map_range(pipe->screen, st_obj->buffer, offset, length, flags);
+ if (obj->Pointer) {
+ obj->Pointer = (ubyte *) obj->Pointer + offset;
obj->Offset = offset;
obj->Length = length;
- map += offset;
+ obj->AccessFlags = access;
}
- return map;
+ return obj->Pointer;
}
diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c
index 668acbccb8..8a8c99f7e1 100644
--- a/src/mesa/state_tracker/st_cb_clear.c
+++ b/src/mesa/state_tracker/st_cb_clear.c
@@ -280,7 +280,11 @@ clear_with_quad(GLcontext *ctx,
static INLINE GLboolean
check_clear_color_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
{
- if (ctx->Scissor.Enabled)
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
return TRUE;
if (!ctx->Color.ColorMask[0] ||
@@ -300,7 +304,11 @@ check_clear_depth_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
GLboolean maskStencil
= (ctx->Stencil.WriteMask[0] & stencilMax) != stencilMax;
- if (ctx->Scissor.Enabled)
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
return TRUE;
if (maskStencil)
@@ -319,7 +327,11 @@ check_clear_depth_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
const struct st_renderbuffer *strb = st_renderbuffer(rb);
const GLboolean isDS = pf_is_depth_and_stencil(strb->surface->format);
- if (ctx->Scissor.Enabled)
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
return TRUE;
if (isDS &&
@@ -345,7 +357,11 @@ check_clear_stencil_with_quad(GLcontext *ctx, struct gl_renderbuffer *rb)
if (maskStencil)
return TRUE;
- if (ctx->Scissor.Enabled)
+ if (ctx->Scissor.Enabled &&
+ (ctx->Scissor.X != 0 ||
+ ctx->Scissor.Y != 0 ||
+ ctx->Scissor.Width < rb->Width ||
+ ctx->Scissor.Height < rb->Height))
return TRUE;
/* This is correct, but it is necessary to look at the depth clear
diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c
index 8b5094a04f..99f3ba678b 100644
--- a/src/mesa/state_tracker/st_cb_drawpixels.c
+++ b/src/mesa/state_tracker/st_cb_drawpixels.c
@@ -60,6 +60,7 @@
#include "pipe/p_inlines.h"
#include "util/u_tile.h"
#include "util/u_draw_quad.h"
+#include "util/u_math.h"
#include "shader/prog_instruction.h"
#include "cso_cache/cso_context.h"
@@ -97,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
@@ -341,6 +342,7 @@ make_texture(struct st_context *st,
enum pipe_format pipeFormat;
GLuint cpp;
GLenum baseFormat;
+ int ptw, pth;
baseFormat = _mesa_base_format(format);
@@ -351,14 +353,35 @@ make_texture(struct st_context *st,
assert(pipeFormat);
cpp = st_sizeof_format(pipeFormat);
- pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
if (!pixels)
return NULL;
- pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, width, height, 1,
+ /* Need to use POT texture? */
+ ptw = width;
+ pth = height;
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ int l2pt, maxSize;
+
+ l2pt = util_logbase2(width);
+ if (1<<l2pt != width) {
+ ptw = 1<<(l2pt+1);
+ }
+ l2pt = util_logbase2(height);
+ if (1<<l2pt != height) {
+ pth = 1<<(l2pt+1);
+ }
+
+ /* Check against maximum texture size */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(ptw <= maxSize);
+ assert(pth <= maxSize);
+ }
+
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, pipeFormat, 0, ptw, pth, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt) {
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
return NULL;
}
@@ -405,7 +428,7 @@ make_texture(struct st_context *st,
ctx->_ImageTransferState = imageTransferStateSave;
}
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
return pt;
}
@@ -420,10 +443,10 @@ make_texture(struct st_context *st,
static void
draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
GLfloat x1, GLfloat y1, const GLfloat *color,
- GLboolean invertTex)
+ 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 */
@@ -435,8 +458,9 @@ draw_quad(GLcontext *ctx, GLfloat x0, GLfloat y0, GLfloat z,
const GLfloat clip_y0 = y0 / fb_height * 2.0f - 1.0f;
const GLfloat clip_x1 = x1 / fb_width * 2.0f - 1.0f;
const GLfloat clip_y1 = y1 / fb_height * 2.0f - 1.0f;
- const GLfloat sLeft = 0.0f, sRight = 1.0f;
- const GLfloat tTop = invertTex, tBot = 1.0f - tTop;
+ const GLfloat sLeft = 0.0f, sRight = maxXcoord;
+ const GLfloat tTop = invertTex ? maxYcoord : 0.0f;
+ const GLfloat tBot = invertTex ? 0.0f : maxYcoord;
GLuint tex, i;
/* upper-left */
@@ -516,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;
@@ -608,7 +632,9 @@ draw_textured_quad(GLcontext *ctx, GLint x, GLint y, GLfloat z,
y0 = (GLfloat) y;
y1 = y + height * ctx->Pixel.ZoomY;
- draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex);
+ draw_quad(ctx, x0, y0, z, x1, y1, color, invertTex,
+ (GLfloat) width / pt->width[0],
+ (GLfloat) height / pt->height[0]);
/* restore state */
cso_restore_rasterizer(cso);
@@ -626,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;
@@ -648,14 +674,14 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
usage = PIPE_TRANSFER_READ_WRITE;
else
usage = PIPE_TRANSFER_WRITE;
-
+
pt = st_cond_flush_get_tex_transfer(st_context(ctx), strb->texture, 0, 0, 0,
usage, x, y,
width, height);
stmap = screen->transfer_map(screen, pt);
- pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
assert(pixels);
/* if width > MAX_WIDTH, have to process image in chunks */
@@ -749,7 +775,7 @@ draw_stencil_pixels(GLcontext *ctx, GLint x, GLint y,
skipPixels += spanWidth;
}
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
/* unmap the stencil buffer */
screen->transfer_unmap(screen, pt);
@@ -767,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;
@@ -778,28 +804,28 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- _mesa_set_vp_override( ctx, TRUE );
- _mesa_update_state( ctx );
+ /* Mesa state should be up to date by now */
+ assert(ctx->NewState == 0x0);
st_validate_state(st);
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,
@@ -807,8 +833,6 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
pipe_texture_reference(&pt, NULL);
}
}
-
- _mesa_set_vp_override( ctx, FALSE );
}
@@ -842,6 +866,10 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
else
usage = PIPE_TRANSFER_WRITE;
+ if (st_fb_orientation(ctx->DrawBuffer) == Y_0_TOP) {
+ dsty = rbDraw->Base.Height - dsty - height;
+ }
+
ptDraw = st_cond_flush_get_tex_transfer(st_context(ctx),
rbDraw->texture, 0, 0, 0,
usage, dstx, dsty,
@@ -849,7 +877,7 @@ copy_stencil_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
assert(ptDraw->block.width == 1);
assert(ptDraw->block.height == 1);
-
+
/* map the stencil buffer */
drawMap = screen->transfer_map(screen, ptDraw);
@@ -914,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;
@@ -923,6 +951,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
struct pipe_texture *pt;
GLfloat *color;
enum pipe_format srcFormat, texFormat;
+ int ptw, pth;
pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
@@ -966,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;
@@ -1004,13 +1033,34 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy,
height -= -srcy;
srcy = 0;
}
-
+
if (height < 0)
return;
}
- pt = st_texture_create(ctx->st, PIPE_TEXTURE_2D, texFormat, 0,
- width, height, 1,
+ /* Need to use POT texture? */
+ ptw = width;
+ pth = height;
+ if (!screen->get_param(screen, PIPE_CAP_NPOT_TEXTURES)) {
+ int l2pt, maxSize;
+
+ l2pt = util_logbase2(width);
+ if (1<<l2pt != width) {
+ ptw = 1<<(l2pt+1);
+ }
+ l2pt = util_logbase2(height);
+ if (1<<l2pt != height) {
+ pth = 1<<(l2pt+1);
+ }
+
+ /* Check against maximum texture size */
+ maxSize = 1 << (pipe->screen->get_param(pipe->screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS) - 1);
+ assert(ptw <= maxSize);
+ assert(pth <= maxSize);
+ }
+
+ pt = st_texture_create(st, PIPE_TEXTURE_2D, texFormat, 0,
+ ptw, pth, 1,
PIPE_TEXTURE_USAGE_SAMPLER);
if (!pt)
return;
diff --git a/src/mesa/state_tracker/st_cb_fbo.c b/src/mesa/state_tracker/st_cb_fbo.c
index ecdb988033..fe0a121493 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) {
@@ -446,6 +447,35 @@ st_finish_render_texture(GLcontext *ctx,
/**
+ * Validate a renderbuffer attachment for a particular usage.
+ */
+
+static GLboolean
+st_validate_attachment(struct pipe_screen *screen,
+ const struct gl_renderbuffer_attachment *att,
+ GLuint usage)
+{
+ const struct st_texture_object *stObj =
+ st_texture_object(att->Texture);
+
+ /**
+ * Only validate texture attachments for now, since
+ * st_renderbuffer_alloc_storage makes sure that
+ * the format is supported.
+ */
+
+ if (att->Type != GL_TEXTURE)
+ return GL_TRUE;
+
+ if (!stObj)
+ return GL_FALSE;
+
+ return screen->is_format_supported(screen, stObj->pt->format,
+ PIPE_TEXTURE_2D,
+ usage, 0);
+}
+
+/**
* Check that the framebuffer configuration is valid in terms of what
* the driver can support.
*
@@ -454,13 +484,37 @@ st_finish_render_texture(GLcontext *ctx,
static void
st_validate_framebuffer(GLcontext *ctx, struct gl_framebuffer *fb)
{
+ struct pipe_screen *screen = ctx->st->pipe->screen;
const struct gl_renderbuffer *depthRb =
fb->Attachment[BUFFER_DEPTH].Renderbuffer;
const struct gl_renderbuffer *stencilRb =
fb->Attachment[BUFFER_STENCIL].Renderbuffer;
+ GLuint i;
if (stencilRb && depthRb && stencilRb != depthRb) {
fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
+
+ if (!st_validate_attachment(screen,
+ &fb->Attachment[BUFFER_DEPTH],
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
+ if (!st_validate_attachment(screen,
+ &fb->Attachment[BUFFER_STENCIL],
+ PIPE_TEXTURE_USAGE_DEPTH_STENCIL)) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
+ for (i = 0; i < ctx->Const.MaxColorAttachments; i++) {
+ if (!st_validate_attachment(screen,
+ &fb->Attachment[BUFFER_COLOR0 + i],
+ PIPE_TEXTURE_USAGE_RENDER_TARGET)) {
+ fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT;
+ return;
+ }
}
}
diff --git a/src/mesa/state_tracker/st_cb_flush.c b/src/mesa/state_tracker/st_cb_flush.c
index 8ceeeabcd3..1329f807bc 100644
--- a/src/mesa/state_tracker/st_cb_flush.c
+++ b/src/mesa/state_tracker/st_cb_flush.c
@@ -161,4 +161,16 @@ void st_init_flush_functions(struct dd_function_table *functions)
{
functions->Flush = st_glFlush;
functions->Finish = st_glFinish;
+
+ /* Windows opengl32.dll calls glFinish prior to every swapbuffers.
+ * This is unnecessary and degrades performance. Luckily we have some
+ * scope to work around this, as the externally-visible behaviour of
+ * Finish() is identical to Flush() in all cases - no differences in
+ * rendering or ReadPixels are visible if we opt not to wait here.
+ *
+ * Only set this up on windows to avoid suprise elsewhere.
+ */
+#ifdef PIPE_OS_WINDOWS
+ functions->Finish = st_glFlush;
+#endif
}
diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c
index 4398ab2839..b2d5c39a3a 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_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c
index 3bcccd0df4..d82b2a2035 100644
--- a/src/mesa/state_tracker/st_cb_rasterpos.c
+++ b/src/mesa/state_tracker/st_cb_rasterpos.c
@@ -251,7 +251,7 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4])
rs->array[0].Ptr = (GLubyte *) v;
/* draw the point */
- st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, 0, 1);
+ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1);
}
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index ccf1a0b563..75424aa2e7 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -353,7 +353,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
return;
}
- dest = _mesa_map_readpix_pbo(ctx, &clippedPacking, dest);
+ dest = _mesa_map_pbo_dest(ctx, &clippedPacking, dest);
if (!dest)
return;
@@ -380,7 +380,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
if (st_fast_readpixels(ctx, strb, x, y, width, height,
format, type, pack, dest)) {
/* success! */
- _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
+ _mesa_unmap_pbo_dest(ctx, &clippedPacking);
return;
}
@@ -534,7 +534,7 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
screen->tex_transfer_destroy(trans);
- _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
+ _mesa_unmap_pbo_dest(ctx, &clippedPacking);
}
diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c
index 15f84b6638..3520c986b4 100644
--- a/src/mesa/state_tracker/st_cb_texture.c
+++ b/src/mesa/state_tracker/st_cb_texture.c
@@ -56,9 +56,11 @@
#include "pipe/p_context.h"
#include "pipe/p_defines.h"
#include "pipe/p_inlines.h"
+#include "pipe/p_shader_tokens.h"
#include "util/u_tile.h"
#include "util/u_blit.h"
#include "util/u_surface.h"
+#include "util/u_math.h"
#define DBG if (0) printf
@@ -237,16 +239,6 @@ do_memcpy(void *dest, const void *src, size_t n)
}
-static INLINE unsigned
-logbase2(unsigned n)
-{
- unsigned log2 = 0;
- while (n >>= 1)
- ++log2;
- return log2;
-}
-
-
/**
* Return default texture usage bitmask for the given texture format.
*/
@@ -340,9 +332,9 @@ guess_and_alloc_texture(struct st_context *st,
lastLevel = firstLevel;
}
else {
- GLuint l2width = logbase2(width);
- GLuint l2height = logbase2(height);
- GLuint l2depth = logbase2(depth);
+ GLuint l2width = util_logbase2(width);
+ GLuint l2height = util_logbase2(height);
+ GLuint l2depth = util_logbase2(depth);
lastLevel = firstLevel + MAX2(MAX2(l2width, l2height), l2depth);
}
@@ -525,13 +517,19 @@ st_TexImage(GLcontext * ctx,
struct st_texture_image *stImage = st_texture_image(texImage);
GLint postConvWidth, postConvHeight;
GLint texelBytes, sizeInBytes;
- GLuint dstRowStride;
+ GLuint dstRowStride = 0;
struct gl_pixelstore_attrib unpackNB;
- enum pipe_transfer_usage transfer_usage;
+ enum pipe_transfer_usage transfer_usage = 0;
DBG("%s target %s level %d %dx%dx%d border %d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target), level, width, height, depth, border);
+ /* switch to "normal" */
+ if (stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_FALSE;
+ }
+
/* gallium does not support texture borders, strip it off */
if (border) {
strip_texture_border(border, &width, &height, &depth, unpack, &unpackNB);
@@ -660,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.
*/
@@ -672,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;
@@ -713,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);
@@ -755,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);
- }
}
@@ -873,7 +875,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
PIPE_TRANSFER_READ,
0, 0, width, height);
- pixels = _mesa_map_readpix_pbo(ctx, &ctx->Pack, pixels);
+ pixels = _mesa_map_pbo_dest(ctx, &ctx->Pack, pixels);
/* copy/pack data into user buffer */
if (st_equal_formats(stImage->pt->format, format, type)) {
@@ -906,7 +908,7 @@ decompress_with_blit(GLcontext * ctx, GLenum target, GLint level,
}
}
- _mesa_unmap_readpix_pbo(ctx, &ctx->Pack);
+ _mesa_unmap_pbo_dest(ctx, &ctx->Pack);
/* destroy the temp / dest surface */
util_destroy_rgba_surface(dst_texture, dst_surface);
@@ -1047,7 +1049,8 @@ st_TexSubimage(GLcontext *ctx, GLint dims, GLenum target, GLint level,
_mesa_image_image_stride(packing, width, height, format, type);
GLint i;
const GLubyte *src;
- enum pipe_transfer_usage transfer_usage;
+ /* init to silence warning only: */
+ enum pipe_transfer_usage transfer_usage = PIPE_TRANSFER_WRITE;
DBG("%s target %s level %d offset %d,%d %dx%d\n", __FUNCTION__,
_mesa_lookup_enum_by_nr(target),
@@ -1097,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;
@@ -1128,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);
- }
}
@@ -1395,6 +1394,36 @@ fallback_copy_texsubimage(GLcontext *ctx, GLenum target, GLint level,
}
+static unsigned
+compatible_src_dst_formats(const struct gl_renderbuffer *src,
+ const struct gl_texture_image *dst)
+{
+ const GLenum srcFormat = src->_BaseFormat;
+ const GLenum dstLogicalFormat = dst->_BaseFormat;
+
+ if (srcFormat == dstLogicalFormat) {
+ /* This is the same as matching_base_formats, which should
+ * always pass, as it did previously.
+ */
+ return TGSI_WRITEMASK_XYZW;
+ }
+ else if (srcFormat == GL_RGBA &&
+ dstLogicalFormat == GL_RGB) {
+ /* Add a single special case to cope with RGBA->RGB transfers,
+ * setting A to 1.0 to cope with situations where the RGB
+ * destination is actually stored as RGBA.
+ */
+ return TGSI_WRITEMASK_XYZ; /* A ==> 1.0 */
+ }
+ else {
+ /* Otherwise fail.
+ */
+ return 0;
+ }
+}
+
+
+
/**
* Do a CopyTex[Sub]Image1/2/3D() using a hardware (blit) path if possible.
* Note that the region to copy has already been clipped so we know we
@@ -1424,6 +1453,9 @@ st_copy_texsubimage(GLcontext *ctx,
enum pipe_format dest_format, src_format;
GLboolean use_fallback = GL_TRUE;
GLboolean matching_base_formats;
+ GLuint format_writemask;
+ struct pipe_surface *dest_surface = NULL;
+ GLboolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
/* any rendering in progress must flushed before we grab the fb image */
st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL);
@@ -1494,13 +1526,14 @@ st_copy_texsubimage(GLcontext *ctx,
* textured-quad paths.
*/
matching_base_formats = (strb->Base._BaseFormat == texImage->_BaseFormat);
+ format_writemask = compatible_src_dst_formats(&strb->Base, texImage);
- if (matching_base_formats && ctx->_ImageTransferState == 0x0) {
- /* try potential hardware path */
- struct pipe_surface *dest_surface = NULL;
- boolean do_flip = (st_fb_orientation(ctx->ReadBuffer) == Y_0_TOP);
+ if (ctx->_ImageTransferState == 0x0) {
- if (src_format == dest_format && !do_flip) {
+ if (matching_base_formats &&
+ src_format == dest_format &&
+ !do_flip)
+ {
/* use surface_copy() / blit */
dest_surface = screen->get_tex_surface(screen, stImage->pt,
@@ -1520,7 +1553,8 @@ st_copy_texsubimage(GLcontext *ctx,
width, height);
use_fallback = GL_FALSE;
}
- else if (screen->is_format_supported(screen, src_format,
+ else if (format_writemask &&
+ screen->is_format_supported(screen, src_format,
PIPE_TEXTURE_2D,
PIPE_TEXTURE_USAGE_SAMPLER,
0) &&
@@ -1544,14 +1578,15 @@ st_copy_texsubimage(GLcontext *ctx,
srcY0 = srcY;
srcY1 = srcY0 + height;
}
- util_blit_pixels(ctx->st->blit,
- strb->surface,
- srcX, srcY0,
- srcX + width, srcY1,
- dest_surface,
- destX, destY,
- destX + width, destY + height,
- 0.0, PIPE_TEX_MIPFILTER_NEAREST);
+ util_blit_pixels_writemask(ctx->st->blit,
+ strb->surface,
+ srcX, srcY0,
+ srcX + width, srcY1,
+ dest_surface,
+ destX, destY,
+ destX + width, destY + height,
+ 0.0, PIPE_TEX_MIPFILTER_NEAREST,
+ format_writemask);
use_fallback = GL_FALSE;
}
@@ -1566,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 914a507bef..503a5f34a3 100644
--- a/src/mesa/state_tracker/st_draw.c
+++ b/src/mesa/state_tracker/st_draw.c
@@ -533,6 +533,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -545,6 +546,10 @@ st_draw_vbo(GLcontext *ctx,
unsigned num_vbuffers, num_velements;
GLboolean userSpace;
+ /* Gallium probably doesn't want this in some cases. */
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* sanity check for pointer arithmetic below */
assert(sizeof(arrays[0]->Ptr[0]) == 1);
diff --git a/src/mesa/state_tracker/st_draw.h b/src/mesa/state_tracker/st_draw.h
index dcfe7e1536..3e0face656 100644
--- a/src/mesa/state_tracker/st_draw.h
+++ b/src/mesa/state_tracker/st_draw.h
@@ -47,6 +47,7 @@ st_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
@@ -56,6 +57,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index);
diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c
index 2712c131c0..b2d682ef64 100644
--- a/src/mesa/state_tracker/st_draw_feedback.c
+++ b/src/mesa/state_tracker/st_draw_feedback.c
@@ -96,6 +96,7 @@ st_feedback_draw_vbo(GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index)
{
@@ -114,6 +115,9 @@ st_feedback_draw_vbo(GLcontext *ctx,
st_validate_state(ctx->st);
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prims, ib, &min_index, &max_index);
+
/* must get these after state validation! */
vp = ctx->st->vp;
vs = &st->vp->state;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 8a958e8bd8..3f835d38dd 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -233,7 +233,9 @@ void st_init_extensions(struct st_context *st)
if (screen->get_param(screen, PIPE_CAP_POINT_SPRITE)) {
ctx->Extensions.ARB_point_sprite = GL_TRUE;
- ctx->Extensions.NV_point_sprite = GL_TRUE;
+ /* GL_NV_point_sprite is not supported by gallium because we don't
+ * support the GL_POINT_SPRITE_R_MODE_NV option.
+ */
}
if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c
index b243c249e3..dcb90a3107 100644
--- a/src/mesa/state_tracker/st_format.c
+++ b/src/mesa/state_tracker/st_format.c
@@ -435,10 +435,10 @@ st_choose_format(struct pipe_context *pipe, GLenum internalFormat,
case GL_RGB5:
case GL_RGB4:
case GL_R3_G3_B2:
- if (screen->is_format_supported( screen, PIPE_FORMAT_A1R5G5B5_UNORM, target, tex_usage, geom_flags ))
- return PIPE_FORMAT_A1R5G5B5_UNORM;
if (screen->is_format_supported( screen, PIPE_FORMAT_R5G6B5_UNORM, target, tex_usage, geom_flags ))
return PIPE_FORMAT_R5G6B5_UNORM;
+ if (screen->is_format_supported( screen, PIPE_FORMAT_A1R5G5B5_UNORM, target, tex_usage, geom_flags ))
+ return PIPE_FORMAT_A1R5G5B5_UNORM;
return default_rgba_format( screen, target, tex_usage, geom_flags );
case GL_ALPHA:
diff --git a/src/mesa/state_tracker/st_framebuffer.c b/src/mesa/state_tracker/st_framebuffer.c
index ca32b2e573..5c0d335d62 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 6380cd6b2a..b0a1b529f1 100644
--- a/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -27,863 +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:
- if (procType == TGSI_PROCESSOR_FRAGMENT &&
- index == FRAG_ATTRIB_FOGC) {
- if (GET_SWZ(*swizzle, 0) == SWIZZLE_X) {
- /* do nothing we're, ok */
- } else if (GET_SWZ(*swizzle, 0) == SWIZZLE_Y) {
- /* replace the swizzle with xxxx */
- *swizzle = MAKE_SWIZZLE4(SWIZZLE_X,
- SWIZZLE_X,
- SWIZZLE_X,
- SWIZZLE_X);
- /* register after fog */
- return inputMapping[index] + 1;
- } else {
- *swizzle = MAKE_SWIZZLE4(SWIZZLE_Z,
- SWIZZLE_W,
- SWIZZLE_Z,
- SWIZZLE_W);
- /* register after frontface */
- return inputMapping[index] + 2;
- }
- }
- /* inputs are mapped according to the user-defined map */
- return inputMapping[index];
+ case PROGRAM_UNDEFINED:
+ return ureg_src_undef();
+
+ 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_OUTPUT:
- return outputMapping[index];
+ case PROGRAM_STATE_VAR:
+ case PROGRAM_NAMED_PARAM:
+ case PROGRAM_UNIFORM:
+ case PROGRAM_CONSTANT:
+ return t->constants[index];
- case TGSI_FILE_IMMEDIATE:
- if (indirectAccess)
- return index;
- assert(immediateMapping[index] != ~0);
- return immediateMapping[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 )
{
-#if 1
- /* XXX remove this line after we've checked that the rest of gallium
- * can handle the TGSI_TEXTURE_SHADOWx tokens.
- */
- shadow = GL_FALSE;
-#endif
- 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_BGNLOOP2;
- 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_ENDLOOP2;
- 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)
-{
- 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;
-}
-
-
-static struct tgsi_full_declaration
-make_temp_decl(
- GLuint start_index,
- GLuint end_index )
+static void
+compile_instruction(
+ struct st_translate *t,
+ const struct prog_instruction *inst )
{
- 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;
-}
+ 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_addr_decl(
- GLuint start_index,
- GLuint end_index )
-{
- struct tgsi_full_declaration decl;
+ num_dst = _mesa_num_inst_dst_regs( inst->Opcode );
+ num_src = _mesa_num_inst_src_regs( inst->Opcode );
- decl = tgsi_default_full_declaration();
- decl.Declaration.File = TGSI_FILE_ADDRESS;
- decl.DeclarationRange.First = start_index;
- decl.DeclarationRange.Last = end_index;
- return decl;
-}
+ if (num_dst)
+ dst[0] = translate_dst( t,
+ &inst->DstReg,
+ inst->SaturateMode );
-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;
-}
+ for (i = 0; i < num_src; i++)
+ src[i] = translate_src( t, &inst->SrcReg[i] );
-/** 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)
+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;
-
- 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)
-{
- *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;
+ /* 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
@@ -891,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,
@@ -919,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;
}
}
}
@@ -1172,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 b465b3bddc..c0d1ff59e1 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 806e0ca8f6..927f60cc7e 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));
@@ -458,34 +423,20 @@ st_translate_fragment_program(struct st_context *st,
stfp->input_semantic_index[slot] = 1;
interpMode[slot] = TGSI_INTERPOLATE_LINEAR;
break;
- case FRAG_ATTRIB_FOGC: {
- int extra_decls = 0;
- if (stfp->Base.UsesFogFragCoord) {
- stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
- stfp->input_semantic_index[slot] = 0;
- interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
- input_flags[slot] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- if (stfp->Base.UsesFrontFacing) {
- GLint idx = slot + extra_decls;
- stfp->input_semantic_name[idx] = TGSI_SEMANTIC_FACE;
- stfp->input_semantic_index[idx] = 0;
- interpMode[idx] = TGSI_INTERPOLATE_CONSTANT;
- input_flags[idx] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- if (stfp->Base.UsesPointCoord) {
- GLint idx = slot + extra_decls;
- stfp->input_semantic_name[idx] = TGSI_SEMANTIC_GENERIC;
- stfp->input_semantic_index[idx] = num_generic++;
- interpMode[idx] = TGSI_INTERPOLATE_PERSPECTIVE;
- input_flags[idx] = stfp->Base.Base.InputFlags[attr];
- ++extra_decls;
- }
- fs_num_inputs += extra_decls - 1;
- continue;
- }
+ case FRAG_ATTRIB_FOGC:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG;
+ stfp->input_semantic_index[slot] = 0;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
+ break;
+ case FRAG_ATTRIB_FACE:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE;
+ stfp->input_semantic_index[slot] = num_generic++;
+ interpMode[slot] = TGSI_INTERPOLATE_CONSTANT;
+ break;
+ case FRAG_ATTRIB_PNTC:
+ stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC;
+ stfp->input_semantic_index[slot] = num_generic++;
+ interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE;
break;
case FRAG_ATTRIB_TEX0:
case FRAG_ATTRIB_TEX1:
@@ -555,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/state_tracker/st_public.h b/src/mesa/state_tracker/st_public.h
index 04d3a3d7c2..a5fdac32d1 100644
--- a/src/mesa/state_tracker/st_public.h
+++ b/src/mesa/state_tracker/st_public.h
@@ -107,7 +107,9 @@ void st_swapbuffers(struct st_framebuffer *stfb,
struct pipe_surface **front_left,
struct pipe_surface **front_right);
-int st_set_teximage(struct pipe_texture *pt, int target);
+int st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format);
+int st_unbind_texture_surface(struct pipe_surface *ps, int target, int level);
/** Redirect rendering into stfb's surface to a texture image */
int st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
diff --git a/src/mesa/state_tracker/st_texture.c b/src/mesa/state_tracker/st_texture.c
index 10faa633ea..bbc2830e69 100644
--- a/src/mesa/state_tracker/st_texture.c
+++ b/src/mesa/state_tracker/st_texture.c
@@ -32,6 +32,7 @@
#include "st_cb_fbo.h"
#include "st_inlines.h"
#include "main/enums.h"
+#include "main/texobj.h"
#include "main/teximage.h"
#include "main/texstore.h"
@@ -239,7 +240,7 @@ st_surface_data(struct pipe_context *pipe,
struct pipe_screen *screen = pipe->screen;
void *map = screen->transfer_map(screen, dst);
- pipe_copy_rect(map,
+ util_copy_rect(map,
&dst->block,
dst->stride,
dstx, dsty,
@@ -353,25 +354,95 @@ st_texture_image_copy(struct pipe_context *pipe,
}
}
-/** Bind a pipe surface for use as a texture image */
+
+/**
+ * Bind a pipe surface to a texture object. After the call,
+ * the texture object is marked dirty and will be (re-)validated.
+ *
+ * If this is the first surface bound, the texture object is said to
+ * switch from normal to surface based. It will be cleared first in
+ * this case.
+ *
+ * \param ps pipe surface to be unbound
+ * \param target texture target
+ * \param level image level
+ * \param format internal format of the texture
+ */
int
-st_set_teximage(struct pipe_texture *pt, int target)
+st_bind_texture_surface(struct pipe_surface *ps, int target, int level,
+ enum pipe_format format)
{
GET_CURRENT_CONTEXT(ctx);
const GLuint unit = ctx->Texture.CurrentUnit;
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
+ struct st_texture_object *stObj;
struct st_texture_image *stImage;
- int internalFormat;
+ GLenum internalFormat;
- switch (pt->format) {
- case PIPE_FORMAT_A8R8G8B8_UNORM:
- internalFormat = GL_RGBA8;
+ switch (target) {
+ case ST_TEXTURE_2D:
+ target = GL_TEXTURE_2D;
+ break;
+ case ST_TEXTURE_RECT:
+ target = GL_TEXTURE_RECTANGLE_ARB;
break;
default:
return 0;
- };
+ }
+
+ /* map pipe format to base format for now */
+ if (pf_get_component_bits(format, PIPE_FORMAT_COMP_A) > 0)
+ internalFormat = GL_RGBA;
+ else
+ internalFormat = GL_RGB;
+
+ texObj = _mesa_select_tex_object(ctx, texUnit, target);
+ _mesa_lock_texture(ctx, texObj);
+
+ stObj = st_texture_object(texObj);
+ /* switch to surface based */
+ if (!stObj->surface_based) {
+ _mesa_clear_texture_object(ctx, texObj);
+ stObj->surface_based = GL_TRUE;
+ }
+
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ stImage = st_texture_image(texImage);
+
+ _mesa_init_teximage_fields(ctx, target, texImage,
+ ps->width, ps->height, 1, 0, internalFormat);
+ texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat,
+ GL_RGBA, GL_UNSIGNED_BYTE);
+ _mesa_set_fetch_functions(texImage, 2);
+ pipe_texture_reference(&stImage->pt, ps->texture);
+
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ _mesa_unlock_texture(ctx, texObj);
+
+ return 1;
+}
+
+
+/**
+ * Unbind a pipe surface from a texture object. After the call,
+ * the texture object is marked dirty and will be (re-)validated.
+ *
+ * \param ps pipe surface to be unbound
+ * \param target texture target
+ * \param level image level
+ */
+int
+st_unbind_texture_surface(struct pipe_surface *ps, int target, int level)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ const GLuint unit = ctx->Texture.CurrentUnit;
+ struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
+ struct gl_texture_object *texObj;
+ struct gl_texture_image *texImage;
+ struct st_texture_object *stObj;
+ struct st_texture_image *stImage;
switch (target) {
case ST_TEXTURE_2D:
@@ -385,21 +456,28 @@ st_set_teximage(struct pipe_texture *pt, int target)
}
texObj = _mesa_select_tex_object(ctx, texUnit, target);
- texImage = _mesa_get_tex_image(ctx, texObj, target, 0);
+
+ _mesa_lock_texture(ctx, texObj);
+
+ texImage = _mesa_get_tex_image(ctx, texObj, target, level);
+ stObj = st_texture_object(texObj);
stImage = st_texture_image(texImage);
-
- _mesa_init_teximage_fields(ctx, GL_TEXTURE_2D, texImage, pt->width[0],
- pt->height[0], 1, 0, internalFormat);
- texImage->TexFormat = st_ChooseTextureFormat(ctx, internalFormat, GL_RGBA,
- GL_UNSIGNED_BYTE);
- _mesa_set_fetch_functions(texImage, 2);
+ /* Make sure the pipe surface is still bound. The texture object is still
+ * considered surface based even if this is the last bound surface. */
+ if (stImage->pt == ps->texture) {
+ pipe_texture_reference(&stImage->pt, NULL);
+ _mesa_clear_texture_image(ctx, texImage);
- pipe_texture_reference(&stImage->pt, pt);
+ _mesa_dirty_texobj(ctx, texObj, GL_TRUE);
+ }
+ _mesa_unlock_texture(ctx, texObj);
+
return 1;
}
+
/** Redirect rendering into stfb's surface to a texture image */
int
st_bind_teximage(struct st_framebuffer *stfb, uint surfIndex,
diff --git a/src/mesa/state_tracker/st_texture.h b/src/mesa/state_tracker/st_texture.h
index b9d447cb56..60868ce067 100644
--- a/src/mesa/state_tracker/st_texture.h
+++ b/src/mesa/state_tracker/st_texture.h
@@ -69,6 +69,11 @@ struct st_texture_object
struct pipe_texture *pt;
GLboolean teximage_realloc;
+
+ /* True if there is/was a surface bound to this texture object. It helps
+ * track whether the texture object is surface based or not.
+ */
+ GLboolean surface_based;
};
diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c
index 5e7822cf32..3dbdf2a61a 100644
--- a/src/mesa/swrast/s_bitmap.c
+++ b/src/mesa/swrast/s_bitmap.c
@@ -56,7 +56,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
ASSERT(ctx->RenderMode == GL_RENDER);
- bitmap = _mesa_map_bitmap_pbo(ctx, unpack, bitmap);
+ bitmap = (const GLubyte *) _mesa_map_pbo_source(ctx, unpack, bitmap);
if (!bitmap)
return;
@@ -133,7 +133,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
swrast_render_finish(ctx);
- _mesa_unmap_bitmap_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
}
diff --git a/src/mesa/swrast/s_blit.c b/src/mesa/swrast/s_blit.c
index 0e32cb8f65..8303e4debc 100644
--- a/src/mesa/swrast/s_blit.c
+++ b/src/mesa/swrast/s_blit.c
@@ -24,6 +24,7 @@
#include "main/glheader.h"
+#include "main/image.h"
#include "main/macros.h"
#include "s_context.h"
@@ -104,7 +105,7 @@ static void
blit_nearest(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLenum buffer)
+ GLbitfield buffer)
{
struct gl_renderbuffer *readRb, *drawRb;
@@ -456,7 +457,7 @@ static void
simple_blit(GLcontext *ctx,
GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
- GLenum buffer)
+ GLbitfield buffer)
{
struct gl_renderbuffer *readRb, *drawRb;
const GLint width = srcX1 - srcX0;
@@ -551,184 +552,6 @@ simple_blit(GLcontext *ctx,
/**
- * Clip dst coords against Xmax (or Ymax).
- */
-static INLINE void
-clip_right_or_top(GLint *srcX0, GLint *srcX1,
- GLint *dstX0, GLint *dstX1,
- GLint maxValue)
-{
- GLfloat t, bias;
-
- if (*dstX1 > maxValue) {
- /* X1 outside right edge */
- ASSERT(*dstX0 < maxValue); /* X0 should be inside right edge */
- t = (GLfloat) (maxValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
- /* chop off [t, 1] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX1 = maxValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
- *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
- }
- else if (*dstX0 > maxValue) {
- /* X0 outside right edge */
- ASSERT(*dstX1 < maxValue); /* X1 should be inside right edge */
- t = (GLfloat) (maxValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
- /* chop off [t, 1] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX0 = maxValue;
- bias = (*srcX0 < *srcX1) ? -0.5 : 0.5;
- *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
- }
-}
-
-
-/**
- * Clip dst coords against Xmin (or Ymin).
- */
-static INLINE void
-clip_left_or_bottom(GLint *srcX0, GLint *srcX1,
- GLint *dstX0, GLint *dstX1,
- GLint minValue)
-{
- GLfloat t, bias;
-
- if (*dstX0 < minValue) {
- /* X0 outside left edge */
- ASSERT(*dstX1 > minValue); /* X1 should be inside left edge */
- t = (GLfloat) (minValue - *dstX0) / (GLfloat) (*dstX1 - *dstX0);
- /* chop off [0, t] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX0 = minValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */
- *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias);
- }
- else if (*dstX1 < minValue) {
- /* X1 outside left edge */
- ASSERT(*dstX0 > minValue); /* X0 should be inside left edge */
- t = (GLfloat) (minValue - *dstX1) / (GLfloat) (*dstX0 - *dstX1);
- /* chop off [0, t] part */
- ASSERT(t >= 0.0 && t <= 1.0);
- *dstX1 = minValue;
- bias = (*srcX0 < *srcX1) ? 0.5 : -0.5;
- *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias);
- }
-}
-
-
-/**
- * Do clipping of blit src/dest rectangles.
- * The dest rect is clipped against both the buffer bounds and scissor bounds.
- * The src rect is just clipped against the buffer bounds.
- *
- * When either the src or dest rect is clipped, the other is also clipped
- * proportionately!
- *
- * Note that X0 need not be less than X1 (same for Y) for either the source
- * and dest rects. That makes the clipping a little trickier.
- *
- * \return GL_TRUE if anything is left to draw, GL_FALSE if totally clipped
- */
-static GLboolean
-clip_blit(GLcontext *ctx,
- GLint *srcX0, GLint *srcY0, GLint *srcX1, GLint *srcY1,
- GLint *dstX0, GLint *dstY0, GLint *dstX1, GLint *dstY1)
-{
- const GLint srcXmin = 0;
- const GLint srcXmax = ctx->ReadBuffer->Width;
- const GLint srcYmin = 0;
- const GLint srcYmax = ctx->ReadBuffer->Height;
-
- /* these include scissor bounds */
- const GLint dstXmin = ctx->DrawBuffer->_Xmin;
- const GLint dstXmax = ctx->DrawBuffer->_Xmax;
- const GLint dstYmin = ctx->DrawBuffer->_Ymin;
- const GLint dstYmax = ctx->DrawBuffer->_Ymax;
-
- /*
- printf("PreClipX: src: %d .. %d dst: %d .. %d\n",
- *srcX0, *srcX1, *dstX0, *dstX1);
- printf("PreClipY: src: %d .. %d dst: %d .. %d\n",
- *srcY0, *srcY1, *dstY0, *dstY1);
- */
-
- /* trivial rejection tests */
- if (*dstX0 == *dstX1)
- return GL_FALSE; /* no width */
- if (*dstX0 <= dstXmin && *dstX1 <= dstXmin)
- return GL_FALSE; /* totally out (left) of bounds */
- if (*dstX0 >= dstXmax && *dstX1 >= dstXmax)
- return GL_FALSE; /* totally out (right) of bounds */
-
- if (*dstY0 == *dstY1)
- return GL_FALSE;
- if (*dstY0 <= dstYmin && *dstY1 <= dstYmin)
- return GL_FALSE;
- if (*dstY0 >= dstYmax && *dstY1 >= dstYmax)
- return GL_FALSE;
-
- if (*srcX0 == *srcX1)
- return GL_FALSE;
- if (*srcX0 <= srcXmin && *srcX1 <= srcXmin)
- return GL_FALSE;
- if (*srcX0 >= srcXmax && *srcX1 >= srcXmax)
- return GL_FALSE;
-
- if (*srcY0 == *srcY1)
- return GL_FALSE;
- if (*srcY0 <= srcYmin && *srcY1 <= srcYmin)
- return GL_FALSE;
- if (*srcY0 >= srcYmax && *srcY1 >= srcYmax)
- return GL_FALSE;
-
- /*
- * dest clip
- */
- clip_right_or_top(srcX0, srcX1, dstX0, dstX1, dstXmax);
- clip_right_or_top(srcY0, srcY1, dstY0, dstY1, dstYmax);
- clip_left_or_bottom(srcX0, srcX1, dstX0, dstX1, dstXmin);
- clip_left_or_bottom(srcY0, srcY1, dstY0, dstY1, dstYmin);
-
- /*
- * src clip (just swap src/dst values from above)
- */
- clip_right_or_top(dstX0, dstX1, srcX0, srcX1, srcXmax);
- clip_right_or_top(dstY0, dstY1, srcY0, srcY1, srcYmax);
- clip_left_or_bottom(dstX0, dstX1, srcX0, srcX1, srcXmin);
- clip_left_or_bottom(dstY0, dstY1, srcY0, srcY1, srcYmin);
-
- /*
- printf("PostClipX: src: %d .. %d dst: %d .. %d\n",
- *srcX0, *srcX1, *dstX0, *dstX1);
- printf("PostClipY: src: %d .. %d dst: %d .. %d\n",
- *srcY0, *srcY1, *dstY0, *dstY1);
- */
-
- ASSERT(*dstX0 >= dstXmin);
- ASSERT(*dstX0 <= dstXmax);
- ASSERT(*dstX1 >= dstXmin);
- ASSERT(*dstX1 <= dstXmax);
-
- ASSERT(*dstY0 >= dstYmin);
- ASSERT(*dstY0 <= dstYmax);
- ASSERT(*dstY1 >= dstYmin);
- ASSERT(*dstY1 <= dstYmax);
-
- ASSERT(*srcX0 >= srcXmin);
- ASSERT(*srcX0 <= srcXmax);
- ASSERT(*srcX1 >= srcXmin);
- ASSERT(*srcX1 <= srcXmax);
-
- ASSERT(*srcY0 >= srcYmin);
- ASSERT(*srcY0 <= srcYmax);
- ASSERT(*srcY1 >= srcYmin);
- ASSERT(*srcY1 <= srcYmax);
-
- return GL_TRUE;
-}
-
-
-/**
* Software fallback for glBlitFramebufferEXT().
*/
void
@@ -737,7 +560,7 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter)
{
- static const GLint buffers[3] = {
+ static const GLbitfield buffers[3] = {
GL_COLOR_BUFFER_BIT,
GL_DEPTH_BUFFER_BIT,
GL_STENCIL_BUFFER_BIT
@@ -747,8 +570,8 @@ _swrast_BlitFramebuffer(GLcontext *ctx,
if (!ctx->DrawBuffer->_NumColorDrawBuffers)
return;
- if (!clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
- &dstX0, &dstY0, &dstX1, &dstY1)) {
+ if (!_mesa_clip_blit(ctx, &srcX0, &srcY0, &srcX1, &srcY1,
+ &dstX0, &dstY0, &dstX1, &dstY1)) {
return;
}
diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c
index e7c2ace32c..abf0008565 100644
--- a/src/mesa/swrast/s_context.c
+++ b/src/mesa/swrast/s_context.c
@@ -220,6 +220,9 @@ _swrast_update_deferred_texture(GLcontext *ctx)
/* Z comes from fragment program/shader */
swrast->_DeferredTexture = GL_FALSE;
}
+ else if (fprog && fprog->UsesKill) {
+ swrast->_DeferredTexture = GL_FALSE;
+ }
else if (ctx->Query.CurrentOcclusionObject) {
/* occlusion query depends on shader discard/kill results */
swrast->_DeferredTexture = GL_FALSE;
diff --git a/src/mesa/swrast/s_depth.c b/src/mesa/swrast/s_depth.c
index 26e23f02d5..1a428fb1a2 100644
--- a/src/mesa/swrast/s_depth.c
+++ b/src/mesa/swrast/s_depth.c
@@ -497,6 +497,33 @@ depth_test_span32( GLcontext *ctx, GLuint n,
return passed;
}
+/* Apply ARB_depth_clamp to span of fragments. */
+void
+_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span )
+{
+ struct gl_framebuffer *fb = ctx->DrawBuffer;
+ struct gl_renderbuffer *rb = fb->_DepthBuffer;
+ const GLuint count = span->end;
+ GLuint *zValues = span->array->z;
+ GLuint near, far;
+ int i;
+
+ if (rb->DataType == GL_UNSIGNED_SHORT) {
+ near = FLOAT_TO_UINT(ctx->Viewport.Near);
+ far = FLOAT_TO_UINT(ctx->Viewport.Far);
+ } else {
+ assert(rb->DataType == GL_UNSIGNED_INT);
+ CLAMPED_FLOAT_TO_USHORT(near, ctx->Viewport.Near);
+ CLAMPED_FLOAT_TO_USHORT(far, ctx->Viewport.Far);
+ }
+ for (i = 0; i < count; i++) {
+ if (zValues[i] < near)
+ zValues[i] = near;
+ if (zValues[i] > far)
+ zValues[i] = far;
+ }
+}
+
/*
diff --git a/src/mesa/swrast/s_depth.h b/src/mesa/swrast/s_depth.h
index 3688625683..7eae366742 100644
--- a/src/mesa/swrast/s_depth.h
+++ b/src/mesa/swrast/s_depth.h
@@ -33,6 +33,8 @@
extern GLuint
_swrast_depth_test_span( GLcontext *ctx, SWspan *span);
+extern void
+_swrast_depth_clamp_span( GLcontext *ctx, SWspan *span );
extern GLboolean
_swrast_depth_bounds_test( GLcontext *ctx, SWspan *span );
diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c
index a9ef8e685f..6970b2e9cb 100644
--- a/src/mesa/swrast/s_drawpix.c
+++ b/src/mesa/swrast/s_drawpix.c
@@ -831,11 +831,13 @@ _swrast_DrawPixels( GLcontext *ctx,
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLboolean save_vp_override = ctx->VertexProgram._Overriden;
- /* We are creating fragments directly, without going through vertex programs.
+ /* We are creating fragments directly, without going through vertex
+ * programs.
*
- * This override flag tells the fragment processing code that its input comes
- * from a non-standard source, and it may therefore not rely on optimizations
- * that assume e.g. constant color if there is no color vertex array.
+ * This override flag tells the fragment processing code that its input
+ * comes from a non-standard source, and it may therefore not rely on
+ * optimizations that assume e.g. constant color if there is no color
+ * vertex array.
*/
_mesa_set_vp_override(ctx, GL_TRUE);
@@ -847,7 +849,7 @@ _swrast_DrawPixels( GLcontext *ctx,
if (swrast->NewState)
_swrast_validate_derived( ctx );
- pixels = _mesa_map_drawpix_pbo(ctx, unpack, pixels);
+ pixels = _mesa_map_pbo_source(ctx, unpack, pixels);
if (!pixels) {
swrast_render_finish(ctx);
_mesa_set_vp_override(ctx, save_vp_override);
@@ -892,58 +894,5 @@ _swrast_DrawPixels( GLcontext *ctx,
swrast_render_finish(ctx);
_mesa_set_vp_override(ctx, save_vp_override);
- _mesa_unmap_drawpix_pbo(ctx, unpack);
+ _mesa_unmap_pbo_source(ctx, unpack);
}
-
-
-
-#if 0 /* experimental */
-/*
- * Execute glDrawDepthPixelsMESA().
- */
-void
-_swrast_DrawDepthPixelsMESA( GLcontext *ctx,
- GLint x, GLint y,
- GLsizei width, GLsizei height,
- GLenum colorFormat, GLenum colorType,
- const GLvoid *colors,
- GLenum depthType, const GLvoid *depths,
- const struct gl_pixelstore_attrib *unpack )
-{
- SWcontext *swrast = SWRAST_CONTEXT(ctx);
-
- if (swrast->NewState)
- _swrast_validate_derived( ctx );
-
- swrast_render_start(ctx);
-
- switch (colorFormat) {
- case GL_COLOR_INDEX:
- if (ctx->Visual.rgbMode)
- draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType,
- unpack, colors);
- else
- draw_index_pixels(ctx, x, y, width, height, colorType,
- unpack, colors);
- break;
- case GL_RED:
- case GL_GREEN:
- case GL_BLUE:
- case GL_ALPHA:
- case GL_LUMINANCE:
- case GL_LUMINANCE_ALPHA:
- case GL_RGB:
- case GL_BGR:
- case GL_RGBA:
- case GL_BGRA:
- case GL_ABGR_EXT:
- draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType,
- unpack, colors);
- break;
- default:
- _mesa_problem(ctx, "unexpected format in glDrawDepthPixelsMESA");
- }
-
- swrast_render_finish(ctx);
-}
-#endif
diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c
index 7bb914b658..47ed25ee10 100644
--- a/src/mesa/swrast/s_feedback.c
+++ b/src/mesa/swrast/s_feedback.c
@@ -58,7 +58,7 @@ void
_swrast_feedback_triangle(GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2)
{
- if (_swrast_culltriangle(ctx, v0, v1, v2)) {
+ if (!_swrast_culltriangle(ctx, v0, v1, v2)) {
_mesa_feedback_token(ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN);
_mesa_feedback_token(ctx, (GLfloat) 3); /* three vertices */
@@ -113,7 +113,7 @@ void
_swrast_select_triangle(GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2)
{
- if (_swrast_culltriangle(ctx, v0, v1, v2)) {
+ if (!_swrast_culltriangle(ctx, v0, v1, v2)) {
const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF;
_mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs );
diff --git a/src/mesa/swrast/s_fragprog.c b/src/mesa/swrast/s_fragprog.c
index b71fb9eae9..613a91b0ec 100644
--- a/src/mesa/swrast/s_fragprog.c
+++ b/src/mesa/swrast/s_fragprog.c
@@ -157,9 +157,8 @@ init_machine(GLcontext *ctx, struct gl_program_machine *machine,
/* if running a GLSL program (not ARB_fragment_program) */
if (ctx->Shader.CurrentProgram) {
- /* Store front/back facing value in register FOGC.Y */
- machine->Attribs[FRAG_ATTRIB_FOGC][col][1] = 1.0 - span->facing;
- /* Note FOGC.ZW is gl_PointCoord if drawing a sprite */
+ /* Store front/back facing value */
+ machine->Attribs[FRAG_ATTRIB_FACE][col][0] = 1.0 - span->facing;
}
machine->CurElement = col;
diff --git a/src/mesa/swrast/s_imaging.c b/src/mesa/swrast/s_imaging.c
deleted file mode 100644
index 3578b713f6..0000000000
--- 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_points.c b/src/mesa/swrast/s_points.c
index 0a3ad97a71..50ec2063a5 100644
--- a/src/mesa/swrast/s_points.c
+++ b/src/mesa/swrast/s_points.c
@@ -139,9 +139,10 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
}
ATTRIB_LOOP_BEGIN
- if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) {
+ if (attr >= FRAG_ATTRIB_TEX0 && attr <= FRAG_ATTRIB_TEX7) {
+ /* a texcoord attribute */
const GLuint u = attr - FRAG_ATTRIB_TEX0;
- /* a texcoord */
+ ASSERT(u < Elements(ctx->Point.CoordReplace));
if (ctx->Point.CoordReplace[u]) {
tCoords[numTcoords++] = attr;
@@ -170,15 +171,15 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
continue;
}
}
- else if (attr == FRAG_ATTRIB_FOGC) {
- /* GLSL gl_PointCoord is stored in fog.zw */
- span.attrStart[FRAG_ATTRIB_FOGC][2] = 0.0;
- span.attrStart[FRAG_ATTRIB_FOGC][3] = 0.0; /* t0 set below */
- span.attrStepX[FRAG_ATTRIB_FOGC][2] = dsdx;
- span.attrStepX[FRAG_ATTRIB_FOGC][3] = 0.0;
- span.attrStepY[FRAG_ATTRIB_FOGC][2] = 0.0;
- span.attrStepY[FRAG_ATTRIB_FOGC][3] = dtdy;
- tCoords[numTcoords++] = FRAG_ATTRIB_FOGC;
+ else if (attr == FRAG_ATTRIB_PNTC) {
+ /* GLSL gl_PointCoord.xy (.zw undefined) */
+ span.attrStart[FRAG_ATTRIB_PNTC][0] = 0.0;
+ span.attrStart[FRAG_ATTRIB_PNTC][1] = 0.0; /* t0 set below */
+ span.attrStepX[FRAG_ATTRIB_PNTC][0] = dsdx;
+ span.attrStepX[FRAG_ATTRIB_PNTC][1] = 0.0;
+ span.attrStepY[FRAG_ATTRIB_PNTC][0] = 0.0;
+ span.attrStepY[FRAG_ATTRIB_PNTC][1] = dtdy;
+ tCoords[numTcoords++] = FRAG_ATTRIB_PNTC;
continue;
}
/* use vertex's texcoord/attrib */
@@ -221,10 +222,7 @@ sprite_point(GLcontext *ctx, const SWvertex *vert)
GLuint i;
/* setup texcoord T for this row */
for (i = 0; i < numTcoords; i++) {
- if (tCoords[i] == FRAG_ATTRIB_FOGC)
- span.attrStart[FRAG_ATTRIB_FOGC][3] = tcoord;
- else
- span.attrStart[tCoords[i]][1] = tcoord;
+ span.attrStart[tCoords[i]][1] = tcoord;
}
/* these might get changed by span clipping */
diff --git a/src/mesa/swrast/s_readpix.c b/src/mesa/swrast/s_readpix.c
index e901fc6b5d..48b9408d24 100644
--- a/src/mesa/swrast/s_readpix.c
+++ b/src/mesa/swrast/s_readpix.c
@@ -574,7 +574,7 @@ _swrast_ReadPixels( GLcontext *ctx,
return;
}
- pixels = _mesa_map_readpix_pbo(ctx, &clippedPacking, pixels);
+ pixels = _mesa_map_pbo_dest(ctx, &clippedPacking, pixels);
if (!pixels)
return;
@@ -616,5 +616,5 @@ _swrast_ReadPixels( GLcontext *ctx,
swrast_render_finish(ctx);
- _mesa_unmap_readpix_pbo(ctx, &clippedPacking);
+ _mesa_unmap_pbo_dest(ctx, &clippedPacking);
}
diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c
index 0e2793b474..a45eac438e 100644
--- a/src/mesa/swrast/s_span.c
+++ b/src/mesa/swrast/s_span.c
@@ -880,6 +880,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span)
stipple_polygon_span(ctx, span);
}
+ if (ctx->Transform.DepthClamp)
+ _swrast_depth_clamp_span(ctx, span);
+
/* Stencil and Z testing */
if (ctx->Stencil._Enabled || ctx->Depth.Test) {
if (!(span->arrayMask & SPAN_Z))
diff --git a/src/mesa/swrast/s_stencil.c b/src/mesa/swrast/s_stencil.c
index 2e84ddec71..e9e9d3a4f1 100644
--- a/src/mesa/swrast/s_stencil.c
+++ b/src/mesa/swrast/s_stencil.c
@@ -231,8 +231,9 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
GLubyte fail[MAX_WIDTH];
GLboolean allfail = GL_FALSE;
GLuint i;
- GLstencil r, s;
const GLuint valueMask = ctx->Stencil.ValueMask[face];
+ const GLstencil r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
+ GLstencil s;
ASSERT(n <= MAX_WIDTH);
@@ -260,7 +261,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
allfail = GL_TRUE;
break;
case GL_LESS:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
@@ -279,7 +279,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
}
break;
case GL_LEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
@@ -298,7 +297,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
}
break;
case GL_GREATER:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
@@ -317,7 +315,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
}
break;
case GL_GEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
@@ -336,7 +333,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
}
break;
case GL_EQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
@@ -355,7 +351,6 @@ do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
}
break;
case GL_NOTEQUAL:
- r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
diff --git a/src/mesa/swrast/s_texfilter.c b/src/mesa/swrast/s_texfilter.c
index 216c107e3f..004d4e05ae 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;
diff --git a/src/mesa/swrast/s_texstore.c b/src/mesa/swrast/s_texstore.c
deleted file mode 100644
index f9ff9ad6a4..0000000000
--- 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/s_triangle.c b/src/mesa/swrast/s_triangle.c
index 9260e35066..1ab0e19f92 100644
--- a/src/mesa/swrast/s_triangle.c
+++ b/src/mesa/swrast/s_triangle.c
@@ -44,8 +44,9 @@
#include "s_triangle.h"
-/*
- * Just used for feedback mode.
+/**
+ * Test if a triangle should be culled. Used for feedback and selection mode.
+ * \return GL_TRUE if the triangle is to be culled, GL_FALSE otherwise.
*/
GLboolean
_swrast_culltriangle( GLcontext *ctx,
@@ -53,16 +54,17 @@ _swrast_culltriangle( GLcontext *ctx,
const SWvertex *v1,
const SWvertex *v2 )
{
+ SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLfloat ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0];
GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1];
GLfloat c = ex*fy-ey*fx;
- if (c * SWRAST_CONTEXT(ctx)->_BackfaceCullSign > 0)
- return 0;
+ if (c * swrast->_BackfaceSign * swrast->_BackfaceCullSign <= 0.0F)
+ return GL_FALSE;
- return 1;
+ return GL_TRUE;
}
diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h
index c319ca62f9..c183b315b6 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/tnl/t_context.c b/src/mesa/tnl/t_context.c
index f69b122046..f2771cde09 100644
--- a/src/mesa/tnl/t_context.c
+++ b/src/mesa/tnl/t_context.c
@@ -81,7 +81,7 @@ _tnl_CreateContext( GLcontext *ctx )
tnl->nr_blocks = 0;
/* plug in the VBO drawing function */
- vbo_set_draw_func(ctx, _tnl_draw_prims);
+ vbo_set_draw_func(ctx, _tnl_vbo_draw_prims);
_math_init_transformation();
_math_init_translate();
diff --git a/src/mesa/tnl/t_context.h b/src/mesa/tnl/t_context.h
index c19eb3df3c..6137c2d2fe 100644
--- a/src/mesa/tnl/t_context.h
+++ b/src/mesa/tnl/t_context.h
@@ -548,4 +548,8 @@ typedef struct
#define MAX_TYPES TYPE_IDX(GL_DOUBLE)+1 /* 0xa + 1 */
+extern void
+tnl_clip_prepare(GLcontext *ctx);
+
+
#endif
diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c
index 2ec65d5323..04fa106300 100644
--- a/src/mesa/tnl/t_draw.c
+++ b/src/mesa/tnl/t_draw.c
@@ -316,22 +316,27 @@ static void bind_indices( GLcontext *ctx,
ptr = ADD_POINTERS(ib->obj->Pointer, ib->ptr);
- if (ib->type == GL_UNSIGNED_INT) {
+ if (ib->type == GL_UNSIGNED_INT && VB->Primitive[0].basevertex == 0) {
VB->Elts = (GLuint *) ptr;
}
else {
GLuint *elts = (GLuint *)get_space(ctx, ib->count * sizeof(GLuint));
VB->Elts = elts;
- if (ib->type == GL_UNSIGNED_SHORT) {
+ if (ib->type == GL_UNSIGNED_INT) {
+ const GLuint *in = (GLuint *)ptr;
+ for (i = 0; i < ib->count; i++)
+ *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
+ }
+ else if (ib->type == GL_UNSIGNED_SHORT) {
const GLushort *in = (GLushort *)ptr;
for (i = 0; i < ib->count; i++)
- *elts++ = (GLuint)(*in++);
+ *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
}
else {
const GLubyte *in = (GLubyte *)ptr;
for (i = 0; i < ib->count; i++)
- *elts++ = (GLuint)(*in++);
+ *elts++ = (GLuint)(*in++) + VB->Primitive[0].basevertex;
}
}
}
@@ -360,6 +365,20 @@ static void unmap_vbos( GLcontext *ctx,
}
+void _tnl_vbo_draw_prims(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)
+{
+ if (!index_bounds_valid)
+ vbo_get_minmax_index(ctx, prim, ib, &min_index, &max_index);
+
+ _tnl_draw_prims(ctx, arrays, prim, nr_prims, ib, min_index, max_index);
+}
/* This is the main entrypoint into the slimmed-down software tnl
* module. In a regular swtnl driver, this can be plugged straight
@@ -376,10 +395,14 @@ void _tnl_draw_prims( GLcontext *ctx,
TNLcontext *tnl = TNL_CONTEXT(ctx);
const GLuint TEST_SPLIT = 0;
const GLint max = TEST_SPLIT ? 8 : tnl->vb.Size - MAX_CLIPPED_VERTICES;
+ GLuint max_basevertex = prim->basevertex;
+ GLuint i;
+
+ for (i = 1; i < nr_prims; i++)
+ max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
if (0)
{
- GLuint i;
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
for (i = 0; i < nr_prims; i++)
_mesa_printf("prim %d: %s start %d count %d\n", i,
@@ -393,10 +416,10 @@ void _tnl_draw_prims( GLcontext *ctx,
*/
vbo_rebase_prims( ctx, arrays, prim, nr_prims, ib,
min_index, max_index,
- _tnl_draw_prims );
+ _tnl_vbo_draw_prims );
return;
}
- else if (max_index > max) {
+ else if (max_index + max_basevertex > max) {
/* The software TNL pipeline has a fixed amount of storage for
* vertices and it is necessary to split incoming drawing commands
* if they exceed that limit.
@@ -410,8 +433,8 @@ void _tnl_draw_prims( GLcontext *ctx,
* recursively call back into this function.
*/
vbo_split_prims( ctx, arrays, prim, nr_prims, ib,
- 0, max_index,
- _tnl_draw_prims,
+ 0, max_index + prim->basevertex,
+ _tnl_vbo_draw_prims,
&limits );
}
else {
@@ -421,17 +444,34 @@ void _tnl_draw_prims( GLcontext *ctx,
struct gl_buffer_object *bo[VERT_ATTRIB_MAX + 1];
GLuint nr_bo = 0;
- /* Binding inputs may imply mapping some vertex buffer objects.
- * They will need to be unmapped below.
- */
- bind_inputs(ctx, arrays, max_index+1, bo, &nr_bo);
- bind_indices(ctx, ib, bo, &nr_bo);
- bind_prims(ctx, prim, nr_prims );
+ for (i = 0; i < nr_prims;) {
+ GLuint this_nr_prims;
+
+ /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
+ * will rebase the elements to the basevertex, and we'll only
+ * emit strings of prims with the same basevertex in one draw call.
+ */
+ for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
+ this_nr_prims++) {
+ if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
+ break;
+ }
+
+ /* Binding inputs may imply mapping some vertex buffer objects.
+ * They will need to be unmapped below.
+ */
+ bind_prims(ctx, &prim[i], this_nr_prims);
+ bind_inputs(ctx, arrays, max_index + prim[i].basevertex + 1,
+ bo, &nr_bo);
+ bind_indices(ctx, ib, bo, &nr_bo);
- TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
+ TNL_CONTEXT(ctx)->Driver.RunPipeline(ctx);
- unmap_vbos(ctx, bo, nr_bo);
- free_space(ctx);
+ unmap_vbos(ctx, bo, nr_bo);
+ free_space(ctx);
+
+ i += this_nr_prims;
+ }
}
}
diff --git a/src/mesa/tnl/t_rasterpos.c b/src/mesa/tnl/t_rasterpos.c
index f1fdddf0f5..99b6787455 100644
--- a/src/mesa/tnl/t_rasterpos.c
+++ b/src/mesa/tnl/t_rasterpos.c
@@ -46,11 +46,10 @@
* \return zero if outside view volume, or one if inside.
*/
static GLuint
-viewclip_point( const GLfloat v[] )
+viewclip_point_xy( const GLfloat v[] )
{
if ( v[0] > v[3] || v[0] < -v[3]
- || v[1] > v[3] || v[1] < -v[3]
- || v[2] > v[3] || v[2] < -v[3] ) {
+ || v[1] > v[3] || v[1] < -v[3] ) {
return 0;
}
else {
@@ -408,18 +407,18 @@ _tnl_RasterPos(GLcontext *ctx, const GLfloat vObj[4])
/* apply projection matrix: clip = Proj * eye */
TRANSFORM_POINT( clip, ctx->ProjectionMatrixStack.Top->m, eye );
- /* clip to view volume */
- if (ctx->Transform.RasterPositionUnclipped) {
- /* GL_IBM_rasterpos_clip: only clip against Z */
+ /* clip to view volume. */
+ if (!ctx->Transform.DepthClamp) {
if (viewclip_point_z(clip) == 0) {
ctx->Current.RasterPosValid = GL_FALSE;
return;
}
}
- else if (viewclip_point(clip) == 0) {
- /* Normal OpenGL behaviour */
- ctx->Current.RasterPosValid = GL_FALSE;
- return;
+ if (!ctx->Transform.RasterPositionUnclipped) {
+ if (viewclip_point_xy(clip) == 0) {
+ ctx->Current.RasterPosValid = GL_FALSE;
+ return;
+ }
}
/* clip to user clipping planes */
@@ -443,6 +442,12 @@ _tnl_RasterPos(GLcontext *ctx, const GLfloat vObj[4])
/ ctx->DrawBuffer->_DepthMaxF;
ctx->Current.RasterPos[3] = clip[3];
+ if (ctx->Transform.DepthClamp) {
+ ctx->Current.RasterPos[3] = CLAMP(ctx->Current.RasterPos[3],
+ ctx->Viewport.Near,
+ ctx->Viewport.Far);
+ }
+
/* compute raster distance */
if (ctx->Fog.FogCoordinateSource == GL_FOG_COORDINATE_EXT)
ctx->Current.RasterDistance = ctx->Current.Attrib[VERT_ATTRIB_FOG][0];
diff --git a/src/mesa/tnl/t_vb_program.c b/src/mesa/tnl/t_vb_program.c
index 66c5e13729..c10a27614f 100644
--- a/src/mesa/tnl/t_vb_program.c
+++ b/src/mesa/tnl/t_vb_program.c
@@ -131,13 +131,16 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store)
store->ormask = 0;
store->andmask = CLIP_FRUSTUM_BITS;
+ tnl_clip_prepare(ctx);
+
if (tnl->NeedNdcCoords) {
VB->NdcPtr =
_mesa_clip_tab[VB->ClipPtr->size]( VB->ClipPtr,
&store->ndcCoords,
store->clipmask,
&store->ormask,
- &store->andmask );
+ &store->andmask,
+ !ctx->Transform.DepthClamp );
}
else {
VB->NdcPtr = NULL;
@@ -145,7 +148,8 @@ do_ndc_cliptest(GLcontext *ctx, struct vp_stage_data *store)
NULL,
store->clipmask,
&store->ormask,
- &store->andmask );
+ &store->andmask,
+ !ctx->Transform.DepthClamp );
}
if (store->andmask) {
@@ -386,6 +390,9 @@ run_vp( GLcontext *ctx, struct tnl_pipeline_stage *stage )
#endif
COPY_4V(store->results[attr].data[i], machine.Outputs[attr]);
}
+#ifdef NAN_CHECK
+ ASSERT(machine.Outputs[0][3] != 0.0F);
+#endif
#if 0
printf("HPOS: %f %f %f %f\n",
machine.Outputs[0][0],
diff --git a/src/mesa/tnl/t_vb_vertex.c b/src/mesa/tnl/t_vb_vertex.c
index 30aa7c4086..4734754ea4 100644
--- a/src/mesa/tnl/t_vb_vertex.c
+++ b/src/mesa/tnl/t_vb_vertex.c
@@ -118,6 +118,22 @@ static void (*(usercliptab[5]))( GLcontext *,
};
+void
+tnl_clip_prepare(GLcontext *ctx)
+{
+ /* Neither the x86 nor sparc asm cliptest functions have been updated
+ * for ARB_depth_clamp, so force the C paths.
+ */
+ if (ctx->Transform.DepthClamp) {
+ static GLboolean c_funcs_installed = GL_FALSE;
+ if (!c_funcs_installed) {
+ init_c_cliptest();
+ c_funcs_installed = GL_TRUE;
+ }
+ }
+}
+
+
static GLboolean run_vertex_stage( GLcontext *ctx,
struct tnl_pipeline_stage *stage )
@@ -129,6 +145,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
if (ctx->VertexProgram._Current)
return GL_TRUE;
+ tnl_clip_prepare(ctx);
+
if (ctx->_NeedEyeCoords) {
/* Separate modelview transformation:
* Use combined ModelProject to avoid some depth artifacts
@@ -173,7 +191,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
&store->proj,
store->clipmask,
&store->ormask,
- &store->andmask );
+ &store->andmask,
+ !ctx->Transform.DepthClamp );
}
else {
VB->NdcPtr = NULL;
@@ -181,7 +200,8 @@ static GLboolean run_vertex_stage( GLcontext *ctx,
NULL,
store->clipmask,
&store->ormask,
- &store->andmask );
+ &store->andmask,
+ !ctx->Transform.DepthClamp );
}
if (store->andmask)
diff --git a/src/mesa/tnl/tnl.h b/src/mesa/tnl/tnl.h
index 4d628aa9a6..9c66d3b019 100644
--- a/src/mesa/tnl/tnl.h
+++ b/src/mesa/tnl/tnl.h
@@ -81,6 +81,16 @@ _tnl_draw_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index);
+void
+_tnl_vbo_draw_prims( 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);
+
extern void
_mesa_load_tracked_matrices(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo.h b/src/mesa/vbo/vbo.h
index 5362226c2f..b24ecfd7cd 100644
--- a/src/mesa/vbo/vbo.h
+++ b/src/mesa/vbo/vbo.h
@@ -44,6 +44,7 @@ struct _mesa_prim {
GLuint start;
GLuint count;
+ GLint basevertex;
};
/* Would like to call this a "vbo_index_buffer", but this would be
@@ -69,6 +70,7 @@ typedef void (*vbo_draw_func)( GLcontext *ctx,
const struct _mesa_prim *prims,
GLuint nr_prims,
const struct _mesa_index_buffer *ib,
+ GLboolean index_bounds_valid,
GLuint min_index,
GLuint max_index );
@@ -112,7 +114,10 @@ void vbo_rebase_prims( GLcontext *ctx,
GLuint min_index,
GLuint max_index,
vbo_draw_func draw );
-
+void
+vbo_get_minmax_index(GLcontext *ctx, const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index);
void vbo_use_buffer_objects(GLcontext *ctx);
diff --git a/src/mesa/vbo/vbo_exec_api.c b/src/mesa/vbo/vbo_exec_api.c
index b746a77bc1..387d4ee3d4 100644
--- a/src/mesa/vbo/vbo_exec_api.c
+++ b/src/mesa/vbo/vbo_exec_api.c
@@ -486,23 +486,6 @@ static void GLAPIENTRY vbo_exec_EvalPoint2( GLint i, GLint j )
}
-/**
- * Check if programs/shaders are enabled and valid at glBegin time.
- */
-GLboolean
-vbo_validate_shaders(GLcontext *ctx)
-{
- if ((ctx->VertexProgram.Enabled && !ctx->VertexProgram._Enabled) ||
- (ctx->FragmentProgram.Enabled && !ctx->FragmentProgram._Enabled)) {
- return GL_FALSE;
- }
- if (ctx->Shader.CurrentProgram && !ctx->Shader.CurrentProgram->LinkStatus) {
- return GL_FALSE;
- }
- return GL_TRUE;
-}
-
-
/* Build a list of primitives on the fly. Keep
* ctx->Driver.CurrentExecPrimitive uptodate as well.
*/
@@ -521,9 +504,7 @@ static void GLAPIENTRY vbo_exec_Begin( GLenum mode )
return;
}
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glBegin (invalid vertex/fragment program)");
+ if (!_mesa_valid_to_render(ctx, "glBegin")) {
return;
}
diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c
index f4b9b2f744..668dc6eb24 100644
--- a/src/mesa/vbo/vbo_exec_array.c
+++ b/src/mesa/vbo/vbo_exec_array.c
@@ -33,6 +33,7 @@
#include "main/api_noop.h"
#include "main/varray.h"
#include "main/bufferobj.h"
+#include "main/macros.h"
#include "glapi/dispatch.h"
#include "vbo_context.h"
@@ -41,13 +42,27 @@
/**
* Compute min and max elements for glDraw[Range]Elements() calls.
*/
-static void
-get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
- GLuint *min_index, GLuint *max_index)
+void
+vbo_get_minmax_index(GLcontext *ctx,
+ const struct _mesa_prim *prim,
+ const struct _mesa_index_buffer *ib,
+ GLuint *min_index, GLuint *max_index)
{
GLuint i;
+ GLsizei count = prim->count;
+ const void *indices;
+
+ if (_mesa_is_bufferobj(ib->obj)) {
+ const GLvoid *map = ctx->Driver.MapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ GL_READ_ONLY,
+ ib->obj);
+ indices = ADD_POINTERS(map, ib->ptr);
+ } else {
+ indices = ib->ptr;
+ }
- switch(type) {
+ switch (ib->type) {
case GL_UNSIGNED_INT: {
const GLuint *ui_indices = (const GLuint *)indices;
GLuint max_ui = ui_indices[count-1];
@@ -88,6 +103,12 @@ get_minmax_index(GLuint count, GLuint type, const GLvoid *indices,
assert(0);
break;
}
+
+ if (_mesa_is_bufferobj(ib->obj)) {
+ ctx->Driver.UnmapBuffer(ctx,
+ GL_ELEMENT_ARRAY_BUFFER_ARB,
+ ib->obj);
+ }
}
@@ -101,7 +122,7 @@ check_array_data(GLcontext *ctx, struct gl_client_array *array,
{
if (array->Enabled) {
const void *data = array->Ptr;
- if (array->BufferObj->Name) {
+ if (_mesa_is_bufferobj(array->BufferObj)) {
if (!array->BufferObj->Pointer) {
/* need to map now */
array->BufferObj->Pointer = ctx->Driver.MapBuffer(ctx,
@@ -146,8 +167,8 @@ static void
unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
{
if (array->Enabled &&
- array->BufferObj->Name &&
- array->BufferObj->Pointer) {
+ _mesa_is_bufferobj(array->BufferObj) &&
+ _mesa_bufferobj_mapped(array->BufferObj)) {
ctx->Driver.UnmapBuffer(ctx,
GL_ARRAY_BUFFER_ARB,
array->BufferObj);
@@ -160,13 +181,13 @@ unmap_array_buffer(GLcontext *ctx, struct gl_client_array *array)
*/
static void
check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
- const void *elements)
+ const void *elements, GLint basevertex)
{
struct gl_array_object *arrayObj = ctx->Array.ArrayObj;
const void *elemMap;
GLint i, k;
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
elemMap = ctx->Driver.MapBuffer(ctx,
GL_ELEMENT_ARRAY_BUFFER_ARB,
GL_READ_ONLY,
@@ -205,7 +226,7 @@ check_draw_elements_data(GLcontext *ctx, GLsizei count, GLenum elemType,
}
}
- if (ctx->Array.ElementArrayBufferObj->Name) {
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj)) {
ctx->Driver.UnmapBuffer(ctx,
GL_ELEMENT_ARRAY_BUFFER_ARB,
ctx->Array.ElementArrayBufferObj);
@@ -469,8 +490,7 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
if (ctx->NewState)
_mesa_update_state( ctx );
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArrays(bad shader)");
+ if (!_mesa_valid_to_render(ctx, "glDrawArrays")) {
return;
}
@@ -498,9 +518,10 @@ vbo_exec_DrawArrays(GLenum mode, GLint start, GLsizei count)
prim[0].start = start;
prim[0].count = count;
prim[0].indexed = 0;
+ prim[0].basevertex = 0;
vbo->draw_prims( ctx, exec->array.inputs, prim, 1, NULL,
- start, start + count - 1 );
+ GL_TRUE, start, start + count - 1 );
#if 0
print_draw_arrays(ctx, exec, mode, start, count);
@@ -566,70 +587,36 @@ dump_element_buffer(GLcontext *ctx, GLenum type)
ctx->Array.ElementArrayBufferObj);
}
-
-static void GLAPIENTRY
-vbo_exec_DrawRangeElements(GLenum mode,
- GLuint start, GLuint end,
- GLsizei count, GLenum type, const GLvoid *indices)
+/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+static void
+vbo_validated_drawrangeelements(GLcontext *ctx, GLenum mode,
+ GLboolean index_bounds_valid,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
{
- GET_CURRENT_CONTEXT(ctx);
struct vbo_context *vbo = vbo_context(ctx);
struct vbo_exec_context *exec = &vbo->exec;
struct _mesa_index_buffer ib;
struct _mesa_prim prim[1];
- if (!_mesa_validate_DrawRangeElements( ctx, mode, start, end, count,
- type, indices ))
- return;
-
- 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(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)",
- start, end, count, type, indices, end,
- 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;
- }
- else if (0) {
- _mesa_printf("glDraw[Range]Elements"
- "(start %u, end %u, type 0x%x, count %d) ElemBuf %u\n",
- start, end, type, count,
- ctx->Array.ElementArrayBufferObj->Name);
- }
-
-#if 0
- check_draw_elements_data(ctx, count, type, indices);
-#else
- (void) check_draw_elements_data;
-#endif
-
FLUSH_CURRENT( ctx, 0 );
if (ctx->NewState)
_mesa_update_state( ctx );
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawRangeElements(bad shader)");
+ if (!_mesa_valid_to_render(ctx, "glDraw[Range]Elements")) {
return;
}
- bind_arrays( ctx );
-
if (ctx->NewState)
_mesa_update_state( ctx );
+ bind_arrays( ctx );
+
ib.count = count;
- ib.type = type;
+ ib.type = type;
ib.obj = ctx->Array.ElementArrayBufferObj;
ib.ptr = indices;
@@ -641,6 +628,7 @@ vbo_exec_DrawRangeElements(GLenum mode,
prim[0].start = 0;
prim[0].count = count;
prim[0].indexed = 1;
+ prim[0].basevertex = basevertex;
/* Need to give special consideration to rendering a range of
* indices starting somewhere above zero. Typically the
@@ -673,7 +661,102 @@ vbo_exec_DrawRangeElements(GLenum mode,
* for the latter case elsewhere.
*/
- vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib, start, end );
+ vbo->draw_prims( ctx, exec->array.inputs, prim, 1, &ib,
+ index_bounds_valid, start, end );
+}
+
+static void GLAPIENTRY
+vbo_exec_DrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
+{
+ 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(start %u, end %u, count %d, "
+ "type 0x%x, indices %p, base %d)\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, basevertex,
+ 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);
+
+#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) {
+ _mesa_warning(ctx, "glDraw[Range]Elements(start %u, end %u, "
+ "count %d, type 0x%x, indices %p, base %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, basevertex,
+ 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}"
+ "(start %u, end %u, type 0x%x, count %d) ElemBuf %u, "
+ "base %d\n",
+ start, end, type, count,
+ ctx->Array.ElementArrayBufferObj->Name,
+ basevertex);
+ }
+
+#if 0
+ check_draw_elements_data(ctx, count, type, indices);
+#else
+ (void) check_draw_elements_data;
+#endif
+
+ vbo_validated_drawrangeelements(ctx, mode, GL_TRUE, start, end,
+ count, type, indices, basevertex);
+}
+
+static void GLAPIENTRY
+vbo_exec_DrawRangeElements(GLenum mode,
+ GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices)
+{
+ vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
+ indices, 0);
}
@@ -682,35 +765,204 @@ vbo_exec_DrawElements(GLenum mode, GLsizei count, GLenum type,
const GLvoid *indices)
{
GET_CURRENT_CONTEXT(ctx);
- GLuint min_index = 0;
- GLuint max_index = 0;
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
+ return;
+
+ vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+ count, type, indices, 0);
+}
+
+static void GLAPIENTRY
+vbo_exec_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices,
+ basevertex ))
return;
- if (!vbo_validate_shaders(ctx)) {
- _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawElements(bad shader)");
+ vbo_validated_drawrangeelements(ctx, mode, GL_FALSE, ~0, ~0,
+ count, type, indices, basevertex);
+}
+
+/* Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements */
+static void
+vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode,
+ const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount,
+ const GLint *basevertex)
+{
+ struct vbo_context *vbo = vbo_context(ctx);
+ struct vbo_exec_context *exec = &vbo->exec;
+ struct _mesa_index_buffer ib;
+ struct _mesa_prim *prim;
+ unsigned int index_type_size = 0;
+ uintptr_t min_index_ptr, max_index_ptr;
+ GLboolean fallback = GL_FALSE;
+ int i;
+
+ if (primcount == 0)
+ return;
+
+ FLUSH_CURRENT( ctx, 0 );
+
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
+
+ if (!_mesa_valid_to_render(ctx, "glMultiDrawElements")) {
return;
}
- if (ctx->Array.ElementArrayBufferObj->Name) {
- const GLvoid *map = ctx->Driver.MapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- GL_READ_ONLY,
- ctx->Array.ElementArrayBufferObj);
+ if (ctx->NewState)
+ _mesa_update_state( ctx );
- get_minmax_index(count, type, ADD_POINTERS(map, indices),
- &min_index, &max_index);
+ prim = _mesa_calloc(primcount * sizeof(*prim));
+ if (prim == NULL) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glMultiDrawElements");
+ return;
+ }
- ctx->Driver.UnmapBuffer(ctx,
- GL_ELEMENT_ARRAY_BUFFER_ARB,
- ctx->Array.ElementArrayBufferObj);
+ /* Decide if we can do this all as one set of primitives sharing the
+ * same index buffer, or if we have to reset the index pointer per primitive.
+ */
+ bind_arrays( ctx );
+
+ switch (type) {
+ case GL_UNSIGNED_INT:
+ index_type_size = 4;
+ break;
+ case GL_UNSIGNED_SHORT:
+ index_type_size = 2;
+ break;
+ case GL_UNSIGNED_BYTE:
+ index_type_size = 1;
+ break;
+ default:
+ assert(0);
+ }
+
+ min_index_ptr = (uintptr_t)indices[0];
+ max_index_ptr = 0;
+ for (i = 0; i < primcount; i++) {
+ min_index_ptr = MIN2(min_index_ptr, (uintptr_t)indices[i]);
+ max_index_ptr = MAX2(max_index_ptr, (uintptr_t)indices[i] +
+ index_type_size * count[i]);
+ }
+
+ /* Check if we can handle this thing as a bunch of index offsets from the
+ * same index pointer. If we can't, then we have to fall back to doing
+ * a draw_prims per primitive.
+ */
+ if (index_type_size != 1) {
+ for (i = 0; i < primcount; i++) {
+ if ((((uintptr_t)indices[i] - min_index_ptr) % index_type_size) != 0) {
+ fallback = GL_TRUE;
+ break;
+ }
+ }
}
- else {
- get_minmax_index(count, type, indices, &min_index, &max_index);
+
+ /* If the index buffer isn't in a VBO, then treating the application's
+ * subranges of the index buffer as one large index buffer may lead to
+ * us reading unmapped memory.
+ */
+ if (!_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
+ fallback = GL_TRUE;
+
+ if (!fallback) {
+ ib.count = (max_index_ptr - min_index_ptr) / index_type_size;
+ ib.type = type;
+ ib.obj = ctx->Array.ElementArrayBufferObj;
+ ib.ptr = (void *)min_index_ptr;
+
+ for (i = 0; i < primcount; i++) {
+ prim[i].begin = (i == 0);
+ prim[i].end = (i == primcount - 1);
+ prim[i].weak = 0;
+ prim[i].pad = 0;
+ prim[i].mode = mode;
+ prim[i].start = ((uintptr_t)indices[i] - min_index_ptr) / index_type_size;
+ prim[i].count = count[i];
+ prim[i].indexed = 1;
+ if (basevertex != NULL)
+ prim[i].basevertex = basevertex[i];
+ else
+ prim[i].basevertex = 0;
+ }
+
+ vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib,
+ GL_FALSE, ~0, ~0);
+ } else {
+ for (i = 0; i < primcount; i++) {
+ ib.count = count[i];
+ ib.type = type;
+ ib.obj = ctx->Array.ElementArrayBufferObj;
+ ib.ptr = indices[i];
+
+
+ prim[0].begin = 1;
+ prim[0].end = 1;
+ prim[0].weak = 0;
+ prim[0].pad = 0;
+ prim[0].mode = mode;
+ prim[0].start = 0;
+ prim[0].count = count[i];
+ prim[0].indexed = 1;
+ if (basevertex != NULL)
+ prim[0].basevertex = basevertex[i];
+ else
+ prim[0].basevertex = 0;
+ }
+
+ vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib,
+ GL_FALSE, ~0, ~0);
+ }
+ _mesa_free(prim);
+}
+
+static void GLAPIENTRY
+vbo_exec_MultiDrawElements(GLenum mode,
+ const GLsizei *count, GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ for (i = 0; i < primcount; i++) {
+ if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
+ 0))
+ return;
+ }
+
+ vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
+ NULL);
+}
+
+static void GLAPIENTRY
+vbo_exec_MultiDrawElementsBaseVertex(GLenum mode,
+ const GLsizei *count, GLenum type,
+ const GLvoid **indices,
+ GLsizei primcount,
+ const GLsizei *basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ GLint i;
+
+ ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx);
+
+ for (i = 0; i < primcount; i++) {
+ if (!_mesa_validate_DrawElements(ctx, mode, count[i], type, indices[i],
+ basevertex[i]))
+ return;
}
- vbo_exec_DrawRangeElements(mode, min_index, max_index, count, type, indices);
+ vbo_validated_multidrawelements(ctx, mode, count, type, indices, primcount,
+ basevertex);
}
@@ -725,10 +977,18 @@ vbo_exec_array_init( struct vbo_exec_context *exec )
exec->vtxfmt.DrawArrays = vbo_exec_DrawArrays;
exec->vtxfmt.DrawElements = vbo_exec_DrawElements;
exec->vtxfmt.DrawRangeElements = vbo_exec_DrawRangeElements;
+ exec->vtxfmt.MultiDrawElementsEXT = vbo_exec_MultiDrawElements;
+ exec->vtxfmt.DrawElementsBaseVertex = vbo_exec_DrawElementsBaseVertex;
+ exec->vtxfmt.DrawRangeElementsBaseVertex = vbo_exec_DrawRangeElementsBaseVertex;
+ exec->vtxfmt.MultiDrawElementsBaseVertex = vbo_exec_MultiDrawElementsBaseVertex;
#else
exec->vtxfmt.DrawArrays = _mesa_noop_DrawArrays;
exec->vtxfmt.DrawElements = _mesa_noop_DrawElements;
exec->vtxfmt.DrawRangeElements = _mesa_noop_DrawRangeElements;
+ exec->vtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
+ exec->vtxfmt.DrawElementsBaseVertex = _mesa_noop_DrawElementsBaseVertex;
+ exec->vtxfmt.DrawRangeElementsBaseVertex = _mesa_noop_DrawRangeElementsBaseVertex;
+ exec->vtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
#endif
}
@@ -756,6 +1016,13 @@ _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type,
vbo_exec_DrawElements(mode, count, type, indices);
}
+void GLAPIENTRY
+_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ vbo_exec_DrawElementsBaseVertex(mode, count, type, indices, basevertex);
+}
+
/* This API entrypoint is not ordinarily used */
void GLAPIENTRY
@@ -764,3 +1031,30 @@ _mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count,
{
vbo_exec_DrawRangeElements(mode, start, end, count, type, indices);
}
+
+void GLAPIENTRY
+_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end,
+ GLsizei count, GLenum type,
+ const GLvoid *indices, GLint basevertex)
+{
+ vbo_exec_DrawRangeElementsBaseVertex(mode, start, end, count, type,
+ indices, basevertex);
+}
+
+/* GL_EXT_multi_draw_arrays */
+void GLAPIENTRY
+_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount)
+{
+ vbo_exec_MultiDrawElements(mode, count, type, indices, primcount);
+}
+
+void GLAPIENTRY
+_mesa_MultiDrawElementsBaseVertex(GLenum mode,
+ const GLsizei *count, GLenum type,
+ const GLvoid **indices, GLsizei primcount,
+ const GLint *basevertex)
+{
+ vbo_exec_MultiDrawElementsBaseVertex(mode, count, type, indices,
+ primcount, basevertex);
+}
diff --git a/src/mesa/vbo/vbo_exec_draw.c b/src/mesa/vbo/vbo_exec_draw.c
index 18419928b2..0c258c535e 100644
--- a/src/mesa/vbo/vbo_exec_draw.c
+++ b/src/mesa/vbo/vbo_exec_draw.c
@@ -214,11 +214,13 @@ vbo_exec_bind_arrays( GLcontext *ctx )
/* override the default array set above */
exec->vtx.inputs[attr] = &arrays[attr];
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
/* a real buffer obj: Ptr is an offset, not a pointer*/
GLsizeiptr offset;
assert(exec->vtx.bufferobj->Pointer); /* buf should be mapped */
- offset = (GLbyte *) data - (GLbyte *) exec->vtx.bufferobj->Pointer;
+ offset = (GLbyte *) data -
+ (GLbyte *) exec->vtx.bufferobj->Pointer +
+ exec->vtx.bufferobj->Offset;
assert(offset >= 0);
arrays[attr].Ptr = (void *) offset;
}
@@ -251,7 +253,7 @@ vbo_exec_vtx_unmap( struct vbo_exec_context *exec )
{
GLenum target = GL_ARRAY_BUFFER_ARB;
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
GLcontext *ctx = exec->ctx;
if (ctx->Driver.FlushMappedBufferRange) {
@@ -291,7 +293,7 @@ vbo_exec_vtx_map( struct vbo_exec_context *exec )
MESA_MAP_NOWAIT_BIT;
const GLenum usage = GL_STREAM_DRAW_ARB;
- if (exec->vtx.bufferobj->Name == 0)
+ if (!_mesa_is_bufferobj(exec->vtx.bufferobj))
return;
if (exec->vtx.buffer_map != NULL) {
@@ -365,7 +367,7 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
if (ctx->NewState)
_mesa_update_state( ctx );
- if (exec->vtx.bufferobj->Name) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj)) {
vbo_exec_vtx_unmap( exec );
}
@@ -378,12 +380,13 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
exec->vtx.prim,
exec->vtx.prim_count,
NULL,
+ GL_TRUE,
0,
exec->vtx.vert_count - 1);
/* If using a real VBO, get new storage -- unless asked not to.
*/
- if (exec->vtx.bufferobj->Name && !unmap) {
+ if (_mesa_is_bufferobj(exec->vtx.bufferobj) && !unmap) {
vbo_exec_vtx_map( exec );
}
}
@@ -392,12 +395,13 @@ vbo_exec_vtx_flush( struct vbo_exec_context *exec, GLboolean unmap )
/* May have to unmap explicitly if we didn't draw:
*/
if (unmap &&
- exec->vtx.bufferobj->Name &&
+ _mesa_is_bufferobj(exec->vtx.bufferobj) &&
exec->vtx.buffer_map) {
vbo_exec_vtx_unmap( exec );
}
- if (unmap)
+
+ if (unmap || exec->vtx.vertex_size == 0)
exec->vtx.max_vert = 0;
else
exec->vtx.max_vert = ((VBO_VERT_BUFFER_SIZE - exec->vtx.buffer_used) /
diff --git a/src/mesa/vbo/vbo_rebase.c b/src/mesa/vbo/vbo_rebase.c
index ea87dede64..55a82ee369 100644
--- a/src/mesa/vbo/vbo_rebase.c
+++ b/src/mesa/vbo/vbo_rebase.c
@@ -126,7 +126,23 @@ void vbo_rebase_prims( GLcontext *ctx,
if (0)
_mesa_printf("%s %d..%d\n", __FUNCTION__, min_index, max_index);
- if (ib) {
+
+ /* 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.
+ */
+ tmp_prims = (struct _mesa_prim *)_mesa_malloc(sizeof(*prim) * nr_prims);
+
+ for (i = 0; i < nr_prims; i++) {
+ tmp_prims[i] = prim[i];
+ tmp_prims[i].basevertex -= min_index;
+ }
+
+ prim = tmp_prims;
+ } else if (ib) {
/* Unfortunately need to adjust each index individually.
*/
GLboolean map_ib = ib->obj->Name && !ib->obj->Pointer;
@@ -208,6 +224,7 @@ void vbo_rebase_prims( GLcontext *ctx,
prim,
nr_prims,
ib,
+ GL_TRUE,
0,
max_index - min_index );
diff --git a/src/mesa/vbo/vbo_save_api.c b/src/mesa/vbo/vbo_save_api.c
index d00d304d2e..41cd21d04b 100644
--- a/src/mesa/vbo/vbo_save_api.c
+++ b/src/mesa/vbo/vbo_save_api.c
@@ -73,6 +73,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "main/dlist.h"
#include "main/enums.h"
#include "main/macros.h"
+#include "main/api_noop.h"
#include "main/api_validate.h"
#include "main/api_arrayelt.h"
#include "main/vtxfmt.h"
@@ -825,6 +826,33 @@ static void GLAPIENTRY _save_DrawRangeElements(GLenum mode,
_mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
}
+static void GLAPIENTRY _save_DrawElementsBaseVertex(GLenum mode,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ (void) mode; (void) count; (void) type; (void) indices; (void)basevertex;
+
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawElements" );
+}
+
+static void GLAPIENTRY _save_DrawRangeElementsBaseVertex(GLenum mode,
+ GLuint start,
+ GLuint end,
+ GLsizei count,
+ GLenum type,
+ const GLvoid *indices,
+ GLint basevertex)
+{
+ GET_CURRENT_CONTEXT(ctx);
+ (void) mode; (void) start; (void) end; (void) count; (void) type;
+ (void) indices; (void)basevertex;
+
+ _mesa_compile_error( ctx, GL_INVALID_OPERATION, "glDrawRangeElements" );
+}
+
static void GLAPIENTRY _save_DrawArrays(GLenum mode, GLint start, GLsizei count)
{
GET_CURRENT_CONTEXT(ctx);
@@ -906,12 +934,12 @@ static void GLAPIENTRY _save_OBE_DrawElements(GLenum mode, GLsizei count, GLenum
GET_CURRENT_CONTEXT(ctx);
GLint i;
- if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices ))
+ if (!_mesa_validate_DrawElements( ctx, mode, count, type, indices, 0 ))
return;
_ae_map_vbos( ctx );
- if (ctx->Array.ElementArrayBufferObj->Name)
+ if (_mesa_is_bufferobj(ctx->Array.ElementArrayBufferObj))
indices = ADD_POINTERS(ctx->Array.ElementArrayBufferObj->Pointer, indices);
vbo_save_NotifyBegin( ctx, mode | VBO_SAVE_PRIM_WEAK );
@@ -947,7 +975,7 @@ static void GLAPIENTRY _save_OBE_DrawRangeElements(GLenum mode,
GET_CURRENT_CONTEXT(ctx);
if (_mesa_validate_DrawRangeElements( ctx, mode,
start, end,
- count, type, indices ))
+ count, type, indices, 0 ))
_save_OBE_DrawElements( mode, count, type, indices );
}
@@ -1038,7 +1066,11 @@ static void _save_vtxfmt_init( GLcontext *ctx )
vfmt->DrawArrays = _save_DrawArrays;
vfmt->DrawElements = _save_DrawElements;
vfmt->DrawRangeElements = _save_DrawRangeElements;
-
+ vfmt->DrawElementsBaseVertex = _save_DrawElementsBaseVertex;
+ vfmt->DrawRangeElementsBaseVertex = _save_DrawRangeElementsBaseVertex;
+ /* Loops back into vfmt->DrawElements */
+ vfmt->MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
+ vfmt->MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
}
@@ -1228,6 +1260,9 @@ void vbo_save_api_init( struct vbo_save_context *save )
ctx->ListState.ListVtxfmt.DrawArrays = _save_OBE_DrawArrays;
ctx->ListState.ListVtxfmt.DrawElements = _save_OBE_DrawElements;
ctx->ListState.ListVtxfmt.DrawRangeElements = _save_OBE_DrawRangeElements;
+ /* loops back into _save_OBE_DrawElements */
+ ctx->ListState.ListVtxfmt.MultiDrawElementsEXT = _mesa_noop_MultiDrawElements;
+ ctx->ListState.ListVtxfmt.MultiDrawElementsBaseVertex = _mesa_noop_MultiDrawElementsBaseVertex;
_mesa_install_save_vtxfmt( ctx, &ctx->ListState.ListVtxfmt );
}
diff --git a/src/mesa/vbo/vbo_save_draw.c b/src/mesa/vbo/vbo_save_draw.c
index 5110648c28..d834fa1f2e 100644
--- a/src/mesa/vbo/vbo_save_draw.c
+++ b/src/mesa/vbo/vbo_save_draw.c
@@ -279,6 +279,7 @@ void vbo_save_playback_vertex_list( GLcontext *ctx, void *data )
node->prim,
node->prim_count,
NULL,
+ GL_TRUE,
0, /* Node is a VBO, so this is ok */
node->count - 1);
}
diff --git a/src/mesa/vbo/vbo_split.c b/src/mesa/vbo/vbo_split.c
index 58e879628d..c445acca7d 100644
--- a/src/mesa/vbo/vbo_split.c
+++ b/src/mesa/vbo/vbo_split.c
@@ -50,6 +50,7 @@
#include "main/glheader.h"
#include "main/imports.h"
#include "main/mtypes.h"
+#include "main/macros.h"
#include "vbo_split.h"
#include "vbo.h"
@@ -107,7 +108,12 @@ void vbo_split_prims( GLcontext *ctx,
vbo_draw_func draw,
const struct split_limits *limits )
{
-
+ GLuint max_basevertex = prim->basevertex;
+ GLuint i;
+
+ for (i = 1; i < nr_prims; i++)
+ max_basevertex = MAX2(max_basevertex, prim[i].basevertex);
+
if (ib) {
if (limits->max_indices == 0) {
/* Could traverse the indices, re-emitting vertices in turn.
diff --git a/src/mesa/vbo/vbo_split_copy.c b/src/mesa/vbo/vbo_split_copy.c
index d7ffebf607..c45190b9dd 100644
--- a/src/mesa/vbo/vbo_split_copy.c
+++ b/src/mesa/vbo/vbo_split_copy.c
@@ -30,6 +30,7 @@
*/
#include "main/glheader.h"
+#include "main/bufferobj.h"
#include "main/imports.h"
#include "main/image.h"
#include "main/macros.h"
@@ -194,6 +195,7 @@ flush( struct copy_context *copy )
copy->dstprim,
copy->dstprim_nr,
&copy->dstib,
+ GL_TRUE,
0,
copy->dstbuf_nr );
@@ -443,7 +445,7 @@ replay_init( struct copy_context *copy )
copy->varying[j].size = attr_size(copy->array[i]);
copy->vertex_size += attr_size(copy->array[i]);
- if (vbo->Name && !vbo->Pointer)
+ if (_mesa_is_bufferobj(vbo) && !_mesa_bufferobj_mapped(vbo))
ctx->Driver.MapBuffer(ctx, GL_ARRAY_BUFFER, GL_READ_ONLY, vbo);
copy->varying[j].src_ptr = ADD_POINTERS(vbo->Pointer,
@@ -457,7 +459,8 @@ replay_init( struct copy_context *copy )
* caller convert non-indexed prims to indexed. Could alternately
* do it internally.
*/
- if (copy->ib->obj->Name && !copy->ib->obj->Pointer)
+ if (_mesa_is_bufferobj(copy->ib->obj) &&
+ !_mesa_bufferobj_mapped(copy->ib->obj))
ctx->Driver.MapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, GL_READ_ONLY,
copy->ib->obj);
@@ -561,13 +564,14 @@ replay_finish( struct copy_context *copy )
*/
for (i = 0; i < copy->nr_varying; i++) {
struct gl_buffer_object *vbo = copy->varying[i].array->BufferObj;
- if (vbo->Name && vbo->Pointer)
+ if (_mesa_is_bufferobj(vbo) && _mesa_bufferobj_mapped(vbo))
ctx->Driver.UnmapBuffer(ctx, GL_ARRAY_BUFFER, vbo);
}
/* Unmap index buffer:
*/
- if (copy->ib->obj->Name && copy->ib->obj->Pointer) {
+ if (_mesa_is_bufferobj(copy->ib->obj) &&
+ _mesa_bufferobj_mapped(copy->ib->obj)) {
ctx->Driver.UnmapBuffer(ctx, GL_ELEMENT_ARRAY_BUFFER, copy->ib->obj);
}
}
@@ -585,28 +589,40 @@ void vbo_split_copy( GLcontext *ctx,
const struct split_limits *limits )
{
struct copy_context copy;
- GLuint i;
+ GLuint i, this_nr_prims;
+
+ for (i = 0; i < nr_prims;) {
+ /* Our SW TNL pipeline doesn't handle basevertex yet, so bind_indices
+ * will rebase the elements to the basevertex, and we'll only
+ * emit strings of prims with the same basevertex in one draw call.
+ */
+ for (this_nr_prims = 1; i + this_nr_prims < nr_prims;
+ this_nr_prims++) {
+ if (prim[i].basevertex != prim[i + this_nr_prims].basevertex)
+ break;
+ }
- memset(&copy, 0, sizeof(copy));
+ memset(&copy, 0, sizeof(copy));
- /* Require indexed primitives:
- */
- assert(ib);
-
- copy.ctx = ctx;
- copy.array = arrays;
- copy.prim = prim;
- copy.nr_prims = nr_prims;
- copy.ib = ib;
- copy.draw = draw;
- copy.limits = limits;
+ /* Require indexed primitives:
+ */
+ assert(ib);
- /* Clear the vertex cache:
- */
- for (i = 0; i < ELT_TABLE_SIZE; i++)
- copy.vert_cache[i].in = ~0;
+ copy.ctx = ctx;
+ copy.array = arrays;
+ copy.prim = &prim[i];
+ copy.nr_prims = this_nr_prims;
+ copy.ib = ib;
+ copy.draw = draw;
+ copy.limits = limits;
- replay_init(&copy);
- replay_elts(&copy);
- replay_finish(&copy);
+ /* Clear the vertex cache:
+ */
+ for (i = 0; i < ELT_TABLE_SIZE; i++)
+ copy.vert_cache[i].in = ~0;
+
+ replay_init(&copy);
+ replay_elts(&copy);
+ replay_finish(&copy);
+ }
}
diff --git a/src/mesa/vbo/vbo_split_inplace.c b/src/mesa/vbo/vbo_split_inplace.c
index 266bc56c82..da84eaa6ea 100644
--- a/src/mesa/vbo/vbo_split_inplace.c
+++ b/src/mesa/vbo/vbo_split_inplace.c
@@ -59,11 +59,11 @@ struct split_context {
static void flush_vertex( struct split_context *split )
{
GLuint min_index, max_index;
+ GLuint i;
if (!split->dstprim_nr)
return;
- GLuint i;
min_index = split->dstprim[0].start;
max_index = min_index + split->dstprim[0].count - 1;
@@ -85,6 +85,7 @@ static void flush_vertex( struct split_context *split )
split->dstprim,
split->dstprim_nr,
NULL,
+ GL_TRUE,
min_index,
max_index);
diff --git a/src/mesa/x86-64/glapi_x86-64.S b/src/mesa/x86-64/glapi_x86-64.S
index 90ad36a8f3..72d0532906 100644
--- a/src/mesa/x86-64/glapi_x86-64.S
+++ b/src/mesa/x86-64/glapi_x86-64.S
@@ -45,7 +45,7 @@
# define GL_PREFIX(n) GLNAME(CONCAT(gl,n))
# endif
-#if defined(PTHREADS) || defined(USE_XTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
# define THREADS
#endif
@@ -21350,12 +21350,414 @@ GL_PREFIX(CopyBufferSubData):
.size GL_PREFIX(CopyBufferSubData), .-GL_PREFIX(CopyBufferSubData)
.p2align 4,,15
+ .globl GL_PREFIX(ClientWaitSync)
+ .type GL_PREFIX(ClientWaitSync), @function
+GL_PREFIX(ClientWaitSync):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4536(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4536(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4536(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4536(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(ClientWaitSync), .-GL_PREFIX(ClientWaitSync)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(DeleteSync)
+ .type GL_PREFIX(DeleteSync), @function
+GL_PREFIX(DeleteSync):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4544(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ call _x86_64_get_dispatch@PLT
+ popq %rdi
+ movq 4544(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4544(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ call _glapi_get_dispatch
+ popq %rdi
+ movq 4544(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(DeleteSync), .-GL_PREFIX(DeleteSync)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(FenceSync)
+ .type GL_PREFIX(FenceSync), @function
+GL_PREFIX(FenceSync):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4552(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rbp
+ call _x86_64_get_dispatch@PLT
+ popq %rbp
+ popq %rsi
+ popq %rdi
+ movq 4552(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4552(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rbp
+ call _glapi_get_dispatch
+ popq %rbp
+ popq %rsi
+ popq %rdi
+ movq 4552(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(FenceSync), .-GL_PREFIX(FenceSync)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(GetInteger64v)
+ .type GL_PREFIX(GetInteger64v), @function
+GL_PREFIX(GetInteger64v):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4560(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rbp
+ call _x86_64_get_dispatch@PLT
+ popq %rbp
+ popq %rsi
+ popq %rdi
+ movq 4560(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4560(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rbp
+ call _glapi_get_dispatch
+ popq %rbp
+ popq %rsi
+ popq %rdi
+ movq 4560(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(GetInteger64v), .-GL_PREFIX(GetInteger64v)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(GetSynciv)
+ .type GL_PREFIX(GetSynciv), @function
+GL_PREFIX(GetSynciv):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4568(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ call _x86_64_get_dispatch@PLT
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4568(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4568(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ call _glapi_get_dispatch
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4568(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(GetSynciv), .-GL_PREFIX(GetSynciv)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(IsSync)
+ .type GL_PREFIX(IsSync), @function
+GL_PREFIX(IsSync):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4576(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ call _x86_64_get_dispatch@PLT
+ popq %rdi
+ movq 4576(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4576(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ call _glapi_get_dispatch
+ popq %rdi
+ movq 4576(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(IsSync), .-GL_PREFIX(IsSync)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(WaitSync)
+ .type GL_PREFIX(WaitSync), @function
+GL_PREFIX(WaitSync):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4584(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4584(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4584(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4584(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(WaitSync), .-GL_PREFIX(WaitSync)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(DrawElementsBaseVertex)
+ .type GL_PREFIX(DrawElementsBaseVertex), @function
+GL_PREFIX(DrawElementsBaseVertex):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4592(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ call _x86_64_get_dispatch@PLT
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4592(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4592(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ call _glapi_get_dispatch
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4592(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(DrawElementsBaseVertex), .-GL_PREFIX(DrawElementsBaseVertex)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(DrawRangeElementsBaseVertex)
+ .type GL_PREFIX(DrawRangeElementsBaseVertex), @function
+GL_PREFIX(DrawRangeElementsBaseVertex):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4600(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ pushq %r9
+ pushq %rbp
+ call _x86_64_get_dispatch@PLT
+ popq %rbp
+ popq %r9
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4600(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4600(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ pushq %r9
+ pushq %rbp
+ call _glapi_get_dispatch
+ popq %rbp
+ popq %r9
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4600(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(DrawRangeElementsBaseVertex), .-GL_PREFIX(DrawRangeElementsBaseVertex)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(MultiDrawElementsBaseVertex)
+ .type GL_PREFIX(MultiDrawElementsBaseVertex), @function
+GL_PREFIX(MultiDrawElementsBaseVertex):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 4608(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ pushq %r9
+ pushq %rbp
+ call _x86_64_get_dispatch@PLT
+ popq %rbp
+ popq %r9
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4608(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 4608(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ pushq %rcx
+ pushq %r8
+ pushq %r9
+ pushq %rbp
+ call _glapi_get_dispatch
+ popq %rbp
+ popq %r9
+ popq %r8
+ popq %rcx
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 4608(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(MultiDrawElementsBaseVertex), .-GL_PREFIX(MultiDrawElementsBaseVertex)
+
+ .p2align 4,,15
.globl GL_PREFIX(PolygonOffsetEXT)
.type GL_PREFIX(PolygonOffsetEXT), @function
GL_PREFIX(PolygonOffsetEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4536(%rax), %r11
+ movq 4616(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -21365,13 +21767,13 @@ GL_PREFIX(PolygonOffsetEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4536(%rax), %r11
+ movq 4616(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4536(%rax), %r11
+ movq 4616(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -21381,19 +21783,19 @@ GL_PREFIX(PolygonOffsetEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4536(%rax), %r11
+ movq 4616(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PolygonOffsetEXT), .-GL_PREFIX(PolygonOffsetEXT)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_568)
- .type GL_PREFIX(_dispatch_stub_568), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_568))
-GL_PREFIX(_dispatch_stub_568):
+ .globl GL_PREFIX(_dispatch_stub_578)
+ .type GL_PREFIX(_dispatch_stub_578), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_578))
+GL_PREFIX(_dispatch_stub_578):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4544(%rax), %r11
+ movq 4624(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21403,13 +21805,13 @@ GL_PREFIX(_dispatch_stub_568):
popq %rbp
popq %rsi
popq %rdi
- movq 4544(%rax), %r11
+ movq 4624(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4544(%rax), %r11
+ movq 4624(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21419,19 +21821,19 @@ GL_PREFIX(_dispatch_stub_568):
popq %rbp
popq %rsi
popq %rdi
- movq 4544(%rax), %r11
+ movq 4624(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_568), .-GL_PREFIX(_dispatch_stub_568)
+ .size GL_PREFIX(_dispatch_stub_578), .-GL_PREFIX(_dispatch_stub_578)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_569)
- .type GL_PREFIX(_dispatch_stub_569), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_569))
-GL_PREFIX(_dispatch_stub_569):
+ .globl GL_PREFIX(_dispatch_stub_579)
+ .type GL_PREFIX(_dispatch_stub_579), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_579))
+GL_PREFIX(_dispatch_stub_579):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4552(%rax), %r11
+ movq 4632(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21441,13 +21843,13 @@ GL_PREFIX(_dispatch_stub_569):
popq %rbp
popq %rsi
popq %rdi
- movq 4552(%rax), %r11
+ movq 4632(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4552(%rax), %r11
+ movq 4632(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21457,19 +21859,19 @@ GL_PREFIX(_dispatch_stub_569):
popq %rbp
popq %rsi
popq %rdi
- movq 4552(%rax), %r11
+ movq 4632(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_569), .-GL_PREFIX(_dispatch_stub_569)
+ .size GL_PREFIX(_dispatch_stub_579), .-GL_PREFIX(_dispatch_stub_579)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_570)
- .type GL_PREFIX(_dispatch_stub_570), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_570))
-GL_PREFIX(_dispatch_stub_570):
+ .globl GL_PREFIX(_dispatch_stub_580)
+ .type GL_PREFIX(_dispatch_stub_580), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_580))
+GL_PREFIX(_dispatch_stub_580):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4560(%rax), %r11
+ movq 4640(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -21479,13 +21881,13 @@ GL_PREFIX(_dispatch_stub_570):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4560(%rax), %r11
+ movq 4640(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4560(%rax), %r11
+ movq 4640(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -21495,19 +21897,19 @@ GL_PREFIX(_dispatch_stub_570):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4560(%rax), %r11
+ movq 4640(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_570), .-GL_PREFIX(_dispatch_stub_570)
+ .size GL_PREFIX(_dispatch_stub_580), .-GL_PREFIX(_dispatch_stub_580)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_571)
- .type GL_PREFIX(_dispatch_stub_571), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_571))
-GL_PREFIX(_dispatch_stub_571):
+ .globl GL_PREFIX(_dispatch_stub_581)
+ .type GL_PREFIX(_dispatch_stub_581), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_581))
+GL_PREFIX(_dispatch_stub_581):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4568(%rax), %r11
+ movq 4648(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21517,13 +21919,13 @@ GL_PREFIX(_dispatch_stub_571):
popq %rbp
popq %rsi
popq %rdi
- movq 4568(%rax), %r11
+ movq 4648(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4568(%rax), %r11
+ movq 4648(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21533,19 +21935,19 @@ GL_PREFIX(_dispatch_stub_571):
popq %rbp
popq %rsi
popq %rdi
- movq 4568(%rax), %r11
+ movq 4648(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_571), .-GL_PREFIX(_dispatch_stub_571)
+ .size GL_PREFIX(_dispatch_stub_581), .-GL_PREFIX(_dispatch_stub_581)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_572)
- .type GL_PREFIX(_dispatch_stub_572), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_572))
-GL_PREFIX(_dispatch_stub_572):
+ .globl GL_PREFIX(_dispatch_stub_582)
+ .type GL_PREFIX(_dispatch_stub_582), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_582))
+GL_PREFIX(_dispatch_stub_582):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4576(%rax), %r11
+ movq 4656(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21555,13 +21957,13 @@ GL_PREFIX(_dispatch_stub_572):
popq %rbp
popq %rsi
popq %rdi
- movq 4576(%rax), %r11
+ movq 4656(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4576(%rax), %r11
+ movq 4656(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21571,19 +21973,19 @@ GL_PREFIX(_dispatch_stub_572):
popq %rbp
popq %rsi
popq %rdi
- movq 4576(%rax), %r11
+ movq 4656(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_572), .-GL_PREFIX(_dispatch_stub_572)
+ .size GL_PREFIX(_dispatch_stub_582), .-GL_PREFIX(_dispatch_stub_582)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_573)
- .type GL_PREFIX(_dispatch_stub_573), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_573))
-GL_PREFIX(_dispatch_stub_573):
+ .globl GL_PREFIX(_dispatch_stub_583)
+ .type GL_PREFIX(_dispatch_stub_583), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_583))
+GL_PREFIX(_dispatch_stub_583):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4584(%rax), %r11
+ movq 4664(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21593,13 +21995,13 @@ GL_PREFIX(_dispatch_stub_573):
popq %rbp
popq %rsi
popq %rdi
- movq 4584(%rax), %r11
+ movq 4664(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4584(%rax), %r11
+ movq 4664(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21609,19 +22011,19 @@ GL_PREFIX(_dispatch_stub_573):
popq %rbp
popq %rsi
popq %rdi
- movq 4584(%rax), %r11
+ movq 4664(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_573), .-GL_PREFIX(_dispatch_stub_573)
+ .size GL_PREFIX(_dispatch_stub_583), .-GL_PREFIX(_dispatch_stub_583)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_574)
- .type GL_PREFIX(_dispatch_stub_574), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_574))
-GL_PREFIX(_dispatch_stub_574):
+ .globl GL_PREFIX(_dispatch_stub_584)
+ .type GL_PREFIX(_dispatch_stub_584), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_584))
+GL_PREFIX(_dispatch_stub_584):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4592(%rax), %r11
+ movq 4672(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21631,13 +22033,13 @@ GL_PREFIX(_dispatch_stub_574):
popq %rbp
popq %rsi
popq %rdi
- movq 4592(%rax), %r11
+ movq 4672(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4592(%rax), %r11
+ movq 4672(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21647,40 +22049,40 @@ GL_PREFIX(_dispatch_stub_574):
popq %rbp
popq %rsi
popq %rdi
- movq 4592(%rax), %r11
+ movq 4672(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_574), .-GL_PREFIX(_dispatch_stub_574)
+ .size GL_PREFIX(_dispatch_stub_584), .-GL_PREFIX(_dispatch_stub_584)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_575)
- .type GL_PREFIX(_dispatch_stub_575), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_575))
-GL_PREFIX(_dispatch_stub_575):
+ .globl GL_PREFIX(_dispatch_stub_585)
+ .type GL_PREFIX(_dispatch_stub_585), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_585))
+GL_PREFIX(_dispatch_stub_585):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4600(%rax), %r11
+ movq 4680(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4600(%rax), %r11
+ movq 4680(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4600(%rax), %r11
+ movq 4680(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4600(%rax), %r11
+ movq 4680(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_575), .-GL_PREFIX(_dispatch_stub_575)
+ .size GL_PREFIX(_dispatch_stub_585), .-GL_PREFIX(_dispatch_stub_585)
.p2align 4,,15
.globl GL_PREFIX(ColorPointerEXT)
@@ -21688,7 +22090,7 @@ GL_PREFIX(_dispatch_stub_575):
GL_PREFIX(ColorPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4608(%rax), %r11
+ movq 4688(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21702,13 +22104,13 @@ GL_PREFIX(ColorPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4608(%rax), %r11
+ movq 4688(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4608(%rax), %r11
+ movq 4688(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21722,7 +22124,7 @@ GL_PREFIX(ColorPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4608(%rax), %r11
+ movq 4688(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ColorPointerEXT), .-GL_PREFIX(ColorPointerEXT)
@@ -21733,7 +22135,7 @@ GL_PREFIX(ColorPointerEXT):
GL_PREFIX(EdgeFlagPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4616(%rax), %r11
+ movq 4696(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21743,13 +22145,13 @@ GL_PREFIX(EdgeFlagPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4616(%rax), %r11
+ movq 4696(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4616(%rax), %r11
+ movq 4696(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21759,7 +22161,7 @@ GL_PREFIX(EdgeFlagPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4616(%rax), %r11
+ movq 4696(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(EdgeFlagPointerEXT), .-GL_PREFIX(EdgeFlagPointerEXT)
@@ -21770,7 +22172,7 @@ GL_PREFIX(EdgeFlagPointerEXT):
GL_PREFIX(IndexPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4624(%rax), %r11
+ movq 4704(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21784,13 +22186,13 @@ GL_PREFIX(IndexPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4624(%rax), %r11
+ movq 4704(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4624(%rax), %r11
+ movq 4704(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21804,7 +22206,7 @@ GL_PREFIX(IndexPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4624(%rax), %r11
+ movq 4704(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(IndexPointerEXT), .-GL_PREFIX(IndexPointerEXT)
@@ -21815,7 +22217,7 @@ GL_PREFIX(IndexPointerEXT):
GL_PREFIX(NormalPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4632(%rax), %r11
+ movq 4712(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21829,13 +22231,13 @@ GL_PREFIX(NormalPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4632(%rax), %r11
+ movq 4712(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4632(%rax), %r11
+ movq 4712(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21849,7 +22251,7 @@ GL_PREFIX(NormalPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4632(%rax), %r11
+ movq 4712(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(NormalPointerEXT), .-GL_PREFIX(NormalPointerEXT)
@@ -21860,7 +22262,7 @@ GL_PREFIX(NormalPointerEXT):
GL_PREFIX(TexCoordPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4640(%rax), %r11
+ movq 4720(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21874,13 +22276,13 @@ GL_PREFIX(TexCoordPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4640(%rax), %r11
+ movq 4720(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4640(%rax), %r11
+ movq 4720(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21894,7 +22296,7 @@ GL_PREFIX(TexCoordPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4640(%rax), %r11
+ movq 4720(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(TexCoordPointerEXT), .-GL_PREFIX(TexCoordPointerEXT)
@@ -21905,7 +22307,7 @@ GL_PREFIX(TexCoordPointerEXT):
GL_PREFIX(VertexPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4648(%rax), %r11
+ movq 4728(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21919,13 +22321,13 @@ GL_PREFIX(VertexPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4648(%rax), %r11
+ movq 4728(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4648(%rax), %r11
+ movq 4728(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -21939,7 +22341,7 @@ GL_PREFIX(VertexPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4648(%rax), %r11
+ movq 4728(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexPointerEXT), .-GL_PREFIX(VertexPointerEXT)
@@ -21950,7 +22352,7 @@ GL_PREFIX(VertexPointerEXT):
GL_PREFIX(PointParameterfEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4656(%rax), %r11
+ movq 4736(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -21960,13 +22362,13 @@ GL_PREFIX(PointParameterfEXT):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4656(%rax), %r11
+ movq 4736(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4656(%rax), %r11
+ movq 4736(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -21976,7 +22378,7 @@ GL_PREFIX(PointParameterfEXT):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4656(%rax), %r11
+ movq 4736(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PointParameterfEXT), .-GL_PREFIX(PointParameterfEXT)
@@ -21987,7 +22389,7 @@ GL_PREFIX(PointParameterfEXT):
GL_PREFIX(PointParameterfvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4664(%rax), %r11
+ movq 4744(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -21997,13 +22399,13 @@ GL_PREFIX(PointParameterfvEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 4664(%rax), %r11
+ movq 4744(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4664(%rax), %r11
+ movq 4744(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22013,7 +22415,7 @@ GL_PREFIX(PointParameterfvEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 4664(%rax), %r11
+ movq 4744(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PointParameterfvEXT), .-GL_PREFIX(PointParameterfvEXT)
@@ -22024,7 +22426,7 @@ GL_PREFIX(PointParameterfvEXT):
GL_PREFIX(LockArraysEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4672(%rax), %r11
+ movq 4752(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22034,13 +22436,13 @@ GL_PREFIX(LockArraysEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 4672(%rax), %r11
+ movq 4752(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4672(%rax), %r11
+ movq 4752(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22050,7 +22452,7 @@ GL_PREFIX(LockArraysEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 4672(%rax), %r11
+ movq 4752(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(LockArraysEXT), .-GL_PREFIX(LockArraysEXT)
@@ -22061,37 +22463,37 @@ GL_PREFIX(LockArraysEXT):
GL_PREFIX(UnlockArraysEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4680(%rax), %r11
+ movq 4760(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rbp
call _x86_64_get_dispatch@PLT
popq %rbp
- movq 4680(%rax), %r11
+ movq 4760(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4680(%rax), %r11
+ movq 4760(%rax), %r11
jmp *%r11
1:
pushq %rbp
call _glapi_get_dispatch
popq %rbp
- movq 4680(%rax), %r11
+ movq 4760(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(UnlockArraysEXT), .-GL_PREFIX(UnlockArraysEXT)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_586)
- .type GL_PREFIX(_dispatch_stub_586), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_586))
-GL_PREFIX(_dispatch_stub_586):
+ .globl GL_PREFIX(_dispatch_stub_596)
+ .type GL_PREFIX(_dispatch_stub_596), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_596))
+GL_PREFIX(_dispatch_stub_596):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4688(%rax), %r11
+ movq 4768(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22101,13 +22503,13 @@ GL_PREFIX(_dispatch_stub_586):
popq %rbp
popq %rsi
popq %rdi
- movq 4688(%rax), %r11
+ movq 4768(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4688(%rax), %r11
+ movq 4768(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22117,19 +22519,19 @@ GL_PREFIX(_dispatch_stub_586):
popq %rbp
popq %rsi
popq %rdi
- movq 4688(%rax), %r11
+ movq 4768(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_586), .-GL_PREFIX(_dispatch_stub_586)
+ .size GL_PREFIX(_dispatch_stub_596), .-GL_PREFIX(_dispatch_stub_596)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_587)
- .type GL_PREFIX(_dispatch_stub_587), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_587))
-GL_PREFIX(_dispatch_stub_587):
+ .globl GL_PREFIX(_dispatch_stub_597)
+ .type GL_PREFIX(_dispatch_stub_597), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_597))
+GL_PREFIX(_dispatch_stub_597):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4696(%rax), %r11
+ movq 4776(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22139,13 +22541,13 @@ GL_PREFIX(_dispatch_stub_587):
popq %rbp
popq %rsi
popq %rdi
- movq 4696(%rax), %r11
+ movq 4776(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4696(%rax), %r11
+ movq 4776(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22155,10 +22557,10 @@ GL_PREFIX(_dispatch_stub_587):
popq %rbp
popq %rsi
popq %rdi
- movq 4696(%rax), %r11
+ movq 4776(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_587), .-GL_PREFIX(_dispatch_stub_587)
+ .size GL_PREFIX(_dispatch_stub_597), .-GL_PREFIX(_dispatch_stub_597)
.p2align 4,,15
.globl GL_PREFIX(SecondaryColor3bEXT)
@@ -22166,7 +22568,7 @@ GL_PREFIX(_dispatch_stub_587):
GL_PREFIX(SecondaryColor3bEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4704(%rax), %r11
+ movq 4784(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22176,13 +22578,13 @@ GL_PREFIX(SecondaryColor3bEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4704(%rax), %r11
+ movq 4784(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4704(%rax), %r11
+ movq 4784(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22192,7 +22594,7 @@ GL_PREFIX(SecondaryColor3bEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4704(%rax), %r11
+ movq 4784(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3bEXT), .-GL_PREFIX(SecondaryColor3bEXT)
@@ -22203,25 +22605,25 @@ GL_PREFIX(SecondaryColor3bEXT):
GL_PREFIX(SecondaryColor3bvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4712(%rax), %r11
+ movq 4792(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4712(%rax), %r11
+ movq 4792(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4712(%rax), %r11
+ movq 4792(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4712(%rax), %r11
+ movq 4792(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3bvEXT), .-GL_PREFIX(SecondaryColor3bvEXT)
@@ -22232,7 +22634,7 @@ GL_PREFIX(SecondaryColor3bvEXT):
GL_PREFIX(SecondaryColor3dEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4720(%rax), %r11
+ movq 4800(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -22244,13 +22646,13 @@ GL_PREFIX(SecondaryColor3dEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4720(%rax), %r11
+ movq 4800(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4720(%rax), %r11
+ movq 4800(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -22262,7 +22664,7 @@ GL_PREFIX(SecondaryColor3dEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4720(%rax), %r11
+ movq 4800(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3dEXT), .-GL_PREFIX(SecondaryColor3dEXT)
@@ -22273,25 +22675,25 @@ GL_PREFIX(SecondaryColor3dEXT):
GL_PREFIX(SecondaryColor3dvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4728(%rax), %r11
+ movq 4808(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4728(%rax), %r11
+ movq 4808(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4728(%rax), %r11
+ movq 4808(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4728(%rax), %r11
+ movq 4808(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3dvEXT), .-GL_PREFIX(SecondaryColor3dvEXT)
@@ -22302,7 +22704,7 @@ GL_PREFIX(SecondaryColor3dvEXT):
GL_PREFIX(SecondaryColor3fEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4736(%rax), %r11
+ movq 4816(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -22314,13 +22716,13 @@ GL_PREFIX(SecondaryColor3fEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4736(%rax), %r11
+ movq 4816(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4736(%rax), %r11
+ movq 4816(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -22332,7 +22734,7 @@ GL_PREFIX(SecondaryColor3fEXT):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 4736(%rax), %r11
+ movq 4816(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3fEXT), .-GL_PREFIX(SecondaryColor3fEXT)
@@ -22343,25 +22745,25 @@ GL_PREFIX(SecondaryColor3fEXT):
GL_PREFIX(SecondaryColor3fvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4744(%rax), %r11
+ movq 4824(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4744(%rax), %r11
+ movq 4824(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4744(%rax), %r11
+ movq 4824(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4744(%rax), %r11
+ movq 4824(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3fvEXT), .-GL_PREFIX(SecondaryColor3fvEXT)
@@ -22372,7 +22774,7 @@ GL_PREFIX(SecondaryColor3fvEXT):
GL_PREFIX(SecondaryColor3iEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4752(%rax), %r11
+ movq 4832(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22382,13 +22784,13 @@ GL_PREFIX(SecondaryColor3iEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4752(%rax), %r11
+ movq 4832(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4752(%rax), %r11
+ movq 4832(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22398,7 +22800,7 @@ GL_PREFIX(SecondaryColor3iEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4752(%rax), %r11
+ movq 4832(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3iEXT), .-GL_PREFIX(SecondaryColor3iEXT)
@@ -22409,25 +22811,25 @@ GL_PREFIX(SecondaryColor3iEXT):
GL_PREFIX(SecondaryColor3ivEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4760(%rax), %r11
+ movq 4840(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4760(%rax), %r11
+ movq 4840(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4760(%rax), %r11
+ movq 4840(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4760(%rax), %r11
+ movq 4840(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3ivEXT), .-GL_PREFIX(SecondaryColor3ivEXT)
@@ -22438,7 +22840,7 @@ GL_PREFIX(SecondaryColor3ivEXT):
GL_PREFIX(SecondaryColor3sEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4768(%rax), %r11
+ movq 4848(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22448,13 +22850,13 @@ GL_PREFIX(SecondaryColor3sEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4768(%rax), %r11
+ movq 4848(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4768(%rax), %r11
+ movq 4848(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22464,7 +22866,7 @@ GL_PREFIX(SecondaryColor3sEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4768(%rax), %r11
+ movq 4848(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3sEXT), .-GL_PREFIX(SecondaryColor3sEXT)
@@ -22475,25 +22877,25 @@ GL_PREFIX(SecondaryColor3sEXT):
GL_PREFIX(SecondaryColor3svEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4776(%rax), %r11
+ movq 4856(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4776(%rax), %r11
+ movq 4856(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4776(%rax), %r11
+ movq 4856(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4776(%rax), %r11
+ movq 4856(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3svEXT), .-GL_PREFIX(SecondaryColor3svEXT)
@@ -22504,7 +22906,7 @@ GL_PREFIX(SecondaryColor3svEXT):
GL_PREFIX(SecondaryColor3ubEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4784(%rax), %r11
+ movq 4864(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22514,13 +22916,13 @@ GL_PREFIX(SecondaryColor3ubEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4784(%rax), %r11
+ movq 4864(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4784(%rax), %r11
+ movq 4864(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22530,7 +22932,7 @@ GL_PREFIX(SecondaryColor3ubEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4784(%rax), %r11
+ movq 4864(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3ubEXT), .-GL_PREFIX(SecondaryColor3ubEXT)
@@ -22541,25 +22943,25 @@ GL_PREFIX(SecondaryColor3ubEXT):
GL_PREFIX(SecondaryColor3ubvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4792(%rax), %r11
+ movq 4872(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4792(%rax), %r11
+ movq 4872(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4792(%rax), %r11
+ movq 4872(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4792(%rax), %r11
+ movq 4872(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3ubvEXT), .-GL_PREFIX(SecondaryColor3ubvEXT)
@@ -22570,7 +22972,7 @@ GL_PREFIX(SecondaryColor3ubvEXT):
GL_PREFIX(SecondaryColor3uiEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4800(%rax), %r11
+ movq 4880(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22580,13 +22982,13 @@ GL_PREFIX(SecondaryColor3uiEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4800(%rax), %r11
+ movq 4880(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4800(%rax), %r11
+ movq 4880(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22596,7 +22998,7 @@ GL_PREFIX(SecondaryColor3uiEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4800(%rax), %r11
+ movq 4880(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3uiEXT), .-GL_PREFIX(SecondaryColor3uiEXT)
@@ -22607,25 +23009,25 @@ GL_PREFIX(SecondaryColor3uiEXT):
GL_PREFIX(SecondaryColor3uivEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4808(%rax), %r11
+ movq 4888(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4808(%rax), %r11
+ movq 4888(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4808(%rax), %r11
+ movq 4888(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4808(%rax), %r11
+ movq 4888(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3uivEXT), .-GL_PREFIX(SecondaryColor3uivEXT)
@@ -22636,7 +23038,7 @@ GL_PREFIX(SecondaryColor3uivEXT):
GL_PREFIX(SecondaryColor3usEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4816(%rax), %r11
+ movq 4896(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22646,13 +23048,13 @@ GL_PREFIX(SecondaryColor3usEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4816(%rax), %r11
+ movq 4896(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4816(%rax), %r11
+ movq 4896(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22662,7 +23064,7 @@ GL_PREFIX(SecondaryColor3usEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4816(%rax), %r11
+ movq 4896(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3usEXT), .-GL_PREFIX(SecondaryColor3usEXT)
@@ -22673,25 +23075,25 @@ GL_PREFIX(SecondaryColor3usEXT):
GL_PREFIX(SecondaryColor3usvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4824(%rax), %r11
+ movq 4904(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4824(%rax), %r11
+ movq 4904(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4824(%rax), %r11
+ movq 4904(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4824(%rax), %r11
+ movq 4904(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColor3usvEXT), .-GL_PREFIX(SecondaryColor3usvEXT)
@@ -22702,7 +23104,7 @@ GL_PREFIX(SecondaryColor3usvEXT):
GL_PREFIX(SecondaryColorPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4832(%rax), %r11
+ movq 4912(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22716,13 +23118,13 @@ GL_PREFIX(SecondaryColorPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4832(%rax), %r11
+ movq 4912(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4832(%rax), %r11
+ movq 4912(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22736,7 +23138,7 @@ GL_PREFIX(SecondaryColorPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4832(%rax), %r11
+ movq 4912(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SecondaryColorPointerEXT), .-GL_PREFIX(SecondaryColorPointerEXT)
@@ -22747,7 +23149,7 @@ GL_PREFIX(SecondaryColorPointerEXT):
GL_PREFIX(MultiDrawArraysEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4840(%rax), %r11
+ movq 4920(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22761,13 +23163,13 @@ GL_PREFIX(MultiDrawArraysEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4840(%rax), %r11
+ movq 4920(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4840(%rax), %r11
+ movq 4920(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22781,7 +23183,7 @@ GL_PREFIX(MultiDrawArraysEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4840(%rax), %r11
+ movq 4920(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(MultiDrawArraysEXT), .-GL_PREFIX(MultiDrawArraysEXT)
@@ -22792,7 +23194,7 @@ GL_PREFIX(MultiDrawArraysEXT):
GL_PREFIX(MultiDrawElementsEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4848(%rax), %r11
+ movq 4928(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22806,13 +23208,13 @@ GL_PREFIX(MultiDrawElementsEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4848(%rax), %r11
+ movq 4928(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4848(%rax), %r11
+ movq 4928(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22826,7 +23228,7 @@ GL_PREFIX(MultiDrawElementsEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4848(%rax), %r11
+ movq 4928(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(MultiDrawElementsEXT), .-GL_PREFIX(MultiDrawElementsEXT)
@@ -22837,7 +23239,7 @@ GL_PREFIX(MultiDrawElementsEXT):
GL_PREFIX(FogCoordPointerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4856(%rax), %r11
+ movq 4936(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -22847,13 +23249,13 @@ GL_PREFIX(FogCoordPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4856(%rax), %r11
+ movq 4936(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4856(%rax), %r11
+ movq 4936(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -22863,7 +23265,7 @@ GL_PREFIX(FogCoordPointerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4856(%rax), %r11
+ movq 4936(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FogCoordPointerEXT), .-GL_PREFIX(FogCoordPointerEXT)
@@ -22874,7 +23276,7 @@ GL_PREFIX(FogCoordPointerEXT):
GL_PREFIX(FogCoorddEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4864(%rax), %r11
+ movq 4944(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $8, %rsp
@@ -22882,13 +23284,13 @@ GL_PREFIX(FogCoorddEXT):
call _x86_64_get_dispatch@PLT
movq (%rsp), %xmm0
addq $8, %rsp
- movq 4864(%rax), %r11
+ movq 4944(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4864(%rax), %r11
+ movq 4944(%rax), %r11
jmp *%r11
1:
subq $8, %rsp
@@ -22896,7 +23298,7 @@ GL_PREFIX(FogCoorddEXT):
call _glapi_get_dispatch
movq (%rsp), %xmm0
addq $8, %rsp
- movq 4864(%rax), %r11
+ movq 4944(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FogCoorddEXT), .-GL_PREFIX(FogCoorddEXT)
@@ -22907,25 +23309,25 @@ GL_PREFIX(FogCoorddEXT):
GL_PREFIX(FogCoorddvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4872(%rax), %r11
+ movq 4952(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4872(%rax), %r11
+ movq 4952(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4872(%rax), %r11
+ movq 4952(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4872(%rax), %r11
+ movq 4952(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FogCoorddvEXT), .-GL_PREFIX(FogCoorddvEXT)
@@ -22936,7 +23338,7 @@ GL_PREFIX(FogCoorddvEXT):
GL_PREFIX(FogCoordfEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4880(%rax), %r11
+ movq 4960(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $8, %rsp
@@ -22944,13 +23346,13 @@ GL_PREFIX(FogCoordfEXT):
call _x86_64_get_dispatch@PLT
movq (%rsp), %xmm0
addq $8, %rsp
- movq 4880(%rax), %r11
+ movq 4960(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4880(%rax), %r11
+ movq 4960(%rax), %r11
jmp *%r11
1:
subq $8, %rsp
@@ -22958,7 +23360,7 @@ GL_PREFIX(FogCoordfEXT):
call _glapi_get_dispatch
movq (%rsp), %xmm0
addq $8, %rsp
- movq 4880(%rax), %r11
+ movq 4960(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FogCoordfEXT), .-GL_PREFIX(FogCoordfEXT)
@@ -22969,58 +23371,58 @@ GL_PREFIX(FogCoordfEXT):
GL_PREFIX(FogCoordfvEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4888(%rax), %r11
+ movq 4968(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4888(%rax), %r11
+ movq 4968(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4888(%rax), %r11
+ movq 4968(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4888(%rax), %r11
+ movq 4968(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FogCoordfvEXT), .-GL_PREFIX(FogCoordfvEXT)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_612)
- .type GL_PREFIX(_dispatch_stub_612), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_612))
-GL_PREFIX(_dispatch_stub_612):
+ .globl GL_PREFIX(_dispatch_stub_622)
+ .type GL_PREFIX(_dispatch_stub_622), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_622))
+GL_PREFIX(_dispatch_stub_622):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4896(%rax), %r11
+ movq 4976(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 4896(%rax), %r11
+ movq 4976(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4896(%rax), %r11
+ movq 4976(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 4896(%rax), %r11
+ movq 4976(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_612), .-GL_PREFIX(_dispatch_stub_612)
+ .size GL_PREFIX(_dispatch_stub_622), .-GL_PREFIX(_dispatch_stub_622)
.p2align 4,,15
.globl GL_PREFIX(BlendFuncSeparateEXT)
@@ -23028,7 +23430,7 @@ GL_PREFIX(_dispatch_stub_612):
GL_PREFIX(BlendFuncSeparateEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4904(%rax), %r11
+ movq 4984(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23042,13 +23444,13 @@ GL_PREFIX(BlendFuncSeparateEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4904(%rax), %r11
+ movq 4984(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4904(%rax), %r11
+ movq 4984(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23062,7 +23464,7 @@ GL_PREFIX(BlendFuncSeparateEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 4904(%rax), %r11
+ movq 4984(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BlendFuncSeparateEXT), .-GL_PREFIX(BlendFuncSeparateEXT)
@@ -23073,25 +23475,25 @@ GL_PREFIX(BlendFuncSeparateEXT):
GL_PREFIX(FlushVertexArrayRangeNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4912(%rax), %r11
+ movq 4992(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rbp
call _x86_64_get_dispatch@PLT
popq %rbp
- movq 4912(%rax), %r11
+ movq 4992(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4912(%rax), %r11
+ movq 4992(%rax), %r11
jmp *%r11
1:
pushq %rbp
call _glapi_get_dispatch
popq %rbp
- movq 4912(%rax), %r11
+ movq 4992(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FlushVertexArrayRangeNV), .-GL_PREFIX(FlushVertexArrayRangeNV)
@@ -23102,7 +23504,7 @@ GL_PREFIX(FlushVertexArrayRangeNV):
GL_PREFIX(VertexArrayRangeNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4920(%rax), %r11
+ movq 5000(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23112,13 +23514,13 @@ GL_PREFIX(VertexArrayRangeNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4920(%rax), %r11
+ movq 5000(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4920(%rax), %r11
+ movq 5000(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23128,7 +23530,7 @@ GL_PREFIX(VertexArrayRangeNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4920(%rax), %r11
+ movq 5000(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexArrayRangeNV), .-GL_PREFIX(VertexArrayRangeNV)
@@ -23139,7 +23541,7 @@ GL_PREFIX(VertexArrayRangeNV):
GL_PREFIX(CombinerInputNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4928(%rax), %r11
+ movq 5008(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23157,13 +23559,13 @@ GL_PREFIX(CombinerInputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4928(%rax), %r11
+ movq 5008(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4928(%rax), %r11
+ movq 5008(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23181,7 +23583,7 @@ GL_PREFIX(CombinerInputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4928(%rax), %r11
+ movq 5008(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerInputNV), .-GL_PREFIX(CombinerInputNV)
@@ -23192,7 +23594,7 @@ GL_PREFIX(CombinerInputNV):
GL_PREFIX(CombinerOutputNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4936(%rax), %r11
+ movq 5016(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23210,13 +23612,13 @@ GL_PREFIX(CombinerOutputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4936(%rax), %r11
+ movq 5016(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4936(%rax), %r11
+ movq 5016(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23234,7 +23636,7 @@ GL_PREFIX(CombinerOutputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4936(%rax), %r11
+ movq 5016(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerOutputNV), .-GL_PREFIX(CombinerOutputNV)
@@ -23245,7 +23647,7 @@ GL_PREFIX(CombinerOutputNV):
GL_PREFIX(CombinerParameterfNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4944(%rax), %r11
+ movq 5024(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -23255,13 +23657,13 @@ GL_PREFIX(CombinerParameterfNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4944(%rax), %r11
+ movq 5024(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4944(%rax), %r11
+ movq 5024(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -23271,7 +23673,7 @@ GL_PREFIX(CombinerParameterfNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 4944(%rax), %r11
+ movq 5024(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerParameterfNV), .-GL_PREFIX(CombinerParameterfNV)
@@ -23282,7 +23684,7 @@ GL_PREFIX(CombinerParameterfNV):
GL_PREFIX(CombinerParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4952(%rax), %r11
+ movq 5032(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23292,13 +23694,13 @@ GL_PREFIX(CombinerParameterfvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4952(%rax), %r11
+ movq 5032(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4952(%rax), %r11
+ movq 5032(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23308,7 +23710,7 @@ GL_PREFIX(CombinerParameterfvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4952(%rax), %r11
+ movq 5032(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerParameterfvNV), .-GL_PREFIX(CombinerParameterfvNV)
@@ -23319,7 +23721,7 @@ GL_PREFIX(CombinerParameterfvNV):
GL_PREFIX(CombinerParameteriNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4960(%rax), %r11
+ movq 5040(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23329,13 +23731,13 @@ GL_PREFIX(CombinerParameteriNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4960(%rax), %r11
+ movq 5040(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4960(%rax), %r11
+ movq 5040(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23345,7 +23747,7 @@ GL_PREFIX(CombinerParameteriNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4960(%rax), %r11
+ movq 5040(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerParameteriNV), .-GL_PREFIX(CombinerParameteriNV)
@@ -23356,7 +23758,7 @@ GL_PREFIX(CombinerParameteriNV):
GL_PREFIX(CombinerParameterivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4968(%rax), %r11
+ movq 5048(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23366,13 +23768,13 @@ GL_PREFIX(CombinerParameterivNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4968(%rax), %r11
+ movq 5048(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4968(%rax), %r11
+ movq 5048(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23382,7 +23784,7 @@ GL_PREFIX(CombinerParameterivNV):
popq %rbp
popq %rsi
popq %rdi
- movq 4968(%rax), %r11
+ movq 5048(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CombinerParameterivNV), .-GL_PREFIX(CombinerParameterivNV)
@@ -23393,7 +23795,7 @@ GL_PREFIX(CombinerParameterivNV):
GL_PREFIX(FinalCombinerInputNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4976(%rax), %r11
+ movq 5056(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23407,13 +23809,13 @@ GL_PREFIX(FinalCombinerInputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4976(%rax), %r11
+ movq 5056(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4976(%rax), %r11
+ movq 5056(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23427,7 +23829,7 @@ GL_PREFIX(FinalCombinerInputNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4976(%rax), %r11
+ movq 5056(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FinalCombinerInputNV), .-GL_PREFIX(FinalCombinerInputNV)
@@ -23438,7 +23840,7 @@ GL_PREFIX(FinalCombinerInputNV):
GL_PREFIX(GetCombinerInputParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4984(%rax), %r11
+ movq 5064(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23452,13 +23854,13 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4984(%rax), %r11
+ movq 5064(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4984(%rax), %r11
+ movq 5064(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23472,7 +23874,7 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4984(%rax), %r11
+ movq 5064(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetCombinerInputParameterfvNV), .-GL_PREFIX(GetCombinerInputParameterfvNV)
@@ -23483,7 +23885,7 @@ GL_PREFIX(GetCombinerInputParameterfvNV):
GL_PREFIX(GetCombinerInputParameterivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 4992(%rax), %r11
+ movq 5072(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23497,13 +23899,13 @@ GL_PREFIX(GetCombinerInputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4992(%rax), %r11
+ movq 5072(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 4992(%rax), %r11
+ movq 5072(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23517,7 +23919,7 @@ GL_PREFIX(GetCombinerInputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 4992(%rax), %r11
+ movq 5072(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetCombinerInputParameterivNV), .-GL_PREFIX(GetCombinerInputParameterivNV)
@@ -23528,7 +23930,7 @@ GL_PREFIX(GetCombinerInputParameterivNV):
GL_PREFIX(GetCombinerOutputParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5000(%rax), %r11
+ movq 5080(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23542,13 +23944,13 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5000(%rax), %r11
+ movq 5080(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5000(%rax), %r11
+ movq 5080(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23562,7 +23964,7 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5000(%rax), %r11
+ movq 5080(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetCombinerOutputParameterfvNV), .-GL_PREFIX(GetCombinerOutputParameterfvNV)
@@ -23573,7 +23975,7 @@ GL_PREFIX(GetCombinerOutputParameterfvNV):
GL_PREFIX(GetCombinerOutputParameterivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5008(%rax), %r11
+ movq 5088(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23587,13 +23989,13 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5008(%rax), %r11
+ movq 5088(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5008(%rax), %r11
+ movq 5088(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23607,7 +24009,7 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5008(%rax), %r11
+ movq 5088(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetCombinerOutputParameterivNV), .-GL_PREFIX(GetCombinerOutputParameterivNV)
@@ -23618,7 +24020,7 @@ GL_PREFIX(GetCombinerOutputParameterivNV):
GL_PREFIX(GetFinalCombinerInputParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5016(%rax), %r11
+ movq 5096(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23628,13 +24030,13 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5016(%rax), %r11
+ movq 5096(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5016(%rax), %r11
+ movq 5096(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23644,7 +24046,7 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5016(%rax), %r11
+ movq 5096(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetFinalCombinerInputParameterfvNV), .-GL_PREFIX(GetFinalCombinerInputParameterfvNV)
@@ -23655,7 +24057,7 @@ GL_PREFIX(GetFinalCombinerInputParameterfvNV):
GL_PREFIX(GetFinalCombinerInputParameterivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5024(%rax), %r11
+ movq 5104(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23665,13 +24067,13 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5024(%rax), %r11
+ movq 5104(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5024(%rax), %r11
+ movq 5104(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23681,7 +24083,7 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5024(%rax), %r11
+ movq 5104(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetFinalCombinerInputParameterivNV), .-GL_PREFIX(GetFinalCombinerInputParameterivNV)
@@ -23692,25 +24094,25 @@ GL_PREFIX(GetFinalCombinerInputParameterivNV):
GL_PREFIX(ResizeBuffersMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5032(%rax), %r11
+ movq 5112(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rbp
call _x86_64_get_dispatch@PLT
popq %rbp
- movq 5032(%rax), %r11
+ movq 5112(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5032(%rax), %r11
+ movq 5112(%rax), %r11
jmp *%r11
1:
pushq %rbp
call _glapi_get_dispatch
popq %rbp
- movq 5032(%rax), %r11
+ movq 5112(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ResizeBuffersMESA), .-GL_PREFIX(ResizeBuffersMESA)
@@ -23721,7 +24123,7 @@ GL_PREFIX(ResizeBuffersMESA):
GL_PREFIX(WindowPos2dMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5040(%rax), %r11
+ movq 5120(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -23731,13 +24133,13 @@ GL_PREFIX(WindowPos2dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5040(%rax), %r11
+ movq 5120(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5040(%rax), %r11
+ movq 5120(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -23747,7 +24149,7 @@ GL_PREFIX(WindowPos2dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5040(%rax), %r11
+ movq 5120(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2dMESA), .-GL_PREFIX(WindowPos2dMESA)
@@ -23758,25 +24160,25 @@ GL_PREFIX(WindowPos2dMESA):
GL_PREFIX(WindowPos2dvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5048(%rax), %r11
+ movq 5128(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5048(%rax), %r11
+ movq 5128(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5048(%rax), %r11
+ movq 5128(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5048(%rax), %r11
+ movq 5128(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2dvMESA), .-GL_PREFIX(WindowPos2dvMESA)
@@ -23787,7 +24189,7 @@ GL_PREFIX(WindowPos2dvMESA):
GL_PREFIX(WindowPos2fMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5056(%rax), %r11
+ movq 5136(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -23797,13 +24199,13 @@ GL_PREFIX(WindowPos2fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5056(%rax), %r11
+ movq 5136(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5056(%rax), %r11
+ movq 5136(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -23813,7 +24215,7 @@ GL_PREFIX(WindowPos2fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5056(%rax), %r11
+ movq 5136(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2fMESA), .-GL_PREFIX(WindowPos2fMESA)
@@ -23824,25 +24226,25 @@ GL_PREFIX(WindowPos2fMESA):
GL_PREFIX(WindowPos2fvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5064(%rax), %r11
+ movq 5144(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5064(%rax), %r11
+ movq 5144(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5064(%rax), %r11
+ movq 5144(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5064(%rax), %r11
+ movq 5144(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2fvMESA), .-GL_PREFIX(WindowPos2fvMESA)
@@ -23853,7 +24255,7 @@ GL_PREFIX(WindowPos2fvMESA):
GL_PREFIX(WindowPos2iMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5072(%rax), %r11
+ movq 5152(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23863,13 +24265,13 @@ GL_PREFIX(WindowPos2iMESA):
popq %rbp
popq %rsi
popq %rdi
- movq 5072(%rax), %r11
+ movq 5152(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5072(%rax), %r11
+ movq 5152(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23879,7 +24281,7 @@ GL_PREFIX(WindowPos2iMESA):
popq %rbp
popq %rsi
popq %rdi
- movq 5072(%rax), %r11
+ movq 5152(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2iMESA), .-GL_PREFIX(WindowPos2iMESA)
@@ -23890,25 +24292,25 @@ GL_PREFIX(WindowPos2iMESA):
GL_PREFIX(WindowPos2ivMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5080(%rax), %r11
+ movq 5160(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5080(%rax), %r11
+ movq 5160(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5080(%rax), %r11
+ movq 5160(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5080(%rax), %r11
+ movq 5160(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2ivMESA), .-GL_PREFIX(WindowPos2ivMESA)
@@ -23919,7 +24321,7 @@ GL_PREFIX(WindowPos2ivMESA):
GL_PREFIX(WindowPos2sMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5088(%rax), %r11
+ movq 5168(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -23929,13 +24331,13 @@ GL_PREFIX(WindowPos2sMESA):
popq %rbp
popq %rsi
popq %rdi
- movq 5088(%rax), %r11
+ movq 5168(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5088(%rax), %r11
+ movq 5168(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -23945,7 +24347,7 @@ GL_PREFIX(WindowPos2sMESA):
popq %rbp
popq %rsi
popq %rdi
- movq 5088(%rax), %r11
+ movq 5168(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2sMESA), .-GL_PREFIX(WindowPos2sMESA)
@@ -23956,25 +24358,25 @@ GL_PREFIX(WindowPos2sMESA):
GL_PREFIX(WindowPos2svMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5096(%rax), %r11
+ movq 5176(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5096(%rax), %r11
+ movq 5176(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5096(%rax), %r11
+ movq 5176(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5096(%rax), %r11
+ movq 5176(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos2svMESA), .-GL_PREFIX(WindowPos2svMESA)
@@ -23985,7 +24387,7 @@ GL_PREFIX(WindowPos2svMESA):
GL_PREFIX(WindowPos3dMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5104(%rax), %r11
+ movq 5184(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -23997,13 +24399,13 @@ GL_PREFIX(WindowPos3dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5104(%rax), %r11
+ movq 5184(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5104(%rax), %r11
+ movq 5184(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -24015,7 +24417,7 @@ GL_PREFIX(WindowPos3dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5104(%rax), %r11
+ movq 5184(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3dMESA), .-GL_PREFIX(WindowPos3dMESA)
@@ -24026,25 +24428,25 @@ GL_PREFIX(WindowPos3dMESA):
GL_PREFIX(WindowPos3dvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5112(%rax), %r11
+ movq 5192(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5112(%rax), %r11
+ movq 5192(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5112(%rax), %r11
+ movq 5192(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5112(%rax), %r11
+ movq 5192(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3dvMESA), .-GL_PREFIX(WindowPos3dvMESA)
@@ -24055,7 +24457,7 @@ GL_PREFIX(WindowPos3dvMESA):
GL_PREFIX(WindowPos3fMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5120(%rax), %r11
+ movq 5200(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -24067,13 +24469,13 @@ GL_PREFIX(WindowPos3fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5120(%rax), %r11
+ movq 5200(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5120(%rax), %r11
+ movq 5200(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -24085,7 +24487,7 @@ GL_PREFIX(WindowPos3fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $24, %rsp
- movq 5120(%rax), %r11
+ movq 5200(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3fMESA), .-GL_PREFIX(WindowPos3fMESA)
@@ -24096,25 +24498,25 @@ GL_PREFIX(WindowPos3fMESA):
GL_PREFIX(WindowPos3fvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5128(%rax), %r11
+ movq 5208(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5128(%rax), %r11
+ movq 5208(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5128(%rax), %r11
+ movq 5208(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5128(%rax), %r11
+ movq 5208(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3fvMESA), .-GL_PREFIX(WindowPos3fvMESA)
@@ -24125,7 +24527,7 @@ GL_PREFIX(WindowPos3fvMESA):
GL_PREFIX(WindowPos3iMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5136(%rax), %r11
+ movq 5216(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24135,13 +24537,13 @@ GL_PREFIX(WindowPos3iMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5136(%rax), %r11
+ movq 5216(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5136(%rax), %r11
+ movq 5216(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24151,7 +24553,7 @@ GL_PREFIX(WindowPos3iMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5136(%rax), %r11
+ movq 5216(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3iMESA), .-GL_PREFIX(WindowPos3iMESA)
@@ -24162,25 +24564,25 @@ GL_PREFIX(WindowPos3iMESA):
GL_PREFIX(WindowPos3ivMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5144(%rax), %r11
+ movq 5224(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5144(%rax), %r11
+ movq 5224(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5144(%rax), %r11
+ movq 5224(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5144(%rax), %r11
+ movq 5224(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3ivMESA), .-GL_PREFIX(WindowPos3ivMESA)
@@ -24191,7 +24593,7 @@ GL_PREFIX(WindowPos3ivMESA):
GL_PREFIX(WindowPos3sMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5152(%rax), %r11
+ movq 5232(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24201,13 +24603,13 @@ GL_PREFIX(WindowPos3sMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5152(%rax), %r11
+ movq 5232(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5152(%rax), %r11
+ movq 5232(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24217,7 +24619,7 @@ GL_PREFIX(WindowPos3sMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5152(%rax), %r11
+ movq 5232(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3sMESA), .-GL_PREFIX(WindowPos3sMESA)
@@ -24228,25 +24630,25 @@ GL_PREFIX(WindowPos3sMESA):
GL_PREFIX(WindowPos3svMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5160(%rax), %r11
+ movq 5240(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5160(%rax), %r11
+ movq 5240(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5160(%rax), %r11
+ movq 5240(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5160(%rax), %r11
+ movq 5240(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos3svMESA), .-GL_PREFIX(WindowPos3svMESA)
@@ -24257,7 +24659,7 @@ GL_PREFIX(WindowPos3svMESA):
GL_PREFIX(WindowPos4dMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5168(%rax), %r11
+ movq 5248(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -24271,13 +24673,13 @@ GL_PREFIX(WindowPos4dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $40, %rsp
- movq 5168(%rax), %r11
+ movq 5248(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5168(%rax), %r11
+ movq 5248(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -24291,7 +24693,7 @@ GL_PREFIX(WindowPos4dMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $40, %rsp
- movq 5168(%rax), %r11
+ movq 5248(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4dMESA), .-GL_PREFIX(WindowPos4dMESA)
@@ -24302,25 +24704,25 @@ GL_PREFIX(WindowPos4dMESA):
GL_PREFIX(WindowPos4dvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5176(%rax), %r11
+ movq 5256(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5176(%rax), %r11
+ movq 5256(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5176(%rax), %r11
+ movq 5256(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5176(%rax), %r11
+ movq 5256(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4dvMESA), .-GL_PREFIX(WindowPos4dvMESA)
@@ -24331,7 +24733,7 @@ GL_PREFIX(WindowPos4dvMESA):
GL_PREFIX(WindowPos4fMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5184(%rax), %r11
+ movq 5264(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -24345,13 +24747,13 @@ GL_PREFIX(WindowPos4fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $40, %rsp
- movq 5184(%rax), %r11
+ movq 5264(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5184(%rax), %r11
+ movq 5264(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -24365,7 +24767,7 @@ GL_PREFIX(WindowPos4fMESA):
movq 8(%rsp), %xmm1
movq (%rsp), %xmm0
addq $40, %rsp
- movq 5184(%rax), %r11
+ movq 5264(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4fMESA), .-GL_PREFIX(WindowPos4fMESA)
@@ -24376,25 +24778,25 @@ GL_PREFIX(WindowPos4fMESA):
GL_PREFIX(WindowPos4fvMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5192(%rax), %r11
+ movq 5272(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5192(%rax), %r11
+ movq 5272(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5192(%rax), %r11
+ movq 5272(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5192(%rax), %r11
+ movq 5272(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4fvMESA), .-GL_PREFIX(WindowPos4fvMESA)
@@ -24405,7 +24807,7 @@ GL_PREFIX(WindowPos4fvMESA):
GL_PREFIX(WindowPos4iMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5200(%rax), %r11
+ movq 5280(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24419,13 +24821,13 @@ GL_PREFIX(WindowPos4iMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5200(%rax), %r11
+ movq 5280(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5200(%rax), %r11
+ movq 5280(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24439,7 +24841,7 @@ GL_PREFIX(WindowPos4iMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5200(%rax), %r11
+ movq 5280(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4iMESA), .-GL_PREFIX(WindowPos4iMESA)
@@ -24450,25 +24852,25 @@ GL_PREFIX(WindowPos4iMESA):
GL_PREFIX(WindowPos4ivMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5208(%rax), %r11
+ movq 5288(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5208(%rax), %r11
+ movq 5288(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5208(%rax), %r11
+ movq 5288(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5208(%rax), %r11
+ movq 5288(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4ivMESA), .-GL_PREFIX(WindowPos4ivMESA)
@@ -24479,7 +24881,7 @@ GL_PREFIX(WindowPos4ivMESA):
GL_PREFIX(WindowPos4sMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5216(%rax), %r11
+ movq 5296(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24493,13 +24895,13 @@ GL_PREFIX(WindowPos4sMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5216(%rax), %r11
+ movq 5296(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5216(%rax), %r11
+ movq 5296(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24513,7 +24915,7 @@ GL_PREFIX(WindowPos4sMESA):
popq %rdx
popq %rsi
popq %rdi
- movq 5216(%rax), %r11
+ movq 5296(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4sMESA), .-GL_PREFIX(WindowPos4sMESA)
@@ -24524,37 +24926,37 @@ GL_PREFIX(WindowPos4sMESA):
GL_PREFIX(WindowPos4svMESA):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5224(%rax), %r11
+ movq 5304(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5224(%rax), %r11
+ movq 5304(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5224(%rax), %r11
+ movq 5304(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5224(%rax), %r11
+ movq 5304(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(WindowPos4svMESA), .-GL_PREFIX(WindowPos4svMESA)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_654)
- .type GL_PREFIX(_dispatch_stub_654), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_654))
-GL_PREFIX(_dispatch_stub_654):
+ .globl GL_PREFIX(_dispatch_stub_664)
+ .type GL_PREFIX(_dispatch_stub_664), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_664))
+GL_PREFIX(_dispatch_stub_664):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5232(%rax), %r11
+ movq 5312(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24568,13 +24970,13 @@ GL_PREFIX(_dispatch_stub_654):
popq %rdx
popq %rsi
popq %rdi
- movq 5232(%rax), %r11
+ movq 5312(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5232(%rax), %r11
+ movq 5312(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24588,19 +24990,19 @@ GL_PREFIX(_dispatch_stub_654):
popq %rdx
popq %rsi
popq %rdi
- movq 5232(%rax), %r11
+ movq 5312(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_654), .-GL_PREFIX(_dispatch_stub_654)
+ .size GL_PREFIX(_dispatch_stub_664), .-GL_PREFIX(_dispatch_stub_664)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_655)
- .type GL_PREFIX(_dispatch_stub_655), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_655))
-GL_PREFIX(_dispatch_stub_655):
+ .globl GL_PREFIX(_dispatch_stub_665)
+ .type GL_PREFIX(_dispatch_stub_665), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_665))
+GL_PREFIX(_dispatch_stub_665):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5240(%rax), %r11
+ movq 5320(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24618,13 +25020,13 @@ GL_PREFIX(_dispatch_stub_655):
popq %rdx
popq %rsi
popq %rdi
- movq 5240(%rax), %r11
+ movq 5320(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5240(%rax), %r11
+ movq 5320(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24642,19 +25044,19 @@ GL_PREFIX(_dispatch_stub_655):
popq %rdx
popq %rsi
popq %rdi
- movq 5240(%rax), %r11
+ movq 5320(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_655), .-GL_PREFIX(_dispatch_stub_655)
+ .size GL_PREFIX(_dispatch_stub_665), .-GL_PREFIX(_dispatch_stub_665)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_656)
- .type GL_PREFIX(_dispatch_stub_656), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_656))
-GL_PREFIX(_dispatch_stub_656):
+ .globl GL_PREFIX(_dispatch_stub_666)
+ .type GL_PREFIX(_dispatch_stub_666), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_666))
+GL_PREFIX(_dispatch_stub_666):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5248(%rax), %r11
+ movq 5328(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24664,13 +25066,13 @@ GL_PREFIX(_dispatch_stub_656):
popq %rbp
popq %rsi
popq %rdi
- movq 5248(%rax), %r11
+ movq 5328(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5248(%rax), %r11
+ movq 5328(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24680,49 +25082,49 @@ GL_PREFIX(_dispatch_stub_656):
popq %rbp
popq %rsi
popq %rdi
- movq 5248(%rax), %r11
+ movq 5328(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_656), .-GL_PREFIX(_dispatch_stub_656)
+ .size GL_PREFIX(_dispatch_stub_666), .-GL_PREFIX(_dispatch_stub_666)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_657)
- .type GL_PREFIX(_dispatch_stub_657), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_657))
-GL_PREFIX(_dispatch_stub_657):
+ .globl GL_PREFIX(_dispatch_stub_667)
+ .type GL_PREFIX(_dispatch_stub_667), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_667))
+GL_PREFIX(_dispatch_stub_667):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5256(%rax), %r11
+ movq 5336(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5256(%rax), %r11
+ movq 5336(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5256(%rax), %r11
+ movq 5336(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5256(%rax), %r11
+ movq 5336(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_657), .-GL_PREFIX(_dispatch_stub_657)
+ .size GL_PREFIX(_dispatch_stub_667), .-GL_PREFIX(_dispatch_stub_667)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_658)
- .type GL_PREFIX(_dispatch_stub_658), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_658))
-GL_PREFIX(_dispatch_stub_658):
+ .globl GL_PREFIX(_dispatch_stub_668)
+ .type GL_PREFIX(_dispatch_stub_668), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_668))
+GL_PREFIX(_dispatch_stub_668):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5264(%rax), %r11
+ movq 5344(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24732,13 +25134,13 @@ GL_PREFIX(_dispatch_stub_658):
popq %rbp
popq %rsi
popq %rdi
- movq 5264(%rax), %r11
+ movq 5344(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5264(%rax), %r11
+ movq 5344(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24748,19 +25150,19 @@ GL_PREFIX(_dispatch_stub_658):
popq %rbp
popq %rsi
popq %rdi
- movq 5264(%rax), %r11
+ movq 5344(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_658), .-GL_PREFIX(_dispatch_stub_658)
+ .size GL_PREFIX(_dispatch_stub_668), .-GL_PREFIX(_dispatch_stub_668)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_659)
- .type GL_PREFIX(_dispatch_stub_659), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_659))
-GL_PREFIX(_dispatch_stub_659):
+ .globl GL_PREFIX(_dispatch_stub_669)
+ .type GL_PREFIX(_dispatch_stub_669), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_669))
+GL_PREFIX(_dispatch_stub_669):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5272(%rax), %r11
+ movq 5352(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24770,13 +25172,13 @@ GL_PREFIX(_dispatch_stub_659):
popq %rdx
popq %rsi
popq %rdi
- movq 5272(%rax), %r11
+ movq 5352(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5272(%rax), %r11
+ movq 5352(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24786,49 +25188,49 @@ GL_PREFIX(_dispatch_stub_659):
popq %rdx
popq %rsi
popq %rdi
- movq 5272(%rax), %r11
+ movq 5352(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_659), .-GL_PREFIX(_dispatch_stub_659)
+ .size GL_PREFIX(_dispatch_stub_669), .-GL_PREFIX(_dispatch_stub_669)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_660)
- .type GL_PREFIX(_dispatch_stub_660), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_660))
-GL_PREFIX(_dispatch_stub_660):
+ .globl GL_PREFIX(_dispatch_stub_670)
+ .type GL_PREFIX(_dispatch_stub_670), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_670))
+GL_PREFIX(_dispatch_stub_670):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5280(%rax), %r11
+ movq 5360(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5280(%rax), %r11
+ movq 5360(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5280(%rax), %r11
+ movq 5360(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5280(%rax), %r11
+ movq 5360(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_660), .-GL_PREFIX(_dispatch_stub_660)
+ .size GL_PREFIX(_dispatch_stub_670), .-GL_PREFIX(_dispatch_stub_670)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_661)
- .type GL_PREFIX(_dispatch_stub_661), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_661))
-GL_PREFIX(_dispatch_stub_661):
+ .globl GL_PREFIX(_dispatch_stub_671)
+ .type GL_PREFIX(_dispatch_stub_671), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_671))
+GL_PREFIX(_dispatch_stub_671):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5288(%rax), %r11
+ movq 5368(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24838,13 +25240,13 @@ GL_PREFIX(_dispatch_stub_661):
popq %rbp
popq %rsi
popq %rdi
- movq 5288(%rax), %r11
+ movq 5368(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5288(%rax), %r11
+ movq 5368(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24854,40 +25256,40 @@ GL_PREFIX(_dispatch_stub_661):
popq %rbp
popq %rsi
popq %rdi
- movq 5288(%rax), %r11
+ movq 5368(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_661), .-GL_PREFIX(_dispatch_stub_661)
+ .size GL_PREFIX(_dispatch_stub_671), .-GL_PREFIX(_dispatch_stub_671)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_662)
- .type GL_PREFIX(_dispatch_stub_662), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_662))
-GL_PREFIX(_dispatch_stub_662):
+ .globl GL_PREFIX(_dispatch_stub_672)
+ .type GL_PREFIX(_dispatch_stub_672), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_672))
+GL_PREFIX(_dispatch_stub_672):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5296(%rax), %r11
+ movq 5376(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5296(%rax), %r11
+ movq 5376(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5296(%rax), %r11
+ movq 5376(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5296(%rax), %r11
+ movq 5376(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_662), .-GL_PREFIX(_dispatch_stub_662)
+ .size GL_PREFIX(_dispatch_stub_672), .-GL_PREFIX(_dispatch_stub_672)
.p2align 4,,15
.globl GL_PREFIX(AreProgramsResidentNV)
@@ -24895,7 +25297,7 @@ GL_PREFIX(_dispatch_stub_662):
GL_PREFIX(AreProgramsResidentNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5304(%rax), %r11
+ movq 5384(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24905,13 +25307,13 @@ GL_PREFIX(AreProgramsResidentNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5304(%rax), %r11
+ movq 5384(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5304(%rax), %r11
+ movq 5384(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24921,7 +25323,7 @@ GL_PREFIX(AreProgramsResidentNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5304(%rax), %r11
+ movq 5384(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(AreProgramsResidentNV), .-GL_PREFIX(AreProgramsResidentNV)
@@ -24932,7 +25334,7 @@ GL_PREFIX(AreProgramsResidentNV):
GL_PREFIX(BindProgramNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5312(%rax), %r11
+ movq 5392(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24942,13 +25344,13 @@ GL_PREFIX(BindProgramNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5312(%rax), %r11
+ movq 5392(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5312(%rax), %r11
+ movq 5392(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24958,7 +25360,7 @@ GL_PREFIX(BindProgramNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5312(%rax), %r11
+ movq 5392(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BindProgramNV), .-GL_PREFIX(BindProgramNV)
@@ -24969,7 +25371,7 @@ GL_PREFIX(BindProgramNV):
GL_PREFIX(DeleteProgramsNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5320(%rax), %r11
+ movq 5400(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -24979,13 +25381,13 @@ GL_PREFIX(DeleteProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5320(%rax), %r11
+ movq 5400(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5320(%rax), %r11
+ movq 5400(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -24995,7 +25397,7 @@ GL_PREFIX(DeleteProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5320(%rax), %r11
+ movq 5400(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(DeleteProgramsNV), .-GL_PREFIX(DeleteProgramsNV)
@@ -25006,7 +25408,7 @@ GL_PREFIX(DeleteProgramsNV):
GL_PREFIX(ExecuteProgramNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5328(%rax), %r11
+ movq 5408(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25016,13 +25418,13 @@ GL_PREFIX(ExecuteProgramNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5328(%rax), %r11
+ movq 5408(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5328(%rax), %r11
+ movq 5408(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25032,7 +25434,7 @@ GL_PREFIX(ExecuteProgramNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5328(%rax), %r11
+ movq 5408(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ExecuteProgramNV), .-GL_PREFIX(ExecuteProgramNV)
@@ -25043,7 +25445,7 @@ GL_PREFIX(ExecuteProgramNV):
GL_PREFIX(GenProgramsNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5336(%rax), %r11
+ movq 5416(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25053,13 +25455,13 @@ GL_PREFIX(GenProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5336(%rax), %r11
+ movq 5416(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5336(%rax), %r11
+ movq 5416(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25069,7 +25471,7 @@ GL_PREFIX(GenProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5336(%rax), %r11
+ movq 5416(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GenProgramsNV), .-GL_PREFIX(GenProgramsNV)
@@ -25080,7 +25482,7 @@ GL_PREFIX(GenProgramsNV):
GL_PREFIX(GetProgramParameterdvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5344(%rax), %r11
+ movq 5424(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25094,13 +25496,13 @@ GL_PREFIX(GetProgramParameterdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5344(%rax), %r11
+ movq 5424(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5344(%rax), %r11
+ movq 5424(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25114,7 +25516,7 @@ GL_PREFIX(GetProgramParameterdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5344(%rax), %r11
+ movq 5424(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramParameterdvNV), .-GL_PREFIX(GetProgramParameterdvNV)
@@ -25125,7 +25527,7 @@ GL_PREFIX(GetProgramParameterdvNV):
GL_PREFIX(GetProgramParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5352(%rax), %r11
+ movq 5432(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25139,13 +25541,13 @@ GL_PREFIX(GetProgramParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5352(%rax), %r11
+ movq 5432(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5352(%rax), %r11
+ movq 5432(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25159,7 +25561,7 @@ GL_PREFIX(GetProgramParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5352(%rax), %r11
+ movq 5432(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramParameterfvNV), .-GL_PREFIX(GetProgramParameterfvNV)
@@ -25170,7 +25572,7 @@ GL_PREFIX(GetProgramParameterfvNV):
GL_PREFIX(GetProgramStringNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5360(%rax), %r11
+ movq 5440(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25180,13 +25582,13 @@ GL_PREFIX(GetProgramStringNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5360(%rax), %r11
+ movq 5440(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5360(%rax), %r11
+ movq 5440(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25196,7 +25598,7 @@ GL_PREFIX(GetProgramStringNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5360(%rax), %r11
+ movq 5440(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramStringNV), .-GL_PREFIX(GetProgramStringNV)
@@ -25207,7 +25609,7 @@ GL_PREFIX(GetProgramStringNV):
GL_PREFIX(GetProgramivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5368(%rax), %r11
+ movq 5448(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25217,13 +25619,13 @@ GL_PREFIX(GetProgramivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5368(%rax), %r11
+ movq 5448(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5368(%rax), %r11
+ movq 5448(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25233,7 +25635,7 @@ GL_PREFIX(GetProgramivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5368(%rax), %r11
+ movq 5448(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramivNV), .-GL_PREFIX(GetProgramivNV)
@@ -25244,7 +25646,7 @@ GL_PREFIX(GetProgramivNV):
GL_PREFIX(GetTrackMatrixivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5376(%rax), %r11
+ movq 5456(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25258,13 +25660,13 @@ GL_PREFIX(GetTrackMatrixivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5376(%rax), %r11
+ movq 5456(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5376(%rax), %r11
+ movq 5456(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25278,7 +25680,7 @@ GL_PREFIX(GetTrackMatrixivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5376(%rax), %r11
+ movq 5456(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetTrackMatrixivNV), .-GL_PREFIX(GetTrackMatrixivNV)
@@ -25289,7 +25691,7 @@ GL_PREFIX(GetTrackMatrixivNV):
GL_PREFIX(GetVertexAttribPointervNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5384(%rax), %r11
+ movq 5464(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25299,13 +25701,13 @@ GL_PREFIX(GetVertexAttribPointervNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5384(%rax), %r11
+ movq 5464(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5384(%rax), %r11
+ movq 5464(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25315,7 +25717,7 @@ GL_PREFIX(GetVertexAttribPointervNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5384(%rax), %r11
+ movq 5464(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetVertexAttribPointervNV), .-GL_PREFIX(GetVertexAttribPointervNV)
@@ -25326,7 +25728,7 @@ GL_PREFIX(GetVertexAttribPointervNV):
GL_PREFIX(GetVertexAttribdvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5392(%rax), %r11
+ movq 5472(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25336,13 +25738,13 @@ GL_PREFIX(GetVertexAttribdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5392(%rax), %r11
+ movq 5472(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5392(%rax), %r11
+ movq 5472(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25352,7 +25754,7 @@ GL_PREFIX(GetVertexAttribdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5392(%rax), %r11
+ movq 5472(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetVertexAttribdvNV), .-GL_PREFIX(GetVertexAttribdvNV)
@@ -25363,7 +25765,7 @@ GL_PREFIX(GetVertexAttribdvNV):
GL_PREFIX(GetVertexAttribfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5400(%rax), %r11
+ movq 5480(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25373,13 +25775,13 @@ GL_PREFIX(GetVertexAttribfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5400(%rax), %r11
+ movq 5480(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5400(%rax), %r11
+ movq 5480(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25389,7 +25791,7 @@ GL_PREFIX(GetVertexAttribfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5400(%rax), %r11
+ movq 5480(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetVertexAttribfvNV), .-GL_PREFIX(GetVertexAttribfvNV)
@@ -25400,7 +25802,7 @@ GL_PREFIX(GetVertexAttribfvNV):
GL_PREFIX(GetVertexAttribivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5408(%rax), %r11
+ movq 5488(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25410,13 +25812,13 @@ GL_PREFIX(GetVertexAttribivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5408(%rax), %r11
+ movq 5488(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5408(%rax), %r11
+ movq 5488(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25426,7 +25828,7 @@ GL_PREFIX(GetVertexAttribivNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5408(%rax), %r11
+ movq 5488(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetVertexAttribivNV), .-GL_PREFIX(GetVertexAttribivNV)
@@ -25437,25 +25839,25 @@ GL_PREFIX(GetVertexAttribivNV):
GL_PREFIX(IsProgramNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5416(%rax), %r11
+ movq 5496(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5416(%rax), %r11
+ movq 5496(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5416(%rax), %r11
+ movq 5496(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5416(%rax), %r11
+ movq 5496(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(IsProgramNV), .-GL_PREFIX(IsProgramNV)
@@ -25466,7 +25868,7 @@ GL_PREFIX(IsProgramNV):
GL_PREFIX(LoadProgramNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5424(%rax), %r11
+ movq 5504(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25480,13 +25882,13 @@ GL_PREFIX(LoadProgramNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5424(%rax), %r11
+ movq 5504(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5424(%rax), %r11
+ movq 5504(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25500,7 +25902,7 @@ GL_PREFIX(LoadProgramNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5424(%rax), %r11
+ movq 5504(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(LoadProgramNV), .-GL_PREFIX(LoadProgramNV)
@@ -25511,7 +25913,7 @@ GL_PREFIX(LoadProgramNV):
GL_PREFIX(ProgramParameters4dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5432(%rax), %r11
+ movq 5512(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25525,13 +25927,13 @@ GL_PREFIX(ProgramParameters4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5432(%rax), %r11
+ movq 5512(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5432(%rax), %r11
+ movq 5512(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25545,7 +25947,7 @@ GL_PREFIX(ProgramParameters4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5432(%rax), %r11
+ movq 5512(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramParameters4dvNV), .-GL_PREFIX(ProgramParameters4dvNV)
@@ -25556,7 +25958,7 @@ GL_PREFIX(ProgramParameters4dvNV):
GL_PREFIX(ProgramParameters4fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5440(%rax), %r11
+ movq 5520(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25570,13 +25972,13 @@ GL_PREFIX(ProgramParameters4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5440(%rax), %r11
+ movq 5520(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5440(%rax), %r11
+ movq 5520(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25590,7 +25992,7 @@ GL_PREFIX(ProgramParameters4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5440(%rax), %r11
+ movq 5520(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramParameters4fvNV), .-GL_PREFIX(ProgramParameters4fvNV)
@@ -25601,7 +26003,7 @@ GL_PREFIX(ProgramParameters4fvNV):
GL_PREFIX(RequestResidentProgramsNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5448(%rax), %r11
+ movq 5528(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25611,13 +26013,13 @@ GL_PREFIX(RequestResidentProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5448(%rax), %r11
+ movq 5528(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5448(%rax), %r11
+ movq 5528(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25627,7 +26029,7 @@ GL_PREFIX(RequestResidentProgramsNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5448(%rax), %r11
+ movq 5528(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(RequestResidentProgramsNV), .-GL_PREFIX(RequestResidentProgramsNV)
@@ -25638,7 +26040,7 @@ GL_PREFIX(RequestResidentProgramsNV):
GL_PREFIX(TrackMatrixNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5456(%rax), %r11
+ movq 5536(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25652,13 +26054,13 @@ GL_PREFIX(TrackMatrixNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5456(%rax), %r11
+ movq 5536(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5456(%rax), %r11
+ movq 5536(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25672,7 +26074,7 @@ GL_PREFIX(TrackMatrixNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5456(%rax), %r11
+ movq 5536(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(TrackMatrixNV), .-GL_PREFIX(TrackMatrixNV)
@@ -25683,7 +26085,7 @@ GL_PREFIX(TrackMatrixNV):
GL_PREFIX(VertexAttrib1dNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5464(%rax), %r11
+ movq 5544(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -25693,13 +26095,13 @@ GL_PREFIX(VertexAttrib1dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5464(%rax), %r11
+ movq 5544(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5464(%rax), %r11
+ movq 5544(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -25709,7 +26111,7 @@ GL_PREFIX(VertexAttrib1dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5464(%rax), %r11
+ movq 5544(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1dNV), .-GL_PREFIX(VertexAttrib1dNV)
@@ -25720,7 +26122,7 @@ GL_PREFIX(VertexAttrib1dNV):
GL_PREFIX(VertexAttrib1dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5472(%rax), %r11
+ movq 5552(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25730,13 +26132,13 @@ GL_PREFIX(VertexAttrib1dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5472(%rax), %r11
+ movq 5552(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5472(%rax), %r11
+ movq 5552(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25746,7 +26148,7 @@ GL_PREFIX(VertexAttrib1dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5472(%rax), %r11
+ movq 5552(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1dvNV), .-GL_PREFIX(VertexAttrib1dvNV)
@@ -25757,7 +26159,7 @@ GL_PREFIX(VertexAttrib1dvNV):
GL_PREFIX(VertexAttrib1fNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5480(%rax), %r11
+ movq 5560(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -25767,13 +26169,13 @@ GL_PREFIX(VertexAttrib1fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5480(%rax), %r11
+ movq 5560(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5480(%rax), %r11
+ movq 5560(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -25783,7 +26185,7 @@ GL_PREFIX(VertexAttrib1fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5480(%rax), %r11
+ movq 5560(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1fNV), .-GL_PREFIX(VertexAttrib1fNV)
@@ -25794,7 +26196,7 @@ GL_PREFIX(VertexAttrib1fNV):
GL_PREFIX(VertexAttrib1fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5488(%rax), %r11
+ movq 5568(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25804,13 +26206,13 @@ GL_PREFIX(VertexAttrib1fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5488(%rax), %r11
+ movq 5568(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5488(%rax), %r11
+ movq 5568(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25820,7 +26222,7 @@ GL_PREFIX(VertexAttrib1fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5488(%rax), %r11
+ movq 5568(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1fvNV), .-GL_PREFIX(VertexAttrib1fvNV)
@@ -25831,7 +26233,7 @@ GL_PREFIX(VertexAttrib1fvNV):
GL_PREFIX(VertexAttrib1sNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5496(%rax), %r11
+ movq 5576(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25841,13 +26243,13 @@ GL_PREFIX(VertexAttrib1sNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5496(%rax), %r11
+ movq 5576(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5496(%rax), %r11
+ movq 5576(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25857,7 +26259,7 @@ GL_PREFIX(VertexAttrib1sNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5496(%rax), %r11
+ movq 5576(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1sNV), .-GL_PREFIX(VertexAttrib1sNV)
@@ -25868,7 +26270,7 @@ GL_PREFIX(VertexAttrib1sNV):
GL_PREFIX(VertexAttrib1svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5504(%rax), %r11
+ movq 5584(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25878,13 +26280,13 @@ GL_PREFIX(VertexAttrib1svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5504(%rax), %r11
+ movq 5584(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5504(%rax), %r11
+ movq 5584(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25894,7 +26296,7 @@ GL_PREFIX(VertexAttrib1svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5504(%rax), %r11
+ movq 5584(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib1svNV), .-GL_PREFIX(VertexAttrib1svNV)
@@ -25905,7 +26307,7 @@ GL_PREFIX(VertexAttrib1svNV):
GL_PREFIX(VertexAttrib2dNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5512(%rax), %r11
+ movq 5592(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -25917,13 +26319,13 @@ GL_PREFIX(VertexAttrib2dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5512(%rax), %r11
+ movq 5592(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5512(%rax), %r11
+ movq 5592(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -25935,7 +26337,7 @@ GL_PREFIX(VertexAttrib2dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5512(%rax), %r11
+ movq 5592(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2dNV), .-GL_PREFIX(VertexAttrib2dNV)
@@ -25946,7 +26348,7 @@ GL_PREFIX(VertexAttrib2dNV):
GL_PREFIX(VertexAttrib2dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5520(%rax), %r11
+ movq 5600(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -25956,13 +26358,13 @@ GL_PREFIX(VertexAttrib2dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5520(%rax), %r11
+ movq 5600(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5520(%rax), %r11
+ movq 5600(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -25972,7 +26374,7 @@ GL_PREFIX(VertexAttrib2dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5520(%rax), %r11
+ movq 5600(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2dvNV), .-GL_PREFIX(VertexAttrib2dvNV)
@@ -25983,7 +26385,7 @@ GL_PREFIX(VertexAttrib2dvNV):
GL_PREFIX(VertexAttrib2fNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5528(%rax), %r11
+ movq 5608(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $24, %rsp
@@ -25995,13 +26397,13 @@ GL_PREFIX(VertexAttrib2fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5528(%rax), %r11
+ movq 5608(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5528(%rax), %r11
+ movq 5608(%rax), %r11
jmp *%r11
1:
subq $24, %rsp
@@ -26013,7 +26415,7 @@ GL_PREFIX(VertexAttrib2fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $24, %rsp
- movq 5528(%rax), %r11
+ movq 5608(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2fNV), .-GL_PREFIX(VertexAttrib2fNV)
@@ -26024,7 +26426,7 @@ GL_PREFIX(VertexAttrib2fNV):
GL_PREFIX(VertexAttrib2fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5536(%rax), %r11
+ movq 5616(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26034,13 +26436,13 @@ GL_PREFIX(VertexAttrib2fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5536(%rax), %r11
+ movq 5616(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5536(%rax), %r11
+ movq 5616(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26050,7 +26452,7 @@ GL_PREFIX(VertexAttrib2fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5536(%rax), %r11
+ movq 5616(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2fvNV), .-GL_PREFIX(VertexAttrib2fvNV)
@@ -26061,7 +26463,7 @@ GL_PREFIX(VertexAttrib2fvNV):
GL_PREFIX(VertexAttrib2sNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5544(%rax), %r11
+ movq 5624(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26071,13 +26473,13 @@ GL_PREFIX(VertexAttrib2sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5544(%rax), %r11
+ movq 5624(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5544(%rax), %r11
+ movq 5624(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26087,7 +26489,7 @@ GL_PREFIX(VertexAttrib2sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5544(%rax), %r11
+ movq 5624(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2sNV), .-GL_PREFIX(VertexAttrib2sNV)
@@ -26098,7 +26500,7 @@ GL_PREFIX(VertexAttrib2sNV):
GL_PREFIX(VertexAttrib2svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5552(%rax), %r11
+ movq 5632(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26108,13 +26510,13 @@ GL_PREFIX(VertexAttrib2svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5552(%rax), %r11
+ movq 5632(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5552(%rax), %r11
+ movq 5632(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26124,7 +26526,7 @@ GL_PREFIX(VertexAttrib2svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5552(%rax), %r11
+ movq 5632(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib2svNV), .-GL_PREFIX(VertexAttrib2svNV)
@@ -26135,7 +26537,7 @@ GL_PREFIX(VertexAttrib2svNV):
GL_PREFIX(VertexAttrib3dNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5560(%rax), %r11
+ movq 5640(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -26149,13 +26551,13 @@ GL_PREFIX(VertexAttrib3dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5560(%rax), %r11
+ movq 5640(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5560(%rax), %r11
+ movq 5640(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -26169,7 +26571,7 @@ GL_PREFIX(VertexAttrib3dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5560(%rax), %r11
+ movq 5640(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3dNV), .-GL_PREFIX(VertexAttrib3dNV)
@@ -26180,7 +26582,7 @@ GL_PREFIX(VertexAttrib3dNV):
GL_PREFIX(VertexAttrib3dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5568(%rax), %r11
+ movq 5648(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26190,13 +26592,13 @@ GL_PREFIX(VertexAttrib3dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5568(%rax), %r11
+ movq 5648(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5568(%rax), %r11
+ movq 5648(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26206,7 +26608,7 @@ GL_PREFIX(VertexAttrib3dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5568(%rax), %r11
+ movq 5648(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3dvNV), .-GL_PREFIX(VertexAttrib3dvNV)
@@ -26217,7 +26619,7 @@ GL_PREFIX(VertexAttrib3dvNV):
GL_PREFIX(VertexAttrib3fNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5576(%rax), %r11
+ movq 5656(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -26231,13 +26633,13 @@ GL_PREFIX(VertexAttrib3fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5576(%rax), %r11
+ movq 5656(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5576(%rax), %r11
+ movq 5656(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -26251,7 +26653,7 @@ GL_PREFIX(VertexAttrib3fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5576(%rax), %r11
+ movq 5656(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3fNV), .-GL_PREFIX(VertexAttrib3fNV)
@@ -26262,7 +26664,7 @@ GL_PREFIX(VertexAttrib3fNV):
GL_PREFIX(VertexAttrib3fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5584(%rax), %r11
+ movq 5664(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26272,13 +26674,13 @@ GL_PREFIX(VertexAttrib3fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5584(%rax), %r11
+ movq 5664(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5584(%rax), %r11
+ movq 5664(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26288,7 +26690,7 @@ GL_PREFIX(VertexAttrib3fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5584(%rax), %r11
+ movq 5664(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3fvNV), .-GL_PREFIX(VertexAttrib3fvNV)
@@ -26299,7 +26701,7 @@ GL_PREFIX(VertexAttrib3fvNV):
GL_PREFIX(VertexAttrib3sNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5592(%rax), %r11
+ movq 5672(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26313,13 +26715,13 @@ GL_PREFIX(VertexAttrib3sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5592(%rax), %r11
+ movq 5672(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5592(%rax), %r11
+ movq 5672(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26333,7 +26735,7 @@ GL_PREFIX(VertexAttrib3sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5592(%rax), %r11
+ movq 5672(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3sNV), .-GL_PREFIX(VertexAttrib3sNV)
@@ -26344,7 +26746,7 @@ GL_PREFIX(VertexAttrib3sNV):
GL_PREFIX(VertexAttrib3svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5600(%rax), %r11
+ movq 5680(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26354,13 +26756,13 @@ GL_PREFIX(VertexAttrib3svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5600(%rax), %r11
+ movq 5680(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5600(%rax), %r11
+ movq 5680(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26370,7 +26772,7 @@ GL_PREFIX(VertexAttrib3svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5600(%rax), %r11
+ movq 5680(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib3svNV), .-GL_PREFIX(VertexAttrib3svNV)
@@ -26381,7 +26783,7 @@ GL_PREFIX(VertexAttrib3svNV):
GL_PREFIX(VertexAttrib4dNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5608(%rax), %r11
+ movq 5688(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -26397,13 +26799,13 @@ GL_PREFIX(VertexAttrib4dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5608(%rax), %r11
+ movq 5688(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5608(%rax), %r11
+ movq 5688(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -26419,7 +26821,7 @@ GL_PREFIX(VertexAttrib4dNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5608(%rax), %r11
+ movq 5688(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4dNV), .-GL_PREFIX(VertexAttrib4dNV)
@@ -26430,7 +26832,7 @@ GL_PREFIX(VertexAttrib4dNV):
GL_PREFIX(VertexAttrib4dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5616(%rax), %r11
+ movq 5696(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26440,13 +26842,13 @@ GL_PREFIX(VertexAttrib4dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5616(%rax), %r11
+ movq 5696(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5616(%rax), %r11
+ movq 5696(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26456,7 +26858,7 @@ GL_PREFIX(VertexAttrib4dvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5616(%rax), %r11
+ movq 5696(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4dvNV), .-GL_PREFIX(VertexAttrib4dvNV)
@@ -26467,7 +26869,7 @@ GL_PREFIX(VertexAttrib4dvNV):
GL_PREFIX(VertexAttrib4fNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5624(%rax), %r11
+ movq 5704(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $40, %rsp
@@ -26483,13 +26885,13 @@ GL_PREFIX(VertexAttrib4fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5624(%rax), %r11
+ movq 5704(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5624(%rax), %r11
+ movq 5704(%rax), %r11
jmp *%r11
1:
subq $40, %rsp
@@ -26505,7 +26907,7 @@ GL_PREFIX(VertexAttrib4fNV):
movq 8(%rsp), %xmm0
movq (%rsp), %rdi
addq $40, %rsp
- movq 5624(%rax), %r11
+ movq 5704(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4fNV), .-GL_PREFIX(VertexAttrib4fNV)
@@ -26516,7 +26918,7 @@ GL_PREFIX(VertexAttrib4fNV):
GL_PREFIX(VertexAttrib4fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5632(%rax), %r11
+ movq 5712(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26526,13 +26928,13 @@ GL_PREFIX(VertexAttrib4fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5632(%rax), %r11
+ movq 5712(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5632(%rax), %r11
+ movq 5712(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26542,7 +26944,7 @@ GL_PREFIX(VertexAttrib4fvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5632(%rax), %r11
+ movq 5712(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4fvNV), .-GL_PREFIX(VertexAttrib4fvNV)
@@ -26553,7 +26955,7 @@ GL_PREFIX(VertexAttrib4fvNV):
GL_PREFIX(VertexAttrib4sNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5640(%rax), %r11
+ movq 5720(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26567,13 +26969,13 @@ GL_PREFIX(VertexAttrib4sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5640(%rax), %r11
+ movq 5720(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5640(%rax), %r11
+ movq 5720(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26587,7 +26989,7 @@ GL_PREFIX(VertexAttrib4sNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5640(%rax), %r11
+ movq 5720(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4sNV), .-GL_PREFIX(VertexAttrib4sNV)
@@ -26598,7 +27000,7 @@ GL_PREFIX(VertexAttrib4sNV):
GL_PREFIX(VertexAttrib4svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5648(%rax), %r11
+ movq 5728(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26608,13 +27010,13 @@ GL_PREFIX(VertexAttrib4svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5648(%rax), %r11
+ movq 5728(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5648(%rax), %r11
+ movq 5728(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26624,7 +27026,7 @@ GL_PREFIX(VertexAttrib4svNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5648(%rax), %r11
+ movq 5728(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4svNV), .-GL_PREFIX(VertexAttrib4svNV)
@@ -26635,7 +27037,7 @@ GL_PREFIX(VertexAttrib4svNV):
GL_PREFIX(VertexAttrib4ubNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5656(%rax), %r11
+ movq 5736(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26649,13 +27051,13 @@ GL_PREFIX(VertexAttrib4ubNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5656(%rax), %r11
+ movq 5736(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5656(%rax), %r11
+ movq 5736(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26669,7 +27071,7 @@ GL_PREFIX(VertexAttrib4ubNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5656(%rax), %r11
+ movq 5736(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4ubNV), .-GL_PREFIX(VertexAttrib4ubNV)
@@ -26680,7 +27082,7 @@ GL_PREFIX(VertexAttrib4ubNV):
GL_PREFIX(VertexAttrib4ubvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5664(%rax), %r11
+ movq 5744(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26690,13 +27092,13 @@ GL_PREFIX(VertexAttrib4ubvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5664(%rax), %r11
+ movq 5744(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5664(%rax), %r11
+ movq 5744(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26706,7 +27108,7 @@ GL_PREFIX(VertexAttrib4ubvNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5664(%rax), %r11
+ movq 5744(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttrib4ubvNV), .-GL_PREFIX(VertexAttrib4ubvNV)
@@ -26717,7 +27119,7 @@ GL_PREFIX(VertexAttrib4ubvNV):
GL_PREFIX(VertexAttribPointerNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5672(%rax), %r11
+ movq 5752(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26731,13 +27133,13 @@ GL_PREFIX(VertexAttribPointerNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5672(%rax), %r11
+ movq 5752(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5672(%rax), %r11
+ movq 5752(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26751,7 +27153,7 @@ GL_PREFIX(VertexAttribPointerNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5672(%rax), %r11
+ movq 5752(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribPointerNV), .-GL_PREFIX(VertexAttribPointerNV)
@@ -26762,7 +27164,7 @@ GL_PREFIX(VertexAttribPointerNV):
GL_PREFIX(VertexAttribs1dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5680(%rax), %r11
+ movq 5760(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26772,13 +27174,13 @@ GL_PREFIX(VertexAttribs1dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5680(%rax), %r11
+ movq 5760(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5680(%rax), %r11
+ movq 5760(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26788,7 +27190,7 @@ GL_PREFIX(VertexAttribs1dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5680(%rax), %r11
+ movq 5760(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs1dvNV), .-GL_PREFIX(VertexAttribs1dvNV)
@@ -26799,7 +27201,7 @@ GL_PREFIX(VertexAttribs1dvNV):
GL_PREFIX(VertexAttribs1fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5688(%rax), %r11
+ movq 5768(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26809,13 +27211,13 @@ GL_PREFIX(VertexAttribs1fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5688(%rax), %r11
+ movq 5768(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5688(%rax), %r11
+ movq 5768(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26825,7 +27227,7 @@ GL_PREFIX(VertexAttribs1fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5688(%rax), %r11
+ movq 5768(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs1fvNV), .-GL_PREFIX(VertexAttribs1fvNV)
@@ -26836,7 +27238,7 @@ GL_PREFIX(VertexAttribs1fvNV):
GL_PREFIX(VertexAttribs1svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5696(%rax), %r11
+ movq 5776(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26846,13 +27248,13 @@ GL_PREFIX(VertexAttribs1svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5696(%rax), %r11
+ movq 5776(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5696(%rax), %r11
+ movq 5776(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26862,7 +27264,7 @@ GL_PREFIX(VertexAttribs1svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5696(%rax), %r11
+ movq 5776(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs1svNV), .-GL_PREFIX(VertexAttribs1svNV)
@@ -26873,7 +27275,7 @@ GL_PREFIX(VertexAttribs1svNV):
GL_PREFIX(VertexAttribs2dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5704(%rax), %r11
+ movq 5784(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26883,13 +27285,13 @@ GL_PREFIX(VertexAttribs2dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5704(%rax), %r11
+ movq 5784(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5704(%rax), %r11
+ movq 5784(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26899,7 +27301,7 @@ GL_PREFIX(VertexAttribs2dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5704(%rax), %r11
+ movq 5784(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs2dvNV), .-GL_PREFIX(VertexAttribs2dvNV)
@@ -26910,7 +27312,7 @@ GL_PREFIX(VertexAttribs2dvNV):
GL_PREFIX(VertexAttribs2fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5712(%rax), %r11
+ movq 5792(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26920,13 +27322,13 @@ GL_PREFIX(VertexAttribs2fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5712(%rax), %r11
+ movq 5792(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5712(%rax), %r11
+ movq 5792(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26936,7 +27338,7 @@ GL_PREFIX(VertexAttribs2fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5712(%rax), %r11
+ movq 5792(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs2fvNV), .-GL_PREFIX(VertexAttribs2fvNV)
@@ -26947,7 +27349,7 @@ GL_PREFIX(VertexAttribs2fvNV):
GL_PREFIX(VertexAttribs2svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5720(%rax), %r11
+ movq 5800(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26957,13 +27359,13 @@ GL_PREFIX(VertexAttribs2svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5720(%rax), %r11
+ movq 5800(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5720(%rax), %r11
+ movq 5800(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -26973,7 +27375,7 @@ GL_PREFIX(VertexAttribs2svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5720(%rax), %r11
+ movq 5800(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs2svNV), .-GL_PREFIX(VertexAttribs2svNV)
@@ -26984,7 +27386,7 @@ GL_PREFIX(VertexAttribs2svNV):
GL_PREFIX(VertexAttribs3dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5728(%rax), %r11
+ movq 5808(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -26994,13 +27396,13 @@ GL_PREFIX(VertexAttribs3dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5728(%rax), %r11
+ movq 5808(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5728(%rax), %r11
+ movq 5808(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27010,7 +27412,7 @@ GL_PREFIX(VertexAttribs3dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5728(%rax), %r11
+ movq 5808(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs3dvNV), .-GL_PREFIX(VertexAttribs3dvNV)
@@ -27021,7 +27423,7 @@ GL_PREFIX(VertexAttribs3dvNV):
GL_PREFIX(VertexAttribs3fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5736(%rax), %r11
+ movq 5816(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27031,13 +27433,13 @@ GL_PREFIX(VertexAttribs3fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5736(%rax), %r11
+ movq 5816(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5736(%rax), %r11
+ movq 5816(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27047,7 +27449,7 @@ GL_PREFIX(VertexAttribs3fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5736(%rax), %r11
+ movq 5816(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs3fvNV), .-GL_PREFIX(VertexAttribs3fvNV)
@@ -27058,7 +27460,7 @@ GL_PREFIX(VertexAttribs3fvNV):
GL_PREFIX(VertexAttribs3svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5744(%rax), %r11
+ movq 5824(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27068,13 +27470,13 @@ GL_PREFIX(VertexAttribs3svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5744(%rax), %r11
+ movq 5824(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5744(%rax), %r11
+ movq 5824(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27084,7 +27486,7 @@ GL_PREFIX(VertexAttribs3svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5744(%rax), %r11
+ movq 5824(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs3svNV), .-GL_PREFIX(VertexAttribs3svNV)
@@ -27095,7 +27497,7 @@ GL_PREFIX(VertexAttribs3svNV):
GL_PREFIX(VertexAttribs4dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5752(%rax), %r11
+ movq 5832(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27105,13 +27507,13 @@ GL_PREFIX(VertexAttribs4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5752(%rax), %r11
+ movq 5832(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5752(%rax), %r11
+ movq 5832(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27121,7 +27523,7 @@ GL_PREFIX(VertexAttribs4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5752(%rax), %r11
+ movq 5832(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs4dvNV), .-GL_PREFIX(VertexAttribs4dvNV)
@@ -27132,7 +27534,7 @@ GL_PREFIX(VertexAttribs4dvNV):
GL_PREFIX(VertexAttribs4fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5760(%rax), %r11
+ movq 5840(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27142,13 +27544,13 @@ GL_PREFIX(VertexAttribs4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5760(%rax), %r11
+ movq 5840(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5760(%rax), %r11
+ movq 5840(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27158,7 +27560,7 @@ GL_PREFIX(VertexAttribs4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5760(%rax), %r11
+ movq 5840(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs4fvNV), .-GL_PREFIX(VertexAttribs4fvNV)
@@ -27169,7 +27571,7 @@ GL_PREFIX(VertexAttribs4fvNV):
GL_PREFIX(VertexAttribs4svNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5768(%rax), %r11
+ movq 5848(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27179,13 +27581,13 @@ GL_PREFIX(VertexAttribs4svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5768(%rax), %r11
+ movq 5848(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5768(%rax), %r11
+ movq 5848(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27195,7 +27597,7 @@ GL_PREFIX(VertexAttribs4svNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5768(%rax), %r11
+ movq 5848(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs4svNV), .-GL_PREFIX(VertexAttribs4svNV)
@@ -27206,7 +27608,7 @@ GL_PREFIX(VertexAttribs4svNV):
GL_PREFIX(VertexAttribs4ubvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5776(%rax), %r11
+ movq 5856(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27216,13 +27618,13 @@ GL_PREFIX(VertexAttribs4ubvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5776(%rax), %r11
+ movq 5856(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5776(%rax), %r11
+ movq 5856(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27232,7 +27634,7 @@ GL_PREFIX(VertexAttribs4ubvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5776(%rax), %r11
+ movq 5856(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(VertexAttribs4ubvNV), .-GL_PREFIX(VertexAttribs4ubvNV)
@@ -27243,7 +27645,7 @@ GL_PREFIX(VertexAttribs4ubvNV):
GL_PREFIX(GetTexBumpParameterfvATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5784(%rax), %r11
+ movq 5864(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27253,13 +27655,13 @@ GL_PREFIX(GetTexBumpParameterfvATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5784(%rax), %r11
+ movq 5864(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5784(%rax), %r11
+ movq 5864(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27269,7 +27671,7 @@ GL_PREFIX(GetTexBumpParameterfvATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5784(%rax), %r11
+ movq 5864(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetTexBumpParameterfvATI), .-GL_PREFIX(GetTexBumpParameterfvATI)
@@ -27280,7 +27682,7 @@ GL_PREFIX(GetTexBumpParameterfvATI):
GL_PREFIX(GetTexBumpParameterivATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5792(%rax), %r11
+ movq 5872(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27290,13 +27692,13 @@ GL_PREFIX(GetTexBumpParameterivATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5792(%rax), %r11
+ movq 5872(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5792(%rax), %r11
+ movq 5872(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27306,7 +27708,7 @@ GL_PREFIX(GetTexBumpParameterivATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5792(%rax), %r11
+ movq 5872(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetTexBumpParameterivATI), .-GL_PREFIX(GetTexBumpParameterivATI)
@@ -27317,7 +27719,7 @@ GL_PREFIX(GetTexBumpParameterivATI):
GL_PREFIX(TexBumpParameterfvATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5800(%rax), %r11
+ movq 5880(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27327,13 +27729,13 @@ GL_PREFIX(TexBumpParameterfvATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5800(%rax), %r11
+ movq 5880(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5800(%rax), %r11
+ movq 5880(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27343,7 +27745,7 @@ GL_PREFIX(TexBumpParameterfvATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5800(%rax), %r11
+ movq 5880(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(TexBumpParameterfvATI), .-GL_PREFIX(TexBumpParameterfvATI)
@@ -27354,7 +27756,7 @@ GL_PREFIX(TexBumpParameterfvATI):
GL_PREFIX(TexBumpParameterivATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5808(%rax), %r11
+ movq 5888(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27364,13 +27766,13 @@ GL_PREFIX(TexBumpParameterivATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5808(%rax), %r11
+ movq 5888(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5808(%rax), %r11
+ movq 5888(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27380,7 +27782,7 @@ GL_PREFIX(TexBumpParameterivATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5808(%rax), %r11
+ movq 5888(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(TexBumpParameterivATI), .-GL_PREFIX(TexBumpParameterivATI)
@@ -27391,7 +27793,7 @@ GL_PREFIX(TexBumpParameterivATI):
GL_PREFIX(AlphaFragmentOp1ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5816(%rax), %r11
+ movq 5896(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27409,13 +27811,13 @@ GL_PREFIX(AlphaFragmentOp1ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5816(%rax), %r11
+ movq 5896(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5816(%rax), %r11
+ movq 5896(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27433,7 +27835,7 @@ GL_PREFIX(AlphaFragmentOp1ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5816(%rax), %r11
+ movq 5896(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(AlphaFragmentOp1ATI), .-GL_PREFIX(AlphaFragmentOp1ATI)
@@ -27444,7 +27846,7 @@ GL_PREFIX(AlphaFragmentOp1ATI):
GL_PREFIX(AlphaFragmentOp2ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5824(%rax), %r11
+ movq 5904(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27462,13 +27864,13 @@ GL_PREFIX(AlphaFragmentOp2ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5824(%rax), %r11
+ movq 5904(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5824(%rax), %r11
+ movq 5904(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27486,7 +27888,7 @@ GL_PREFIX(AlphaFragmentOp2ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5824(%rax), %r11
+ movq 5904(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(AlphaFragmentOp2ATI), .-GL_PREFIX(AlphaFragmentOp2ATI)
@@ -27497,7 +27899,7 @@ GL_PREFIX(AlphaFragmentOp2ATI):
GL_PREFIX(AlphaFragmentOp3ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5832(%rax), %r11
+ movq 5912(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27515,13 +27917,13 @@ GL_PREFIX(AlphaFragmentOp3ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5832(%rax), %r11
+ movq 5912(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5832(%rax), %r11
+ movq 5912(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27539,7 +27941,7 @@ GL_PREFIX(AlphaFragmentOp3ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5832(%rax), %r11
+ movq 5912(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(AlphaFragmentOp3ATI), .-GL_PREFIX(AlphaFragmentOp3ATI)
@@ -27550,25 +27952,25 @@ GL_PREFIX(AlphaFragmentOp3ATI):
GL_PREFIX(BeginFragmentShaderATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5840(%rax), %r11
+ movq 5920(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rbp
call _x86_64_get_dispatch@PLT
popq %rbp
- movq 5840(%rax), %r11
+ movq 5920(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5840(%rax), %r11
+ movq 5920(%rax), %r11
jmp *%r11
1:
pushq %rbp
call _glapi_get_dispatch
popq %rbp
- movq 5840(%rax), %r11
+ movq 5920(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BeginFragmentShaderATI), .-GL_PREFIX(BeginFragmentShaderATI)
@@ -27579,25 +27981,25 @@ GL_PREFIX(BeginFragmentShaderATI):
GL_PREFIX(BindFragmentShaderATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5848(%rax), %r11
+ movq 5928(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5848(%rax), %r11
+ movq 5928(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5848(%rax), %r11
+ movq 5928(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5848(%rax), %r11
+ movq 5928(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BindFragmentShaderATI), .-GL_PREFIX(BindFragmentShaderATI)
@@ -27608,7 +28010,7 @@ GL_PREFIX(BindFragmentShaderATI):
GL_PREFIX(ColorFragmentOp1ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5856(%rax), %r11
+ movq 5936(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27626,13 +28028,13 @@ GL_PREFIX(ColorFragmentOp1ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5856(%rax), %r11
+ movq 5936(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5856(%rax), %r11
+ movq 5936(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27650,7 +28052,7 @@ GL_PREFIX(ColorFragmentOp1ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5856(%rax), %r11
+ movq 5936(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ColorFragmentOp1ATI), .-GL_PREFIX(ColorFragmentOp1ATI)
@@ -27661,7 +28063,7 @@ GL_PREFIX(ColorFragmentOp1ATI):
GL_PREFIX(ColorFragmentOp2ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5864(%rax), %r11
+ movq 5944(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27679,13 +28081,13 @@ GL_PREFIX(ColorFragmentOp2ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5864(%rax), %r11
+ movq 5944(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5864(%rax), %r11
+ movq 5944(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27703,7 +28105,7 @@ GL_PREFIX(ColorFragmentOp2ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5864(%rax), %r11
+ movq 5944(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ColorFragmentOp2ATI), .-GL_PREFIX(ColorFragmentOp2ATI)
@@ -27714,7 +28116,7 @@ GL_PREFIX(ColorFragmentOp2ATI):
GL_PREFIX(ColorFragmentOp3ATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5872(%rax), %r11
+ movq 5952(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27732,13 +28134,13 @@ GL_PREFIX(ColorFragmentOp3ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5872(%rax), %r11
+ movq 5952(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5872(%rax), %r11
+ movq 5952(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27756,7 +28158,7 @@ GL_PREFIX(ColorFragmentOp3ATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5872(%rax), %r11
+ movq 5952(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ColorFragmentOp3ATI), .-GL_PREFIX(ColorFragmentOp3ATI)
@@ -27767,25 +28169,25 @@ GL_PREFIX(ColorFragmentOp3ATI):
GL_PREFIX(DeleteFragmentShaderATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5880(%rax), %r11
+ movq 5960(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5880(%rax), %r11
+ movq 5960(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5880(%rax), %r11
+ movq 5960(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5880(%rax), %r11
+ movq 5960(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(DeleteFragmentShaderATI), .-GL_PREFIX(DeleteFragmentShaderATI)
@@ -27796,25 +28198,25 @@ GL_PREFIX(DeleteFragmentShaderATI):
GL_PREFIX(EndFragmentShaderATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5888(%rax), %r11
+ movq 5968(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rbp
call _x86_64_get_dispatch@PLT
popq %rbp
- movq 5888(%rax), %r11
+ movq 5968(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5888(%rax), %r11
+ movq 5968(%rax), %r11
jmp *%r11
1:
pushq %rbp
call _glapi_get_dispatch
popq %rbp
- movq 5888(%rax), %r11
+ movq 5968(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(EndFragmentShaderATI), .-GL_PREFIX(EndFragmentShaderATI)
@@ -27825,25 +28227,25 @@ GL_PREFIX(EndFragmentShaderATI):
GL_PREFIX(GenFragmentShadersATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5896(%rax), %r11
+ movq 5976(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5896(%rax), %r11
+ movq 5976(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5896(%rax), %r11
+ movq 5976(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5896(%rax), %r11
+ movq 5976(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GenFragmentShadersATI), .-GL_PREFIX(GenFragmentShadersATI)
@@ -27854,7 +28256,7 @@ GL_PREFIX(GenFragmentShadersATI):
GL_PREFIX(PassTexCoordATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5904(%rax), %r11
+ movq 5984(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27864,13 +28266,13 @@ GL_PREFIX(PassTexCoordATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5904(%rax), %r11
+ movq 5984(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5904(%rax), %r11
+ movq 5984(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27880,7 +28282,7 @@ GL_PREFIX(PassTexCoordATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5904(%rax), %r11
+ movq 5984(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PassTexCoordATI), .-GL_PREFIX(PassTexCoordATI)
@@ -27891,7 +28293,7 @@ GL_PREFIX(PassTexCoordATI):
GL_PREFIX(SampleMapATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5912(%rax), %r11
+ movq 5992(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27901,13 +28303,13 @@ GL_PREFIX(SampleMapATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5912(%rax), %r11
+ movq 5992(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5912(%rax), %r11
+ movq 5992(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27917,7 +28319,7 @@ GL_PREFIX(SampleMapATI):
popq %rdx
popq %rsi
popq %rdi
- movq 5912(%rax), %r11
+ movq 5992(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SampleMapATI), .-GL_PREFIX(SampleMapATI)
@@ -27928,7 +28330,7 @@ GL_PREFIX(SampleMapATI):
GL_PREFIX(SetFragmentShaderConstantATI):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5920(%rax), %r11
+ movq 6000(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27938,13 +28340,13 @@ GL_PREFIX(SetFragmentShaderConstantATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5920(%rax), %r11
+ movq 6000(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5920(%rax), %r11
+ movq 6000(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27954,7 +28356,7 @@ GL_PREFIX(SetFragmentShaderConstantATI):
popq %rbp
popq %rsi
popq %rdi
- movq 5920(%rax), %r11
+ movq 6000(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(SetFragmentShaderConstantATI), .-GL_PREFIX(SetFragmentShaderConstantATI)
@@ -27965,7 +28367,7 @@ GL_PREFIX(SetFragmentShaderConstantATI):
GL_PREFIX(PointParameteriNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5928(%rax), %r11
+ movq 6008(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -27975,13 +28377,13 @@ GL_PREFIX(PointParameteriNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5928(%rax), %r11
+ movq 6008(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5928(%rax), %r11
+ movq 6008(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -27991,7 +28393,7 @@ GL_PREFIX(PointParameteriNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5928(%rax), %r11
+ movq 6008(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PointParameteriNV), .-GL_PREFIX(PointParameteriNV)
@@ -28002,7 +28404,7 @@ GL_PREFIX(PointParameteriNV):
GL_PREFIX(PointParameterivNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5936(%rax), %r11
+ movq 6016(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28012,13 +28414,13 @@ GL_PREFIX(PointParameterivNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5936(%rax), %r11
+ movq 6016(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5936(%rax), %r11
+ movq 6016(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28028,79 +28430,79 @@ GL_PREFIX(PointParameterivNV):
popq %rbp
popq %rsi
popq %rdi
- movq 5936(%rax), %r11
+ movq 6016(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(PointParameterivNV), .-GL_PREFIX(PointParameterivNV)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_743)
- .type GL_PREFIX(_dispatch_stub_743), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_743))
-GL_PREFIX(_dispatch_stub_743):
+ .globl GL_PREFIX(_dispatch_stub_753)
+ .type GL_PREFIX(_dispatch_stub_753), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_753))
+GL_PREFIX(_dispatch_stub_753):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5944(%rax), %r11
+ movq 6024(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5944(%rax), %r11
+ movq 6024(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5944(%rax), %r11
+ movq 6024(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5944(%rax), %r11
+ movq 6024(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_743), .-GL_PREFIX(_dispatch_stub_743)
+ .size GL_PREFIX(_dispatch_stub_753), .-GL_PREFIX(_dispatch_stub_753)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_744)
- .type GL_PREFIX(_dispatch_stub_744), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_744))
-GL_PREFIX(_dispatch_stub_744):
+ .globl GL_PREFIX(_dispatch_stub_754)
+ .type GL_PREFIX(_dispatch_stub_754), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_754))
+GL_PREFIX(_dispatch_stub_754):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5952(%rax), %r11
+ movq 6032(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5952(%rax), %r11
+ movq 6032(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5952(%rax), %r11
+ movq 6032(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5952(%rax), %r11
+ movq 6032(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_744), .-GL_PREFIX(_dispatch_stub_744)
+ .size GL_PREFIX(_dispatch_stub_754), .-GL_PREFIX(_dispatch_stub_754)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_745)
- .type GL_PREFIX(_dispatch_stub_745), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_745))
-GL_PREFIX(_dispatch_stub_745):
+ .globl GL_PREFIX(_dispatch_stub_755)
+ .type GL_PREFIX(_dispatch_stub_755), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_755))
+GL_PREFIX(_dispatch_stub_755):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5960(%rax), %r11
+ movq 6040(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28110,13 +28512,13 @@ GL_PREFIX(_dispatch_stub_745):
popq %rbp
popq %rsi
popq %rdi
- movq 5960(%rax), %r11
+ movq 6040(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5960(%rax), %r11
+ movq 6040(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28126,19 +28528,19 @@ GL_PREFIX(_dispatch_stub_745):
popq %rbp
popq %rsi
popq %rdi
- movq 5960(%rax), %r11
+ movq 6040(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_745), .-GL_PREFIX(_dispatch_stub_745)
+ .size GL_PREFIX(_dispatch_stub_755), .-GL_PREFIX(_dispatch_stub_755)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_746)
- .type GL_PREFIX(_dispatch_stub_746), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_746))
-GL_PREFIX(_dispatch_stub_746):
+ .globl GL_PREFIX(_dispatch_stub_756)
+ .type GL_PREFIX(_dispatch_stub_756), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_756))
+GL_PREFIX(_dispatch_stub_756):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5968(%rax), %r11
+ movq 6048(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28148,13 +28550,13 @@ GL_PREFIX(_dispatch_stub_746):
popq %rbp
popq %rsi
popq %rdi
- movq 5968(%rax), %r11
+ movq 6048(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5968(%rax), %r11
+ movq 6048(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28164,40 +28566,40 @@ GL_PREFIX(_dispatch_stub_746):
popq %rbp
popq %rsi
popq %rdi
- movq 5968(%rax), %r11
+ movq 6048(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_746), .-GL_PREFIX(_dispatch_stub_746)
+ .size GL_PREFIX(_dispatch_stub_756), .-GL_PREFIX(_dispatch_stub_756)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_747)
- .type GL_PREFIX(_dispatch_stub_747), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_747))
-GL_PREFIX(_dispatch_stub_747):
+ .globl GL_PREFIX(_dispatch_stub_757)
+ .type GL_PREFIX(_dispatch_stub_757), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_757))
+GL_PREFIX(_dispatch_stub_757):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5976(%rax), %r11
+ movq 6056(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 5976(%rax), %r11
+ movq 6056(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5976(%rax), %r11
+ movq 6056(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 5976(%rax), %r11
+ movq 6056(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_747), .-GL_PREFIX(_dispatch_stub_747)
+ .size GL_PREFIX(_dispatch_stub_757), .-GL_PREFIX(_dispatch_stub_757)
.p2align 4,,15
.globl GL_PREFIX(GetProgramNamedParameterdvNV)
@@ -28205,7 +28607,7 @@ GL_PREFIX(_dispatch_stub_747):
GL_PREFIX(GetProgramNamedParameterdvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5984(%rax), %r11
+ movq 6064(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28219,13 +28621,13 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5984(%rax), %r11
+ movq 6064(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5984(%rax), %r11
+ movq 6064(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28239,7 +28641,7 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5984(%rax), %r11
+ movq 6064(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramNamedParameterdvNV), .-GL_PREFIX(GetProgramNamedParameterdvNV)
@@ -28250,7 +28652,7 @@ GL_PREFIX(GetProgramNamedParameterdvNV):
GL_PREFIX(GetProgramNamedParameterfvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 5992(%rax), %r11
+ movq 6072(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28264,13 +28666,13 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5992(%rax), %r11
+ movq 6072(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 5992(%rax), %r11
+ movq 6072(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28284,7 +28686,7 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 5992(%rax), %r11
+ movq 6072(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetProgramNamedParameterfvNV), .-GL_PREFIX(GetProgramNamedParameterfvNV)
@@ -28295,7 +28697,7 @@ GL_PREFIX(GetProgramNamedParameterfvNV):
GL_PREFIX(ProgramNamedParameter4dNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6000(%rax), %r11
+ movq 6080(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $56, %rsp
@@ -28315,13 +28717,13 @@ GL_PREFIX(ProgramNamedParameter4dNV):
movq 8(%rsp), %rsi
movq (%rsp), %rdi
addq $56, %rsp
- movq 6000(%rax), %r11
+ movq 6080(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6000(%rax), %r11
+ movq 6080(%rax), %r11
jmp *%r11
1:
subq $56, %rsp
@@ -28341,7 +28743,7 @@ GL_PREFIX(ProgramNamedParameter4dNV):
movq 8(%rsp), %rsi
movq (%rsp), %rdi
addq $56, %rsp
- movq 6000(%rax), %r11
+ movq 6080(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramNamedParameter4dNV), .-GL_PREFIX(ProgramNamedParameter4dNV)
@@ -28352,7 +28754,7 @@ GL_PREFIX(ProgramNamedParameter4dNV):
GL_PREFIX(ProgramNamedParameter4dvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6008(%rax), %r11
+ movq 6088(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28366,13 +28768,13 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 6008(%rax), %r11
+ movq 6088(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6008(%rax), %r11
+ movq 6088(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28386,7 +28788,7 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 6008(%rax), %r11
+ movq 6088(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramNamedParameter4dvNV), .-GL_PREFIX(ProgramNamedParameter4dvNV)
@@ -28397,7 +28799,7 @@ GL_PREFIX(ProgramNamedParameter4dvNV):
GL_PREFIX(ProgramNamedParameter4fNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6016(%rax), %r11
+ movq 6096(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
subq $56, %rsp
@@ -28417,13 +28819,13 @@ GL_PREFIX(ProgramNamedParameter4fNV):
movq 8(%rsp), %rsi
movq (%rsp), %rdi
addq $56, %rsp
- movq 6016(%rax), %r11
+ movq 6096(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6016(%rax), %r11
+ movq 6096(%rax), %r11
jmp *%r11
1:
subq $56, %rsp
@@ -28443,7 +28845,7 @@ GL_PREFIX(ProgramNamedParameter4fNV):
movq 8(%rsp), %rsi
movq (%rsp), %rdi
addq $56, %rsp
- movq 6016(%rax), %r11
+ movq 6096(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramNamedParameter4fNV), .-GL_PREFIX(ProgramNamedParameter4fNV)
@@ -28454,7 +28856,7 @@ GL_PREFIX(ProgramNamedParameter4fNV):
GL_PREFIX(ProgramNamedParameter4fvNV):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6024(%rax), %r11
+ movq 6104(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28468,13 +28870,13 @@ GL_PREFIX(ProgramNamedParameter4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 6024(%rax), %r11
+ movq 6104(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6024(%rax), %r11
+ movq 6104(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28488,19 +28890,19 @@ GL_PREFIX(ProgramNamedParameter4fvNV):
popq %rdx
popq %rsi
popq %rdi
- movq 6024(%rax), %r11
+ movq 6104(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProgramNamedParameter4fvNV), .-GL_PREFIX(ProgramNamedParameter4fvNV)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_754)
- .type GL_PREFIX(_dispatch_stub_754), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_754))
-GL_PREFIX(_dispatch_stub_754):
+ .globl GL_PREFIX(_dispatch_stub_764)
+ .type GL_PREFIX(_dispatch_stub_764), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_764))
+GL_PREFIX(_dispatch_stub_764):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6032(%rax), %r11
+ movq 6112(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28510,13 +28912,13 @@ GL_PREFIX(_dispatch_stub_754):
popq %rbp
popq %rsi
popq %rdi
- movq 6032(%rax), %r11
+ movq 6112(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6032(%rax), %r11
+ movq 6112(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28526,19 +28928,19 @@ GL_PREFIX(_dispatch_stub_754):
popq %rbp
popq %rsi
popq %rdi
- movq 6032(%rax), %r11
+ movq 6112(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_754), .-GL_PREFIX(_dispatch_stub_754)
+ .size GL_PREFIX(_dispatch_stub_764), .-GL_PREFIX(_dispatch_stub_764)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_755)
- .type GL_PREFIX(_dispatch_stub_755), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_755))
-GL_PREFIX(_dispatch_stub_755):
+ .globl GL_PREFIX(_dispatch_stub_765)
+ .type GL_PREFIX(_dispatch_stub_765), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_765))
+GL_PREFIX(_dispatch_stub_765):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6040(%rax), %r11
+ movq 6120(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28548,13 +28950,13 @@ GL_PREFIX(_dispatch_stub_755):
popq %rbp
popq %rsi
popq %rdi
- movq 6040(%rax), %r11
+ movq 6120(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6040(%rax), %r11
+ movq 6120(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28564,10 +28966,10 @@ GL_PREFIX(_dispatch_stub_755):
popq %rbp
popq %rsi
popq %rdi
- movq 6040(%rax), %r11
+ movq 6120(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_755), .-GL_PREFIX(_dispatch_stub_755)
+ .size GL_PREFIX(_dispatch_stub_765), .-GL_PREFIX(_dispatch_stub_765)
.p2align 4,,15
.globl GL_PREFIX(BindFramebufferEXT)
@@ -28575,7 +28977,7 @@ GL_PREFIX(_dispatch_stub_755):
GL_PREFIX(BindFramebufferEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6048(%rax), %r11
+ movq 6128(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28585,13 +28987,13 @@ GL_PREFIX(BindFramebufferEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6048(%rax), %r11
+ movq 6128(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6048(%rax), %r11
+ movq 6128(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28601,7 +29003,7 @@ GL_PREFIX(BindFramebufferEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6048(%rax), %r11
+ movq 6128(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BindFramebufferEXT), .-GL_PREFIX(BindFramebufferEXT)
@@ -28612,7 +29014,7 @@ GL_PREFIX(BindFramebufferEXT):
GL_PREFIX(BindRenderbufferEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6056(%rax), %r11
+ movq 6136(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28622,13 +29024,13 @@ GL_PREFIX(BindRenderbufferEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6056(%rax), %r11
+ movq 6136(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6056(%rax), %r11
+ movq 6136(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28638,7 +29040,7 @@ GL_PREFIX(BindRenderbufferEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6056(%rax), %r11
+ movq 6136(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(BindRenderbufferEXT), .-GL_PREFIX(BindRenderbufferEXT)
@@ -28649,25 +29051,25 @@ GL_PREFIX(BindRenderbufferEXT):
GL_PREFIX(CheckFramebufferStatusEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6064(%rax), %r11
+ movq 6144(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 6064(%rax), %r11
+ movq 6144(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6064(%rax), %r11
+ movq 6144(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 6064(%rax), %r11
+ movq 6144(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(CheckFramebufferStatusEXT), .-GL_PREFIX(CheckFramebufferStatusEXT)
@@ -28678,7 +29080,7 @@ GL_PREFIX(CheckFramebufferStatusEXT):
GL_PREFIX(DeleteFramebuffersEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6072(%rax), %r11
+ movq 6152(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28688,13 +29090,13 @@ GL_PREFIX(DeleteFramebuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6072(%rax), %r11
+ movq 6152(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6072(%rax), %r11
+ movq 6152(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28704,7 +29106,7 @@ GL_PREFIX(DeleteFramebuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6072(%rax), %r11
+ movq 6152(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(DeleteFramebuffersEXT), .-GL_PREFIX(DeleteFramebuffersEXT)
@@ -28715,7 +29117,7 @@ GL_PREFIX(DeleteFramebuffersEXT):
GL_PREFIX(DeleteRenderbuffersEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6080(%rax), %r11
+ movq 6160(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28725,13 +29127,13 @@ GL_PREFIX(DeleteRenderbuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6080(%rax), %r11
+ movq 6160(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6080(%rax), %r11
+ movq 6160(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28741,7 +29143,7 @@ GL_PREFIX(DeleteRenderbuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6080(%rax), %r11
+ movq 6160(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(DeleteRenderbuffersEXT), .-GL_PREFIX(DeleteRenderbuffersEXT)
@@ -28752,7 +29154,7 @@ GL_PREFIX(DeleteRenderbuffersEXT):
GL_PREFIX(FramebufferRenderbufferEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6088(%rax), %r11
+ movq 6168(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28766,13 +29168,13 @@ GL_PREFIX(FramebufferRenderbufferEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6088(%rax), %r11
+ movq 6168(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6088(%rax), %r11
+ movq 6168(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28786,7 +29188,7 @@ GL_PREFIX(FramebufferRenderbufferEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6088(%rax), %r11
+ movq 6168(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FramebufferRenderbufferEXT), .-GL_PREFIX(FramebufferRenderbufferEXT)
@@ -28797,7 +29199,7 @@ GL_PREFIX(FramebufferRenderbufferEXT):
GL_PREFIX(FramebufferTexture1DEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6096(%rax), %r11
+ movq 6176(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28811,13 +29213,13 @@ GL_PREFIX(FramebufferTexture1DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6096(%rax), %r11
+ movq 6176(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6096(%rax), %r11
+ movq 6176(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28831,7 +29233,7 @@ GL_PREFIX(FramebufferTexture1DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6096(%rax), %r11
+ movq 6176(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FramebufferTexture1DEXT), .-GL_PREFIX(FramebufferTexture1DEXT)
@@ -28842,7 +29244,7 @@ GL_PREFIX(FramebufferTexture1DEXT):
GL_PREFIX(FramebufferTexture2DEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6104(%rax), %r11
+ movq 6184(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28856,13 +29258,13 @@ GL_PREFIX(FramebufferTexture2DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6104(%rax), %r11
+ movq 6184(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6104(%rax), %r11
+ movq 6184(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28876,7 +29278,7 @@ GL_PREFIX(FramebufferTexture2DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6104(%rax), %r11
+ movq 6184(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FramebufferTexture2DEXT), .-GL_PREFIX(FramebufferTexture2DEXT)
@@ -28887,7 +29289,7 @@ GL_PREFIX(FramebufferTexture2DEXT):
GL_PREFIX(FramebufferTexture3DEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6112(%rax), %r11
+ movq 6192(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28905,13 +29307,13 @@ GL_PREFIX(FramebufferTexture3DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6112(%rax), %r11
+ movq 6192(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6112(%rax), %r11
+ movq 6192(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28929,7 +29331,7 @@ GL_PREFIX(FramebufferTexture3DEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6112(%rax), %r11
+ movq 6192(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FramebufferTexture3DEXT), .-GL_PREFIX(FramebufferTexture3DEXT)
@@ -28940,7 +29342,7 @@ GL_PREFIX(FramebufferTexture3DEXT):
GL_PREFIX(GenFramebuffersEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6120(%rax), %r11
+ movq 6200(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28950,13 +29352,13 @@ GL_PREFIX(GenFramebuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6120(%rax), %r11
+ movq 6200(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6120(%rax), %r11
+ movq 6200(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -28966,7 +29368,7 @@ GL_PREFIX(GenFramebuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6120(%rax), %r11
+ movq 6200(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GenFramebuffersEXT), .-GL_PREFIX(GenFramebuffersEXT)
@@ -28977,7 +29379,7 @@ GL_PREFIX(GenFramebuffersEXT):
GL_PREFIX(GenRenderbuffersEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6128(%rax), %r11
+ movq 6208(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -28987,13 +29389,13 @@ GL_PREFIX(GenRenderbuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6128(%rax), %r11
+ movq 6208(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6128(%rax), %r11
+ movq 6208(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29003,7 +29405,7 @@ GL_PREFIX(GenRenderbuffersEXT):
popq %rbp
popq %rsi
popq %rdi
- movq 6128(%rax), %r11
+ movq 6208(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GenRenderbuffersEXT), .-GL_PREFIX(GenRenderbuffersEXT)
@@ -29014,25 +29416,25 @@ GL_PREFIX(GenRenderbuffersEXT):
GL_PREFIX(GenerateMipmapEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6136(%rax), %r11
+ movq 6216(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 6136(%rax), %r11
+ movq 6216(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6136(%rax), %r11
+ movq 6216(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 6136(%rax), %r11
+ movq 6216(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GenerateMipmapEXT), .-GL_PREFIX(GenerateMipmapEXT)
@@ -29043,7 +29445,7 @@ GL_PREFIX(GenerateMipmapEXT):
GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6144(%rax), %r11
+ movq 6224(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29057,13 +29459,13 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6144(%rax), %r11
+ movq 6224(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6144(%rax), %r11
+ movq 6224(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29077,7 +29479,7 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6144(%rax), %r11
+ movq 6224(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetFramebufferAttachmentParameterivEXT), .-GL_PREFIX(GetFramebufferAttachmentParameterivEXT)
@@ -29088,7 +29490,7 @@ GL_PREFIX(GetFramebufferAttachmentParameterivEXT):
GL_PREFIX(GetRenderbufferParameterivEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6152(%rax), %r11
+ movq 6232(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29098,13 +29500,13 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6152(%rax), %r11
+ movq 6232(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6152(%rax), %r11
+ movq 6232(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29114,7 +29516,7 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6152(%rax), %r11
+ movq 6232(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(GetRenderbufferParameterivEXT), .-GL_PREFIX(GetRenderbufferParameterivEXT)
@@ -29125,25 +29527,25 @@ GL_PREFIX(GetRenderbufferParameterivEXT):
GL_PREFIX(IsFramebufferEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6160(%rax), %r11
+ movq 6240(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 6160(%rax), %r11
+ movq 6240(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6160(%rax), %r11
+ movq 6240(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 6160(%rax), %r11
+ movq 6240(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(IsFramebufferEXT), .-GL_PREFIX(IsFramebufferEXT)
@@ -29154,25 +29556,25 @@ GL_PREFIX(IsFramebufferEXT):
GL_PREFIX(IsRenderbufferEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6168(%rax), %r11
+ movq 6248(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 6168(%rax), %r11
+ movq 6248(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6168(%rax), %r11
+ movq 6248(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 6168(%rax), %r11
+ movq 6248(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(IsRenderbufferEXT), .-GL_PREFIX(IsRenderbufferEXT)
@@ -29183,7 +29585,7 @@ GL_PREFIX(IsRenderbufferEXT):
GL_PREFIX(RenderbufferStorageEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6176(%rax), %r11
+ movq 6256(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29197,13 +29599,13 @@ GL_PREFIX(RenderbufferStorageEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6176(%rax), %r11
+ movq 6256(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6176(%rax), %r11
+ movq 6256(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29217,19 +29619,19 @@ GL_PREFIX(RenderbufferStorageEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6176(%rax), %r11
+ movq 6256(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(RenderbufferStorageEXT), .-GL_PREFIX(RenderbufferStorageEXT)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_773)
- .type GL_PREFIX(_dispatch_stub_773), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_773))
-GL_PREFIX(_dispatch_stub_773):
+ .globl GL_PREFIX(_dispatch_stub_783)
+ .type GL_PREFIX(_dispatch_stub_783), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_783))
+GL_PREFIX(_dispatch_stub_783):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6184(%rax), %r11
+ movq 6264(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29247,13 +29649,13 @@ GL_PREFIX(_dispatch_stub_773):
popq %rdx
popq %rsi
popq %rdi
- movq 6184(%rax), %r11
+ movq 6264(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6184(%rax), %r11
+ movq 6264(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29271,10 +29673,86 @@ GL_PREFIX(_dispatch_stub_773):
popq %rdx
popq %rsi
popq %rdi
- movq 6184(%rax), %r11
+ movq 6264(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_773), .-GL_PREFIX(_dispatch_stub_773)
+ .size GL_PREFIX(_dispatch_stub_783), .-GL_PREFIX(_dispatch_stub_783)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(_dispatch_stub_784)
+ .type GL_PREFIX(_dispatch_stub_784), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_784))
+GL_PREFIX(_dispatch_stub_784):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 6272(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6272(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 6272(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6272(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(_dispatch_stub_784), .-GL_PREFIX(_dispatch_stub_784)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(_dispatch_stub_785)
+ .type GL_PREFIX(_dispatch_stub_785), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_785))
+GL_PREFIX(_dispatch_stub_785):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 6280(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6280(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 6280(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6280(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(_dispatch_stub_785), .-GL_PREFIX(_dispatch_stub_785)
.p2align 4,,15
.globl GL_PREFIX(FramebufferTextureLayerEXT)
@@ -29282,7 +29760,7 @@ GL_PREFIX(_dispatch_stub_773):
GL_PREFIX(FramebufferTextureLayerEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6192(%rax), %r11
+ movq 6288(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29296,13 +29774,13 @@ GL_PREFIX(FramebufferTextureLayerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6192(%rax), %r11
+ movq 6288(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6192(%rax), %r11
+ movq 6288(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29316,7 +29794,7 @@ GL_PREFIX(FramebufferTextureLayerEXT):
popq %rdx
popq %rsi
popq %rdi
- movq 6192(%rax), %r11
+ movq 6288(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(FramebufferTextureLayerEXT), .-GL_PREFIX(FramebufferTextureLayerEXT)
@@ -29327,37 +29805,113 @@ GL_PREFIX(FramebufferTextureLayerEXT):
GL_PREFIX(ProvokingVertexEXT):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6200(%rax), %r11
+ movq 6296(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
call _x86_64_get_dispatch@PLT
popq %rdi
- movq 6200(%rax), %r11
+ movq 6296(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6200(%rax), %r11
+ movq 6296(%rax), %r11
jmp *%r11
1:
pushq %rdi
call _glapi_get_dispatch
popq %rdi
- movq 6200(%rax), %r11
+ movq 6296(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
.size GL_PREFIX(ProvokingVertexEXT), .-GL_PREFIX(ProvokingVertexEXT)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_776)
- .type GL_PREFIX(_dispatch_stub_776), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_776))
-GL_PREFIX(_dispatch_stub_776):
+ .globl GL_PREFIX(_dispatch_stub_788)
+ .type GL_PREFIX(_dispatch_stub_788), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_788))
+GL_PREFIX(_dispatch_stub_788):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6208(%rax), %r11
+ movq 6304(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6304(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 6304(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6304(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(_dispatch_stub_788), .-GL_PREFIX(_dispatch_stub_788)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(_dispatch_stub_789)
+ .type GL_PREFIX(_dispatch_stub_789), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_789))
+GL_PREFIX(_dispatch_stub_789):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 6312(%rax), %r11
+ jmp *%r11
+#elif defined(PTHREADS)
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _x86_64_get_dispatch@PLT
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6312(%rax), %r11
+ jmp *%r11
+#else
+ movq _glapi_Dispatch(%rip), %rax
+ testq %rax, %rax
+ je 1f
+ movq 6312(%rax), %r11
+ jmp *%r11
+1:
+ pushq %rdi
+ pushq %rsi
+ pushq %rdx
+ call _glapi_get_dispatch
+ popq %rdx
+ popq %rsi
+ popq %rdi
+ movq 6312(%rax), %r11
+ jmp *%r11
+#endif /* defined(GLX_USE_TLS) */
+ .size GL_PREFIX(_dispatch_stub_789), .-GL_PREFIX(_dispatch_stub_789)
+
+ .p2align 4,,15
+ .globl GL_PREFIX(_dispatch_stub_790)
+ .type GL_PREFIX(_dispatch_stub_790), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_790))
+GL_PREFIX(_dispatch_stub_790):
+#if defined(GLX_USE_TLS)
+ call _x86_64_get_dispatch@PLT
+ movq 6320(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29371,13 +29925,13 @@ GL_PREFIX(_dispatch_stub_776):
popq %rdx
popq %rsi
popq %rdi
- movq 6208(%rax), %r11
+ movq 6320(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6208(%rax), %r11
+ movq 6320(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29391,19 +29945,19 @@ GL_PREFIX(_dispatch_stub_776):
popq %rdx
popq %rsi
popq %rdi
- movq 6208(%rax), %r11
+ movq 6320(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_776), .-GL_PREFIX(_dispatch_stub_776)
+ .size GL_PREFIX(_dispatch_stub_790), .-GL_PREFIX(_dispatch_stub_790)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_777)
- .type GL_PREFIX(_dispatch_stub_777), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_777))
-GL_PREFIX(_dispatch_stub_777):
+ .globl GL_PREFIX(_dispatch_stub_791)
+ .type GL_PREFIX(_dispatch_stub_791), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_791))
+GL_PREFIX(_dispatch_stub_791):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6216(%rax), %r11
+ movq 6328(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29417,13 +29971,13 @@ GL_PREFIX(_dispatch_stub_777):
popq %rdx
popq %rsi
popq %rdi
- movq 6216(%rax), %r11
+ movq 6328(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6216(%rax), %r11
+ movq 6328(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29437,19 +29991,19 @@ GL_PREFIX(_dispatch_stub_777):
popq %rdx
popq %rsi
popq %rdi
- movq 6216(%rax), %r11
+ movq 6328(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_777), .-GL_PREFIX(_dispatch_stub_777)
+ .size GL_PREFIX(_dispatch_stub_791), .-GL_PREFIX(_dispatch_stub_791)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_778)
- .type GL_PREFIX(_dispatch_stub_778), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_778))
-GL_PREFIX(_dispatch_stub_778):
+ .globl GL_PREFIX(_dispatch_stub_792)
+ .type GL_PREFIX(_dispatch_stub_792), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_792))
+GL_PREFIX(_dispatch_stub_792):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6224(%rax), %r11
+ movq 6336(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29463,13 +30017,13 @@ GL_PREFIX(_dispatch_stub_778):
popq %rdx
popq %rsi
popq %rdi
- movq 6224(%rax), %r11
+ movq 6336(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6224(%rax), %r11
+ movq 6336(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29483,19 +30037,19 @@ GL_PREFIX(_dispatch_stub_778):
popq %rdx
popq %rsi
popq %rdi
- movq 6224(%rax), %r11
+ movq 6336(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_778), .-GL_PREFIX(_dispatch_stub_778)
+ .size GL_PREFIX(_dispatch_stub_792), .-GL_PREFIX(_dispatch_stub_792)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_779)
- .type GL_PREFIX(_dispatch_stub_779), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_779))
-GL_PREFIX(_dispatch_stub_779):
+ .globl GL_PREFIX(_dispatch_stub_793)
+ .type GL_PREFIX(_dispatch_stub_793), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_793))
+GL_PREFIX(_dispatch_stub_793):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6232(%rax), %r11
+ movq 6344(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29505,13 +30059,13 @@ GL_PREFIX(_dispatch_stub_779):
popq %rdx
popq %rsi
popq %rdi
- movq 6232(%rax), %r11
+ movq 6344(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6232(%rax), %r11
+ movq 6344(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29521,19 +30075,19 @@ GL_PREFIX(_dispatch_stub_779):
popq %rdx
popq %rsi
popq %rdi
- movq 6232(%rax), %r11
+ movq 6344(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_779), .-GL_PREFIX(_dispatch_stub_779)
+ .size GL_PREFIX(_dispatch_stub_793), .-GL_PREFIX(_dispatch_stub_793)
.p2align 4,,15
- .globl GL_PREFIX(_dispatch_stub_780)
- .type GL_PREFIX(_dispatch_stub_780), @function
- HIDDEN(GL_PREFIX(_dispatch_stub_780))
-GL_PREFIX(_dispatch_stub_780):
+ .globl GL_PREFIX(_dispatch_stub_794)
+ .type GL_PREFIX(_dispatch_stub_794), @function
+ HIDDEN(GL_PREFIX(_dispatch_stub_794))
+GL_PREFIX(_dispatch_stub_794):
#if defined(GLX_USE_TLS)
call _x86_64_get_dispatch@PLT
- movq 6240(%rax), %r11
+ movq 6352(%rax), %r11
jmp *%r11
#elif defined(PTHREADS)
pushq %rdi
@@ -29543,13 +30097,13 @@ GL_PREFIX(_dispatch_stub_780):
popq %rdx
popq %rsi
popq %rdi
- movq 6240(%rax), %r11
+ movq 6352(%rax), %r11
jmp *%r11
#else
movq _glapi_Dispatch(%rip), %rax
testq %rax, %rax
je 1f
- movq 6240(%rax), %r11
+ movq 6352(%rax), %r11
jmp *%r11
1:
pushq %rdi
@@ -29559,10 +30113,10 @@ GL_PREFIX(_dispatch_stub_780):
popq %rdx
popq %rsi
popq %rdi
- movq 6240(%rax), %r11
+ movq 6352(%rax), %r11
jmp *%r11
#endif /* defined(GLX_USE_TLS) */
- .size GL_PREFIX(_dispatch_stub_780), .-GL_PREFIX(_dispatch_stub_780)
+ .size GL_PREFIX(_dispatch_stub_794), .-GL_PREFIX(_dispatch_stub_794)
.globl GL_PREFIX(ArrayElementEXT) ; .set GL_PREFIX(ArrayElementEXT), GL_PREFIX(ArrayElement)
.globl GL_PREFIX(BindTextureEXT) ; .set GL_PREFIX(BindTextureEXT), GL_PREFIX(BindTexture)
@@ -29817,9 +30371,9 @@ GL_PREFIX(_dispatch_stub_780):
.globl GL_PREFIX(IsProgramARB) ; .set GL_PREFIX(IsProgramARB), GL_PREFIX(IsProgramNV)
.globl GL_PREFIX(PointParameteri) ; .set GL_PREFIX(PointParameteri), GL_PREFIX(PointParameteriNV)
.globl GL_PREFIX(PointParameteriv) ; .set GL_PREFIX(PointParameteriv), GL_PREFIX(PointParameterivNV)
- .globl GL_PREFIX(DeleteVertexArrays) ; .set GL_PREFIX(DeleteVertexArrays), GL_PREFIX(_dispatch_stub_745)
- .globl GL_PREFIX(IsVertexArray) ; .set GL_PREFIX(IsVertexArray), GL_PREFIX(_dispatch_stub_747)
- .globl GL_PREFIX(BlendEquationSeparate) ; .set GL_PREFIX(BlendEquationSeparate), GL_PREFIX(_dispatch_stub_755)
+ .globl GL_PREFIX(DeleteVertexArrays) ; .set GL_PREFIX(DeleteVertexArrays), GL_PREFIX(_dispatch_stub_755)
+ .globl GL_PREFIX(IsVertexArray) ; .set GL_PREFIX(IsVertexArray), GL_PREFIX(_dispatch_stub_757)
+ .globl GL_PREFIX(BlendEquationSeparate) ; .set GL_PREFIX(BlendEquationSeparate), GL_PREFIX(_dispatch_stub_765)
.globl GL_PREFIX(BindFramebuffer) ; .set GL_PREFIX(BindFramebuffer), GL_PREFIX(BindFramebufferEXT)
.globl GL_PREFIX(BindRenderbuffer) ; .set GL_PREFIX(BindRenderbuffer), GL_PREFIX(BindRenderbufferEXT)
.globl GL_PREFIX(CheckFramebufferStatus) ; .set GL_PREFIX(CheckFramebufferStatus), GL_PREFIX(CheckFramebufferStatusEXT)
@@ -29837,8 +30391,9 @@ GL_PREFIX(_dispatch_stub_780):
.globl GL_PREFIX(IsFramebuffer) ; .set GL_PREFIX(IsFramebuffer), GL_PREFIX(IsFramebufferEXT)
.globl GL_PREFIX(IsRenderbuffer) ; .set GL_PREFIX(IsRenderbuffer), GL_PREFIX(IsRenderbufferEXT)
.globl GL_PREFIX(RenderbufferStorage) ; .set GL_PREFIX(RenderbufferStorage), GL_PREFIX(RenderbufferStorageEXT)
- .globl GL_PREFIX(BlitFramebuffer) ; .set GL_PREFIX(BlitFramebuffer), GL_PREFIX(_dispatch_stub_773)
+ .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/Makefile b/src/mesa/x86/Makefile
index aa49a9134a..69122c114b 100644
--- a/src/mesa/x86/Makefile
+++ b/src/mesa/x86/Makefile
@@ -21,7 +21,7 @@ clean:
gen_matypes: gen_matypes.c
- $(HOST_CC) $(INCLUDE_DIRS) $(HOST_CFLAGS) gen_matypes.c -o gen_matypes
+ $(HOST_CC) $(ARCH_FLAGS) $(INCLUDE_DIRS) $(HOST_CFLAGS) gen_matypes.c -o gen_matypes
# need some special rules here, unfortunately
matypes.h: ../main/mtypes.h ../tnl/t_context.h gen_matypes
diff --git a/src/mesa/x86/glapi_x86.S b/src/mesa/x86/glapi_x86.S
index 40fc6f2229..12c77f434e 100644
--- a/src/mesa/x86/glapi_x86.S
+++ b/src/mesa/x86/glapi_x86.S
@@ -52,7 +52,7 @@
#define GLOBL_FN(x) GLOBL x
#endif
-#if defined(PTHREADS) || defined(USE_XTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
+#if defined(PTHREADS) || defined(SOLARIS_THREADS) || defined(WIN32_THREADS) || defined(BEOS_THREADS)
# define THREADS
#endif
@@ -718,23 +718,33 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(BindVertexArray, _gloffset_BindVertexArray, BindVertexArray@4)
GL_STUB(GenVertexArrays, _gloffset_GenVertexArrays, GenVertexArrays@8)
GL_STUB(CopyBufferSubData, _gloffset_CopyBufferSubData, CopyBufferSubData@20)
+ GL_STUB(ClientWaitSync, _gloffset_ClientWaitSync, ClientWaitSync@12)
+ GL_STUB(DeleteSync, _gloffset_DeleteSync, DeleteSync@4)
+ GL_STUB(FenceSync, _gloffset_FenceSync, FenceSync@8)
+ GL_STUB(GetInteger64v, _gloffset_GetInteger64v, GetInteger64v@8)
+ GL_STUB(GetSynciv, _gloffset_GetSynciv, GetSynciv@20)
+ GL_STUB(IsSync, _gloffset_IsSync, IsSync@4)
+ GL_STUB(WaitSync, _gloffset_WaitSync, WaitSync@12)
+ GL_STUB(DrawElementsBaseVertex, _gloffset_DrawElementsBaseVertex, DrawElementsBaseVertex@20)
+ GL_STUB(DrawRangeElementsBaseVertex, _gloffset_DrawRangeElementsBaseVertex, DrawRangeElementsBaseVertex@28)
+ GL_STUB(MultiDrawElementsBaseVertex, _gloffset_MultiDrawElementsBaseVertex, MultiDrawElementsBaseVertex@24)
GL_STUB(PolygonOffsetEXT, _gloffset_PolygonOffsetEXT, PolygonOffsetEXT@8)
- GL_STUB(_dispatch_stub_568, _gloffset_GetPixelTexGenParameterfvSGIS, _dispatch_stub_568@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_568, _dispatch_stub_568@8))
- GL_STUB(_dispatch_stub_569, _gloffset_GetPixelTexGenParameterivSGIS, _dispatch_stub_569@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_569, _dispatch_stub_569@8))
- GL_STUB(_dispatch_stub_570, _gloffset_PixelTexGenParameterfSGIS, _dispatch_stub_570@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_570, _dispatch_stub_570@8))
- GL_STUB(_dispatch_stub_571, _gloffset_PixelTexGenParameterfvSGIS, _dispatch_stub_571@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_571, _dispatch_stub_571@8))
- GL_STUB(_dispatch_stub_572, _gloffset_PixelTexGenParameteriSGIS, _dispatch_stub_572@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_572, _dispatch_stub_572@8))
- GL_STUB(_dispatch_stub_573, _gloffset_PixelTexGenParameterivSGIS, _dispatch_stub_573@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_573, _dispatch_stub_573@8))
- GL_STUB(_dispatch_stub_574, _gloffset_SampleMaskSGIS, _dispatch_stub_574@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_574, _dispatch_stub_574@8))
- GL_STUB(_dispatch_stub_575, _gloffset_SamplePatternSGIS, _dispatch_stub_575@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_575, _dispatch_stub_575@4))
+ GL_STUB(_dispatch_stub_578, _gloffset_GetPixelTexGenParameterfvSGIS, _dispatch_stub_578@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_578, _dispatch_stub_578@8))
+ GL_STUB(_dispatch_stub_579, _gloffset_GetPixelTexGenParameterivSGIS, _dispatch_stub_579@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_579, _dispatch_stub_579@8))
+ GL_STUB(_dispatch_stub_580, _gloffset_PixelTexGenParameterfSGIS, _dispatch_stub_580@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_580, _dispatch_stub_580@8))
+ GL_STUB(_dispatch_stub_581, _gloffset_PixelTexGenParameterfvSGIS, _dispatch_stub_581@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_581, _dispatch_stub_581@8))
+ GL_STUB(_dispatch_stub_582, _gloffset_PixelTexGenParameteriSGIS, _dispatch_stub_582@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_582, _dispatch_stub_582@8))
+ GL_STUB(_dispatch_stub_583, _gloffset_PixelTexGenParameterivSGIS, _dispatch_stub_583@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_583, _dispatch_stub_583@8))
+ GL_STUB(_dispatch_stub_584, _gloffset_SampleMaskSGIS, _dispatch_stub_584@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_584, _dispatch_stub_584@8))
+ GL_STUB(_dispatch_stub_585, _gloffset_SamplePatternSGIS, _dispatch_stub_585@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_585, _dispatch_stub_585@4))
GL_STUB(ColorPointerEXT, _gloffset_ColorPointerEXT, ColorPointerEXT@20)
GL_STUB(EdgeFlagPointerEXT, _gloffset_EdgeFlagPointerEXT, EdgeFlagPointerEXT@12)
GL_STUB(IndexPointerEXT, _gloffset_IndexPointerEXT, IndexPointerEXT@16)
@@ -745,10 +755,10 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(PointParameterfvEXT, _gloffset_PointParameterfvEXT, PointParameterfvEXT@8)
GL_STUB(LockArraysEXT, _gloffset_LockArraysEXT, LockArraysEXT@8)
GL_STUB(UnlockArraysEXT, _gloffset_UnlockArraysEXT, UnlockArraysEXT@0)
- GL_STUB(_dispatch_stub_586, _gloffset_CullParameterdvEXT, _dispatch_stub_586@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_586, _dispatch_stub_586@8))
- GL_STUB(_dispatch_stub_587, _gloffset_CullParameterfvEXT, _dispatch_stub_587@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_587, _dispatch_stub_587@8))
+ GL_STUB(_dispatch_stub_596, _gloffset_CullParameterdvEXT, _dispatch_stub_596@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_596, _dispatch_stub_596@8))
+ GL_STUB(_dispatch_stub_597, _gloffset_CullParameterfvEXT, _dispatch_stub_597@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_597, _dispatch_stub_597@8))
GL_STUB(SecondaryColor3bEXT, _gloffset_SecondaryColor3bEXT, SecondaryColor3bEXT@12)
GL_STUB(SecondaryColor3bvEXT, _gloffset_SecondaryColor3bvEXT, SecondaryColor3bvEXT@4)
GL_STUB(SecondaryColor3dEXT, _gloffset_SecondaryColor3dEXT, SecondaryColor3dEXT@24)
@@ -773,8 +783,8 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(FogCoorddvEXT, _gloffset_FogCoorddvEXT, FogCoorddvEXT@4)
GL_STUB(FogCoordfEXT, _gloffset_FogCoordfEXT, FogCoordfEXT@4)
GL_STUB(FogCoordfvEXT, _gloffset_FogCoordfvEXT, FogCoordfvEXT@4)
- GL_STUB(_dispatch_stub_612, _gloffset_PixelTexGenSGIX, _dispatch_stub_612@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_612, _dispatch_stub_612@4))
+ GL_STUB(_dispatch_stub_622, _gloffset_PixelTexGenSGIX, _dispatch_stub_622@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_622, _dispatch_stub_622@4))
GL_STUB(BlendFuncSeparateEXT, _gloffset_BlendFuncSeparateEXT, BlendFuncSeparateEXT@16)
GL_STUB(FlushVertexArrayRangeNV, _gloffset_FlushVertexArrayRangeNV, FlushVertexArrayRangeNV@0)
GL_STUB(VertexArrayRangeNV, _gloffset_VertexArrayRangeNV, VertexArrayRangeNV@8)
@@ -816,24 +826,24 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(WindowPos4ivMESA, _gloffset_WindowPos4ivMESA, WindowPos4ivMESA@4)
GL_STUB(WindowPos4sMESA, _gloffset_WindowPos4sMESA, WindowPos4sMESA@16)
GL_STUB(WindowPos4svMESA, _gloffset_WindowPos4svMESA, WindowPos4svMESA@4)
- GL_STUB(_dispatch_stub_654, _gloffset_MultiModeDrawArraysIBM, _dispatch_stub_654@20)
- HIDDEN(GL_PREFIX(_dispatch_stub_654, _dispatch_stub_654@20))
- GL_STUB(_dispatch_stub_655, _gloffset_MultiModeDrawElementsIBM, _dispatch_stub_655@24)
- HIDDEN(GL_PREFIX(_dispatch_stub_655, _dispatch_stub_655@24))
- GL_STUB(_dispatch_stub_656, _gloffset_DeleteFencesNV, _dispatch_stub_656@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_656, _dispatch_stub_656@8))
- GL_STUB(_dispatch_stub_657, _gloffset_FinishFenceNV, _dispatch_stub_657@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_657, _dispatch_stub_657@4))
- GL_STUB(_dispatch_stub_658, _gloffset_GenFencesNV, _dispatch_stub_658@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_658, _dispatch_stub_658@8))
- GL_STUB(_dispatch_stub_659, _gloffset_GetFenceivNV, _dispatch_stub_659@12)
- HIDDEN(GL_PREFIX(_dispatch_stub_659, _dispatch_stub_659@12))
- GL_STUB(_dispatch_stub_660, _gloffset_IsFenceNV, _dispatch_stub_660@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_660, _dispatch_stub_660@4))
- GL_STUB(_dispatch_stub_661, _gloffset_SetFenceNV, _dispatch_stub_661@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_661, _dispatch_stub_661@8))
- GL_STUB(_dispatch_stub_662, _gloffset_TestFenceNV, _dispatch_stub_662@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_662, _dispatch_stub_662@4))
+ GL_STUB(_dispatch_stub_664, _gloffset_MultiModeDrawArraysIBM, _dispatch_stub_664@20)
+ HIDDEN(GL_PREFIX(_dispatch_stub_664, _dispatch_stub_664@20))
+ GL_STUB(_dispatch_stub_665, _gloffset_MultiModeDrawElementsIBM, _dispatch_stub_665@24)
+ HIDDEN(GL_PREFIX(_dispatch_stub_665, _dispatch_stub_665@24))
+ GL_STUB(_dispatch_stub_666, _gloffset_DeleteFencesNV, _dispatch_stub_666@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_666, _dispatch_stub_666@8))
+ GL_STUB(_dispatch_stub_667, _gloffset_FinishFenceNV, _dispatch_stub_667@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_667, _dispatch_stub_667@4))
+ GL_STUB(_dispatch_stub_668, _gloffset_GenFencesNV, _dispatch_stub_668@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_668, _dispatch_stub_668@8))
+ GL_STUB(_dispatch_stub_669, _gloffset_GetFenceivNV, _dispatch_stub_669@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_669, _dispatch_stub_669@12))
+ GL_STUB(_dispatch_stub_670, _gloffset_IsFenceNV, _dispatch_stub_670@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_670, _dispatch_stub_670@4))
+ GL_STUB(_dispatch_stub_671, _gloffset_SetFenceNV, _dispatch_stub_671@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_671, _dispatch_stub_671@8))
+ GL_STUB(_dispatch_stub_672, _gloffset_TestFenceNV, _dispatch_stub_672@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_672, _dispatch_stub_672@4))
GL_STUB(AreProgramsResidentNV, _gloffset_AreProgramsResidentNV, AreProgramsResidentNV@12)
GL_STUB(BindProgramNV, _gloffset_BindProgramNV, BindProgramNV@8)
GL_STUB(DeleteProgramsNV, _gloffset_DeleteProgramsNV, DeleteProgramsNV@8)
@@ -914,26 +924,26 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(SetFragmentShaderConstantATI, _gloffset_SetFragmentShaderConstantATI, SetFragmentShaderConstantATI@8)
GL_STUB(PointParameteriNV, _gloffset_PointParameteriNV, PointParameteriNV@8)
GL_STUB(PointParameterivNV, _gloffset_PointParameterivNV, PointParameterivNV@8)
- GL_STUB(_dispatch_stub_743, _gloffset_ActiveStencilFaceEXT, _dispatch_stub_743@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_743, _dispatch_stub_743@4))
- GL_STUB(_dispatch_stub_744, _gloffset_BindVertexArrayAPPLE, _dispatch_stub_744@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_744, _dispatch_stub_744@4))
- GL_STUB(_dispatch_stub_745, _gloffset_DeleteVertexArraysAPPLE, _dispatch_stub_745@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_745, _dispatch_stub_745@8))
- GL_STUB(_dispatch_stub_746, _gloffset_GenVertexArraysAPPLE, _dispatch_stub_746@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_746, _dispatch_stub_746@8))
- GL_STUB(_dispatch_stub_747, _gloffset_IsVertexArrayAPPLE, _dispatch_stub_747@4)
- HIDDEN(GL_PREFIX(_dispatch_stub_747, _dispatch_stub_747@4))
+ GL_STUB(_dispatch_stub_753, _gloffset_ActiveStencilFaceEXT, _dispatch_stub_753@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_753, _dispatch_stub_753@4))
+ GL_STUB(_dispatch_stub_754, _gloffset_BindVertexArrayAPPLE, _dispatch_stub_754@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_754, _dispatch_stub_754@4))
+ GL_STUB(_dispatch_stub_755, _gloffset_DeleteVertexArraysAPPLE, _dispatch_stub_755@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_755, _dispatch_stub_755@8))
+ GL_STUB(_dispatch_stub_756, _gloffset_GenVertexArraysAPPLE, _dispatch_stub_756@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_756, _dispatch_stub_756@8))
+ GL_STUB(_dispatch_stub_757, _gloffset_IsVertexArrayAPPLE, _dispatch_stub_757@4)
+ HIDDEN(GL_PREFIX(_dispatch_stub_757, _dispatch_stub_757@4))
GL_STUB(GetProgramNamedParameterdvNV, _gloffset_GetProgramNamedParameterdvNV, GetProgramNamedParameterdvNV@16)
GL_STUB(GetProgramNamedParameterfvNV, _gloffset_GetProgramNamedParameterfvNV, GetProgramNamedParameterfvNV@16)
GL_STUB(ProgramNamedParameter4dNV, _gloffset_ProgramNamedParameter4dNV, ProgramNamedParameter4dNV@44)
GL_STUB(ProgramNamedParameter4dvNV, _gloffset_ProgramNamedParameter4dvNV, ProgramNamedParameter4dvNV@16)
GL_STUB(ProgramNamedParameter4fNV, _gloffset_ProgramNamedParameter4fNV, ProgramNamedParameter4fNV@28)
GL_STUB(ProgramNamedParameter4fvNV, _gloffset_ProgramNamedParameter4fvNV, ProgramNamedParameter4fvNV@16)
- GL_STUB(_dispatch_stub_754, _gloffset_DepthBoundsEXT, _dispatch_stub_754@16)
- HIDDEN(GL_PREFIX(_dispatch_stub_754, _dispatch_stub_754@16))
- GL_STUB(_dispatch_stub_755, _gloffset_BlendEquationSeparateEXT, _dispatch_stub_755@8)
- HIDDEN(GL_PREFIX(_dispatch_stub_755, _dispatch_stub_755@8))
+ GL_STUB(_dispatch_stub_764, _gloffset_DepthBoundsEXT, _dispatch_stub_764@16)
+ HIDDEN(GL_PREFIX(_dispatch_stub_764, _dispatch_stub_764@16))
+ GL_STUB(_dispatch_stub_765, _gloffset_BlendEquationSeparateEXT, _dispatch_stub_765@8)
+ HIDDEN(GL_PREFIX(_dispatch_stub_765, _dispatch_stub_765@8))
GL_STUB(BindFramebufferEXT, _gloffset_BindFramebufferEXT, BindFramebufferEXT@8)
GL_STUB(BindRenderbufferEXT, _gloffset_BindRenderbufferEXT, BindRenderbufferEXT@8)
GL_STUB(CheckFramebufferStatusEXT, _gloffset_CheckFramebufferStatusEXT, CheckFramebufferStatusEXT@4)
@@ -951,20 +961,28 @@ GLNAME(gl_dispatch_functions_start):
GL_STUB(IsFramebufferEXT, _gloffset_IsFramebufferEXT, IsFramebufferEXT@4)
GL_STUB(IsRenderbufferEXT, _gloffset_IsRenderbufferEXT, IsRenderbufferEXT@4)
GL_STUB(RenderbufferStorageEXT, _gloffset_RenderbufferStorageEXT, RenderbufferStorageEXT@16)
- GL_STUB(_dispatch_stub_773, _gloffset_BlitFramebufferEXT, _dispatch_stub_773@40)
- HIDDEN(GL_PREFIX(_dispatch_stub_773, _dispatch_stub_773@40))
+ GL_STUB(_dispatch_stub_783, _gloffset_BlitFramebufferEXT, _dispatch_stub_783@40)
+ HIDDEN(GL_PREFIX(_dispatch_stub_783, _dispatch_stub_783@40))
+ GL_STUB(_dispatch_stub_784, _gloffset_BufferParameteriAPPLE, _dispatch_stub_784@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_784, _dispatch_stub_784@12))
+ GL_STUB(_dispatch_stub_785, _gloffset_FlushMappedBufferRangeAPPLE, _dispatch_stub_785@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_785, _dispatch_stub_785@12))
GL_STUB(FramebufferTextureLayerEXT, _gloffset_FramebufferTextureLayerEXT, FramebufferTextureLayerEXT@20)
GL_STUB(ProvokingVertexEXT, _gloffset_ProvokingVertexEXT, ProvokingVertexEXT@4)
- GL_STUB(_dispatch_stub_776, _gloffset_StencilFuncSeparateATI, _dispatch_stub_776@16)
- HIDDEN(GL_PREFIX(_dispatch_stub_776, _dispatch_stub_776@16))
- GL_STUB(_dispatch_stub_777, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_777@16)
- HIDDEN(GL_PREFIX(_dispatch_stub_777, _dispatch_stub_777@16))
- GL_STUB(_dispatch_stub_778, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_778@16)
- HIDDEN(GL_PREFIX(_dispatch_stub_778, _dispatch_stub_778@16))
- GL_STUB(_dispatch_stub_779, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_779@12)
- HIDDEN(GL_PREFIX(_dispatch_stub_779, _dispatch_stub_779@12))
- GL_STUB(_dispatch_stub_780, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_780@12)
- HIDDEN(GL_PREFIX(_dispatch_stub_780, _dispatch_stub_780@12))
+ GL_STUB(_dispatch_stub_788, _gloffset_GetTexParameterPointervAPPLE, _dispatch_stub_788@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_788, _dispatch_stub_788@12))
+ GL_STUB(_dispatch_stub_789, _gloffset_TextureRangeAPPLE, _dispatch_stub_789@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_789, _dispatch_stub_789@12))
+ GL_STUB(_dispatch_stub_790, _gloffset_StencilFuncSeparateATI, _dispatch_stub_790@16)
+ HIDDEN(GL_PREFIX(_dispatch_stub_790, _dispatch_stub_790@16))
+ GL_STUB(_dispatch_stub_791, _gloffset_ProgramEnvParameters4fvEXT, _dispatch_stub_791@16)
+ HIDDEN(GL_PREFIX(_dispatch_stub_791, _dispatch_stub_791@16))
+ GL_STUB(_dispatch_stub_792, _gloffset_ProgramLocalParameters4fvEXT, _dispatch_stub_792@16)
+ HIDDEN(GL_PREFIX(_dispatch_stub_792, _dispatch_stub_792@16))
+ GL_STUB(_dispatch_stub_793, _gloffset_GetQueryObjecti64vEXT, _dispatch_stub_793@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_793, _dispatch_stub_793@12))
+ GL_STUB(_dispatch_stub_794, _gloffset_GetQueryObjectui64vEXT, _dispatch_stub_794@12)
+ HIDDEN(GL_PREFIX(_dispatch_stub_794, _dispatch_stub_794@12))
GL_STUB_ALIAS(ArrayElementEXT, _gloffset_ArrayElement, ArrayElementEXT@4, ArrayElement, ArrayElement@4)
GL_STUB_ALIAS(BindTextureEXT, _gloffset_BindTexture, BindTextureEXT@8, BindTexture, BindTexture@8)
GL_STUB_ALIAS(DrawArraysEXT, _gloffset_DrawArrays, DrawArraysEXT@12, DrawArrays, DrawArrays@12)
@@ -1298,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/mesa/x86/x86_xform.c b/src/mesa/x86/x86_xform.c
index 16b2b26bcc..52f6b25d81 100644
--- a/src/mesa/x86/x86_xform.c
+++ b/src/mesa/x86/x86_xform.c
@@ -60,21 +60,24 @@ _mesa_x86_cliptest_points4( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask );
+ GLubyte *andMask,
+ GLboolean viewport_z_clip );
extern GLvector4f * _ASMAPI
_mesa_x86_cliptest_points4_np( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
- GLubyte *andMask );
+ GLubyte *andMask,
+ GLboolean viewport_z_clip );
extern void _ASMAPI
_mesa_v16_x86_cliptest_points4( GLfloat *first_vert,
GLfloat *last_vert,
GLubyte *or_mask,
GLubyte *and_mask,
- GLubyte *clip_mask );
+ GLubyte *clip_mask,
+ GLboolean viewport_z_clip );
extern void _ASMAPI
_mesa_v16_x86_general_xform( GLfloat *dest,
diff --git a/src/xvmc/context.c b/src/xvmc/context.c
index 273f658029..9c2b6648bb 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 c8f70c90d0..09e9c98e6a 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 7c5f45bd34..fea351b84f 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 4d5d4c744b..4d7df74170 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 51a837f021..f15c4435f6 100644
--- a/windows/VC8/mesa/mesa/mesa.vcproj
+++ b/windows/VC8/mesa/mesa/mesa.vcproj
@@ -52,6 +52,7 @@
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -122,6 +123,7 @@
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -192,6 +194,7 @@
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -262,6 +265,7 @@
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -379,6 +383,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\cpuinfo.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\debug.c"
>
</File>
@@ -651,10 +659,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\shader\prog_debug.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\shader\prog_execute.c"
>
</File>
@@ -667,6 +671,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\shader\prog_optimize.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\shader\prog_parameter.c"
>
</File>
@@ -775,10 +783,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_imaging.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_lines.c"
>
</File>
@@ -815,10 +819,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\swrast\s_texstore.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\swrast\s_triangle.c"
>
</File>
@@ -1035,6 +1035,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\texgetimage.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\teximage.c"
>
</File>
@@ -1063,10 +1067,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\main\viewport.c"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\vbo\vbo_context.c"
>
</File>
@@ -1123,6 +1123,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\viewport.c"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\vsnprintf.c"
>
<FileConfiguration
@@ -1264,6 +1268,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\cpuinfo.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\dd.h"
>
</File>
@@ -1520,10 +1528,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\shader\prog_debug.h"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\shader\prog_execute.h"
>
</File>
@@ -1536,6 +1540,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\shader\prog_optimize.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\shader\prog_parameter.h"
>
</File>
@@ -1880,6 +1888,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\texgetimage.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\teximage.h"
>
</File>
@@ -1912,10 +1924,6 @@
>
</File>
<File
- RelativePath="..\..\..\..\src\mesa\main\viewport.h"
- >
- </File>
- <File
RelativePath="..\..\..\..\src\mesa\vbo\vbo.h"
>
</File>
@@ -1948,6 +1956,10 @@
>
</File>
<File
+ RelativePath="..\..\..\..\src\mesa\main\viewport.h"
+ >
+ </File>
+ <File
RelativePath="..\..\..\..\src\mesa\main\vtxfmt.h"
>
</File>
diff --git a/windows/VC8/mesa/osmesa/osmesa.vcproj b/windows/VC8/mesa/osmesa/osmesa.vcproj
index d7cd47a6c1..10f2dc9717 100644
--- a/windows/VC8/mesa/osmesa/osmesa.vcproj
+++ b/windows/VC8/mesa/osmesa/osmesa.vcproj
@@ -55,6 +55,7 @@
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -145,6 +146,7 @@
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -236,6 +238,7 @@
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"
@@ -327,6 +330,7 @@
WarningLevel="3"
SuppressStartupBanner="true"
CompileAs="0"
+ ForcedIncludeFiles="../../../../src/mesa/main/compiler.h"
/>
<Tool
Name="VCManagedResourceCompilerTool"