summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Romanick <ian.d.romanick@intel.com>2009-08-18 12:20:36 -0700
committerIan Romanick <ian.d.romanick@intel.com>2009-08-18 12:20:36 -0700
commita512985fd81c1ed4ccc5e69aaa05015cf7ff844d (patch)
tree69e6e898deaeaed2b4dfb5851707c68261c464de
parent0b5af41c6fae2809f4567a7cecbd207e5e4f3ab5 (diff)
parentc80bc3abcd3939e5e2d45aea4b01ff22bfec244b (diff)
Merge branch 'master' into asm-shader-rework-1
Conflicts: src/mesa/shader/arbprogparse.c
-rw-r--r--Makefile13
-rwxr-xr-xbin/mklib1
-rw-r--r--configure.ac15
-rw-r--r--docs/dispatch.html2
-rw-r--r--docs/faq.html13
-rw-r--r--docs/relnotes-7.5.1.html61
-rw-r--r--docs/relnotes-7.5.html10
-rw-r--r--docs/relnotes-7.6.html4
-rw-r--r--docs/relnotes.html1
-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/demos/cubemap.c54
-rw-r--r--progs/egl/Makefile7
-rw-r--r--progs/egl/xeglbindtex.c474
-rw-r--r--progs/glsl/.gitignore1
-rw-r--r--progs/glsl/Makefile162
-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.c13
-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/shadow_sampler.c1
-rw-r--r--progs/glsl/shtest.c629
-rw-r--r--progs/glsl/texaaline.c1
-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/tests/SConscript1
-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/texcompsub.c22
-rw-r--r--progs/tests/texwrap.c18
-rw-r--r--progs/trivial/.gitignore15
-rw-r--r--progs/trivial/Makefile8
-rw-r--r--progs/util/shaderutil.c151
-rw-r--r--progs/util/shaderutil.h26
-rw-r--r--progs/vp/arl-static.txt2
-rw-r--r--progs/vp/arl-unused.txt2
-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/gallium.py2
-rw-r--r--src/egl/drivers/demo/Makefile2
-rw-r--r--src/egl/drivers/demo/demo.c4
-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.c2
-rw-r--r--src/egl/drivers/xdri/egl_xdri.c2
-rw-r--r--src/egl/main/Makefile4
-rw-r--r--src/egl/main/eglapi.c1
-rw-r--r--src/egl/main/eglcompiler.h33
-rw-r--r--src/egl/main/eglconfig.c2
-rw-r--r--src/egl/main/eglconfigutil.c2
-rw-r--r--src/egl/main/eglcontext.c106
-rw-r--r--src/egl/main/eglcontext.h17
-rw-r--r--src/egl/main/eglcurrent.c125
-rw-r--r--src/egl/main/eglcurrent.h8
-rw-r--r--src/egl/main/egldisplay.c114
-rw-r--r--src/egl/main/egldisplay.h26
-rw-r--r--src/egl/main/eglglobals.c66
-rw-r--r--src/egl/main/eglglobals.h17
-rw-r--r--src/egl/main/eglmutex.h52
-rw-r--r--src/egl/main/eglsurface.c5
-rw-r--r--src/egl/main/eglsurface.h19
-rw-r--r--src/gallium/Makefile.template4
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe.c78
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_pstipple.c5
-rw-r--r--src/gallium/auxiliary/draw/draw_pipe_wide_point.c48
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_aos.c17
-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.cpp84
-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.txt28
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.c23
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_build.h2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump.c13
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_dump_c.c8
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c67
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.c258
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_info.h7
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h173
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.c13
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_parse.h6
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c25
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sanity.c29
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_sse2.c55
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_text.c18
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.c797
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ureg.h439
-rw-r--r--src/gallium/auxiliary/util/u_blit.c82
-rw-r--r--src/gallium/auxiliary/util/u_debug.c2
-rw-r--r--src/gallium/auxiliary/util/u_gen_mipmap.c4
-rw-r--r--src/gallium/auxiliary/util/u_math.h75
-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_simple_screen.c3
-rw-r--r--src/gallium/auxiliary/util/u_simple_shaders.c318
-rw-r--r--src/gallium/auxiliary/util/u_surface.h17
-rw-r--r--src/gallium/auxiliary/util/u_tile.c2
-rw-r--r--src/gallium/auxiliary/util/u_time.c12
-rw-r--r--src/gallium/auxiliary/util/u_time.h6
-rw-r--r--src/gallium/auxiliary/util/u_timed_winsys.c3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_gen_fp.c8
-rw-r--r--src/gallium/drivers/cell/ppu/cell_texture.c13
-rw-r--r--src/gallium/drivers/cell/spu/spu_exec.c46
-rw-r--r--src/gallium/drivers/i915simple/i915_batch.h4
-rw-r--r--src/gallium/drivers/i915simple/i915_context.c16
-rw-r--r--src/gallium/drivers/i915simple/i915_fpc_translate.c3
-rw-r--r--src/gallium/drivers/i915simple/i915_screen.c2
-rw-r--r--src/gallium/drivers/i915simple/i915_texture.c30
-rw-r--r--src/gallium/drivers/i915simple/i915_winsys.h1
-rw-r--r--src/gallium/drivers/i965simple/brw_tex_layout.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_vs_emit.c8
-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.c4
-rw-r--r--src/gallium/drivers/identity/id_screen.c2
-rw-r--r--src/gallium/drivers/nouveau/nouveau_screen.c9
-rw-r--r--src/gallium/drivers/nv04/nv04_surface_2d.c102
-rw-r--r--src/gallium/drivers/nv20/nv20_vertprog.c8
-rw-r--r--src/gallium/drivers/nv30/nv30_fragprog.c8
-rw-r--r--src/gallium/drivers/nv30/nv30_screen.c2
-rw-r--r--src/gallium/drivers/nv30/nv30_vertprog.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_fragprog.c8
-rw-r--r--src/gallium/drivers/nv40/nv40_vertprog.c8
-rw-r--r--src/gallium/drivers/nv50/nv50_context.c18
-rw-r--r--src/gallium/drivers/nv50/nv50_context.h1
-rw-r--r--src/gallium/drivers/nv50/nv50_miptree.c28
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c46
-rw-r--r--src/gallium/drivers/nv50/nv50_query.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c55
-rw-r--r--src/gallium/drivers/nv50/nv50_state.c19
-rw-r--r--src/gallium/drivers/nv50/nv50_state_validate.c91
-rw-r--r--src/gallium/drivers/nv50/nv50_surface.c12
-rw-r--r--src/gallium/drivers/nv50/nv50_tex.c31
-rw-r--r--src/gallium/drivers/nv50/nv50_texture.h71
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c76
-rw-r--r--src/gallium/drivers/nv50/nv50_vbo.c87
-rw-r--r--src/gallium/drivers/r300/Makefile19
-rw-r--r--src/gallium/drivers/r300/r300_context.c2
-rw-r--r--src/gallium/drivers/r300/r300_context.h91
-rw-r--r--src/gallium/drivers/r300/r300_debug.c198
-rw-r--r--src/gallium/drivers/r300/r300_debug.h211
-rw-r--r--src/gallium/drivers/r300/r300_emit.c265
-rw-r--r--src/gallium/drivers/r300/r300_emit.h17
-rw-r--r--src/gallium/drivers/r300/r300_fs.c164
-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_screen.c7
-rw-r--r--src/gallium/drivers/r300/r300_state.c29
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c3
-rw-r--r--src/gallium/drivers/r300/r300_state_invariant.c11
-rw-r--r--src/gallium/drivers/r300/r300_surface.c38
-rw-r--r--src/gallium/drivers/r300/r300_texture.c22
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.c337
-rw-r--r--src/gallium/drivers/r300/r300_tgsi_to_rc.h41
-rw-r--r--src/gallium/drivers/r300/r300_vs.c520
-rw-r--r--src/gallium/drivers/r300/r300_vs.h137
-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_texture.c21
-rw-r--r--src/gallium/drivers/trace/tr_drm.c6
-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_defines.h6
-rw-r--r--src/gallium/include/pipe/p_screen.h1
-rw-r--r--src/gallium/include/pipe/p_shader_tokens.h191
-rw-r--r--src/gallium/state_trackers/dri/dri_context.c8
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.c24
-rw-r--r--src/gallium/state_trackers/dri/dri_drawable.h6
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.c7
-rw-r--r--src/gallium/state_trackers/dri/dri_screen.h6
-rw-r--r--src/gallium/state_trackers/egl/egl_context.c2
-rw-r--r--src/gallium/state_trackers/egl/egl_surface.c6
-rw-r--r--src/gallium/state_trackers/glx/xlib/Makefile9
-rw-r--r--src/gallium/state_trackers/glx/xlib/SConscript7
-rw-r--r--src/gallium/state_trackers/glx/xlib/fakeglx.h41
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_api.c (renamed from src/gallium/state_trackers/glx/xlib/fakeglx.c)672
-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.h2
-rw-r--r--src/gallium/state_trackers/vega/asm_filters.h4
-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/xorg/xorg_dri2.c77
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c33
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c52
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.h2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h9
-rw-r--r--src/gallium/winsys/drm/Makefile.template4
-rw-r--r--src/gallium/winsys/drm/intel/dri/SConscript5
-rw-r--r--src/gallium/winsys/drm/intel/egl/Makefile1
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_batchbuffer.c43
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_context.c2
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.c83
-rw-r--r--src/gallium/winsys/drm/intel/gem/intel_be_device.h5
-rw-r--r--src/gallium/winsys/drm/intel/xorg/Makefile1
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.c1
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_buffer.h5
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.c4
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_drm.h8
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.c78
-rw-r--r--src/gallium/winsys/drm/radeon/core/radeon_r300.h18
-rw-r--r--src/gallium/winsys/egl_xlib/egl_xlib.c195
-rw-r--r--src/gallium/winsys/egl_xlib/sw_winsys.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_brw_screen.c1
-rw-r--r--src/gallium/winsys/xlib/xlib_softpipe.c1
-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.c9
-rw-r--r--src/glx/x11/glx_query.c46
-rw-r--r--src/glx/x11/glxclient.h428
-rw-r--r--src/glx/x11/glxcmds.c3621
-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/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/drivers/common/meta.c1249
-rw-r--r--src/mesa/drivers/common/meta.h80
-rw-r--r--src/mesa/drivers/dri/common/.gitignore1
-rw-r--r--src/mesa/drivers/dri/common/dri_metaops.c7
-rw-r--r--src/mesa/drivers/dri/common/dri_util.c2
-rw-r--r--src/mesa/drivers/dri/common/extension_helper.h44
-rw-r--r--src/mesa/drivers/dri/fb/fb_egl.c4
-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.c4
-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
-rw-r--r--src/mesa/drivers/dri/i965/Makefile1
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c3
-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_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.h19
-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.c55
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw.h1
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c141
-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_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.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_structs.h15
-rw-r--r--src/mesa/drivers/dri/i965/brw_tex_layout.c13
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c73
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.c8
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c48
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_fp.c112
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c156
-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_sampler_state.c44
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c10
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c31
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h9
-rw-r--r--src/mesa/drivers/dri/intel/intel_extensions.c6
-rw-r--r--src/mesa/drivers/dri/intel/intel_fbo.c71
-rw-r--r--src/mesa/drivers/dri/intel/intel_pixel_copy.c167
-rw-r--r--src/mesa/drivers/dri/intel/intel_regions.c21
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c12
-rw-r--r--src/mesa/drivers/dri/intel/intel_span.c4
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_subimage.c65
-rw-r--r--src/mesa/drivers/dri/r200/.gitignore15
-rw-r--r--src/mesa/drivers/dri/r200/Makefile48
-rw-r--r--src/mesa/drivers/dri/r200/r200_cmdbuf.c48
-rw-r--r--src/mesa/drivers/dri/r200/r200_context.c12
-rw-r--r--src/mesa/drivers/dri/r200/r200_state_init.c10
l---------src/mesa/drivers/dri/r200/radeon_bo_legacy.c1
l---------src/mesa/drivers/dri/r200/radeon_bo_legacy.h1
l---------src/mesa/drivers/dri/r200/radeon_bocs_wrapper.h1
l---------src/mesa/drivers/dri/r200/radeon_chipset.h1
l---------src/mesa/drivers/dri/r200/radeon_cmdbuf.h1
l---------src/mesa/drivers/dri/r200/radeon_common.c1
l---------src/mesa/drivers/dri/r200/radeon_common.h1
l---------src/mesa/drivers/dri/r200/radeon_common_context.c1
l---------src/mesa/drivers/dri/r200/radeon_common_context.h1
l---------src/mesa/drivers/dri/r200/radeon_cs_legacy.c1
l---------src/mesa/drivers/dri/r200/radeon_cs_legacy.h1
l---------src/mesa/drivers/dri/r200/radeon_cs_space_drm.c1
l---------src/mesa/drivers/dri/r200/radeon_dma.c1
l---------src/mesa/drivers/dri/r200/radeon_dma.h1
l---------src/mesa/drivers/dri/r200/radeon_fbo.c1
l---------src/mesa/drivers/dri/r200/radeon_lock.c1
l---------src/mesa/drivers/dri/r200/radeon_lock.h1
l---------src/mesa/drivers/dri/r200/radeon_mipmap_tree.c1
l---------src/mesa/drivers/dri/r200/radeon_mipmap_tree.h1
l---------src/mesa/drivers/dri/r200/radeon_screen.c1
l---------src/mesa/drivers/dri/r200/radeon_screen.h1
l---------src/mesa/drivers/dri/r200/radeon_span.c1
l---------src/mesa/drivers/dri/r200/radeon_span.h1
l---------src/mesa/drivers/dri/r200/radeon_texture.c1
l---------src/mesa/drivers/dri/r200/radeon_texture.h1
l---------src/mesa/drivers/dri/r200/server/radeon.h1
l---------src/mesa/drivers/dri/r200/server/radeon_dri.c1
l---------src/mesa/drivers/dri/r200/server/radeon_dri.h1
l---------src/mesa/drivers/dri/r200/server/radeon_egl.c1
l---------src/mesa/drivers/dri/r200/server/radeon_macros.h1
l---------src/mesa/drivers/dri/r200/server/radeon_reg.h1
-rw-r--r--src/mesa/drivers/dri/r300/.gitignore15
-rw-r--r--src/mesa/drivers/dri/r300/Makefile63
-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.c615
-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.h206
-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.c181
-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)460
-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)314
-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.c81
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.c41
-rw-r--r--src/mesa/drivers/dri/r300/r300_context.h196
-rw-r--r--src/mesa/drivers/dri/r300/r300_draw.c436
-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.c364
-rw-r--r--src/mesa/drivers/dri/r300/r300_fragprog_common.h4
-rw-r--r--src/mesa/drivers/dri/r300/r300_ioctl.c98
-rw-r--r--src/mesa/drivers/dri/r300/r300_queryobj.c250
-rw-r--r--src/mesa/drivers/dri/r300/r300_queryobj.h34
-rw-r--r--src/mesa/drivers/dri/r300/r300_reg.h30
-rw-r--r--src/mesa/drivers/dri/r300/r300_render.c216
-rw-r--r--src/mesa/drivers/dri/r300/r300_shader.c11
-rw-r--r--src/mesa/drivers/dri/r300/r300_state.c247
-rw-r--r--src/mesa/drivers/dri/r300/r300_swtcl.c2
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.c1576
-rw-r--r--src/mesa/drivers/dri/r300/r300_vertprog.h32
l---------src/mesa/drivers/dri/r300/radeon_bo_legacy.c1
l---------src/mesa/drivers/dri/r300/radeon_bo_legacy.h1
l---------src/mesa/drivers/dri/r300/radeon_bocs_wrapper.h1
l---------src/mesa/drivers/dri/r300/radeon_buffer_objects.c1
l---------src/mesa/drivers/dri/r300/radeon_buffer_objects.h1
l---------src/mesa/drivers/dri/r300/radeon_chipset.h1
l---------src/mesa/drivers/dri/r300/radeon_cmdbuf.h1
l---------src/mesa/drivers/dri/r300/radeon_common.c1
l---------src/mesa/drivers/dri/r300/radeon_common.h1
l---------src/mesa/drivers/dri/r300/radeon_common_context.c1
l---------src/mesa/drivers/dri/r300/radeon_common_context.h1
l---------src/mesa/drivers/dri/r300/radeon_cs_legacy.c1
l---------src/mesa/drivers/dri/r300/radeon_cs_legacy.h1
l---------src/mesa/drivers/dri/r300/radeon_cs_space_drm.c1
l---------src/mesa/drivers/dri/r300/radeon_dma.c1
l---------src/mesa/drivers/dri/r300/radeon_dma.h1
l---------src/mesa/drivers/dri/r300/radeon_fbo.c1
l---------src/mesa/drivers/dri/r300/radeon_lock.c1
l---------src/mesa/drivers/dri/r300/radeon_lock.h1
l---------src/mesa/drivers/dri/r300/radeon_mipmap_tree.c1
l---------src/mesa/drivers/dri/r300/radeon_mipmap_tree.h1
-rw-r--r--src/mesa/drivers/dri/r300/radeon_program.c128
l---------src/mesa/drivers/dri/r300/radeon_screen.c1
l---------src/mesa/drivers/dri/r300/radeon_screen.h1
l---------src/mesa/drivers/dri/r300/radeon_span.c1
l---------src/mesa/drivers/dri/r300/radeon_span.h1
l---------src/mesa/drivers/dri/r300/radeon_texture.c1
l---------src/mesa/drivers/dri/r300/radeon_texture.h1
l---------src/mesa/drivers/dri/r300/server/radeon.h1
l---------src/mesa/drivers/dri/r300/server/radeon_dri.c1
l---------src/mesa/drivers/dri/r300/server/radeon_dri.h1
l---------src/mesa/drivers/dri/r300/server/radeon_egl.c1
l---------src/mesa/drivers/dri/r300/server/radeon_macros.h1
l---------src/mesa/drivers/dri/r300/server/radeon_reg.h1
-rw-r--r--src/mesa/drivers/dri/r600/Makefile46
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.c138
-rw-r--r--src/mesa/drivers/dri/r600/r600_cmdbuf.h8
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.c16
-rw-r--r--src/mesa/drivers/dri/r600/r600_context.h18
-rw-r--r--src/mesa/drivers/dri/r600/r600_emit.c23
-rw-r--r--src/mesa/drivers/dri/r600/r600_tex.c61
-rw-r--r--src/mesa/drivers/dri/r600/r600_texstate.c539
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.c55
-rw-r--r--src/mesa/drivers/dri/r600/r700_assembler.h2
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.c269
-rw-r--r--src/mesa/drivers/dri/r600/r700_chip.h37
-rw-r--r--src/mesa/drivers/dri/r600/r700_clear.c1
-rw-r--r--src/mesa/drivers/dri/r600/r700_fragprog.c117
-rw-r--r--src/mesa/drivers/dri/r600/r700_ioctl.c3
-rw-r--r--src/mesa/drivers/dri/r600/r700_oglprog.c2
-rw-r--r--src/mesa/drivers/dri/r600/r700_render.c299
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.c920
-rw-r--r--src/mesa/drivers/dri/r600/r700_state.h4
-rw-r--r--src/mesa/drivers/dri/r600/r700_vertprog.c57
l---------src/mesa/drivers/dri/r600/radeon_bo_legacy.c1
l---------src/mesa/drivers/dri/r600/radeon_bo_legacy.h1
l---------src/mesa/drivers/dri/r600/radeon_bocs_wrapper.h1
l---------src/mesa/drivers/dri/r600/radeon_chipset.h1
l---------src/mesa/drivers/dri/r600/radeon_cmdbuf.h1
l---------src/mesa/drivers/dri/r600/radeon_common.c1
l---------src/mesa/drivers/dri/r600/radeon_common.h1
l---------src/mesa/drivers/dri/r600/radeon_common_context.c1
l---------src/mesa/drivers/dri/r600/radeon_common_context.h1
-rw-r--r--src/mesa/drivers/dri/r600/radeon_context.h76
l---------src/mesa/drivers/dri/r600/radeon_cs_legacy.c1
l---------src/mesa/drivers/dri/r600/radeon_cs_legacy.h1
l---------src/mesa/drivers/dri/r600/radeon_cs_space_drm.c1
l---------src/mesa/drivers/dri/r600/radeon_dma.c1
l---------src/mesa/drivers/dri/r600/radeon_dma.h1
l---------src/mesa/drivers/dri/r600/radeon_fbo.c1
l---------src/mesa/drivers/dri/r600/radeon_lock.c1
l---------src/mesa/drivers/dri/r600/radeon_lock.h1
l---------src/mesa/drivers/dri/r600/radeon_mipmap_tree.c1
l---------src/mesa/drivers/dri/r600/radeon_mipmap_tree.h1
l---------src/mesa/drivers/dri/r600/radeon_screen.c1
l---------src/mesa/drivers/dri/r600/radeon_screen.h1
l---------src/mesa/drivers/dri/r600/radeon_span.c1
l---------src/mesa/drivers/dri/r600/radeon_span.h1
l---------src/mesa/drivers/dri/r600/radeon_texture.c1
l---------src/mesa/drivers/dri/r600/radeon_texture.h1
l---------src/mesa/drivers/dri/r600/server/radeon.h1
l---------src/mesa/drivers/dri/r600/server/radeon_dri.c1
l---------src/mesa/drivers/dri/r600/server/radeon_dri.h1
l---------src/mesa/drivers/dri/r600/server/radeon_egl.c1
l---------src/mesa/drivers/dri/r600/server/radeon_macros.h1
l---------src/mesa/drivers/dri/r600/server/radeon_reg.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_drm.h42
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.c116
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bo_legacy.h3
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_bocs_wrapper.h6
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_buffer_objects.c217
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_buffer_objects.h52
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_chipset.h7
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common.c35
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.c156
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_common_context.h15
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_cs_space_drm.c2
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.c16
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_dma.h8
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_fbo.c14
-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_mipmap_tree.c24
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.c43
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_screen.h1
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_span.c124
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_state_init.c4
-rw-r--r--src/mesa/drivers/dri/radeon/radeon_texture.c39
-rw-r--r--src/mesa/drivers/dri/swrast/swrast.c2
-rw-r--r--src/mesa/drivers/windows/gdi/mesa.def1
-rw-r--r--src/mesa/glapi/ARB_seamless_cube_map.xml12
-rw-r--r--src/mesa/glapi/EXT_framebuffer_object.xml38
-rw-r--r--src/mesa/glapi/EXT_texture_array.xml41
-rw-r--r--src/mesa/glapi/Makefile1
-rw-r--r--src/mesa/glapi/dispatch.h44
-rw-r--r--src/mesa/glapi/gl_API.xml61
-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/glapioffsets.h24
-rw-r--r--src/mesa/glapi/glapitable.h18
-rw-r--r--src/mesa/glapi/glapitemp.h56
-rw-r--r--src/mesa/glapi/glprocs.h644
-rw-r--r--src/mesa/glapi/glthread.c51
-rw-r--r--src/mesa/glapi/glthread.h44
-rw-r--r--src/mesa/main/api_arrayelt.c3
-rw-r--r--src/mesa/main/api_exec.c1
-rw-r--r--src/mesa/main/api_validate.c21
-rw-r--r--src/mesa/main/attrib.c146
-rw-r--r--src/mesa/main/bufferobj.c64
-rw-r--r--src/mesa/main/bufferobj.h20
-rw-r--r--src/mesa/main/colortab.c8
-rw-r--r--src/mesa/main/compiler.h8
-rw-r--r--src/mesa/main/config.h9
-rw-r--r--src/mesa/main/context.c69
-rw-r--r--src/mesa/main/context.h6
-rw-r--r--src/mesa/main/convolve.c20
-rw-r--r--src/mesa/main/debug.c97
-rw-r--r--src/mesa/main/dlist.c304
-rw-r--r--src/mesa/main/drawpix.c142
-rw-r--r--src/mesa/main/enable.c10
-rw-r--r--src/mesa/main/enums.c5980
-rw-r--r--src/mesa/main/extensions.c3
-rw-r--r--src/mesa/main/fbobject.c20
-rw-r--r--src/mesa/main/fog.c2
-rw-r--r--src/mesa/main/framebuffer.c26
-rw-r--r--src/mesa/main/get.c12
-rw-r--r--src/mesa/main/get_gen.py4
-rw-r--r--src/mesa/main/getstring.c1
-rw-r--r--src/mesa/main/histogram.c8
-rw-r--r--src/mesa/main/image.c382
-rw-r--r--src/mesa/main/image.h24
-rw-r--r--src/mesa/main/imports.c85
-rw-r--r--src/mesa/main/imports.h3
-rw-r--r--src/mesa/main/light.c8
-rw-r--r--src/mesa/main/mtypes.h18
-rw-r--r--src/mesa/main/pixel.c24
-rw-r--r--src/mesa/main/polygon.c4
-rw-r--r--src/mesa/main/readpix.c55
-rw-r--r--src/mesa/main/shared.c2
-rw-r--r--src/mesa/main/state.c5
-rw-r--r--src/mesa/main/texenv.c69
-rw-r--r--src/mesa/main/texenvprogram.c15
-rw-r--r--src/mesa/main/texgetimage.c233
-rw-r--r--src/mesa/main/texgetimage.h9
-rw-r--r--src/mesa/main/teximage.c596
-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.c58
-rw-r--r--src/mesa/main/texstate.h18
-rw-r--r--src/mesa/main/texstore.c6
-rw-r--r--src/mesa/main/varray.c41
-rw-r--r--src/mesa/main/varray.h6
-rw-r--r--src/mesa/main/viewport.c4
-rw-r--r--src/mesa/shader/arbprogparse.c7
-rw-r--r--src/mesa/shader/prog_instruction.h9
-rw-r--r--src/mesa/shader/prog_print.c36
-rw-r--r--src/mesa/shader/prog_print.h11
-rw-r--r--src/mesa/shader/programopt.c1
-rw-r--r--src/mesa/shader/shader_api.c12
-rw-r--r--src/mesa/shader/slang/slang_builtin.c183
-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.c34
-rw-r--r--src/mesa/sources.mak3
-rw-r--r--src/mesa/sparc/glapi_sparc.S22
-rw-r--r--src/mesa/state_tracker/st_atom_shader.c17
-rw-r--r--src/mesa/state_tracker/st_cb_blit.c97
-rw-r--r--src/mesa/state_tracker/st_cb_clear.c24
-rw-r--r--src/mesa/state_tracker/st_cb_drawpixels.c74
-rw-r--r--src/mesa/state_tracker/st_cb_fbo.c53
-rw-r--r--src/mesa/state_tracker/st_cb_flush.c12
-rw-r--r--src/mesa/state_tracker/st_cb_rasterpos.c2
-rw-r--r--src/mesa/state_tracker/st_cb_texture.c26
-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_mesa_to_tgsi.c37
-rw-r--r--src/mesa/state_tracker/st_program.c42
-rw-r--r--src/mesa/state_tracker/st_public.h4
-rw-r--r--src/mesa/state_tracker/st_texture.c108
-rw-r--r--src/mesa/state_tracker/st_texture.h5
-rw-r--r--src/mesa/swrast/s_blit.c189
-rw-r--r--src/mesa/swrast/s_fragprog.c5
-rw-r--r--src/mesa/swrast/s_points.c28
-rw-r--r--src/mesa/tnl/t_context.c2
-rw-r--r--src/mesa/tnl/t_draw.c18
-rw-r--r--src/mesa/tnl/t_vb_program.c3
-rw-r--r--src/mesa/tnl/tnl.h10
-rw-r--r--src/mesa/vbo/vbo.h6
-rw-r--r--src/mesa/vbo/vbo_exec_api.c21
-rw-r--r--src/mesa/vbo/vbo_exec_array.c172
-rw-r--r--src/mesa/vbo/vbo_exec_draw.c13
-rw-r--r--src/mesa/vbo/vbo_rebase.c1
-rw-r--r--src/mesa/vbo/vbo_save_api.c2
-rw-r--r--src/mesa/vbo/vbo_save_draw.c1
-rw-r--r--src/mesa/vbo/vbo_split_copy.c12
-rw-r--r--src/mesa/vbo/vbo_split_inplace.c3
-rw-r--r--src/mesa/x86-64/glapi_x86-64.S260
-rw-r--r--src/mesa/x86/glapi_x86.S28
-rw-r--r--windows/VC8/mesa/mesa/mesa.vcproj52
-rw-r--r--windows/VC8/mesa/osmesa/osmesa.vcproj4
616 files changed, 31483 insertions, 20929 deletions
diff --git a/Makefile b/Makefile
index 146c52093b2..6eed65e40b7 100644
--- a/Makefile
+++ b/Makefile
@@ -345,7 +345,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 +390,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 +427,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/bin/mklib b/bin/mklib
index 24449450068..db97087c0a6 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/configure.ac b/configure.ac
index 9b65d96b396..9d318b3fc20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1159,6 +1159,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
diff --git a/docs/dispatch.html b/docs/dispatch.html
index b9ea8822e60..bcab74c7070 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/faq.html b/docs/faq.html
index 11b5d432558..65e279aac57 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/relnotes-7.5.1.html b/docs/relnotes-7.5.1.html
new file mode 100644
index 00000000000..1da086de3b5
--- /dev/null
+++ b/docs/relnotes-7.5.1.html
@@ -0,0 +1,61 @@
+<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 / (date TBD)</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>
+tbd
+</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
+</ul>
+
+
+<h2>Changes</h2>
+<ul>
+</ul>
+
+</body>
+</html>
diff --git a/docs/relnotes-7.5.html b/docs/relnotes-7.5.html
index 8bcacd62e1e..56deca6a86c 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 1e7ccf88bf2..691c0f04cae 100644
--- a/docs/relnotes-7.6.html
+++ b/docs/relnotes-7.6.html
@@ -46,6 +46,10 @@ This was written by Zack Rusin at Tungsten Graphics.
<li>radeon/r200/r300 GL_EXT_framebuffer_object support when used with
kernel memory manager
<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>Added configure --with-max-width=W, --with-max-height=H options to specify
+ max framebuffer, viewport size.
</ul>
diff --git a/docs/relnotes.html b/docs/relnotes.html
index 35a4c7385f7..ddd2e1cdedb 100644
--- a/docs/relnotes.html
+++ b/docs/relnotes.html
@@ -14,6 +14,7 @@ The release notes summarize what's new or changed in each Mesa release.
<UL>
<LI><A HREF="relnotes-7.6.html">7.6 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/GL/glext.h b/include/GL/glext.h
index 5429287d3fb..24e6c5dc80b 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 536fb25a76e..eac09f94fa3 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 3c492dd6348..1f096fb9193 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/demos/cubemap.c b/progs/demos/cubemap.c
index 1f9f2905759..0df5ff09c33 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,8 @@ 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 struct {
@@ -91,7 +96,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[] = {
@@ -231,6 +238,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);
@@ -321,6 +335,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",
@@ -502,23 +521,26 @@ 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));
if (useImageFiles) {
diff --git a/progs/egl/Makefile b/progs/egl/Makefile
index d3c32d46f78..fd72f540cae 100644
--- a/progs/egl/Makefile
+++ b/progs/egl/Makefile
@@ -17,6 +17,7 @@ PROGRAMS = \
eglgears \
eglscreen \
peglgears \
+ xeglbindtex \
xeglgears \
xeglthreads \
xegl_tri
@@ -84,6 +85,12 @@ peglgears.o: peglgears.c $(HEADERS)
$(CC) -c $(CFLAGS) -I$(TOP)/include peglgears.c
+xeglbindtex: xeglbindtex.o $(TOP)/$(LIB_DIR)/libEGL.so
+ $(CC) $(CFLAGS) xeglbindtex.o -L$(TOP)/$(LIB_DIR) -lEGL -lGL $(LIBDRM_LIB) $(APP_LIB_DEPS) -o $@
+
+xeglbindtex.o: xeglbindtex.c $(HEADERS)
+ $(CC) -c $(CFLAGS) -I$(TOP)/include xeglbindtex.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 $@
diff --git a/progs/egl/xeglbindtex.c b/progs/egl/xeglbindtex.c
new file mode 100644
index 00000000000..fdd9fe2b87b
--- /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/glsl/.gitignore b/progs/glsl/.gitignore
index 39d90c23ac5..986775bac22 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 eedd866c957..0875bdd7950 100644
--- a/progs/glsl/Makefile
+++ b/progs/glsl/Makefile
@@ -14,6 +14,11 @@ LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB)
INCLUDE_DIRS = -I$(TOP)/progs/util
+# using : to avoid APP_CC pointing to CC loop
+CC:=$(APP_CC)
+CFLAGS += -I$(INCDIR)
+LDLIBS=$(LIBS)
+
DEMO_SOURCES = \
array.c \
bitmap.c \
@@ -33,6 +38,7 @@ DEMO_SOURCES = \
points.c \
samplers.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)
-
-
+PROG_OBJS = $(DEMO_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 $@
-
-
##### TARGETS #####
default: $(PROGS)
+$(PROG_OBJS): $(UTIL_HEADERS)
+
+$(PROGS): $(UTIL_OBJS)
clean:
-rm -f $(PROGS)
@@ -83,7 +77,6 @@ clean:
-rm -f readtex.*
-
##### Extra dependencies
extfuncs.h: $(TOP)/progs/util/extfuncs.h
@@ -101,138 +94,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 1d08b231e7e..20417aa4626 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 00000000000..8a2152692eb
--- /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 ddb986abcb5..87669aec736 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 22ce7edcdc5..c2fb76e1aa5 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 9cf1e40e3e6..265a5157154 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 9f56a038c96..3dfcec87a56 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 a772ccd716c..526e9b82c10 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 38dffc3e741..b05ef37fae1 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 00000000000..4f4e5c747ea
--- /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 0afe2308012..0d4026e29cf 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 5e971716add..6ec9c833e67 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,8 @@ CreateProgram(const char *vertProgFile, const char *fragProgFile,
glUseProgram(program);
- InitUniforms(program, uniforms);
+ SetUniformValues(program, uniforms);
+ PrintUniforms(Uniforms);
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 00000000000..5be45f6c7cb
--- /dev/null
+++ b/progs/glsl/multitex.shtest
@@ -0,0 +1,6 @@
+vs multitex.vert
+fs multitex.frag
+texture 0 ../images/tile.rgb
+texture 1 ../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 59f594e78bf..fdab263ea6a 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 e972b62673f..7a28f09947c 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 27b73a05dee..5dced6fac3a 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/shadow_sampler.c b/progs/glsl/shadow_sampler.c
index 0a4d04dd8cf..0adc9d88ba4 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 00000000000..2622af13138
--- /dev/null
+++ b/progs/glsl/shtest.c
@@ -0,0 +1,629 @@
+/*
+ * 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
+ *
+ */
+
+
+#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++) {
+ if (Uniforms[i].type == GL_FLOAT) {
+ Uniforms[i].value[0] = RandomFloat(0.0, 1.0);
+ }
+ else {
+ 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.0, 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, const char *texFileName)
+{
+ GLint imgWidth, imgHeight;
+ GLenum imgFormat;
+ GLubyte *image = NULL;
+ GLuint tex;
+ GLenum filter = GL_LINEAR;
+
+ image = LoadRGBImage(texFileName, &imgWidth, &imgHeight, &imgFormat);
+ if (!image) {
+ printf("Couldn't read %s\n", texFileName);
+ exit(1);
+ }
+
+ printf("Load Texture: unit %d: %s %d x %d\n",
+ unit, texFileName, imgWidth, imgHeight);
+
+ glActiveTexture(GL_TEXTURE0 + unit);
+ glGenTextures(1, &tex);
+ glBindTexture(GL_TEXTURE_2D, tex);
+
+ gluBuild2DMipmaps(GL_TEXTURE_2D, 4, imgWidth, imgHeight,
+ imgFormat, GL_UNSIGNED_BYTE, image);
+ free(image);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter);
+ glTexParameteri(GL_TEXTURE_2D, 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_2D", GL_SAMPLER_2D },
+ { 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 texFileName[100];
+ int unit, k;
+ k = sscanf(line + 8, "%d %s", &unit, texFileName);
+ assert(k == 2);
+ LoadTexture(unit, texFileName);
+ }
+ 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)
+{
+ 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);
+ fragShader = CompileShaderFile(GL_FRAGMENT_SHADER, FragShaderFile);
+ Program = LinkShaders(vertShader, fragShader);
+
+ 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[])
+{
+ glutInit(&argc, argv);
+ glutInitWindowSize(400, 400);
+ 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 1f566c86a6a..2481c0f36e0 100644
--- a/progs/glsl/texaaline.c
+++ b/progs/glsl/texaaline.c
@@ -351,7 +351,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 d55f9e7dd97..5b1913a722b 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 7fe27aebfe6..c502f24077e 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 00000000000..887663abd32
--- /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 f7546f25a2e..53bd91ef976 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 b6c1b477dde..a57484f96cc 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 81fcab8c5b8..148991ca83e 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 e791a5759a7..4c8bfa587aa 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/tests/SConscript b/progs/tests/SConscript
index b17fa905936..bb6a1d2b8a9 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/floattex.c b/progs/tests/floattex.c
index ad14cacdcbb..39302ce3aff 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 ca66025d2dc..a09ea58e1da 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 8adfc51bd60..699195bd48c 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 e4818a8fabb..71f29b4ac84 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/texcompsub.c b/progs/tests/texcompsub.c
index 79a5f958a12..50106bf1e22 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 12f045b72e0..92c8a2f14c2 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/trivial/.gitignore b/progs/trivial/.gitignore
index dce733a70ae..4d6e405c500 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 3bd8faff99a..70728616d28 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/shaderutil.c b/progs/util/shaderutil.c
index 13b68d90e0b..489e71cc30c 100644
--- a/progs/util/shaderutil.c
+++ b/progs/util/shaderutil.c
@@ -9,21 +9,12 @@
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <GL/glew.h>
#include <GL/glut.h>
#include "shaderutil.h"
-static void
-Init(void)
-{
- static GLboolean firstCall = GL_TRUE;
- if (firstCall) {
- firstCall = GL_FALSE;
- }
-}
-
-
GLboolean
ShadersSupported(void)
{
@@ -47,8 +38,6 @@ CompileShaderText(GLenum shaderType, const char *text)
GLuint shader;
GLint stat;
- Init();
-
shader = glCreateShader(shaderType);
glShaderSource(shader, 1, (const GLchar **) &text, NULL);
glCompileShader(shader);
@@ -79,9 +68,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);
@@ -136,7 +122,7 @@ LinkShaders(GLuint vertShader, GLuint fragShader)
void
-InitUniforms(GLuint program, struct uniform_info uniforms[])
+SetUniformValues(GLuint program, struct uniform_info uniforms[])
{
GLuint i;
@@ -144,28 +130,133 @@ 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:
+ 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 cfb8c1f3b06..0a6be026759 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);
@@ -28,7 +37,18 @@ extern GLuint
LinkShaders(GLuint vertShader, GLuint fragShader);
extern void
-InitUniforms(GLuint program, struct uniform_info uniforms[]);
+SetUniformValues(GLuint program, struct uniform_info uniforms[]);
+
+extern GLuint
+GetUniforms(GLuint program, struct uniform_info uniforms[]);
+
+extern void
+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 aea87b79a49..83aebf689ea 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 7bdbb8e86c7..c2afe3c0924 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/xdemos/Makefile b/progs/xdemos/Makefile
index 6581df80398..53e1c54ef3c 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 481749be3d8..9f83679acd3 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 bc84ee3dbd2..088f25a357a 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 df9f7ad784b..cd60d460a06 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 00000000000..75255b28605
--- /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/gallium.py b/scons/gallium.py
index e9e799dc78d..bf6172b4d77 100644
--- a/scons/gallium.py
+++ b/scons/gallium.py
@@ -462,6 +462,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/src/egl/drivers/demo/Makefile b/src/egl/drivers/demo/Makefile
index 26694c92fa6..444dfb35bde 100644
--- a/src/egl/drivers/demo/Makefile
+++ b/src/egl/drivers/demo/Makefile
@@ -4,7 +4,7 @@ TOP = ../../../..
include $(TOP)/configs/current
-INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main
+INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/egl/main $(X11_INCLUDES)
SOURCES = demo.c
diff --git a/src/egl/drivers/demo/demo.c b/src/egl/drivers/demo/demo.c
index f316974d836..e8c0c1df5ee 100644
--- a/src/egl/drivers/demo/demo.c
+++ b/src/egl/drivers/demo/demo.c
@@ -236,7 +236,7 @@ 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;
}
@@ -247,7 +247,7 @@ 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;
}
diff --git a/src/egl/drivers/dri/Makefile b/src/egl/drivers/dri/Makefile
index 567edfae973..7339c97c77d 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 3f9617a8f98..9e400be6248 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 207b1ea7793..5ed4b6883f8 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -739,7 +739,7 @@ GLX_eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
return EGL_TRUE;
if (surf) {
_eglUnlinkSurface(surf);
- if (!surf->IsBound)
+ if (!_eglIsSurfaceBound(surf))
free(surf);
return EGL_TRUE;
diff --git a/src/egl/drivers/xdri/egl_xdri.c b/src/egl/drivers/xdri/egl_xdri.c
index e040efdd438..d8d29fcef49 100644
--- a/src/egl/drivers/xdri/egl_xdri.c
+++ b/src/egl/drivers/xdri/egl_xdri.c
@@ -958,7 +958,7 @@ 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) {
+ if (!_eglIsSurfaceBound(&xdri_surf->Base)) {
/*
st_unreference_framebuffer(surf->Framebuffer);
*/
diff --git a/src/egl/main/Makefile b/src/egl/main/Makefile
index e1ff8794b35..ab61d68f2b6 100644
--- a/src/egl/main/Makefile
+++ b/src/egl/main/Makefile
@@ -4,7 +4,7 @@ TOP = ../../..
include $(TOP)/configs/current
-INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi
+INCLUDE_DIRS = -I$(TOP)/include -I$(TOP)/src/mesa/glapi $(X11_INCLUDES)
HEADERS = \
eglcompiler.h \
@@ -20,6 +20,7 @@ HEADERS = \
eglhash.h \
eglmisc.h \
eglmode.h \
+ eglmutex.h \
eglscreen.h \
eglstring.h \
eglsurface.h \
@@ -74,6 +75,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 f0a6f7f9355..fde6b7316c8 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -50,7 +50,6 @@ EGLDisplay EGLAPIENTRY
eglGetDisplay(NativeDisplayType nativeDisplay)
{
_EGLDisplay *dpy;
- _eglInitGlobals();
dpy = _eglFindDisplay(nativeDisplay);
if (!dpy) {
dpy = _eglNewDisplay(nativeDisplay);
diff --git a/src/egl/main/eglcompiler.h b/src/egl/main/eglcompiler.h
index 0b19afedfd3..6b639b75c66 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 f2f32585c73..bbc585b55e9 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);
diff --git a/src/egl/main/eglconfigutil.c b/src/egl/main/eglconfigutil.c
index 138dc729e74..c9d00e79826 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 9ab4286d3a8..88de60d69bb 100644
--- a/src/egl/main/eglcontext.c
+++ b/src/egl/main/eglcontext.c
@@ -96,7 +96,7 @@ _eglDestroyContext(_EGLDriver *drv, EGLDisplay dpy, EGLContext ctx)
_EGLContext *context = _eglLookupContext(ctx);
if (context) {
_eglUnlinkContext(context);
- if (!context->IsBound)
+ if (!_eglIsContextBound(context))
free(context);
return EGL_TRUE;
}
@@ -146,10 +146,11 @@ _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,
+_eglMakeCurrent(_EGLDriver *drv, EGLDisplay display, EGLSurface d,
EGLSurface r, EGLContext context)
{
_EGLThreadInfo *t = _eglGetCurrentThread();
+ _EGLDisplay *dpy = _eglLookupDisplay(display);
_EGLContext *ctx = _eglLookupContext(context);
_EGLSurface *draw = _eglLookupSurface(d);
_EGLSurface *read = _eglLookupSurface(r);
@@ -160,21 +161,23 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
if (_eglIsCurrentThreadDummy())
return _eglError(EGL_BAD_ALLOC, "eglMakeCurrent");
+ if (dpy == NULL)
+ return _eglError(EGL_BAD_DISPLAY, "eglMakeCurrent");
- /* error checking */
if (ctx) {
+ /* error checking */
+ if (ctx->Binding && ctx->Binding != t)
+ return _eglError(EGL_BAD_ACCESS, "eglMakeCurrent");
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;
+ EGLint err = (d == EGL_NO_SURFACE || r == EGL_NO_SURFACE)
+ ? EGL_BAD_MATCH : EGL_BAD_SURFACE;
+ return _eglError(err, "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 +197,10 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface d,
apiIndex = _eglConvertApiToIndex(ctx->ClientAPI);
}
else {
+ if (context != EGL_NO_CONTEXT)
+ return _eglError(EGL_BAD_CONTEXT, "eglMakeCurrent");
+ if (draw != NULL || read != NULL)
+ return _eglError(EGL_BAD_MATCH, "eglMakeCurrent");
apiIndex = t->CurrentAPIIndex;
}
@@ -201,60 +208,47 @@ _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
+ * FIXME They are linked so that they can be unlinked. This is ugly.
+ */
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, display,
+ _eglLinkSurface(oldDrawSurface, dpy));
}
- }
- 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, display,
+ _eglLinkSurface(oldReadSurface, dpy));
}
- }
- 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, display,
+ _eglLinkContext(oldContext, dpy));
}
}
+ /* 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 2fb28d38b91..4276c0980e2 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 */
@@ -51,4 +51,15 @@ _eglMakeCurrent(_EGLDriver *drv, EGLDisplay dpy, EGLSurface draw, EGLSurface rea
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 96152db19fb..4431f964f69 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 f9fdf7bd0f0..8eb241029ec 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 89de609d0b4..feae1d60409 100644
--- a/src/egl/main/egldisplay.c
+++ b/src/egl/main/egldisplay.c
@@ -1,4 +1,3 @@
-
/**
* Functions related to EGLDisplay.
*/
@@ -13,6 +12,67 @@
#include "eglglobals.h"
#include "eglhash.h"
#include "eglstring.h"
+#include "eglmutex.h"
+#include "egllog.h"
+
+
+static _EGL_DECLARE_MUTEX(_eglDisplayInitMutex);
+static _EGLHashtable *_eglDisplayHash;
+/* TODO surface hash table should be per-display */
+static _EGLHashtable *_eglSurfaceHash;
+
+
+/**
+ * Finish display management.
+ */
+static void
+_eglFiniDisplay(void)
+{
+ _eglLockMutex(&_eglDisplayInitMutex);
+ if (_eglDisplayHash) {
+ EGLuint key = _eglHashFirstEntry(_eglDisplayHash);
+
+ while (key) {
+ _EGLDisplay *dpy = (_EGLDisplay *)
+ _eglHashLookup(_eglDisplayHash, key);
+ assert(dpy);
+
+ if (dpy->ContextList || dpy->SurfaceList)
+ _eglLog(_EGL_DEBUG, "Display %u is destroyed with resources", key);
+
+ _eglCleanupDisplay(dpy);
+ free(dpy);
+
+ key = _eglHashNextEntry(_eglDisplayHash, key);
+ }
+
+ _eglDeleteHashTable(_eglDisplayHash);
+ _eglDisplayHash = NULL;
+ _eglDeleteHashTable(_eglSurfaceHash);
+ _eglSurfaceHash = NULL;
+ }
+ _eglUnlockMutex(&_eglDisplayInitMutex);
+}
+
+
+/* This can be avoided if hash table can be statically initialized */
+static INLINE void
+_eglInitDisplay(void)
+{
+ if (!_eglDisplayHash) {
+ _eglLockMutex(&_eglDisplayInitMutex);
+
+ /* check again after acquiring lock */
+ if (!_eglDisplayHash) {
+ _eglDisplayHash = _eglNewHashTable();
+ _eglSurfaceHash = _eglNewHashTable();
+
+ _eglAddAtExitCall(_eglFiniDisplay);
+ }
+
+ _eglUnlockMutex(&_eglDisplayInitMutex);
+ }
+}
/**
@@ -31,6 +91,9 @@ _eglNewDisplay(NativeDisplayType nativeDisplay)
dpy->Xdpy = (Display *) nativeDisplay;
#endif
+ _eglInitDisplay();
+ dpy->SurfaceHash = _eglSurfaceHash;
+
dpy->DriverName = _eglChooseDriver(dpy);
if (!dpy->DriverName) {
free(dpy);
@@ -49,11 +112,14 @@ EGLDisplay
_eglLinkDisplay(_EGLDisplay *dpy)
{
EGLuint key;
- key = _eglHashGenKey(_eglGlobal.Displays);
+
+ _eglInitDisplay();
+
+ key = _eglHashGenKey(_eglDisplayHash);
assert(key);
/* "link" the display to the hash table */
- _eglHashInsert(_eglGlobal.Displays, key, dpy);
- dpy->Handle = (EGLDisplay) key;
+ _eglHashInsert(_eglDisplayHash, key, dpy);
+ dpy->Handle = (EGLDisplay) _eglUIntToPointer(key);
return dpy->Handle;
}
@@ -66,7 +132,11 @@ _eglLinkDisplay(_EGLDisplay *dpy)
void
_eglUnlinkDisplay(_EGLDisplay *dpy)
{
- _eglHashRemove(_eglGlobal.Displays, (EGLuint) dpy->Handle);
+ EGLuint key = _eglPointerToUInt((void *) dpy->Handle);
+
+ _eglInitDisplay();
+
+ _eglHashRemove(_eglDisplayHash, key);
dpy->Handle = EGL_NO_DISPLAY;
}
@@ -83,7 +153,7 @@ _eglGetDisplayHandle(_EGLDisplay *display)
return EGL_NO_DISPLAY;
}
-
+
/**
* Lookup a handle to find the linked display.
* Return NULL if the handle has no corresponding linked display.
@@ -91,8 +161,11 @@ _eglGetDisplayHandle(_EGLDisplay *display)
_EGLDisplay *
_eglLookupDisplay(EGLDisplay dpy)
{
- EGLuint key = (EGLuint) dpy;
- return (_EGLDisplay *) _eglHashLookup(_eglGlobal.Displays, key);
+ EGLuint key = _eglPointerToUInt((void *) dpy);
+
+ _eglInitDisplay();
+
+ return (_EGLDisplay *) _eglHashLookup(_eglDisplayHash, key);
}
@@ -103,17 +176,20 @@ _eglLookupDisplay(EGLDisplay dpy)
_EGLDisplay *
_eglFindDisplay(NativeDisplayType nativeDisplay)
{
- EGLuint key = _eglHashFirstEntry(_eglGlobal.Displays);
+ EGLuint key;
+
+ _eglInitDisplay();
/* Walk the hash table. Should switch to list if it is a problem. */
+ key = _eglHashFirstEntry(_eglDisplayHash);
while (key) {
_EGLDisplay *dpy = (_EGLDisplay *)
- _eglHashLookup(_eglGlobal.Displays, key);
+ _eglHashLookup(_eglDisplayHash, key);
assert(dpy);
if (dpy->NativeDisplay == nativeDisplay)
return dpy;
- key = _eglHashNextEntry(_eglGlobal.Displays, key);
+ key = _eglHashNextEntry(_eglDisplayHash, key);
}
return NULL;
@@ -224,7 +300,7 @@ _eglUnlinkContext(_EGLContext *ctx)
EGLContext
_eglGetContextHandle(_EGLContext *ctx)
{
- return (EGLContext) (ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT;
+ return (EGLContext) ((ctx && ctx->Display) ? ctx : EGL_NO_CONTEXT);
}
@@ -253,11 +329,11 @@ _eglLinkSurface(_EGLSurface *surf, _EGLDisplay *dpy)
surf->Next = dpy->SurfaceList;
dpy->SurfaceList = surf;
- key = _eglHashGenKey(_eglGlobal.Surfaces);
+ key = _eglHashGenKey(dpy->SurfaceHash);
assert(key);
- _eglHashInsert(_eglGlobal.Surfaces, key, surf);
+ _eglHashInsert(dpy->SurfaceHash, key, surf);
- surf->Handle = (EGLSurface) key;
+ surf->Handle = (EGLSurface) _eglUIntToPointer(key);
return surf->Handle;
}
@@ -270,8 +346,9 @@ void
_eglUnlinkSurface(_EGLSurface *surf)
{
_EGLSurface *prev;
+ EGLuint key = _eglPointerToUInt((void *) surf->Handle);
- _eglHashRemove(_eglGlobal.Surfaces, (EGLuint) surf->Handle);
+ _eglHashRemove(surf->Display->SurfaceHash, key);
surf->Handle = EGL_NO_SURFACE;
prev = surf->Display->SurfaceList;
@@ -314,7 +391,6 @@ _eglGetSurfaceHandle(_EGLSurface *surface)
_EGLSurface *
_eglLookupSurface(EGLSurface surf)
{
- _EGLSurface *c = (_EGLSurface *) _eglHashLookup(_eglGlobal.Surfaces,
- (EGLuint) surf);
- return c;
+ EGLuint key = _eglPointerToUInt((void *) surf);
+ return (_EGLSurface *) _eglHashLookup(_eglSurfaceHash, key);
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 372ed3cd79a..70c59ef5e46 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -6,6 +6,7 @@
#endif
#include "egltypedefs.h"
+#include "eglhash.h"
struct _egl_display
@@ -26,6 +27,10 @@ struct _egl_display
/* lists of linked contexts and surface */
_EGLContext *ContextList;
_EGLSurface *SurfaceList;
+
+ /* hash table to map surfaces to handles */
+ _EGLHashtable *SurfaceHash;
+
#ifdef _EGL_PLATFORM_X
Display *Xdpy;
#endif
@@ -125,4 +130,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/eglglobals.c b/src/egl/main/eglglobals.c
index 55de394ef5f..e93b48e03b8 100644
--- a/src/egl/main/eglglobals.c
+++ b/src/egl/main/eglglobals.c
@@ -1,41 +1,53 @@
#include <stdlib.h>
+#include <assert.h>
#include "eglglobals.h"
+#include "egldisplay.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 */
+ 1, /* FreeScreenHandle */
+ 0x0, /* ClientAPIsMask */
+ { 0x0 }, /* ClientAPIs */
+ 0, /* NumDrivers */
+ { NULL }, /* Drivers */
+ 0, /* NumAtExitCalls */
+ { NULL }, /* AtExitCalls */
+};
- _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 a9443cfbdd8..1e2c6742630 100644
--- a/src/egl/main/eglglobals.h
+++ b/src/egl/main/eglglobals.h
@@ -4,6 +4,7 @@
#include "egltypedefs.h"
#include "eglhash.h"
#include "eglcurrent.h"
+#include "eglmutex.h"
/**
@@ -11,12 +12,7 @@
*/
struct _egl_global
{
- EGLBoolean Initialized;
-
- /* these are private to egldisplay.c */
- _EGLHashtable *Displays;
- _EGLHashtable *Surfaces;
-
+ _EGLMutex *Mutex;
EGLScreenMESA FreeScreenHandle;
/* bitmaks of supported APIs (supported by _some_ driver) */
@@ -26,6 +22,9 @@ struct _egl_global
EGLint NumDrivers;
_EGLDriver *Drivers[10];
+
+ EGLint NumAtExitCalls;
+ void (*AtExitCalls[10])(void);
};
@@ -33,11 +32,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/eglmutex.h b/src/egl/main/eglmutex.h
new file mode 100644
index 00000000000..29faba0f241
--- /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/eglsurface.c b/src/egl/main/eglsurface.c
index 9821e636287..39470511276 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -26,7 +26,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;
@@ -413,7 +414,7 @@ _eglDestroySurface(_EGLDriver *drv, EGLDisplay dpy, EGLSurface surface)
_EGLSurface *surf = _eglLookupSurface(surface);
if (surf) {
_eglUnlinkSurface(surf);
- if (!surf->IsBound)
+ if (!_eglIsSurfaceBound(surf))
free(surf);
return EGL_TRUE;
}
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index f9413eb9d75..88641768449 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -15,12 +15,12 @@ struct _egl_surface
_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;
@@ -100,5 +100,16 @@ _eglCreatePbufferFromClientBuffer(_EGLDriver *drv, EGLDisplay dpy,
#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/gallium/Makefile.template b/src/gallium/Makefile.template
index 98487d43bd6..2e3da436cd7 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
diff --git a/src/gallium/auxiliary/draw/draw_pipe.c b/src/gallium/auxiliary/draw/draw_pipe.c
index 2e3f5b2fc07..1c6d657297c 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_pstipple.c b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
index 30a6d2919d9..283502cdf3e 100644
--- a/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
+++ b/src/gallium/auxiliary/draw/draw_pipe_pstipple.c
@@ -256,7 +256,10 @@ pstip_transform_inst(struct tgsi_transform_context *ctx,
uint size = 4;
immed = tgsi_default_full_immediate();
immed.Immediate.NrTokens = 1 + size; /* one for the token itself */
- immed.u.Pointer = (void *) value;
+ immed.u[0].Float = value[0];
+ immed.u[1].Float = value[1];
+ immed.u[2].Float = value[2];
+ immed.u[3].Float = value[3];
ctx->emit_immediate(ctx, &immed);
}
diff --git a/src/gallium/auxiliary/draw/draw_pipe_wide_point.c b/src/gallium/auxiliary/draw/draw_pipe_wide_point.c
index 014d8c7346d..7d76a7dbf39 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_aos.c b/src/gallium/auxiliary/draw/draw_vs_aos.c
index 9e37a26c1e2..62e04a65f30 100644
--- a/src/gallium/auxiliary/draw/draw_vs_aos.c
+++ b/src/gallium/auxiliary/draw/draw_vs_aos.c
@@ -1758,24 +1758,24 @@ emit_instruction( struct aos_compilation *cp,
case TGSI_OPCODE_SUB:
return emit_SUB(cp, inst);
- case TGSI_OPCODE_LERP:
+ case TGSI_OPCODE_LRP:
// return emit_LERP(cp, inst);
return FALSE;
- case TGSI_OPCODE_FRAC:
+ case TGSI_OPCODE_FRC:
return emit_FRC(cp, inst);
case TGSI_OPCODE_CLAMP:
// return emit_CLAMP(cp, inst);
return FALSE;
- case TGSI_OPCODE_FLOOR:
+ case TGSI_OPCODE_FLR:
return emit_FLR(cp, inst);
case TGSI_OPCODE_ROUND:
return emit_RND(cp, inst);
- case TGSI_OPCODE_EXPBASE2:
+ case TGSI_OPCODE_EX2:
#if FAST_MATH
return emit_EXPBASE2(cp, inst);
#elif 0
@@ -1787,13 +1787,13 @@ emit_instruction( struct aos_compilation *cp,
return FALSE;
#endif
- case TGSI_OPCODE_LOGBASE2:
+ case TGSI_OPCODE_LG2:
return emit_LG2(cp, inst);
- case TGSI_OPCODE_POWER:
+ case TGSI_OPCODE_POW:
return emit_POW(cp, inst);
- case TGSI_OPCODE_CROSSPRODUCT:
+ case TGSI_OPCODE_XPD:
return emit_XPD(cp, inst);
case TGSI_OPCODE_ABS:
@@ -1891,8 +1891,9 @@ static boolean note_immediate( struct aos_compilation *cp,
unsigned pos = cp->num_immediates++;
unsigned j;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
- cp->vaos->machine->immediate[pos][j] = imm->u.ImmediateFloat32[j].Float;
+ cp->vaos->machine->immediate[pos][j] = imm->u[j].Float;
}
return TRUE;
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index 727977bc3af..b3535c0e48e 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 2d2af3085e6..721b7d2d833 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 5b08200d142..bf84401e112 100644
--- a/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
+++ b/src/gallium/auxiliary/gallivm/tgsitollvm.cpp
@@ -160,10 +160,11 @@ translate_immediate(Storage *storage,
{
float vec[4];
int i;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- vec[i] = imm->u.ImmediateFloat32[i].Float;
+ vec[i] = imm->u[i].Float;
break;
default:
assert(0);
@@ -179,10 +180,11 @@ translate_immediateir(StorageSoa *storage,
{
float vec[4];
int i;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; ++i) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- vec[i] = imm->u.ImmediateFloat32[i].Float;
+ vec[i] = imm->u[i].Float;
break;
default:
assert(0);
@@ -336,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;
@@ -348,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;
@@ -366,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]);
}
@@ -522,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;
@@ -538,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;
@@ -580,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;
@@ -593,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;
@@ -617,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:
@@ -778,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]);
}
@@ -910,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;
@@ -920,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;
@@ -961,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: {
@@ -983,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 b4900e8dbaa..5f0a580b096 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 8200cce42f5..b6bc2924f06 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 a3f4947c734..802ec371189 100644
--- a/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
+++ b/src/gallium/auxiliary/tgsi/tgsi-instruction-set.txt
@@ -665,9 +665,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 +694,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 +856,7 @@ TGSI Instruction Specification
----------
-1.13.1 BGNLOOP2 - Begin Loop
+1.13.1 BGNLOOP - Begin a Loop
TBD
@@ -850,7 +866,7 @@ TGSI Instruction Specification
TBD
-1.13.3 ENDLOOP2 - End Loop
+1.13.3 ENDLOOP - End a Loop
TBD
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.c b/src/gallium/auxiliary/tgsi/tgsi_build.c
index d272533d63c..010d501c601 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.c
@@ -335,7 +335,10 @@ tgsi_default_full_immediate( void )
struct tgsi_full_immediate fullimm;
fullimm.Immediate = tgsi_default_immediate();
- fullimm.u.Pointer = (void *) 0;
+ fullimm.u[0].Float = 0.0f;
+ fullimm.u[1].Float = 0.0f;
+ fullimm.u[2].Float = 0.0f;
+ fullimm.u[3].Float = 0.0f;
return fullimm;
}
@@ -352,19 +355,19 @@ immediate_grow(
header_bodysize_grow( header );
}
-struct tgsi_immediate_float32
+union tgsi_immediate_data
tgsi_build_immediate_float32(
float value,
struct tgsi_immediate *immediate,
struct tgsi_header *header )
{
- struct tgsi_immediate_float32 immediate_float32;
+ union tgsi_immediate_data immediate_data;
- immediate_float32.Float = value;
+ immediate_data.Float = value;
immediate_grow( immediate, header );
- return immediate_float32;
+ return immediate_data;
}
unsigned
@@ -384,16 +387,18 @@ tgsi_build_full_immediate(
*immediate = tgsi_build_immediate( header );
+ assert( full_imm->Immediate.NrTokens <= 4 + 1 );
+
for( i = 0; i < full_imm->Immediate.NrTokens - 1; i++ ) {
- struct tgsi_immediate_float32 *if32;
+ union tgsi_immediate_data *data;
if( maxsize <= size )
return 0;
- if32 = (struct tgsi_immediate_float32 *) &tokens[size];
+ data = (union tgsi_immediate_data *) &tokens[size];
size++;
- *if32 = tgsi_build_immediate_float32(
- full_imm->u.ImmediateFloat32[i].Float,
+ *data = tgsi_build_immediate_float32(
+ full_imm->u[i].Float,
immediate,
header );
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_build.h b/src/gallium/auxiliary/tgsi/tgsi_build.h
index 9a3a077cf2b..17d977b0597 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_build.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_build.h
@@ -119,7 +119,7 @@ tgsi_build_immediate(
struct tgsi_full_immediate
tgsi_default_full_immediate( void );
-struct tgsi_immediate_float32
+union tgsi_immediate_data
tgsi_build_immediate_float32(
float value,
struct tgsi_immediate *immediate,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump.c b/src/gallium/auxiliary/tgsi/tgsi_dump.c
index a6994ecd48b..f36b1114a95 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_dump.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_dump.c
@@ -82,7 +82,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 +91,8 @@ static const char *file_names[] =
"TEMP",
"SAMP",
"ADDR",
- "IMM"
+ "IMM",
+ "LOOP"
};
static const char *interpolate_names[] =
@@ -295,10 +296,12 @@ iter_immediate(
ENM( imm->Immediate.DataType, immediate_type_names );
TXT( " { " );
+
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (i = 0; i < imm->Immediate.NrTokens - 1; i++) {
switch (imm->Immediate.DataType) {
case TGSI_IMM_FLOAT32:
- FLT( imm->u.ImmediateFloat32[i].Float );
+ FLT( imm->u[i].Float );
break;
default:
assert( 0 );
@@ -470,8 +473,8 @@ 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 );
diff --git a/src/gallium/auxiliary/tgsi/tgsi_dump_c.c b/src/gallium/auxiliary/tgsi/tgsi_dump_c.c
index 3dc61c48ca3..4a9c02b1413 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[] =
@@ -283,12 +284,13 @@ dump_immediate_verbose(
UIX( imm->Immediate.Padding );
}
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for( i = 0; i < imm->Immediate.NrTokens - 1; i++ ) {
EOL();
switch( imm->Immediate.DataType ) {
case TGSI_IMM_FLOAT32:
TXT( "\nFloat: " );
- FLT( imm->u.ImmediateFloat32[i].Float );
+ FLT( imm->u[i].Float );
break;
default:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index fe571a86bca..951ecfd5528 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -301,14 +301,14 @@ tgsi_exec_machine_bind_shader(
case TGSI_TOKEN_TYPE_IMMEDIATE:
{
uint size = parse.FullToken.FullImmediate.Immediate.NrTokens - 1;
- assert( size % 4 == 0 );
- assert( mach->ImmLimit + size / 4 <= TGSI_EXEC_NUM_IMMEDIATES );
+ assert( size <= 4 );
+ assert( mach->ImmLimit + 1 <= TGSI_EXEC_NUM_IMMEDIATES );
for( i = 0; i < size; i++ ) {
- mach->Imms[mach->ImmLimit + i / 4][i % 4] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ mach->Imms[mach->ImmLimit][i] =
+ parse.FullToken.FullImmediate.u[i].Float;
}
- mach->ImmLimit += size / 4;
+ mach->ImmLimit += 1;
}
break;
@@ -375,15 +375,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++ ) {
@@ -2020,8 +2014,7 @@ exec_instruction(
switch (inst->Instruction.Opcode) {
case TGSI_OPCODE_ARL:
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
micro_flr( &r[0], &r[0] );
@@ -2290,8 +2283,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);
@@ -2325,8 +2317,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ case TGSI_OPCODE_DP2A:
FETCH( &r[0], 0, CHAN_X );
FETCH( &r[1], 1, CHAN_X );
micro_mul( &r[0], &r[0], &r[1] );
@@ -2344,18 +2335,7 @@ 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_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( &r[0], 0, chan_index );
micro_frc( &r[0], &r[0] );
@@ -2383,8 +2363,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH(&r[0], 0, CHAN_X);
#if FAST_MATH
@@ -2398,8 +2377,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( &r[0], 0, CHAN_X );
micro_lg2( &r[0], &r[0] );
FOR_EACH_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2407,8 +2385,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);
@@ -2419,8 +2396,7 @@ exec_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
- /* TGSI_OPCODE_XPD */
+ case TGSI_OPCODE_XPD:
FETCH(&r[0], 0, CHAN_Y);
FETCH(&r[1], 1, CHAN_Z);
@@ -2462,11 +2438,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);
@@ -3110,9 +3081,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;
@@ -3120,9 +3091,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/auxiliary/tgsi/tgsi_info.c b/src/gallium/auxiliary/tgsi/tgsi_info.c
index 37f2b66d1f6..ccf4b205ffb 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.c
@@ -26,136 +26,156 @@
**************************************************************************/
#include "util/u_debug.h"
+#include "util/u_memory.h"
#include "tgsi_info.h"
static const struct tgsi_opcode_info opcode_info[TGSI_OPCODE_LAST] =
{
- { 1, 1, 0, 0, "ARL", NULL, NULL },
- { 1, 1, 0, 0, "MOV", NULL, NULL },
- { 1, 1, 0, 0, "LIT", NULL, NULL },
- { 1, 1, 0, 0, "RCP", "RECIP", NULL },
- { 1, 1, 0, 0, "RSQ", "RECIPSQRT", NULL },
- { 1, 1, 0, 0, "EXP", "EXPP", NULL },
- { 1, 1, 0, 0, "LOG", NULL, NULL },
- { 1, 2, 0, 0, "MUL", NULL, NULL },
- { 1, 2, 0, 0, "ADD", NULL, NULL },
- { 1, 2, 0, 0, "DP3", "DOT3", NULL },
- { 1, 2, 0, 0, "DP4", "DOT4", NULL },
- { 1, 2, 0, 0, "DST", NULL, NULL },
- { 1, 2, 0, 0, "MIN", NULL, NULL },
- { 1, 2, 0, 0, "MAX", NULL, NULL },
- { 1, 2, 0, 0, "SLT", "SETLT", NULL },
- { 1, 2, 0, 0, "SGE", "SETGE", NULL },
- { 1, 3, 0, 0, "MAD", "MADD", NULL },
- { 1, 2, 0, 0, "SUB", NULL, NULL },
- { 1, 3, 0, 0, "LRP", "LERP", NULL },
- { 1, 3, 0, 0, "CND", NULL, NULL },
- { 1, 3, 0, 0, "CND0", NULL, NULL },
- { 1, 3, 0, 0, "DP2A", "DP2ADD", "DOT2ADD" },
- { 1, 2, 0, 0, "INDEX", NULL, NULL },
- { 1, 1, 0, 0, "NEGATE", NULL, NULL },
- { 1, 1, 0, 0, "FRC", "FRAC", NULL },
- { 1, 3, 0, 0, "CLAMP", NULL, NULL },
- { 1, 1, 0, 0, "FLR", "FLOOR", NULL },
- { 1, 1, 0, 0, "ROUND", NULL, NULL },
- { 1, 1, 0, 0, "EX2", "EXPBASE2", NULL },
- { 1, 1, 0, 0, "LG2", "LOGBASE2", "LOGP" },
- { 1, 2, 0, 0, "POW", "POWER", NULL },
- { 1, 2, 0, 0, "XPD", "CRS", "CROSSPRODUCT" },
- { 1, 2, 0, 0, "M4X4", "MULTIPLYMATRIX", NULL },
- { 1, 1, 0, 0, "ABS", NULL, NULL },
- { 1, 1, 0, 0, "RCC", NULL, NULL },
- { 1, 2, 0, 0, "DPH", NULL, NULL },
- { 1, 1, 0, 0, "COS", NULL, NULL },
- { 1, 1, 0, 0, "DDX", "DSX", NULL },
- { 1, 1, 0, 0, "DDY", "DSY", NULL },
- { 0, 0, 0, 0, "KILP", NULL, NULL },
- { 1, 1, 0, 0, "PK2H", NULL, NULL },
- { 1, 1, 0, 0, "PK2US", NULL, NULL },
- { 1, 1, 0, 0, "PK4B", NULL, NULL },
- { 1, 1, 0, 0, "PK4UB", NULL, NULL },
- { 1, 2, 0, 0, "RFL", NULL, NULL },
- { 1, 2, 0, 0, "SEQ", NULL, NULL },
- { 1, 2, 0, 0, "SFL", NULL, NULL },
- { 1, 2, 0, 0, "SGT", NULL, NULL },
- { 1, 1, 0, 0, "SIN", NULL, NULL },
- { 1, 2, 0, 0, "SLE", NULL, NULL },
- { 1, 2, 0, 0, "SNE", NULL, NULL },
- { 1, 2, 0, 0, "STR", NULL, NULL },
- { 1, 2, 1, 0, "TEX", "TEXLD", NULL },
- { 1, 4, 1, 0, "TXD", "TEXLDD", NULL },
- { 1, 2, 1, 0, "TXP", NULL, NULL },
- { 1, 1, 0, 0, "UP2H", NULL, NULL },
- { 1, 1, 0, 0, "UP2US", NULL, NULL },
- { 1, 1, 0, 0, "UP4B", NULL, NULL },
- { 1, 1, 0, 0, "UP4UB", NULL, NULL },
- { 1, 3, 0, 0, "X2D", NULL, NULL },
- { 1, 1, 0, 0, "ARA", NULL, NULL },
- { 1, 1, 0, 0, "ARR", "MOVA", NULL },
- { 0, 1, 0, 0, "BRA", NULL, NULL },
- { 0, 0, 0, 1, "CAL", "CALL", NULL },
- { 0, 0, 0, 0, "RET", NULL, NULL },
- { 1, 1, 0, 0, "SGN", "SSG", NULL },
- { 1, 3, 0, 0, "CMP", NULL, NULL },
- { 1, 1, 0, 0, "SCS", "SINCOS", NULL },
- { 1, 2, 1, 0, "TXB", "TEXLDB", NULL },
- { 1, 1, 0, 0, "NRM", NULL, NULL },
- { 1, 2, 0, 0, "DIV", NULL, NULL },
- { 1, 2, 0, 0, "DP2", NULL, NULL },
- { 1, 2, 1, 0, "TXL", NULL, NULL },
- { 0, 0, 0, 0, "BRK", "BREAK", NULL },
- { 0, 1, 0, 1, "IF", NULL, NULL },
- { 0, 0, 0, 0, "LOOP", NULL, NULL },
- { 0, 1, 0, 0, "REP", NULL, NULL },
- { 0, 0, 0, 1, "ELSE", NULL, NULL },
- { 0, 0, 0, 0, "ENDIF", NULL, NULL },
- { 0, 0, 0, 0, "ENDLOOP", NULL, NULL },
- { 0, 0, 0, 0, "ENDREP", NULL, NULL },
- { 0, 1, 0, 0, "PUSHA", NULL, NULL },
- { 1, 0, 0, 0, "POPA", NULL, NULL },
- { 1, 1, 0, 0, "CEIL", NULL, NULL },
- { 1, 1, 0, 0, "I2F", NULL, NULL },
- { 1, 1, 0, 0, "NOT", NULL, NULL },
- { 1, 1, 0, 0, "INT", "TRUNC", NULL },
- { 1, 2, 0, 0, "SHL", NULL, NULL },
- { 1, 2, 0, 0, "SHR", NULL, NULL },
- { 1, 2, 0, 0, "AND", NULL, NULL },
- { 1, 2, 0, 0, "OR", NULL, NULL },
- { 1, 2, 0, 0, "MOD", NULL, NULL },
- { 1, 2, 0, 0, "XOR", NULL, NULL },
- { 1, 3, 0, 0, "SAD", NULL, NULL },
- { 1, 2, 1, 0, "TXF", NULL, NULL },
- { 1, 2, 1, 0, "TXQ", NULL, NULL },
- { 0, 0, 0, 0, "CONT", NULL, NULL },
- { 0, 0, 0, 0, "EMIT", NULL, NULL },
- { 0, 0, 0, 0, "ENDPRIM", NULL, NULL },
- { 0, 0, 0, 1, "BGNLOOP2", NULL, NULL },
- { 0, 0, 0, 0, "BGNSUB", NULL, NULL },
- { 0, 0, 0, 1, "ENDLOOP2", NULL, NULL },
- { 0, 0, 0, 0, "ENDSUB", NULL, NULL },
- { 1, 1, 0, 0, "NOISE1", NULL, NULL },
- { 1, 1, 0, 0, "NOISE2", NULL, NULL },
- { 1, 1, 0, 0, "NOISE3", NULL, NULL },
- { 1, 1, 0, 0, "NOISE4", NULL, NULL },
- { 0, 0, 0, 0, "NOP", NULL, NULL },
- { 1, 2, 0, 0, "M4X3", NULL, NULL },
- { 1, 2, 0, 0, "M3X4", NULL, NULL },
- { 1, 2, 0, 0, "M3X3", NULL, NULL },
- { 1, 2, 0, 0, "M3X2", NULL, NULL },
- { 1, 1, 0, 0, "NRM4", NULL, NULL },
- { 0, 1, 0, 0, "CALLNZ", NULL, NULL },
- { 0, 1, 0, 0, "IFC", NULL, NULL },
- { 0, 1, 0, 0, "BREAKC", NULL, NULL },
- { 0, 1, 0, 0, "KIL", "TEXKILL", NULL },
- { 0, 0, 0, 0, "END", NULL, NULL },
- { 1, 1, 0, 0, "SWZ", NULL, NULL }
+ { 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 },
+ { 0, 0, 0, 0, "", 22 }, /* removed */
+ { 0, 0, 0, 0, "", 23 }, /* removed */
+ { 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 },
+ { 0, 0, 0, 0, "", 32 }, /* removed */
+ { 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 },
+ { 1, 1, 0, 0, "BGNFOR", TGSI_OPCODE_BGNFOR },
+ { 0, 1, 0, 0, "REP", TGSI_OPCODE_REP },
+ { 0, 0, 0, 1, "ELSE", TGSI_OPCODE_ELSE },
+ { 0, 0, 0, 0, "ENDIF", TGSI_OPCODE_ENDIF },
+ { 1, 0, 0, 0, "ENDFOR", TGSI_OPCODE_ENDFOR },
+ { 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, "BGNLOOP", TGSI_OPCODE_BGNLOOP },
+ { 0, 0, 0, 0, "BGNSUB", TGSI_OPCODE_BGNSUB },
+ { 0, 0, 0, 1, "ENDLOOP", TGSI_OPCODE_ENDLOOP },
+ { 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 },
+ { 0, 0, 0, 0, "", 108 }, /* removed */
+ { 0, 0, 0, 0, "", 109 }, /* removed */
+ { 0, 0, 0, 0, "", 110 }, /* removed */
+ { 0, 0, 0, 0, "", 111 }, /* removed */
+ { 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 }
};
const struct tgsi_opcode_info *
tgsi_get_opcode_info( uint opcode )
{
+ static boolean firsttime = 1;
+
+ if (firsttime) {
+ unsigned i;
+ firsttime = 0;
+ for (i = 0; i < Elements(opcode_info); i++)
+ assert(opcode_info[i].opcode == i);
+ }
+
if (opcode < TGSI_OPCODE_LAST)
return &opcode_info[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 077e25acd7f..b2375c69710 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_info.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_info.h
@@ -41,13 +41,16 @@ struct tgsi_opcode_info
boolean is_tex;
boolean is_branch;
const char *mnemonic;
- const char *alt_mnemonic1;
- const char *alt_mnemonic2;
+ uint opcode;
};
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 00000000000..ed594a3e2c7
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_opcode_tmp.h
@@ -0,0 +1,173 @@
+/**************************************************************************
+ *
+ * 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(CND0)
+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.c b/src/gallium/auxiliary/tgsi/tgsi_parse.c
index 7f2cfb7988f..4870f82b6bd 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.c
@@ -42,9 +42,6 @@ void
tgsi_full_token_free(
union tgsi_full_token *full_token )
{
- if( full_token->Token.Type == TGSI_TOKEN_TYPE_IMMEDIATE ) {
- FREE( (void *) full_token->FullImmediate.u.Pointer );
- }
}
unsigned
@@ -156,14 +153,8 @@ tgsi_parse_token(
case TGSI_IMM_FLOAT32:
{
uint imm_count = imm->Immediate.NrTokens - 1;
- struct tgsi_immediate_float32 *data;
-
- data = (struct tgsi_immediate_float32 *) MALLOC(sizeof(struct tgsi_immediate_float32) * imm_count);
- if (data) {
- for (i = 0; i < imm_count; i++) {
- next_token(ctx, &data[i]);
- }
- imm->u.ImmediateFloat32 = data;
+ for (i = 0; i < imm_count; i++) {
+ next_token(ctx, &imm->u[i]);
}
}
break;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_parse.h b/src/gallium/auxiliary/tgsi/tgsi_parse.h
index a289e26e3ac..1035bda1a87 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/tgsi_parse.h
@@ -73,11 +73,7 @@ struct tgsi_full_declaration
struct tgsi_full_immediate
{
struct tgsi_immediate Immediate;
- union
- {
- const void *Pointer;
- const struct tgsi_immediate_float32 *ImmediateFloat32;
- } u;
+ union tgsi_immediate_data u[4];
};
#define TGSI_FULL_MAX_DST_REGISTERS 2
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index 0c64ae57131..2d6ad12ffbd 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;
@@ -1111,10 +1112,10 @@ emit_instruction(struct gen_context *gen,
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 +1318,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");
}
@@ -1333,7 +1336,7 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
for (i = 0; i < size; i++) {
immediates[num_immediates][i] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ parse.FullToken.FullImmediate.u[i].Float;
}
num_immediates++;
}
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sanity.c b/src/gallium/auxiliary/tgsi/tgsi_sanity.c
index 6f1f5c2b4b0..4fe8553c423 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
@@ -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++;
diff --git a/src/gallium/auxiliary/tgsi/tgsi_sse2.c b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
index 4c3343d26c3..cfec5cfc019 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_sse2.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_sse2.c
@@ -36,6 +36,7 @@
#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"
@@ -1467,15 +1468,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;
@@ -2064,8 +2065,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_LERP:
- /* TGSI_OPCODE_LRP */
+ case TGSI_OPCODE_LRP:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
FETCH( func, *inst, 1, 1, chan_index );
@@ -2085,8 +2085,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ 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 */
emit_mul( func, 0, 1 ); /* xmm0 = xmm0 * xmm1 */
@@ -2101,16 +2100,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_INDEX:
- return 0;
- break;
-
- case TGSI_OPCODE_NEGATE:
- return 0;
- break;
-
- case TGSI_OPCODE_FRAC:
- /* TGSI_OPCODE_FRC */
+ case TGSI_OPCODE_FRC:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
emit_frc( func, 0, 0 );
@@ -2122,8 +2112,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_FLOOR:
- /* TGSI_OPCODE_FLR */
+ case TGSI_OPCODE_FLR:
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
FETCH( func, *inst, 0, 0, chan_index );
emit_flr( func, 0, 0 );
@@ -2139,8 +2128,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_EXPBASE2:
- /* TGSI_OPCODE_EX2 */
+ case TGSI_OPCODE_EX2:
FETCH( func, *inst, 0, 0, CHAN_X );
emit_ex2( func, 0, 0 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2148,8 +2136,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_LOGBASE2:
- /* TGSI_OPCODE_LG2 */
+ case TGSI_OPCODE_LG2:
FETCH( func, *inst, 0, 0, CHAN_X );
emit_lg2( func, 0, 0 );
FOR_EACH_DST0_ENABLED_CHANNEL( *inst, chan_index ) {
@@ -2157,8 +2144,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_POWER:
- /* TGSI_OPCODE_POW */
+ case TGSI_OPCODE_POW:
FETCH( func, *inst, 0, 0, CHAN_X );
FETCH( func, *inst, 1, 1, CHAN_X );
emit_pow( func, 0, 0, 0, 1 );
@@ -2167,8 +2153,7 @@ emit_instruction(
}
break;
- case TGSI_OPCODE_CROSSPRODUCT:
- /* TGSI_OPCODE_XPD */
+ case TGSI_OPCODE_XPD:
if( IS_DST0_CHANNEL_ENABLED( *inst, CHAN_X ) ||
IS_DST0_CHANNEL_ENABLED( *inst, CHAN_Y ) ) {
FETCH( func, *inst, 1, 1, CHAN_Z );
@@ -2214,10 +2199,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 );
@@ -2551,7 +2532,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_LOOP:
+ case TGSI_OPCODE_BGNFOR:
return 0;
break;
@@ -2567,7 +2548,7 @@ emit_instruction(
return 0;
break;
- case TGSI_OPCODE_ENDLOOP:
+ case TGSI_OPCODE_ENDFOR:
return 0;
break;
@@ -2937,8 +2918,10 @@ 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");
}
@@ -2953,7 +2936,7 @@ tgsi_emit_sse2(
assert(num_immediates < TGSI_EXEC_NUM_IMMEDIATES);
for( i = 0; i < size; i++ ) {
immediates[num_immediates][i] =
- parse.FullToken.FullImmediate.u.ImmediateFloat32[i].Float;
+ parse.FullToken.FullImmediate.u[i].Float;
}
#if 0
debug_printf("SSE FS immediate[%d] = %f %f %f %f\n",
diff --git a/src/gallium/auxiliary/tgsi/tgsi_text.c b/src/gallium/auxiliary/tgsi/tgsi_text.c
index a76bbc91400..d438450b1e4 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
@@ -789,16 +790,6 @@ match_inst_mnemonic(const char **pcur,
if (str_match_no_case(pcur, info->mnemonic)) {
return TRUE;
}
- if (info->alt_mnemonic1) {
- if (str_match_no_case(pcur, info->alt_mnemonic1)) {
- return TRUE;
- }
- if (info->alt_mnemonic2) {
- if (str_match_no_case(pcur, info->alt_mnemonic2)) {
- return TRUE;
- }
- }
- }
return FALSE;
}
@@ -1091,7 +1082,10 @@ static boolean parse_immediate( struct translate_ctx *ctx )
imm = tgsi_default_full_immediate();
imm.Immediate.NrTokens += 4;
imm.Immediate.DataType = TGSI_IMM_FLOAT32;
- imm.u.Pointer = values;
+ imm.u[0].Float = values[0];
+ imm.u[1].Float = values[1];
+ imm.u[2].Float = values[2];
+ imm.u[3].Float = values[3];
advance = tgsi_build_full_immediate(
&imm,
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ureg.c b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
new file mode 100644
index 00000000000..ba84a82b2b0
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.c
@@ -0,0 +1,797 @@
+/**************************************************************************
+ *
+ * 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_dump.h"
+#include "util/u_memory.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_IMMEDIATE 32
+#define UREG_MAX_TEMP 256
+
+#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;
+ } input[UREG_MAX_INPUT];
+ unsigned nr_inputs;
+
+ 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;
+
+ unsigned temps_active[UREG_MAX_TEMP / 32];
+ unsigned nr_temps;
+
+ unsigned nr_constants;
+ unsigned nr_samplers;
+
+ struct ureg_tokens domain[2];
+};
+
+static union tgsi_any_token error_tokens[32];
+
+static void tokens_error( struct ureg_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.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.Absolute = 0;
+ src.Index = index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+
+static struct ureg_src
+ureg_DECL_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned interp_mode )
+{
+ unsigned i;
+
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ if (ureg->input[i].semantic_name == name &&
+ ureg->input[i].semantic_index == index)
+ goto out;
+ }
+
+ if (ureg->nr_inputs < UREG_MAX_INPUT) {
+ ureg->input[i].semantic_name = name;
+ ureg->input[i].semantic_index = index;
+ ureg->input[i].interp = interp_mode;
+ ureg->nr_inputs++;
+ }
+ else {
+ set_bad( ureg );
+ }
+
+out:
+ return ureg_src_register( TGSI_FILE_INPUT, i );
+}
+
+
+
+struct ureg_src
+ureg_DECL_fs_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index,
+ unsigned interp )
+{
+ return ureg_DECL_input( ureg, name, index, interp );
+}
+
+
+struct ureg_src
+ureg_DECL_vs_input( struct ureg_program *ureg,
+ unsigned name,
+ unsigned index )
+{
+ return ureg_DECL_input( ureg, name, index, TGSI_INTERPOLATE_CONSTANT );
+}
+
+
+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 )
+{
+ return ureg_src_register( TGSI_FILE_TEMPORARY, ureg->nr_constants++ );
+}
+
+
+/* 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.Index < UREG_MAX_TEMP)
+ ureg->temps_active[tmp.Index/32] &= ~(1 << (tmp.Index % 32));
+}
+
+
+/* Allocate a new sampler.
+ */
+struct ureg_src ureg_DECL_sampler( struct ureg_program *ureg )
+{
+ return ureg_src_register( TGSI_FILE_SAMPLER, ureg->nr_samplers++ );
+}
+
+
+
+
+static int match_or_expand_immediate( const float *v,
+ unsigned nr,
+ float *v2,
+ unsigned *nr2,
+ unsigned *swizzle )
+{
+ unsigned i, j;
+
+ 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;
+ 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:
+ 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;
+
+ 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.Indirect = src.Indirect;
+ out[n].src.Index = src.Index;
+ n++;
+
+ if (src.Absolute) {
+ out[n].value = 0;
+ out[n].src_ext_mod.Absolute = 1;
+ n++;
+ }
+
+ if (src.Indirect) {
+ out[n].value = 0;
+ out[n].src.File = TGSI_FILE_ADDRESS;
+ out[n].src.SwizzleX = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleY = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleW = TGSI_SWIZZLE_X;
+ out[n].src.Indirect = 0;
+ out[n].src.Index = 0;
+ 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;
+
+ 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 = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleY = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleZ = TGSI_SWIZZLE_X;
+ out[n].src.SwizzleW = TGSI_SWIZZLE_X;
+ out[n].src.Indirect = 0;
+ out[n].src.Index = 0;
+ n++;
+ }
+
+ assert(n == size);
+}
+
+
+
+unsigned
+ureg_emit_insn(struct ureg_program *ureg,
+ unsigned opcode,
+ boolean saturate,
+ unsigned num_dst,
+ unsigned num_src )
+{
+ union tgsi_any_token *out;
+
+ 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.NrTokens = 0;
+ out[0].insn.NumDstRegs = num_dst;
+ out[0].insn.NumSrcRegs = num_src;
+ out[0].insn.Padding = 0;
+ out[0].insn.Extended = 0;
+
+ 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;
+
+ 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;
+}
+
+
+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 );
+
+ out->insn.NrTokens = ureg->domain[DOMAIN_INSN].count - insn - 1;
+}
+
+
+
+
+
+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;
+
+ for (i = 0; i < ureg->nr_inputs; i++) {
+ emit_decl( ureg,
+ TGSI_FILE_INPUT,
+ i,
+ ureg->input[i].semantic_name,
+ ureg->input[i].semantic_index,
+ ureg->input[i].interp );
+ }
+
+ 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 );
+ }
+
+ if (ureg->nr_samplers) {
+ emit_decl_range( ureg,
+ TGSI_FILE_SAMPLER,
+ 0, ureg->nr_samplers );
+ }
+
+ if (ureg->nr_constants) {
+ emit_decl_range( ureg,
+ TGSI_FILE_CONSTANT,
+ 0, ureg->nr_constants );
+ }
+
+ if (ureg->nr_temps) {
+ emit_decl_range( ureg,
+ TGSI_FILE_TEMPORARY,
+ 0, ureg->nr_temps );
+ }
+
+ 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,
+ unsigned insn )
+{
+ 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;
+}
+
+
+void *ureg_create_shader( struct ureg_program *ureg )
+{
+ struct pipe_shader_state state;
+ unsigned insn;
+
+ emit_header( ureg );
+ emit_decls( ureg );
+ copy_instructions( ureg );
+ fixup_header_size( ureg, insn );
+
+ 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;
+ }
+
+ state.tokens = (const struct tgsi_token *)ureg->domain[DOMAIN_DECL].tokens;
+
+ if (0) {
+ debug_printf("%s: emitted shader %d tokens:\n", __FUNCTION__,
+ ureg->domain[DOMAIN_DECL].count);
+ tgsi_dump( state.tokens, 0 );
+ }
+
+ if (ureg->processor == TGSI_PROCESSOR_VERTEX)
+ return ureg->pipe->create_vs_state( ureg->pipe, &state );
+ else
+ return ureg->pipe->create_fs_state( ureg->pipe, &state );
+}
+
+
+
+
+struct ureg_program *ureg_create( struct pipe_context *pipe,
+ unsigned processor )
+{
+ struct ureg_program *ureg = CALLOC_STRUCT( ureg_program );
+ if (ureg == NULL)
+ return NULL;
+
+ ureg->pipe = pipe;
+ 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 00000000000..0a976fd63b7
--- /dev/null
+++ b/src/gallium/auxiliary/tgsi/tgsi_ureg.h
@@ -0,0 +1,439 @@
+/**************************************************************************
+ *
+ * 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"
+
+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 */
+};
+
+/* 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 */
+};
+
+struct pipe_context;
+
+struct ureg_program *
+ureg_create( struct pipe_context *pipe,
+ unsigned processor );
+
+void *
+ureg_create_shader( struct ureg_program * );
+
+void
+ureg_destroy( struct ureg_program * );
+
+
+/***********************************************************************
+ * Convenience routine:
+ */
+static INLINE void *ureg_create_shader_and_destroy( struct ureg_program *p )
+{
+ void *result = ureg_create_shader( p );
+ 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 semantic_name,
+ unsigned semantic_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 * );
+
+struct ureg_dst
+ureg_DECL_temporary( struct ureg_program * );
+
+void
+ureg_release_temporary( struct ureg_program *ureg,
+ struct ureg_dst tmp );
+
+struct ureg_src
+ureg_DECL_sampler( struct ureg_program * );
+
+
+static INLINE struct ureg_src
+ureg_DECL_immediate4f( 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_DECL_immediate3f( 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_DECL_immediate2f( 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_DECL_immediate1f( struct ureg_program *ureg,
+ float a)
+{
+ float v[1];
+ v[0] = a;
+ return ureg_DECL_immediate( ureg, v, 1 );
+}
+
+/***********************************************************************
+ * 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 )
+{
+ reg.Negate ^= 1;
+ return reg;
+}
+
+static INLINE struct ureg_src
+ureg_abs( struct ureg_src reg )
+{
+ 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));
+
+ 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 )
+{
+ reg.WriteMask &= writemask;
+ return reg;
+}
+
+static INLINE struct ureg_dst
+ureg_saturate( struct ureg_dst reg )
+{
+ reg.Saturate = 1;
+ 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.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.Absolute = 0;
+ src.Index = dst.Index;
+ src.Negate = 0;
+
+ return src;
+}
+
+
+
+#endif
diff --git a/src/gallium/auxiliary/util/u_blit.c b/src/gallium/auxiliary/util/u_blit.c
index 414cf910254..cda6dbd46d7 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"
@@ -155,7 +156,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 +178,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,9 +264,38 @@ 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
@@ -285,10 +318,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 +367,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));
diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c
index a5ca0b72bd7..96d400c839b 100644
--- a/src/gallium/auxiliary/util/u_debug.c
+++ b/src/gallium/auxiliary/util/u_debug.c
@@ -143,11 +143,9 @@ void _debug_vprintf(const char *format, va_list ap)
#elif defined(PIPE_SUBSYSTEM_WINDOWS_MINIPORT)
/* TODO */
#else /* !PIPE_SUBSYSTEM_WINDOWS */
-#ifdef DEBUG
fflush(stdout);
vfprintf(stderr, format, ap);
#endif
-#endif
}
diff --git a/src/gallium/auxiliary/util/u_gen_mipmap.c b/src/gallium/auxiliary/util/u_gen_mipmap.c
index ca797486a0e..edc37561ab1 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"
diff --git a/src/gallium/auxiliary/util/u_math.h b/src/gallium/auxiliary/util/u_math.h
index e5003af01d8..57410e78b02 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)
{
@@ -274,7 +284,6 @@ util_fast_pow(float x, float y)
}
-
/**
* Floor(x), returned as int.
*/
@@ -284,8 +293,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;
@@ -305,9 +314,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,7 +349,7 @@ 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;
@@ -351,7 +360,7 @@ unsigned ffs( unsigned u )
{
unsigned i;
- if( u == 0 ) {
+ if (u == 0) {
return 0;
}
@@ -378,7 +387,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)
{
@@ -409,7 +421,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) )
@@ -422,6 +450,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 0b18d043adb..c3f8c918338 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 151a480d34d..4b75d4ba1d0 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 ce20e487635..6b158aae6e4 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_simple_screen.c b/src/gallium/auxiliary/util/u_simple_screen.c
index 8114b53cd0d..f01296b40fc 100644
--- a/src/gallium/auxiliary/util/u_simple_screen.c
+++ b/src/gallium/auxiliary/util/u_simple_screen.c
@@ -65,12 +65,13 @@ 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);
+ format, usage, tex_usage, stride);
buffer->screen = screen;
diff --git a/src/gallium/auxiliary/util/u_simple_shaders.c b/src/gallium/auxiliary/util/u_simple_shaders.c
index e519c354d25..1152d62e73e 100644
--- a/src/gallium/auxiliary/util/u_simple_shaders.c
+++ b/src/gallium/auxiliary/util/u_simple_shaders.c
@@ -42,9 +42,7 @@
#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 +56,31 @@ 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;
+ struct ureg_program *ureg;
+ uint i;
- /* shader header
- */
- *(struct tgsi_version *) &tokens[0] = tgsi_build_version();
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_VERTEX );
+ if (ureg == NULL)
+ return NULL;
- 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 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);
- }
-
- /* 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);
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ src = ureg_DECL_vs_input( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ dst = ureg_DECL_output( ureg,
+ semantic_names[i],
+ semantic_indexes[i]);
+
+ ureg_MOV( ureg, dst, src );
}
- /* 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;
+ ureg_END( ureg );
- return pipe->create_vs_state(pipe, &shader);
+ return ureg_create_shader_and_destroy( ureg );
}
@@ -158,99 +94,29 @@ util_make_vertex_passthrough_shader(struct pipe_context *pipe,
void *
util_make_fragment_tex_shader(struct pipe_context *pipe)
{
- 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();
-
- processor = (struct tgsi_processor *) &tokens[2];
- *processor = tgsi_build_processor( procType, header );
-
- ti = 3;
-
- /* 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);
-
- /* 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);
-
- /* 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);
+ struct ureg_program *ureg;
+ struct ureg_src sampler;
+ struct ureg_src tex;
+ struct ureg_dst out;
+
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ sampler = ureg_DECL_sampler( ureg );
+
+ tex = ureg_DECL_fs_input( ureg,
+ TGSI_SEMANTIC_GENERIC, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
+
+ out = ureg_DECL_output( ureg,
+ TGSI_SEMANTIC_COLOR,
+ 0 );
+
+ ureg_TEX( ureg, out, TGSI_TEXTURE_2D, tex, sampler );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg );
}
@@ -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 );
-
- /* 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 );
-
- assert(ti < Elements(tokens));
-
-#if 0 /*debug*/
- tgsi_dump(tokens, 0);
-#endif
-
- shader.tokens = tokens;
-
- return pipe->create_fs_state(pipe, &shader);
+ struct ureg_program *ureg;
+ struct ureg_src src;
+ struct ureg_dst dst;
+
+ ureg = ureg_create( pipe, TGSI_PROCESSOR_FRAGMENT );
+ if (ureg == NULL)
+ return NULL;
+
+ src = ureg_DECL_fs_input( ureg, TGSI_SEMANTIC_COLOR, 0,
+ TGSI_INTERPOLATE_PERSPECTIVE );
+
+ dst = ureg_DECL_output( ureg, TGSI_SEMANTIC_COLOR, 0 );
+
+ ureg_MOV( ureg, dst, src );
+ ureg_END( ureg );
+
+ return ureg_create_shader_and_destroy( ureg );
}
diff --git a/src/gallium/auxiliary/util/u_surface.h b/src/gallium/auxiliary/util/u_surface.h
index a5b73cfc20a..ce84ed7ad06 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 a0c8ed88f74..422bc76003a 100644
--- a/src/gallium/auxiliary/util/u_tile.c
+++ b/src/gallium/auxiliary/util/u_tile.c
@@ -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,
diff --git a/src/gallium/auxiliary/util/u_time.c b/src/gallium/auxiliary/util/u_time.c
index 5268cbf79ce..c16cdd0b226 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)
#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)
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)
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)
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)
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)
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 6bca6077a2a..7a5c54d9b23 100644
--- a/src/gallium/auxiliary/util/u_time.h
+++ b/src/gallium/auxiliary/util/u_time.h
@@ -38,7 +38,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)
#include <time.h> /* timeval */
#include <unistd.h> /* usleep */
#endif
@@ -58,7 +58,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)
struct timeval tv;
#else
int64_t counter;
@@ -89,7 +89,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)
#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 77b2a3a1c87..178acdca4df 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/drivers/cell/ppu/cell_gen_fp.c b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
index 5a889a6119d..58a8b5d0b0f 100644
--- a/src/gallium/drivers/cell/ppu/cell_gen_fp.c
+++ b/src/gallium/drivers/cell/ppu/cell_gen_fp.c
@@ -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);
@@ -1875,9 +1875,9 @@ emit_immediate(struct codegen *gen, const struct tgsi_full_immediate *immed)
assert(gen->num_imm < MAX_TEMPS);
for (ch = 0; ch < 4; ch++) {
- float val = immed->u.ImmediateFloat32[ch].Float;
+ float val = immed->u[ch].Float;
- if (ch > 0 && val == immed->u.ImmediateFloat32[ch - 1].Float) {
+ if (ch > 0 && val == immed->u[ch - 1].Float) {
/* re-use previous register */
gen->imm_regs[gen->num_imm][ch] = gen->imm_regs[gen->num_imm][ch - 1];
}
diff --git a/src/gallium/drivers/cell/ppu/cell_texture.c b/src/gallium/drivers/cell/ppu/cell_texture.c
index e26594448f0..6a63a0e6ced 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 e27df2dfb38..6db9501128c 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);
@@ -1158,21 +1154,11 @@ exec_instruction(
ASSERT (0);
break;
- case TGSI_OPCODE_DOT2ADD:
- /* TGSI_OPCODE_DP2A */
+ case 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 +1170,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 +1186,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 +1196,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 +1204,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 +1215,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 +1257,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 +1758,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 +1768,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/i915_batch.h b/src/gallium/drivers/i915simple/i915_batch.h
index a433cf054de..c6e68ea38a2 100644
--- a/src/gallium/drivers/i915simple/i915_batch.h
+++ b/src/gallium/drivers/i915simple/i915_batch.h
@@ -50,8 +50,8 @@ 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);
+ return dwords * 4 <= batch->size - (batch->ptr - batch->map) &&
+ relocs <= (batch->max_relocs - batch->relocs);
}
static INLINE size_t
diff --git a/src/gallium/drivers/i915simple/i915_context.c b/src/gallium/drivers/i915simple/i915_context.c
index ccf9bb31fb0..bf69c8e9f53 100644
--- a/src/gallium/drivers/i915simple/i915_context.c
+++ b/src/gallium/drivers/i915simple/i915_context.c
@@ -142,10 +142,14 @@ i915_is_texture_referenced( struct pipe_context *pipe,
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
@@ -153,10 +157,14 @@ 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
}
diff --git a/src/gallium/drivers/i915simple/i915_fpc_translate.c b/src/gallium/drivers/i915simple/i915_fpc_translate.c
index 961c1bf2134..89504ced276 100644
--- a/src/gallium/drivers/i915simple/i915_fpc_translate.c
+++ b/src/gallium/drivers/i915simple/i915_fpc_translate.c
@@ -975,8 +975,9 @@ i915_translate_instructions(struct i915_fp_compile *p,
= &parse.FullToken.FullImmediate;
const uint pos = p->num_immediates++;
uint j;
+ assert( imm->Immediate.NrTokens <= 4 + 1 );
for (j = 0; j < imm->Immediate.NrTokens - 1; j++) {
- p->immediates[pos][j] = imm->u.ImmediateFloat32[j].Float;
+ p->immediates[pos][j] = imm->u[j].Float;
}
}
break;
diff --git a/src/gallium/drivers/i915simple/i915_screen.c b/src/gallium/drivers/i915simple/i915_screen.c
index f4aa8e60d81..a3de38d5860 100644